Ch 42 Agent 编排:LangGraph 与状态机¶
面包屑
本书主页 › Part VII Data+AI 转型 › Ch 42
项目第 4 年 · Data+AI转型期——Agent编排
本章你将学到¶
- LangGraph StateGraph 机制:State/Node/Edge/Checkpointer/Store(含 State TypedDict 与 StateGraph 骨架伪代码)
- 节点拓扑、路由决策与状态模型设计(含 9 节点 + 7 条件路由装配伪代码)
- 修复回路与 SQL 缓存快路径(含自愈节点、缓存命中伪代码)+ HITL 审批流程
- ReAct / Plan-and-Execute / Reflexion 三理论的统一
42.1 LangGraph StateGraph 机制¶
LangGraph 是 LangChain 出品的 Agent 编排框架,核心抽象是 StateGraph(状态图)——把 Agent 流程建模为"状态驱动的有向图"。说实话,刚开始接触的时候我觉得这概念挺平淡的——就是节点和边嘛,有什么新鲜的。但真正上手用之后才意识到,它真正厉害的地方不在"图"本身,而在把 LLM 的不可预测性装进了一个可审计、可断点恢复的状态容器里。
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
subgraph StateGraph机制["LangGraph StateGraph 核心概念"]
S[State<br/>全局状态对象<br/>~50 个字段]
N[Node<br/>处理节点<br/>每个节点读/写 State]
E[Edge<br/>边:节点间转移<br/>含条件路由]
C@{ icon: "codicon:refresh", form: "rounded", label: Checkpointer<br/>检查点<br/>可回滚/恢复, pos: "b", h: 36 }
ST@{ icon: "codicon:database", form: "rounded", label: Store<br/>持久存储<br/>跨会话记忆, pos: "b", h: 36 }
end
class S,N,E,C,ST bpProcess
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
linkStyle default stroke:#697077,stroke-width:2px
图 42-1 LangGraph StateGraph 机制
| 概念 | 作用 | 在 NewtonData 中的体现 |
|---|---|---|
| State | 全局状态,在节点间传递 | ~50 字段(问题/意图/检索结果/SQL/错误/重试次数...) |
| Node | 处理单元,读写 State | 20+ 节点(Supervisor/QU/Router/RAG/Planner/Generator/Guardrail...) |
| Edge | 节点转移,含条件路由 | 7 条路由(正常/重试/缓存命中/护栏失败...) |
| Checkpointer | 状态检查点 | 可恢复中断的会话 |
| Store | 跨会话持久存储 | 记忆系统(见 Ch 45) |
表 42-1 LangGraph StateGraph 机制
引申
LangGraph 与 CDP 平台的 Step Functions 是同一个思想——"状态机编排"。区别在于:Step Functions 编排 AWS 服务(Glue/Lambda),LangGraph 编排 LLM 调用和 Python 逻辑。两者的核心都是"把复杂流程建模为状态图+条件路由",只是执行域不同。
落到代码层面,State 是一个 TypedDict(节点共用的全局状态),节点是读写 State 的函数,图通过 add_node/add_edge/add_conditional_edges 装配:
# 示意:LangGraph State 定义 + StateGraph 骨架
from typing import TypedDict, Annotated
from langgraph.graph import StateGraph, END
class AgentState(TypedDict):
# 核心意图:所有节点共享的全局状态(~50 字段的精简版)
question: str # 原始问题
intent: str # QU 识别的意图
entities: list # 识别的实体/术语
retrieved: list # R/V/G/D 检索结果
sql: str # 生成的 SQL
error: str # 失败原因(供自愈)
retry: int # 自愈重试次数
result: list # 执行结果
viz: dict # 可视化建议
graph = StateGraph(AgentState)
# 节点装配见 42.2
LangGraph 还提供了两个高级控制流原语——Command 和 interrupt——它们在 NewtonData 的 HITL 和动态路由中发挥作用:
# 示意:Command 动态跳转 + interrupt 暂停与恢复
from langgraph.types import Command, interrupt
def guard_node(state: AgentState) -> Command:
# 核心意图①:Command 让节点内部决定跳转目标(比条件边更灵活)
if state.get("guard_passed"):
return Command(update={}, goto="exec") # 通过→执行
if state["retry"] >= 2:
return Command(update={}, goto=END) # 重试上限→结束
return Command(update={"retry": state["retry"] + 1}, goto="heal")
def high_risk_node(state: AgentState) -> dict:
# 核心意图②:interrupt 暂停执行,等待人工审批后恢复(HITL 基础)
approval = interrupt({"sql": state["sql"], "risk": "high"})
# approval 由外部 Command(resume=...) 提供
return {"approved": approval["approved"]}
Command(goto=...) 让节点内部根据状态动态决定跳转目标——比 add_conditional_edges 更灵活,跳转逻辑封装在节点内部而非声明在图编译时。interrupt() 在指定节点暂停执行,等待外部输入(如人工审批)后用 Command(resume=...) 恢复——这是 HITL(Human-in-the-Loop)的基础机制。实际开发和调试中,这两个原语的存在感比想象中高得多,因为真实的用户查询流程很少是纯线性的。
42.2 节点拓扑、路由决策与状态模型设计¶
节点拓扑¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TD
ENTRY[入口] --> SUP[Supervisor<br/>嵌入+治理叠加]
SUP --> QU[Query Understanding<br/>意图/实体识别]
QU --> ROUTER{Router<br/>7 路由}
ROUTER -->|标准查询|RAG@{ icon: "codicon:search", form: "rounded", label: "R/V/G/D 检索", pos: "b", h: 36 }
ROUTER -->|缓存命中|CACHE[SQL Cache 快路径]
ROUTER -->|元数据查询|META[直接回答]
RAG --> RERANK[重排+术语绑定]
RERANK --> PLAN[语义规划器]
PLAN --> GEN@{ icon: "codicon:sparkle", form: "rounded", label: "SQL 生成", pos: "b", h: 36 }
GEN --> GUARD{五层护栏}
GUARD -->|通过|EXEC@{ icon: "logos:aws-redshift", form: "rounded", label: "执行", pos: "b", h: 36 }
GUARD -->|失败|HEAL@{ icon: "codicon:refresh", form: "rounded", label: "自愈回路<br/>corrective_retrieval", pos: "b", h: 36 }
HEAL -->|重试 < 2|RAG
HEAL -->|重试 ≥ 2|FAIL[返回错误]
CACHE --> EXEC
EXEC --> VIZ[可视化+洞察]
VIZ --> EXIT[返回用户]
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
class ENTRY,SUP,QU,RERANK,PLAN,GEN,CACHE,EXEC,VIZ,EXIT bpProcess
class RAG bpProcess
class ROUTER,GUARD bpDecision
class HEAL bpInfo
class META bpData
class FAIL bpError
linkStyle default stroke:#697077,stroke-width:2px
linkStyle 8,9 stroke:#8a3ffc,stroke-width:2px,stroke-dasharray:5
图 42-2 节点拓扑
7 条路由¶
Router 根据 Query Understanding 的输出,用 _INTENT_TO_ROUTE 映射表(非 ML)决定路径。7 条路由覆盖从 KPI 直查到深度分析的全场景:
| 路由 | 触发意图 | 执行路径 | 设计理由 |
|---|---|---|---|
| 标准查询 | KPI 直查 / 趋势对比排名 | RAG→重排→规划→生成→护栏→执行→可视化 | 主路径,覆盖 80% 查询 |
| 缓存命中 | 语义相似度 ≥ 0.92 | 跳过检索+规划+生成,直接护栏→执行 | 用空间换时间 |
| 元数据查询 | "有哪些表"类问题 | 直接回答,不走 SQL 流水线 | 不需要查数据 |
| 深度分析 | 根因分析 / 报告 | + planner 节点 + 三级评估器 | Plan-and-Execute 范式 |
| 图推理 | 关系探索 | graph_rag_agent(NL2Cypher),失败回退 SQL | 图遍历优于 SQL |
| 知识问答 | 政策 / SOP 问答 | 检索→knowledge_qa_agent | 非数据查询 |
| 澄清请求 | 模糊意图 | 检索→follow_up_agent 追问 | 避免在模糊意图上硬生成 |
表 42-2 7 条路由:意图→路径映射
条件路由函数¶
条件边是编排的"控制流大脑"。每个条件函数根据当前状态决定下一个节点:
| 函数 | 位置 | 可能返回值 | 决策依据 |
|---|---|---|---|
_route_after_router |
Router 后 | 7 路由分支 | QU 的 intent_type 映射 |
_route_after_retrieval |
检索后 | rerank / knowledge_qa / no_context / clarify | 检索结果质量 |
_route_after_validation |
护栏后 | execute / corrective_repair / reject | 校验失败类型 |
_route_after_execution |
执行后 | proceed / repair / fail | 执行结果 / 超时 |
_route_after_result |
解释后 | visualize / evaluate / insight / done | 路由计划 |
_route_after_graph_rag |
图推理后 | done / fallback_sql | Cypher 是否成功 |
表 42-3 条件路由函数
上面的拓扑和路由对应到 LangGraph 代码,就是 9 个节点注册到图,再用 add_conditional_edges 声明 Router 和 Guard 的分支逻辑:
# 示意:9 节点 + 7 条件路由的 LangGraph 装配
def router_branch(state: AgentState) -> str: # Router 的 7 路由决策
if state.get("cache_hit"): return "cache" # 语义相似度 ≥0.92 → 快路径
if state["intent"] == "meta": return "meta" # "有哪些表"类 → 直接回答
return "rag" # 标准查询
def guard_branch(state: AgentState) -> str: # Guard 的护栏分支
if state.get("guard_passed"): return "exec"
if state["retry"] >= 2: return END # 自愈达上限 → 结束
return "heal" # 护栏失败 → 自愈
graph.add_node("supervisor", supervisor_node)
graph.add_node("qu", query_understanding_node)
graph.add_node("rag", rag_node) # R/V/G/D 检索
graph.add_node("plan", planner_node) # Steiner 树规划(见 Ch 43)
graph.add_node("gen", generate_sql_node)
graph.add_node("guard", guardrail_node) # 五层护栏(见 Ch 44)
graph.add_node("exec", execute_node)
graph.add_node("viz", visualize_node)
graph.add_node("heal", heal_node)
graph.set_entry_point("supervisor")
graph.add_edge("supervisor", "qu")
graph.add_conditional_edges("qu", router_branch, {"rag": "rag", "cache": "exec", "meta": "viz"})
graph.add_edge("rag", "plan"); graph.add_edge("plan", "gen"); graph.add_edge("gen", "guard")
graph.add_conditional_edges("guard", guard_branch, {"exec": "exec", "heal": "heal", END: END})
graph.add_edge("heal", "rag") # 核心意图:自愈回路回到检索重新生成
graph.add_edge("exec", "viz"); graph.add_edge("viz", END)
app = graph.compile(checkpointer=MemorySaver()) # 检查点支持会话恢复
42.3 修复回路与 SQL 缓存快路径¶
修复回路(自愈)¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TD
GEN[SQL 生成] --> GUARD[护栏校验]
GUARD -->|失败|ANALYZE[分析失败原因<br/>语法错误/列不存在/成本过高]
ANALYZE --> CORRECT[Corrective Retrieval<br/>补充检索修正]
CORRECT --> REGEN[重新生成 SQL]
REGEN --> GUARD
GUARD -->|重试 ≥ 2|FAIL[返回错误+建议]
class GEN,ANALYZE,CORRECT,REGEN bpProcess
class GUARD bpDecision
class FAIL bpError
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
linkStyle default stroke:#697077,stroke-width:2px
图 42-3 修复回路(自愈)
自愈回路对应到代码上,关键是拿护栏返回的失败原因构造"纠错反馈",重新检索正确资产后再生成,retry 计数兜底防止无限循环:
# 示意:自愈回路节点(corrective retrieval)
def heal_node(state: AgentState) -> dict:
# 核心意图:用失败原因构造纠错反馈,重新检索后重生成
feedback = f"上次生成的 SQL 失败:{state['error']}。请修正后重新生成。"
corrected = rag_corrective(state["question"], state["error"]) # 补充检索正确列名/表名
return {"retrieved": corrected, "retry": state["retry"] + 1,
"error": ""} # 清空 error,下一轮 gen 节点带纠错上下文重生成
| 自愈场景 | 修正方式 |
|---|---|
| SQL 语法错误 | 语法解析反馈→重新生成 |
| 列不存在 | R 引擎重新检索正确列名→重新生成 |
| 成本过高 | 规划器调整 join 策略→重新生成 |
| 术语不一致 | 术语绑定重新校准→重新生成 |
表 42-4 自愈场景与修正方式
SQL 缓存快路径¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
Q[用户问题] --> EMBED[问题嵌入]
EMBED --> SIM{与缓存相似度}
SIM -->|≥ 0.92|HIT[缓存命中<br/>直接返回缓存的 SQL]
SIM -->|< 0.92|MISS[缓存未命中<br/>走完整流程]
class Q,EMBED bpProcess
class SIM bpDecision
class HIT bpSuccess
class MISS bpData
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
linkStyle default stroke:#697077,stroke-width:2px
图 42-4 SQL 缓存快路径
# 示意:SQL 语义缓存快路径
def check_cache(question: str, threshold=0.92) -> str | None:
# 核心意图:embedding 相似度 ≥ 阈值直接返回缓存 SQL,跳过检索+规划+生成
q_emb = embed(question)
hit = vector_store.search(q_emb, top_k=1)
if hit and hit.score >= threshold:
return hit.sql # 直接复用历史 SQL(可能需参数微调)
return None
Trade-off
SQL 缓存快路径大幅降低延迟(跳过检索+规划+生成),但缓存命中率取决于问题分布。对于高频重复问题(如"昨天 GMV"),命中率很高;对于新颖问题,命中率低。相似度阈值 0.92 是精确性 vs 命中率的平衡——太高命中率低,太低可能返回错误 SQL。
HITL 审批流程¶
Agent 自动执行所有操作是不现实的。涉及 DDL(建表/删表)、大批量 DELETE、跨租户数据导出这类高风险操作,人工审批(Human-in-the-Loop, HITL)是必要的。LangGraph 支持节点中断(interrupt),Supervisor 检测到高风险操作时暂停流程,推送审批到协作工具,通过后继续:
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart LR
SUP[Supervisor 检测操作] --> RISK{风险等级?}
RISK -->|低风险|AUTO[自动执行]
RISK -->|高风险|PAUSE[暂停流程<br/>生成变更影响评估]
PAUSE --> APPROVE[推送审批<br/>Slack/Teams]
APPROVE -->|业务负责人 approve|RESUME[继续执行]
APPROVE -->|reject / 超时|CANCEL[取消操作<br/>记录审计]
class SUP,PAUSE,APPROVE bpProcess
class RISK bpDecision
class AUTO,RESUME bpSuccess
class CANCEL bpError
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
linkStyle default stroke:#697077,stroke-width:2px
图 42-5 HITL 审批流程
| 风险等级 | 操作类型 | 处理方式 |
|---|---|---|
| 低 | SELECT 查询、LIMIT 限制的结果集 | 自动执行 |
| 中 | 大结果集导出、跨域聚合 | 自动执行 + 审计记录 |
| 高 | DDL、大批量 DELETE/UPDATE、跨租户导出 | HITL 审批 |
表 42-5 HITL 审批流程
引申
HITL 是"受控自治"的最后一道阀门——Agent 可以自治处理低风险操作提升效率,但高风险操作必须有人类把关。这与医药行业 GxP 的"可归属"原则一致:高风险变更必须可追溯到审批人。HITL 把"AI 的效率"和"合规的可控"结合在一起,是企业级 Agentic BI 区别于个人 AI 助手的关键。
42.4 模型分配与 Fallback 链¶
不同节点对 LLM 的要求差异很大——Query Understanding 要快但不需要太强推理,SQL 生成要最强的推理但可以接受延迟,洞察分析要的是长文本生成能力。ModelRegistry 统一管理 task→model 映射,支持 Admin 在线覆盖和 Fallback 链降级:
# 示意:模型分配 + Fallback 链 + Circuit Breaker
class ModelRegistry:
"""统一模型管理——task→model 映射,Admin 可在线覆盖,失败自动降级。"""
_task_models = {
"query_understanding": ["deepseek-v4-flash"], # 快:意图识别不需要最强模型
"sql_generation": ["deepseek-v4-pro", "qwen3.7-max"], # 强:SQL 生成要最强推理
"insight": ["qwen3.7-max"], # 长文本生成
}
_failure_counts = {} # 模型失败计数,用于 Circuit Breaker
def get_model(self, task: str):
chain = self._task_models.get(task, ["deepseek-v4-flash"])
for model in chain:
if self._circuit_open(model): # Circuit Breaker:连续 3 次失败暂停 60s
continue
return model
raise ModelUnavailableError(f"任务 {task} 的所有模型均不可用")
def _circuit_open(self, model: str) -> bool:
# 核心意图:连续 3 次失败暂停模型 60s,避免故障扩散
return self._failure_counts.get(model, 0) >= 3 and not self._cooldown_expired(model)
| 机制 | 说明 | 价值 |
|---|---|---|
| task→model 映射 | 不同任务分配不同模型(快/强/长文本) | 成本与质量平衡——简单任务用便宜模型 |
| Admin 在线覆盖 | Admin 可在数据库中修改模型配置 | 不重启切换模型,运维灵活 |
| Fallback 链 | 主模型失败自动切备选模型 | 不绑定单一 LLM,可用性有保障 |
| Circuit Breaker | 连续 3 次失败暂停模型 60s | 避免故障扩散,快速失败而非排队等待 |
Graph RAG 降级¶
graph_reasoning 路由的 graph_rag_agent 用 NL2Cypher 查 Apache AGE 图。Cypher 生成失败(语法错误、查询不存在的节点)时,自动回退到 SQL 流水线——这是我们刻意保留的降级策略,任何子路径失败都有 fallback,不阻塞用户:
# 示意:Graph RAG 降级到 SQL 流水线
def _route_after_graph_rag(state: AgentState) -> str:
if state.get("graph_rag_success"):
return "done" # Cypher 成功→直接返回图结果
return "fallback_sql" # 失败→回退到 SQL 流水线
42.5 引申:ReAct / Plan-and-Execute / Reflexion 三理论的统一¶
%%{init: {'theme':'base','themeVariables':{'primaryColor':'#edf5ff','primaryTextColor':'#161616','primaryBorderColor':'#0f62fe','lineColor':'#697077','secondaryColor':'#d9fbfb','tertiaryColor':'#f2f4f8','fontSize':'14px'}}}%%
flowchart TB
subgraph 三理论["三种 Agent 理论"]
REACT@{ icon: "codicon:sparkle", form: "rounded", label: ReAct<br/>Reasoning+Acting<br/>思考→行动→观察循环, pos: "b", h: 36 }
PE@{ icon: "codicon:graph", form: "rounded", label: Plan-and-Execute<br/>先规划再执行<br/>分步完成, pos: "b", h: 36 }
REF@{ icon: "codicon:error", form: "rounded", label: Reflexion<br/>自我反思<br/>失败后总结经验, pos: "b", h: 36 }
end
subgraph NewtonData统一["NewtonData 的统一"]
T1@{ icon: "codicon:search", form: "rounded", label: 确定性 DAG = Plan-and-Execute<br/>先规划查询路径再执行, pos: "b", h: 36 }
T2@{ icon: "codicon:refresh", form: "rounded", label: 自愈回路 = Reflexion<br/>失败后分析原因并修正, pos: "b", h: 36 }
T3@{ icon: "codicon:sparkle", form: "rounded", label: 条件路由 = 受控 ReAct<br/>根据结果决定下一步<br/>但路径预定义, pos: "b", h: 36 }
end
REACT -.-> T3
PE -.-> T1
REF -.-> T2
class REACT,PE,REF bpInfo
class T1,T2,T3 bpData
classDef bpProcess fill:#edf5ff,stroke:#0f62fe,stroke-width:2px,color:#161616
classDef bpData fill:#d9fbfb,stroke:#007d79,stroke-width:2px,color:#161616
classDef bpDecision fill:#fcf4d6,stroke:#f1c21b,stroke-width:2px,color:#161616
classDef bpSuccess fill:#defbe6,stroke:#198038,stroke-width:2px,color:#161616
classDef bpError fill:#fff1f1,stroke:#da1e28,stroke-width:2px,color:#161616
classDef bpExternal fill:#f2f4f8,stroke:#697077,stroke-width:2px,color:#161616
classDef bpInfo fill:#f6f2ff,stroke:#8a3ffc,stroke-width:2px,color:#161616
classDef bpGroup fill:#ffffff,stroke:#0f62fe,stroke-width:2px,color:#161616
linkStyle default stroke:#697077,stroke-width:2px
图 42-6 引申:ReAct / Plan-and-Execute / Re...
| 理论 | 核心思想 | 在 NewtonData 中的体现 |
|---|---|---|
| ReAct | 思考→行动→观察循环 | 条件路由(受控版) |
| Plan-and-Execute | 先规划再执行 | 确定性 DAG + 语义规划器 |
| Reflexion | 失败后自我反思 | 自愈回路(corrective retrieval) |
表 42-6 引申:ReAct / Plan-and-Execute / Reflexion 三理论的统一
引申:三理论引用与受控自治
NewtonData 不是简单套用某一种理论,而是"取三者之长"——Plan-and-Execute 的"先规划"保证流程有序,Reflexion 的"自我修正"保证容错性,ReAct 的"根据结果决策"保证灵活性。但与纯 ReAct 不同,NewtonData 的"决策"是预定义的条件路由而非 LLM 自主决策——这是企业级可靠性需要的"受控自治"。
三理论的原始论文:ReAct(arxiv.org/abs/2210.03629)——LLM 交替推理与行动;Plan-and-Execute(arxiv.org/abs/2305.04091)——先规划全局再分步执行;Reflexion(arxiv.org/abs/2303.11366)——失败后自我反思修正。NewtonData 的取舍是用确定性图保证安全可审计(不同于纯 ReAct 的不可预测),用节点内的 LLM 保证局部智能,用 Plan-and-Execute 处理复杂分析,用 Reflexion 做质量兜底。
当前实现可改进之处¶
Trade-off:编排架构的已知局限
- Supervisor 角色过轻:Supervisor 仅在入口出现一次,无法在检索失败、SQL 生成困难等关键决策点介入。架构改进方向:在关键节点后增加状态评估点,由监督逻辑动态调整路径,而非仅做一次入口分发。
- 路由设计缺乏自学习:路由是静态的意图→路径映射,无法从历史查询中自动发现新模式。架构改进方向:增加路由效果反馈环,基于失败率与覆盖率自动提示扩展路由类别。
- 全局状态耦合度高:单一状态对象承载所有环节的中间结果,字段间隐含依赖难以追踪,是"上帝对象"反模式。架构改进方向:按职责分组为子状态域(输入/检索/生成/控制),显式声明依赖关系。
- HITL 覆盖面不足:人机协同中断点仅覆盖可视化环节,SQL 执行前缺高危查询确认。架构改进方向:对高成本/高风险查询增加执行前 HITL 中断点,呼应纵深安全设计。
本章小结¶
- LangGraph StateGraph:State(TypedDict,~50 字段全局状态)+ Node(20+ 节点)+ Edge(7 条路由)+ Checkpointer + Store;Command(goto) 动态跳转 + interrupt/Command(resume) HITL 暂停恢复
- 节点拓扑:Supervisor→QU→Router→RAG→Plan→Gen→Guard→Exec→Viz,9 节点 + 7 条件路由用 add_conditional_edges 装配;7 路由覆盖 KPI 直查→深度分析全场景,6 个条件路由函数控制流
- 自愈回路:护栏失败→分析原因→corrective retrieval→重新生成,最多 2 次——Reflexion 思想(含 heal_node 伪代码);Graph RAG 失败优雅降级到 SQL 流水线
- SQL 缓存快路径:相似度 ≥ 0.92 直接返回缓存 SQL,跳过检索+规划+生成
- HITL 审批流程:高风险操作(DDL/大批量 DELETE/跨租户导出)Supervisor 暂停→推送审批→通过继续/拒绝取消,兼顾 AI 效率与合规可控
- 模型分配与 Fallback 链:ModelRegistry 统一管理 task→model 映射(快/强/长文本),Admin 在线覆盖,主模型失败自动降级,Circuit Breaker 连续 3 次失败暂停 60s
- 三理论统一:Plan-and-Execute(先规划,arxiv.org/abs/2305.04091)+ Reflexion(自愈,arxiv.org/abs/2303.11366)+ 受控 ReAct(条件路由,arxiv.org/abs/2210.03629)——"受控自治"
- 已知不足:Supervisor 过轻、路由静态缺自学习、状态字段过多(上帝对象)、缺 SQL 执行前 HITL 中断点
下一章
Ch 43 语义查询规划器:Steiner 树与代数改写 —— Agent 编排清楚了,接下来看查询规划器如何用 Steiner 树解决 join 路径问题。