纸上余温 - 聊天系统流程图详解
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'; // 完成标记
性能优化
- 流式传输: 所有响应都采用流式传输,提升用户体验
- 向量检索缓存: 相同查询可复用向量结果
- 批量操作: 向量插入采用批量操作(每批100条)
- 重试机制: 向量搜索失败自动重试(最多2次)
- 降级处理: 向量搜索超时返回友好提示
错误处理
- 前端错误: 显示错误消息,允许用户重新输入
- API 错误: 返回结构化错误响应
- Agent 错误: 捕获并发送错误事件
- 向量检索错误: 自动重试,超时返回提示
- LLM 错误: 清理上下文,返回友好提示
安全考虑
- 权限验证: API 层验证用户登录状态
- 内容过滤: 默认只搜索 hide='0' 的公开文章
- 输入验证: 验证所有输入参数
- XSS 防护: Markdown 渲染自动转义
- CSRF 防护: 使用 token 验证