---
type: study
created: 2026-08-11
updated: 2026-08-11
sensitivity: private
status: active
tags:
  - study
  - langchain
  - langgraph
  - typescript
  - workflow-patterns
  - rag
  - sql
topic: LangGraph TypeScript 工作流、Agentic RAG 与 SQL Agent 模式
sources:
  - https://docs.langchain.com/oss/javascript/langgraph/workflows-agents
  - https://docs.langchain.com/oss/javascript/langgraph/agentic-rag
  - https://docs.langchain.com/oss/javascript/langgraph/sql-agent
last_verified: 2026-08-11
---
# TypeScript 工作流、Agentic RAG 与 SQL Agent 模式

## Workflow 与 Agent

- Workflow：代码预先规定路径和顺序，强调可预测、可测试、可审计。
- Agent：模型动态决定工具与下一步，适合问题和解法无法事先完全确定的场景。

生产系统通常是混合体：外层工作流控制权限、预算、审批、数据库写入和终止条件；局部 agent 在受限工具集内规划。

LangGraph 为两者提供 persistence、streaming、HITL、debug、deployment 与 State/reducer，但不会自动提供业务安全边界。

## 六种通用编排模式

### Prompt chaining

每个模型调用处理上一步输出。适合可拆解、每步可验证的任务，例如翻译后校验、生成后事实检查。

关键设计：

- 每步使用结构化输入输出；
- 在昂贵下游前设置质量 gate；
- 保存原始输入和每步结果，而非只保存最终文本；
- 上游失败不要继续放大。

Graph API 用顺序 edge 和 conditional edge；Functional API 用顺序 task 与 if。

### Parallelization

多个独立子任务并行，或同一任务用不同视角重复执行再汇总。TypeScript Functional API 以 Promise.all 表达；Graph API 用同一节点的多个 outgoing edge。

风险：

- provider 并发和 rate limit；
- reducer 合并顺序；
- 多个 branch 写同一 key；
- 部分成功后的重放；
- 成本随分支数量线性增加。

### Routing

先分类，再进入专用节点。分类通常用结构化输出约束为有限 enum；conditional router 把 enum 映射到节点名。

路由器不能决定它无权决定的资源 ID、租户或写权限。低置信度应进入澄清/保守路径，而不是随机选一个高权限工具。

### Orchestrator-worker

orchestrator 动态拆分未知数量子任务，worker 并行处理，最后综合。

Graph API 使用 Send 为每个 worker 传专有 State，并用 ReducedValue 聚合结果；Functional API 可先让 task 规划，再 Promise.all 调用 worker task。

必须设置：

- 最大 worker 数与递归深度；
- 任务去重与稳定 ID；
- provider 并发 semaphore；
- 单 worker timeout/retry；
- 聚合 token/内存上限；
- 失败 worker 的 partial-result 策略。

### Evaluator-optimizer

generator 生成，evaluator 给结构化 grade/feedback，不合格则带反馈重做。适合存在明确成功标准但需迭代的任务。

必须有业务终止条件：最大轮次、成本、时间、连续无改进次数。GRAPH_RECURSION_LIMIT 只是最后安全网。

evaluator 与 generator 使用同一模型会产生相关偏差；高风险任务应加入规则校验、不同模型或人工复核。

### ReAct agent

模型 -> tool calls -> ToolNode -> ToolMessage -> 模型，直到模型不再调用工具。

ToolNode 负责并行工具执行、常见错误与 State/context 注入。工具只能读取传给 ToolNode 的完整 State；若手工只传 messages，自定义字段不会自动可见。

TypeScript 工具的第二参数可按 ToolRuntime 类型读取 graph State 与 run context，这是与 Python 注入参数写法不同的地方。

## Graph 与 Functional 的模式对应

| 模式 | Graph API | Functional API |
|---|---|---|
| chain | static/conditional edge | 顺序 await + if |
| parallel | 多 edge + reducer | Promise.all |
| routing | ConditionalEdgeRouter | switch/if |
| dynamic worker | Send + ReducedValue | 动态 task 数组 + Promise.all |
| optimize loop | cycle + terminal router | while + task |
| ReAct | model node + ToolNode cycle | while + model/tool task |

选择 Graph API 时优先显式 State 和可视化；选择 Functional 时所有非确定性与副作用必须进入 task，保证 replay。

## Agentic RAG 的完整回路

官方自定义 RAG agent 不是固定“检索后回答”，而是让模型先决定是否需要检索：

1. 载入与预处理文档；
2. 分块、embedding、写入 vector store；
3. 用 retriever 创建工具；
4. 模型直接回答或生成 retriever tool call；
5. ToolNode 执行检索；
6. grader 判断文档是否相关；
7. 相关则基于上下文生成答案；
8. 不相关则 rewrite question，再回到模型/检索路径。

### State 与节点

示例使用消息型 State。核心节点/路由：

- generateQueryOrRespond；
- retrieve；
- gradeDocuments；
- rewriteQuestion；
- generateAnswer；
- toolsCondition 或自定义 conditional edge。

grader 用 Zod 结构化输出给 yes/no；文档还提供结构化解析失败时的普通文本 fallback。fallback 应被 trace 和监控，不能静默视为同等可靠。

### 检索质量

预处理要明确：

- source provenance 与更新时间；
- chunk size/overlap；
- embedding model 与维度；
- metadata filter 和租户 ACL；
- top-k、阈值、去重与 rerank；
- 索引重建和删除策略。

示例 vector store 与网页 loader 只说明流程，不构成生产数据管线。生产索引要有增量更新、失败重试、版本和可追溯 source ID。

### Prompt injection 边界

官方 grader prompt 明确要求把 retrieved docs 当数据并忽略其中指令。这是必要提示，但不能单独防御提示注入。

还应：

- 把检索内容放在明确数据边界；
- 过滤/标注不可信来源；
- 工具权限与模型文本分离；
- 禁止文档内容修改 system policy；
- 对引用的 source ID 做服务端校验；
- 最终写操作仍需代码权限与人工审批。

### 循环控制

rewrite -> retrieve -> grade 可能无限循环。State 应记录 attempts、查询历史、命中文档 ID 和质量分；达到阈值后返回“不足以回答”或转人工，而不是持续花费 token。

### 答案与引用

最终 answer 应只基于允许的 context，并输出可验证的 source ID。不要让模型随意生成 URL；引用映射由服务端从检索结果构造。

## SQL Agent 的受控图

模型生成 SQL 天生高风险。官方示例比通用 ReAct 更可控，将关键工具调用拆成专用节点：

1. list tables；
2. get schema；
3. generate query；
4. check query；
5. execute query；
6. 根据结果回答或继续；
7. 可在 execute 前 interrupt 人工审核。

显式图可以强制“先看表、再看 schema、检查后才执行”，而不是只在 system prompt 中请求模型遵守。

## 数据库安全基线

官方强警告：示例数据库工具是最小演示封装，不可直接用于生产。最低要求：

- 使用只读数据库账号；
- 仅授权允许的 schema/table/view；
- 默认拒绝 INSERT、UPDATE、DELETE、DDL、PRAGMA/扩展调用；
- 设置 statement timeout、row limit、scan/cost limit；
- 禁止多 statement；
- 参数化应用提供的值；
- SQL AST/parser 校验，而不是只查字符串关键字；
- 在只读副本或隔离 analytics warehouse 执行；
- 每次执行记录 user、thread、query hash、审批和行数；
- 返回模型前做列级脱敏和结果大小限制。

最小权限只能降低风险，不能消除模型驱动 SQL 风险。

## SQL 工具与消息协议

每个 AI tool call 必须有同 tool_call_id 的 ToolMessage。专用节点可强制调用指定工具，但仍需维护消息完整性。

query checker 是防线之一，不是数据库防火墙。它也由模型驱动，可能漏判；最终执行 adapter 必须执行确定性 allowlist 和资源限制。

数据库 error 可作为 ToolMessage 反馈模型修正，但：

- 不返回连接串、完整 stack 或数据库内部路径；
- 对语法错误限制重试次数；
- 对权限错误不重试；
- 对 timeout/大扫描先收紧 query，而不是盲目提高限制。

## SQL HITL

执行前 interrupt payload 可包含：

- SQL 文本；
- 参数；
- 目标只读数据源；
- 预计影响/查询范围；
- 风险理由；
- approve/edit/reject 选项。

恢复时：

- approve：执行已审核 query；
- edit：用审核人修改的 args 更新 tool call，再执行；
- reject/feedback：返回模型重新生成或结束。

必须使用 checkpointer 与稳定 thread_id。审批接口还需用户身份、角色权限、一次性 interrupt ID 和重复提交防护。仅依靠 thread_id 不构成授权。

interrupt node 恢复时从开头执行，因此审批前不能已经执行真实 SQL 写操作。即使只读查询，昂贵预检也应幂等并有缓存/限制。

## TypeScript 实现边界

- 使用 Zod/Standard Schema 给 router、grader 和工具输入做运行时校验；interface/type 只在编译期存在。
- Functional API 是 task/entrypoint 函数工厂，不是 Python decorator。
- 并行 worker/tool 使用 Promise；需要显式 semaphore 控制 provider/数据库并发。
- async generator 工具可以通过 tools stream mode 报告进度。
- browser 只显示流式 State、引用和审批；数据库 driver、vector store、模型 key 留在 Node/服务端。
- 文档示例中的模型名、loader、SQLite、内存 vector store 与 API 版本会变化，必须替换成项目锁定版本并端到端编译。

## 何时不用自定义 LangGraph agent

不要因为能画图就自行重写全部基础能力：

- 标准工具调用 agent：优先 LangChain createAgent；
- 标准 SQL 问答：先评估高层 SQL agent，并在外层加确定性安全 adapter；
- 普通固定 RAG：检索链可能比 agentic loop 更可控、更便宜；
- 没有恢复/HITL/复杂路由需求：普通函数或队列 job 足够。

自定义 LangGraph 的收益应来自显式控制、恢复、并发或审计，而不是增加节点数量。

## 模式验收清单

- 每个循环有业务终止、时间和成本上限。
- 每个并行分支有并发上限、timeout 和 reducer。
- router/grade 使用有限结构化 schema，并有失败路径。
- RAG 记录 source provenance、ACL、索引版本和引用映射。
- retrieved text 视为不可信数据，不能授予工具权限。
- SQL 使用只读隔离账号、AST allowlist、row/time/cost limit。
- 高风险 SQL 在执行前 HITL，审批绑定用户、thread 与 interrupt ID。
- ToolMessage 与 tool_call_id 完整配对。
- 外部副作用幂等，checkpoint/replay 不会重复真实动作。
- Node、SDK、provider、数据库和浏览器均做真实集成测试。
