跳到主要内容

23-高阶组合Recipes

核对日期:2026-05-18
官方资料:Middleware https://docs.langchain.com/oss/javascript/langchain/middleware/overview;Context engineering https://docs.langchain.com/oss/javascript/langchain/context-engineering;Guardrails https://docs.langchain.com/oss/javascript/langchain/guardrails;HITL https://docs.langchain.com/oss/javascript/langchain/human-in-the-loop;MCP https://docs.langchain.com/oss/javascript/langchain/mcp;LangSmith https://docs.langchain.com/langsmith/observability-quickstart

官方概念

LangChain 的高级能力不是孤立 API,而是组合模式。生产系统通常同时使用 Agent、Tools、Middleware、Runtime context、Structured output、Memory、Retrieval、Guardrails、HITL、Streaming 和 LangSmith。难点不是“会不会调用”,而是“这些组件如何组合且不互相污染边界”。

机制

Recipe 1:按任务复杂度动态选择模型

适用场景:大多数请求很简单,但少数请求需要更强模型或更长上下文。

实现步骤:

  1. 在 runtime context 中传入用户等级、成本预算、任务类型。
  2. middleware 读取 messages 和 context。
  3. 简单任务走低成本模型,复杂任务走高能力模型。
  4. trace 记录模型选择原因。
  5. eval 分模型统计质量和成本。

TypeScript 伪代码:

const modelRouter = createMiddleware({
name: "ModelRouter",
wrapModelCall: (request, handler) => {
const complexity = estimateComplexity(request.messages);
const model = complexity > 0.7 ? advancedModel : cheapModel;
return handler({ ...request, model });
},
});

验收:

  • 同一 eval dataset 分别统计 cheap/advanced 命中率。
  • 复杂任务确实进入 advanced。
  • 成本预算超限时降级或拒绝。

Recipe 2:按权限动态暴露工具

适用场景:不同角色能使用不同工具,或同一用户在不同租户权限不同。

实现步骤:

  1. 认证服务先生成 runtime context。
  2. middleware 根据 roles/tenant/filter 过滤工具。
  3. 工具执行层再次校验权限。
  4. 记录“哪些工具暴露给模型”。

不要只过滤 UI。模型拿到的 tools 列表才是实际暴露面。

验收:

用例预期
viewer 请求删除数据不暴露 delete 工具
operator 请求更新工单暴露 update 工具且执行层二次鉴权
admin 跨租户请求检索和工具都拒绝

Recipe 3:RAG + Structured Output + Citation

适用场景:知识库问答、政策解释、报告生成。

组合方式:

query -> ACL -> retrieval -> rerank -> prompt context -> structured answer -> citation validation

必须做的二次校验:

  • 每条 citation 是否来自 retrieved docs。
  • answer 中是否引用了无权限文档。
  • refused=false 时 citations 是否非空。
  • conflict 是否被暴露。

结构化 schema:

const answerSchema = z.object({
answer: z.string(),
citations: z.array(citationSchema),
refused: z.boolean(),
refusalReason: z.enum(["NO_EVIDENCE", "NO_PERMISSION", "INJECTION_RISK"]).optional(),
conflicts: z.array(z.string()),
});

Recipe 4:长对话摘要 + 长期记忆

适用场景:学习助手、客服、项目协作 Agent。

组合方式:

组件职责
short-term memory保存当前 thread 的消息和状态
summarize middleware对过长历史做摘要
long-term store保存稳定用户偏好和事实
context builder本轮只注入相关记忆
guardrail防止隐私自动写入

失败模式:

  • 摘要把事实写错。
  • 长期记忆写入未经确认的推断。
  • 所有记忆每轮都注入,造成上下文污染。

验收:

  • 用户要求删除偏好后不再注入。
  • 敏感内容不会进入 store。
  • 摘要前后的关键任务约束一致。

Recipe 5:高风险工具 + HITL + Checkpointer

适用场景:发邮件、付款、删除、外发报告、生产变更。

实现步骤:

  1. 工具 metadata 标记 risk。
  2. HITL middleware 对高风险工具 interrupt。
  3. checkpointer 保存 thread state。
  4. 审批 UI 提供 approve/edit/reject/respond。
  5. 审批结果绑定 tool input hash。
  6. 恢复执行并写 audit。

审批记录:

interface ApprovalRecord {
approvalId: string;
threadId: string;
toolName: string;
toolInputHash: string;
decision: "approve" | "edit" | "reject" | "respond";
approverId: string;
decidedAt: string;
}

Recipe 6:MCP 工具接入 + 最小权限

适用场景:需要连接文件系统、浏览器、数据库、内部工具或第三方服务。

治理原则:

  • MCP server 不等于可信工具。
  • 每个 server 做能力白名单。
  • tools/resources/prompts 分别授权。
  • MCP tool output 视为不可信输入。
  • 对外部 MCP server 做超时、限流和审计。

验收:

检查通过标准
工具清单只有任务需要的工具
资源权限无法读取非授权路径
输出净化外部工具返回不会覆盖 system prompt
trace记录 server、tool、latency、error

Recipe 7:Streaming + 工具进度 + 前端协议

适用场景:长任务、Agent 多步执行、RAG 报告生成。

事件协议建议:

type AgentStreamEvent =
| { type: "token"; text: string }
| { type: "tool_start"; toolName: string }
| { type: "tool_progress"; toolName: string; message: string }
| { type: "tool_end"; toolName: string; ok: boolean }
| { type: "interrupt"; threadId: string; actions: unknown[] }
| { type: "error"; message: string; recoverable: boolean }
| { type: "done"; runId: string };

前端不应该只消费 token。Agent 应用需要展示工具状态、审批中断、错误和最终 run id。

Recipe 8:LangSmith Trace + Eval 闭环

适用场景:任何准备上线的 Agent。

闭环:

  1. trace 记录 messages、model、tools、retrieved docs、structured output。
  2. 从失败 trace 沉淀 dataset。
  3. eval 覆盖工具、RAG、结构化输出、安全、成本。
  4. CI 中跑关键 eval。
  5. 线上监控 drift 和失败样本。

指标:

维度指标
Tool正确工具调用率、缺参率、工具失败率
RAGrecall、citation validity、拒答正确率
Outputschema pass rate、parse retry count
Safetyprompt injection pass rate、PII leak rate
Opslatency、tokens、cost、timeout、retry

Python 差异

Python 组合方式类似,但 middleware、HITL、store、MCP 和 provider 包 API 名称不同。Recipes 的验收标准不应随语言改变;变的是代码实现。

工程边界

  • Recipe 是组合,不是单个函数;每个边界都要有测试。
  • Middleware 顺序改变会改变行为,要记录和评审。
  • HITL 和 streaming 都需要协议,不只是 SDK 调用。
  • LangSmith 能记录和评估,但不能替代你的断言设计。

常见反模式

反模式后果
动态模型无 trace成本和质量无法归因
动态工具只靠前端隐藏模型仍可能调用后端工具
RAG citation 由模型编造审计失败
HITL 不持久化中断后无法恢复
streaming 事件无版本前端升级困难

练习任务

  1. LangChain/src/middleware/pipeline.ts 旁写一份 middleware 顺序说明。
  2. LangChain/src/api/streaming.ts 中对照本章事件协议,标注缺口。
  3. LangChain/scripts/run-eval.ts 增加一个按能力分类统计的输出表。