docs: 明确标注 React 模式在 LangGraph 工作流中的位置
Some checks failed
构建并部署 AI Agent 服务 / deploy (push) Failing after 6m17s

This commit is contained in:
2026-04-26 12:23:09 +08:00
parent bdfa3fae45
commit b78aa63739

137
README.md
View File

@@ -44,7 +44,7 @@
-**模块化设计**:清晰的代码分层,易于扩展和维护
-**模型服务层**:统一的 Embedding、Rerank、Chat 服务接口,支持自动降级
-**子图系统**:模块化的子图架构,共享公共工具(意图理解、人工审核、格式化输出)
-**React 模式**:循环推理 + 超时重试 + 结构化错误处理
-**React 模式**Reasoning → Acting → Observing 循环LLM 先思考再行动,支持多次工具调用
---
@@ -135,26 +135,56 @@ graph TB
```mermaid
stateDiagram-v2
[*] --> RetrieveMemory: 用户输入消息
RetrieveMemory --> MemoryTrigger: 检索历史记忆
MemoryTrigger --> CheckMemory: 检查是否需要触发记忆
CheckMemory --> LLMCall: 记忆充足
CheckMemory --> Summarize: 需要生成摘要
Summarize --> PostgreSQL: 保存摘要
PostgreSQL --> LLMCall: 继续对话
MemoryTrigger --> LLMCall: 检查记忆触发条件
%% ⭐ React (Reasoning → Acting → Observing) 循环开始
LLMCall --> CheckTools: LLM 输出
CheckTools --> ToolNode: 需要调用工具
CheckTools --> Finalize: 直接回复
CheckTools --> CheckSummary: 直接回复
ToolNode --> ExecuteTool: 执行工具
ExecuteTool --> LLMCall: 工具结果返回
ExecuteTool --> LLMCall: 工具结果返回Observing → Reasoning 循环)
%% ⭐ React 循环结束
CheckSummary --> Summarize: 达到摘要阈值
CheckSummary --> Finalize: 未达阈值,直接结束
Summarize --> PostgreSQL: 保存摘要
PostgreSQL --> Finalize: 继续对话
Finalize --> FormatResponse: 格式化响应
FormatResponse --> [*]: SSE 流式输出
note right of LLMCall
⭐ Reasoning
LLM 思考:
- 需要调用工具吗?
- 调用什么工具?
end note
note right of ToolNode
⭐ Acting
执行工具:
- 天气查询
- 文件读取
- RAG 检索
- 等等
end note
note right of ExecuteTool
⭐ Observing
观察工具结果,
返回给 LLM 再次思考
end note
note right of LLMCall
⭐ React 循环
Reasoning → Acting → Observing → Reasoning...
可以多次循环
end note
```
### 数据流向图
@@ -514,7 +544,58 @@ def reciprocal_rank_fusion(doc_lists: List[List[Document]], k: int = 60) -> List
### 2. LangGraph 工作流算法
#### 2.1 状态机设计
#### 2.1 React (Reasoning → Acting → Observing) 模式 ⭐
**设计理念**:让 LLM 先思考Reasoning再行动Acting然后观察结果Observing可以多次循环。
```
┌─────────────────────────────────────────────────────────────────┐
│ React 模式循环 │
├─────────────────────────────────────────────────────────────────┤
│ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 1. Reasoning (思考) │ │
│ │ LLMCall 节点 │ │
│ │ - 分析用户问题 │ │
│ │ - 决定是否需要调用工具 │ │
│ │ - 决定调用哪个工具 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 2. Acting (行动) │ │
│ │ ToolNode 节点 │ │
│ │ - 执行工具调用 │ │
│ │ - 天气查询 / 文件读取 / RAG 检索等 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 3. Observing (观察) │ │
│ │ ExecuteTool → LLMCall │ │
│ │ - 观察工具结果 │ │
│ │ - 返回给 LLM 再次思考 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ ↓ │
│ ┌───────────────────────────────────────────────────────────┐ │
│ │ 4. 循环或结束 │ │
│ │ should_continue 路由 │ │
│ │ - 还需要调用工具吗? → 继续循环 │ │
│ │ - 不需要了 → 结束流程 │ │
│ └───────────────────────────────────────────────────────────┘ │
│ │
└─────────────────────────────────────────────────────────────────┘
```
**关键实现点**
1. **`llm.bind_tools(tools)`** - 在 `create_llm_call_node` 中,让 LLM 知道可以调用哪些工具
2. **`should_continue` 路由函数** - 检查 LLM 输出是否包含 `tool_calls`
3. **`tool_node → llm_call` 循环边** - 工具结果返回给 LLM 再次思考
4. **可以多次循环** - LLM 可以调用多个工具,或者同一个工具多次
**实际代码位置**
- `backend/app/graph/graph_builder.py` 第 79 行:`builder.add_edge("tool_node", "llm_call")`
- `backend/app/nodes/router.py``should_continue` 函数检查 `last_message.tool_calls`
#### 2.2 状态机设计
```python
# 核心状态定义
@@ -527,22 +608,22 @@ class AgentState(TypedDict):
final_response: str # 最终响应
```
**状态流转规则**
**状态流转规则**
```
初始状态 → retrieve_memory → memory_trigger → [条件分支]
┌───────────────────┼───────────────────
↓ ↓
should_summarize 直接回复 需要工具
↓ ↓
summarize → save finalize tool_node
↓ ↓
llm_call ←───────────────┘ llm_call
finalize
┌───────────────────┼───────────────┐
↓ ↓ ↓
should_summarize 直接回复 需要工具
↓ ↓ ↓
summarize → save finalize tool_node
↓ ↓ ↓
llm_call ←───────────────┘ llm_call ←┘
finalize
```
#### 2.2 记忆管理算法
#### 2.3 记忆管理算法
**记忆检索策略:**
```