纸上余温 - 聊天系统流程图详解

2026年04月23日0 次阅读0 人喜欢
聊天系统ReAct AgentRAG向量检索流程图

聊天系统流程图详解

本文档详细描述了"纸上余温"聊天功能的完整流程,包括前后端交互、大模型调用、向量检索等各个环节。

系统架构概述

聊天系统采用 ReAct Agent 驱动的 RAG 架构,通过多轮思考循环实现智能问答:

  • 前端:使用 Ant Design X 组件实现流式展示
  • 后端:使用 ReAct Agent 实现思考-行动-观察循环
  • 向量检索:使用 Qdrant 实现语义搜索
  • 大模型:使用 OpenAI 兼容接口(通过 LangChain)

完整流程图

sequenceDiagram autonumber participant User as 用户 participant Frontend as 聊天页面<br/>(page.tsx) participant API as 聊天 API<br/>(route.ts) participant Agent as ReAct Agent<br/>(agent.ts) participant LLM as 大模型 participant Tools as 工具注册表 participant Embedding as 嵌入服务 participant Qdrant as Qdrant 向量库 participant Parser as 标签解析器<br/>(stream-tags) %% 用户输入 User->>Frontend: 输入问题 Frontend->>Frontend: 创建用户消息 Frontend->>Frontend: 创建 AI 消息占位符 Frontend->>API: POST /api/chat<br/>{message, history} %% API 初始化 API->>API: 验证参数 API->>API: 获取用户信息 API->>API: 构建系统提示词 API->>Agent: chatRAGAgentStream(params) %% Agent 初始化 Agent->>Agent: 生成 think 标签<br/>"正在初始化 RAG Agent..." Agent->>Agent: 构建 ReAct 系统提示词<br/>(包含工具说明、检索策略) Agent->>Agent: 创建 OpenAI 模型实例 Agent->>Agent: 初始化 ReAct Agent Agent->>Agent: 生成 think 标签<br/>"开始思考和检索..." %% ReAct 循环开始 loop ReAct 循环 (最多5轮) %% Thought 阶段 Agent->>LLM: 发送用户问题<br/>+ 系统提示词<br/>+ 历史对话 Agent->>Agent: 生成 startStep 标签<br/>type="thought" %% LLM 流式输出思考过程 loop 流式输出 LLM-->>Agent: 文本块 (chunk) Agent->>Agent: 累积文本 Agent-->>Frontend: 流式发送文本 end %% 解析工具调用 Agent->>Agent: 检测到 JSON-RPC 工具调用 Agent->>Agent: 生成 endStep 标签 %% Action 阶段 Agent->>Agent: 解析工具名称和参数 Agent->>Agent: 生成 step 标签<br/>type="action" %% 工具执行 alt search_articles (语义搜索) Agent->>Tools: 获取 search_articles 工具 Tools->>Embedding: embedText(query) Embedding-->>Tools: 返回查询向量 Tools->>Qdrant: searchSimilarVectors(vector) Qdrant-->>Tools: 返回相似向量结果 Tools->>Tools: 按文章分组结果 Tools-->>Agent: 返回搜索结果 else search_posts_meta (元数据搜索) Agent->>Tools: 获取 search_posts_meta 工具 Tools->>Tools: 查询数据库 Tools-->>Agent: 返回元数据结果 else search_collection (合集搜索) Agent->>Tools: 获取 search_collection 工具 Tools->>Tools: 指定合集搜索 Tools-->>Agent: 返回合集结果 end %% Observation 阶段 Agent->>Agent: 生成 step 标签<br/>type="observation" Agent->>Agent: 将工具结果添加到消息历史 Agent->>Agent: 添加提示词<br/>"基于以上结果给出答案" %% 判断是否继续循环 alt 有工具调用 Agent->>Agent: 继续下一轮迭代 else 无工具调用 Agent->>Agent: 生成 startContent 标签 Agent->>Agent: 清理响应文本 Agent->>Agent: 生成最终答案 Agent->>Agent: 生成 endContent 标签 Agent->>Agent: 退出循环 end end %% 完成 Agent->>Agent: 发送 done 事件 Agent-->>API: 返回流式响应 API-->>Frontend: SSE 流式响应 %% 前端解析和展示 Frontend->>Parser: 创建 StreamTagParser loop 接收流式数据 Frontend->>Parser: parseChunk(chunk) Parser->>Parser: 解析标签 alt <think content="..."/> Parser-->>Frontend: onThink 回调 Frontend->>Frontend: 更新 thoughts 状态 else <step type="thought"> Parser-->>Frontend: onStep 回调<br/>type="thought" Frontend->>Frontend: 流式更新思考内容 else <step type="action"> Parser-->>Frontend: onStep 回调<br/>type="action" Frontend->>Frontend: 更新搜索步骤 else <step type="observation"> Parser-->>Frontend: onStep 回调<br/>type="observation" Frontend->>Frontend: 更新结果展示 else <content>...</content> Parser-->>Frontend: onContent 回调 Frontend->>Frontend: 流式更新答案 end end Parser-->>Frontend: onComplete 回调 Frontend->>Frontend: 设置 loading=false Frontend->>Frontend: 自动滚动到底部

数据流详解

1. 请求阶段

flowchart TD A[用户输入问题] --> B[前端创建消息对象] B --> C[构建历史对话] C --> D[发送 POST 请求] D --> E[/API 路由/] E --> F{验证参数} F -->|失败| G[返回错误] F -->|成功| H[获取用户信息] H --> I[构建系统提示词]

2. ReAct Agent 循环

flowchart TD A[ReAct Agent 开始] --> B[发送提示词到 LLM] B --> C[流式接收响应] C --> D{检测工具调用?} D -->|是| E[解析工具名称和参数] D -->|否| J[生成最终答案] E --> F{选择工具} F --> G[执行工具] G --> H[获取工具结果] H --> I[将结果添加到上下文] I --> B J --> K[生成 content 标签] K --> L[发送完成事件] L --> M[结束]

3. 向量检索流程

flowchart TD A[search_articles 工具] --> B[获取查询文本] B --> C[调用 embedText] C --> D[发送到嵌入 API] D --> E[生成查询向量] E --> F[调用 Qdrant 搜索] F --> G[添加 hide='0' 过滤] G --> H[执行向量相似度搜索] H --> I[返回搜索结果] I --> J[按文章分组] J --> K[获取文章详情] K --> L[返回结构化结果]

4. 前端展示流程

flowchart TD A[接收流式响应] --> B[创建 StreamTagParser] B --> C[循环读取数据块] C --> D[解析标签] D --> E{标签类型?} E -->|think| F[更新 thoughts 状态] E -->|step thought| G[流式更新思考内容] E -->|step action| H[更新搜索步骤] E -->|step observation| I[更新结果展示] E -->|content| J[流式更新答案] F --> K[重新渲染消息] G --> K H --> K I --> K J --> K K --> L{还有数据?} L -->|是| C L -->|否| M[设置 loading=false] M --> N[自动滚动到底部]

标签协议

流式响应使用自定义 XML 标签格式:

flowchart TD A[流式响应协议] --> B["<think content='...'/>"] A --> C["<step type='thought' index='N'>...</step>"] A --> D["<step type='action' index='N'>...</step>"] A --> E["<step type='observation' index='N'>...</step>"] A --> F["<content>...</content>"] B --> G[状态提示] C --> H[思考过程] D --> I[工具调用] E --> J[工具结果] F --> K[最终答案]

标签说明

标签 类型 说明 是否流式
<think content="..."/> 自闭合 状态提示(初始化、检索信息等)
<step type="thought"> 成对 ReAct 思考步骤
<step type="action"> 成对 工具调用信息
<step type="observation"> 成对 工具执行结果
<content> 成对 最终答案

关键组件

前端组件

  • page.tsx: 聊天页面主组件
  • Bubble.List: 消息列表展示
  • Sender: 输入框组件
  • Think: 状态提示组件
  • Collapse: 可折叠的 ReAct 循环展示
  • XMarkdown: Markdown 渲染

后端服务

  • route.ts: API 路由处理
  • agent.ts: ReAct Agent 实现
  • react-agent.ts: ReAct 循环逻辑
  • stream-tags.ts: 标签生成和解析
  • stream.ts: 流式响应处理

AI 工具

  • search-articles: 语义搜索工具
  • search-posts-meta: 元数据搜索工具
  • search-collection: 合集搜索工具

外部服务

  • OpenAI API: 大模型调用
  • Qdrant: 向量数据库
  • SiliconFlow: 嵌入模型 API

状态管理

前端消息状态

typescript 复制代码
interface ChatMessage {
  id: string;
  role: "user" | "assistant";
  content: string;          // 最终答案
  thoughts: string[];       // 状态提示
  reactLoops: ReactLoop[];  // ReAct 循环
  loading?: boolean;        // 加载状态
  expanded?: boolean;       // 展开状态
}

interface ReactLoop {
  index: number;
  steps: ReactStep[];
}

interface ReactStep {
  type: StepType;           // thought | action | observation
  content: string;
  isStreaming?: boolean;
}

后端事件类型

typescript 复制代码
type SSEEventType =
  | 'thought'        // 思考过程(流式)
  | 'action'         // 工具调用
  | 'observation'    // 工具结果
  | 'answer'         // 最终答案
  | 'error'          // 错误信息
  | 'done';          // 完成标记

性能优化

  1. 流式传输: 所有响应都采用流式传输,提升用户体验
  2. 向量检索缓存: 相同查询可复用向量结果
  3. 批量操作: 向量插入采用批量操作(每批100条)
  4. 重试机制: 向量搜索失败自动重试(最多2次)
  5. 降级处理: 向量搜索超时返回友好提示

错误处理

  1. 前端错误: 显示错误消息,允许用户重新输入
  2. API 错误: 返回结构化错误响应
  3. Agent 错误: 捕获并发送错误事件
  4. 向量检索错误: 自动重试,超时返回提示
  5. LLM 错误: 清理上下文,返回友好提示

安全考虑

  1. 权限验证: API 层验证用户登录状态
  2. 内容过滤: 默认只搜索 hide='0' 的公开文章
  3. 输入验证: 验证所有输入参数
  4. XSS 防护: Markdown 渲染自动转义
  5. CSRF 防护: 使用 token 验证
加载评论中...