跳到正文

生产化与选型 ​

一句话:Agent 上线后的问题,八成不是“模型不够聪明”,而是循环失控、上下文爆炸、外部依赖不稳定、权限过大和成本不可见。

适用版本:LangChain v1.x、LangGraph 1.x。部署与观测能力迭代很快,具体产品名与配额以官方文档为准。

为什么需要 ​

Demo 和生产之间隔着五件事:

  1. 可观测:一次请求经过几个节点、调了几次模型、每次多少 token、哪个工具慢。
  2. 可评测:改 prompt、换模型、加工具之后,效果是变好还是变坏。
  3. 可恢复:进程重启、模型超时、工具失败之后,任务能继续而不是重来。
  4. 可控:轮数、并发、成本、权限都有上限。
  5. 可运维:多副本、灰度、回滚、数据隔离。

LangChain/LangGraph 提供了钩子和运行时,但这些能力要自己接上。

核心机制 ​

追踪:先看见,再优化 ​

bash
export LANGSMITH_TRACING=true
export LANGSMITH_API_KEY="..."
export LANGSMITH_PROJECT="prod-agent"

一次 trace 至少要能看到每个节点的耗时、每次模型调用的 in/out token 与费用、每次工具调用的结果;没有这层,线上只能看到“慢”和“贵”,定位不到具体节点。不用 LangSmith 也可以接 OpenTelemetry,但必须让模型调用和工具调用成为独立的 span。

评测:固定数据集 + 回归 ​

层评什么方法
检索该召回的文档有没有进候选Recall@k、MRR、nDCG
单步工具选得对不对、参数对不对标注集 + 规则校验
轨迹步骤是否合理、有没有绕路与参考轨迹对比,或 LLM 评审
最终答案是否正确、是否有引用人工标注 + LLM-as-judge
安全是否越权、是否泄露红队用例

每次改动只跑一遍全量,成本高;日常用小子集做冒烟,发版前跑全量。

部署形态 ​

方式说明适合
自建服务FastAPI/Flask + Postgres checkpointer + 自己的队列已有基础设施、需要深度定制
LangSmith Agent Server托管运行时,自动处理持久化、伸缩、流式想快速上线、接受平台绑定

自建时最容易漏的是:checkpointer 必须外部化。多副本共享同一个 Postgres,才能让任意实例恢复任意 thread。

可靠性模式 ​

  • 超时:模型调用、工具调用、整次 run 三层都要有。
  • 重试:只重试 429/超时/5xx,指数退避 + 抖动;业务错误不重试。
  • 降级与熔断:主模型失败切备用,备用也失败返回可解释错误;某个工具连续失败就暂时摘除,避免拖垮整个 Agent。
  • 幂等:写操作带幂等键,恢复重跑不会重复扣款/发消息。
  • 死信:多次失败的 run 落库人工处理,不要无限重试。

安全边界 ​

风险措施
提示注入(文档/网页/工具输出)工具输出当不可信输入;system prompt 只作约束,不作防线
工具越权最小权限、按用户身份鉴权、危险操作二次确认
代码执行放沙箱,限制网络、文件系统、执行时间
数据泄露多租户 namespace/thread 隔离;日志脱敏
密钥放密钥管理服务,不放进 state、prompt、trace
成本攻击按用户限流、设 token/轮数上限、异常用量告警

一次生产请求的完整链路(框架件怎么各就各位) ​

一条请求自上而下经过哪些框架件、失败时沿哪条虚线返回,是这张图要回答的。

先认三条纵线:入口层只做鉴权、限流与归属校验,中间是装配链,右侧是观测与死信;四条外部依赖的差别只在故障策略,不在调用方式。虚线是全图唯一的失败回程,任何一环超时都要带终止原因回到入口,不能挂住请求。

实战场景 ​

演练一:上线前把四种故障各打一遍(比任何评测集都早暴露问题) ​

演练操作预期表现典型暴露的缺陷
杀进程run 进行中 kill -9 副本另一副本按 thread_id 续跑,不重复扣款副作用没幂等;InMemorySaver 混进了预发
断模型网关对主模型注入 5xxfallback 接管;备用也挂则返回可解释错误无备用直接 500;重试风暴打垮备用
断工具让检索工具持续超时熔断摘除,Agent 降级为"资料暂不可用"无限重试烧光预算;错误堆栈进 prompt
成本攻击单用户脚本刷长对话按用户限流 + token 上限自动降级只限 QPS 不限 token;无租户归因

四项对应开头五件事里的四件(可恢复、可控、可运维、成本可见);演练要定期重跑——每次改 middleware、换模型、动 checkpointer 配置后至少跑前三项。

演练二:单请求成本估算的实际做法 ​

上线评审里"成本可控"要有数,不是形容词。方法:取最近 200 条真实会话,按 每 run 模型调用数 × 平均输入 token × 单价 ×(1+缓存命中折扣) + 工具外呼费 算分布,报 P50 / P95 / 最坏值三个数。经验上 P95 和最坏值的差距来自循环失控(重试叠加、并行扇出聚合),所以最坏值必须用 run_limit 封顶后的分布算,不用自然分布——这也回答了"上限设多少":让封顶后的最坏成本仍是业务可接受值。

场景:什么时候从 LangGraph 迁到 Temporal(选型的边界真的会发生) ​

信号:业务要"审批三小时无响应自动升级给上级,并给申请人发催办"——框架的挂起没有超时和定时器,业务侧要自己搭调度器。这时两条路:

  1. LangGraph 保留编排、外部加调度:挂起 thread 表由业务维护 due_at,定时任务扫表发 Command(resume=...) 或关单——审批量小、逻辑简单时这是正解,别引入第二个引擎;
  2. Temporal 做外层、图做内层:跨系统长事务(扣款、发货、退款多步补偿)交给 Temporal 的事件历史与补偿,模型决策段仍跑在一张 LangGraph 图里作为 activity。分工原则:事务语义归 Temporal,认知流程归 LangGraph,谁承担什么就在谁的持久化模型里。

最小上手 ​

一个可恢复的最小服务:

python
from fastapi import FastAPI
from langchain.agents import create_agent
from langgraph.checkpoint.postgres import PostgresSaver

app = FastAPI()
with PostgresSaver.from_conn_string("postgresql://postgres:postgres@db:5432/agents") as cp:
    cp.setup()
    agent = create_agent(model="openai:<model-id>", tools=[search_kb],
                         system_prompt="你是客服助手。", checkpointer=cp)
@app.post("/chat")
def chat(body: dict):
    cfg = {"configurable": {"thread_id": body["thread_id"]}}
    out = agent.invoke({"messages": [{"role": "user", "content": body["text"]}]}, cfg)
    return {"reply": out["messages"][-1].content}

生产还要补:鉴权、限流、超时、追踪、错误映射、健康检查。

生产动作 ​

  • 按 thread 限流与计量:记录每个用户的模型调用次数、token、工具次数,异常时自动降级。
  • 成本分层与预算前置:分类、摘要、改写用便宜小模型,最终生成用强模型,成本通常能降一个量级;上下文用摘要 + 裁剪 + 检索条数上限,别等模型报超长才处理。
  • 发版带评测:prompt、模型、工具、检索参数任一变更都要跑回归;用 feature flag 灰度。
  • 保留完整 trace 一段时间:至少覆盖一个排障周期;trace 里不要存敏感原文。
  • 定期清理 checkpoint 与 store:长会话和长期记忆都会无限增长。
  • 演练恢复:主动杀进程、断模型、断工具,验证 thread_id 能续跑、审批能恢复。

选型 ​

下表是 2026-08 快照,只覆盖 Java/Python 生态的主流选择(部分框架另有 TS/Go 实现),不是全部框架清单。

方案定位与短板语言栈持久化 / 中断可观测 / 多租户核对
直接调厂商 SDK无框架,自己写循环;短板是每家胶水重写各家 SDK自己实现自己接2026-08
LangChainReAct-first 装配层,底层编译成 LangGraph;短板是抽象泄漏、版本变化快Python / JS通过 checkpointer;HumanInTheLoopLangSmith / OTel;按 thread 隔离2026-08
LangGraph图运行时,持久化是一等能力;短板是要自己设计 statePython / JScheckpointer 内置;interrupt()LangSmith / OTel;按 thread/namespace 隔离2026-08
LlamaIndex检索与索引优先;短板是 Agent 编排相对弱Python / TS索引/文档存储,无执行 checkpoint集成多;namespace2026-08
Claude Agent SDKClaude 生态的 Agent 运行时;短板是绑定 ClaudePython / TS会话管理OTel 等;租户自建2026-08
OpenAI Agents SDKOpenAI 生态,handoff/guardrail 清晰;短板是主要面向 OpenAIPython / JSsession(SQLite/Redis 等);工具审批内置 tracing;租户自建2026-08
Temporal持久化执行引擎;短板是不提供模型与工具抽象Go / Java / Python / TS事件历史一等能力;人工信号/超时自带 UI/metrics;namespace2026-08

不用“生产就绪度:中/高”这种没有判据的标签。如果必须给结论:LangGraph 为高——v1 把持久化与中断做成一等能力;LangChain 是 ReAct-first 装配层,不单独承担运行时职责。判据就是表里的持久化、中断、可观测、多租户四列,而不是印象分。

把上面的选型表压成一条判定路径:先问要不要框架,再依次收窄到具体方案。

先问“要不要框架”,单轮单厂商能直接调 SDK 就不要引入抽象;标准 ReAct 用 LangChain 省胶水,但它的底层仍是 LangGraph,拓扑变复杂时是迁移而不是重写;需要暂停恢复再上 LangGraph;检索为核心看 LlamaIndex;确定性长流程和跨系统补偿交给工作流引擎,别让 LLM 框架承担事务语义。

边界 ​

  • 框架不保证 Agent 可靠:可靠性来自上限、幂等、评测和监控,不是来自抽象层。
  • 托管平台有绑定:部署、追踪、评测一体化很省事,但迁移时要补等价能力。
  • 版本升级是持续成本:v1 已经稳定,但小版本仍会改行为;锁版本并保留回归测试。
  • 多 Agent 不是默认答案:角色拆分增加通信开销和不确定性,单 Agent + 好工具通常更稳。
  • 成本可能失控:长上下文、多轮工具、并行扇出会成倍放大 token;上线前必须做单请求成本估算。
  • 降本数字要带条件:常见的“图/工作流降本 60–70%”只是确定性节点占比高时的粗略估算,不是实测;确定性节点越多、模型调用越少,节省越接近上限,全模型决策的流程可能没有节省。

讲清楚 ​

Agent 生产化可以按五件事检查:能不能看见每次模型和工具调用,有没有固定评测集,挂了能不能恢复,轮数和成本有没有上限,权限和数据有没有隔离。

技术上最关键的是持久化外部化:checkpointer 放 Postgres,多副本共享,任意实例都能按 thread_id 接着跑。再配超时、重试、降级、幂等和死信,才算能扛故障。选型不要从框架出发,从约束出发:单厂商单轮直接调 SDK;标准工具循环用 LangChain;需要暂停恢复和复杂拓扑用 LangGraph;以检索为核心看 LlamaIndex;纯确定性长流程用工作流引擎。框架只降低胶水成本,可靠性和成本控制仍然要自己做。

适用:LangChain v1.x / LangGraph 1.x | 初稿 2026-10

把 AI 工程讲到既懂也会用