From b78aa63739bf69f2fb4a7665645d1c764b0356e1 Mon Sep 17 00:00:00 2001 From: root <953994191@qq.com> Date: Sun, 26 Apr 2026 12:23:09 +0800 Subject: [PATCH] =?UTF-8?q?docs:=20=E6=98=8E=E7=A1=AE=E6=A0=87=E6=B3=A8=20?= =?UTF-8?q?React=20=E6=A8=A1=E5=BC=8F=E5=9C=A8=20LangGraph=20=E5=B7=A5?= =?UTF-8?q?=E4=BD=9C=E6=B5=81=E4=B8=AD=E7=9A=84=E4=BD=8D=E7=BD=AE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- README.md | 137 +++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 109 insertions(+), 28 deletions(-) diff --git a/README.md b/README.md index ee7de8c..238e8a3 100644 --- a/README.md +++ b/README.md @@ -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 记忆管理算法 **记忆检索策略:** ```