业务级 Agent 的 Runtime 设计:从 LangChain 看可靠性工程

🙋‍
我是 Luhui Dev,一个长期拆解 Agent 工程、探索 AI 教育落地的开发者。关注 Agent Harness、LLM 应用工程、AI for Math 与教育 SaaS 产品化实践。

前言

Agent 的 demo 很容易让人兴奋。一个模型,几个工具,一段 prompt,再套一个循环,就能做出会搜索、会写文件、会调用接口的效果。

但 demo 到业务系统之间,有一条很长的沟。我把它叫做 Runtime 鸿沟------跨过去的不是更强的模型,而是一套能托住复杂、不稳定、可中断、可恢复的生产环境运行时。

真正进入业务场景后,Agent 可能要跑几分钟甚至几十分钟,中间会调用多个外部系统,可能需要用户审批,可能遇到网络失败、工具超时、模型输出偏航、权限不足、用户中途插话、进程重启、版本升级。更麻烦的是,它往往还带着状态:当前任务进展到哪里、已经查过什么、写过哪些中间文件、哪些结论还没确认、这个用户能不能访问某份数据。

这时候,单纯优化 prompt 没法解决根本问题。Agent 需要一套运行时,把复杂、不稳定、可中断、可恢复的执行过程托住。

LangChain 最近围绕 production deep agents 谈的 Runtime 很值得分享下,这对做 Agent 产品的人很重要。因为它提醒我们:业务级 Agent 的护城河,不只在某个更漂亮的 agent loop,还在于能不能把状态、权限、恢复、观测和人机协作做成一套稳定的底层能力。

一、业务级 Agent 的失败,不只发生在模型回答错的时候

很多人理解 Agent 可靠性时,第一反应是模型的幻觉问题。这当然重要,但业务系统里,Agent 的失败范围要大得多。

它可能在长任务执行到第 8 步时进程挂了。重新执行会浪费成本,还可能重复调用外部接口,造成脏数据。

它可能调用工具失败。一次 API 超时、一段网页加载失败、一次数据库查询异常,如果没有重试、降级和状态保存,整个任务就会变成一次性赌博。

它可能在等待人工确认时丢失上下文。用户隔了半小时才回来点"确认",系统却不知道之前让他确认的到底是哪一步。

它也可能在交互层失控。Agent 还在跑,用户又发来一句"前面那个方向不对,换成另一个方案",系统到底应该排队、打断、重启,还是拒绝?没有明确策略,体验会非常混乱。

所以,业务级 Agent 的可靠性至少包含六件事:执行可靠、状态可靠、交互可靠、权限可靠、观测可靠、运维可靠。Runtime 的价值,就在于把这些问题尽量产品化、框架化,而不是让每个团队都从零手写一遍。

二、先把 Harness 和 Runtime 分开

我现在的观点里,一个关键切分是:Harness 和 Runtime 不是一回事。

Harness 可以理解为 Agent 的行为外壳。它负责怎么规划任务、怎么写 prompt、能调用哪些工具、是否拆子任务、是否有文件系统、是否使用子 Agent、如何做上下文压缩。这一层直接影响 Agent 看起来聪不聪明。

Runtime 更底层。它负责 Agent 怎么被执行、怎么被保存、怎么被恢复、怎么被中断、怎么被观测、怎么被调度、怎么隔离不同用户、怎么处理并发请求。这一层直接影响 Agent 能不能支持好业务系统。

我发现很多开源 Agent 里,把所有问题都塞进 harness:prompt 里写规则,工具调用里加 try-catch,数据库里随手存一点状态,前端再做一个 loading。短期可以跑,长期会变成一团难以维护的逻辑。

LangChain Runtime 的思路是把 agent loop 上下文之外的共性能力抽出来。

三、Durable Execution:可靠性的第一块地基

如果只能从 LangChain Runtime 学一个设计,我会先看 durable execution。

普通 Web 请求通常是短生命周期:请求进来,处理一下,返回结果,结束。Agent 不一样。一个业务 Agent 可能会执行很多步:理解任务、拆解计划、检索资料、调用工具、写中间文件、等待审批、继续执行、生成报告。这个过程天然跨越多个模型调用、多个工具调用、多个用户交互。

一旦任务变长,系统就必须面对一个问题:如果中间挂了,怎么办?

LangChain/LangGraph 的答案是 checkpoint。执行过程中的关键状态会被持续保存。恢复时,不需要完全从头开始,而是从最近的合理状态继续。对业务系统来说,这不只是节省成本,更是避免副作用重复发生。

具体怎么做?LangGraph 把 Agent 执行建模成一张状态图,每个节点是一步------一次模型调用、一次工具调用、一次条件判断。状态在节点之间流转,每完成一步,整张图的当前快照就会被序列化写入 checkpointer。这里有几个值得拆开看的设计。

第一,checkpoint 的最小单元是节点边界,不是函数调用边界。一次模型流式输出中途挂了,恢复时这次调用整体重来。

第二,state 是结构化的,不是黑箱 pickle 。LangGraph 要求把状态拆成有名字的 channel(如 messagesplanscratchpad),每个 channel 配一个 reducer(messages 用 append,plan 用 overwrite)。这样 checkpoint 之间是结构化 diff,可以追踪、回放,也可以 time travel 到任意一步。

第三,checkpoint 之间是一棵树,不是一条线。每个 checkpoint 都带 parent 引用,可以从任意历史节点拉一个分支重新执行------改一下用户问题、跳过某次审批、试一个不同的工具,都是从同一棵树上长出新枝。

第四,interrupt 和 checkpoint 是同一套机制。在节点前后设 interrupt,本质上就是执行到这里写一个 checkpoint 然后停下来。所以人工审批、用户修改、外部信号唤醒,复用的都是这套持久化能力。这也是为什么 HITL 能做成 Runtime 能力而不是 UI 逻辑。

第五,后端可插拔。dev 用内存或 SQLite,生产用 Postgres 或 Redis。Agent 的可靠性级别可以随业务阶段调整,不必第一天就上重型基础设施。

比如一个 Agent 正在为企业客户生成一份调研报告。它已经完成了资料搜集、竞品整理、初稿生成,正在等待用户确认是否需要拉取内部 CRM 数据。如果这时服务重启,理想状态不是让 Agent 重新搜一遍资料,也不是让用户重新描述需求,而是恢复到"等待确认"这个状态。

这就是 durable execution 的意义:把 Agent 的执行过程从一次性函数调用,变成可保存、可恢复、可继续的任务生命体。

这里其实还需要回答另一些具体的问题,比如Agent 的每一步到底如何算可恢复边界?写入业务系统的操作能不能重复?

四、状态要分层:短期状态、长期记忆、业务数据不能混在一起

Agent 做复杂任务时一定会产生状态。但状态不能一锅炖。

短期状态是当前任务里的上下文:计划是什么,已经执行到哪一步,中间结果是什么,哪些工具调用完成了,哪些待确认。这类状态适合跟 thread、run、checkpoint 绑定。

长期记忆是跨会话的上下文:用户偏好、组织规则、常用工作流、反复出现的约束、可复用知识。这类状态应该进入长期 store,并且按用户、组织、应用、助手等维度做命名空间隔离。

业务数据又是另一层:订单、题目、课件、客户资料、组织资产、权限模型。这类数据通常不应该被 Agent Runtime 随便吞掉,而应该由业务系统自己管理,Agent 通过受控工具访问。

LangChain 的设计对这里很有启发:它把 thread checkpoint 和 long-term store 区分开,同时又允许 deep agent 通过类似虚拟文件系统的方式访问不同层级的状态。对上层 Agent 来说,读写文件和记忆比较自然;对底层系统来说,状态仍然有明确边界。

这对业务系统很关键。很多 Agent 产品早期会把聊天记录、工具结果、用户偏好、业务数据全塞进一个 conversation memory。实现起来是简单,后面会在权限、成本、检索质量、数据清理、合规审计上一起爆雷。

比较稳的做法是:短期状态服务于任务恢复,长期记忆服务于体验连续性,业务数据保持在业务系统内,Agent 只通过权限受控的工具访问。

五、Human-in-the-loop 不是交互装饰,而是可靠性机制

业务级 Agent 很难完全自动化。尤其是涉及写操作、外部系统调用、重要决策、付费资源、用户隐私时,人机协作是必要的安全阀。

这里的关键不只是弹一个确认框。研发实现上真正的问题是:Agent 如何暂停?暂停时保存什么状态?用户多久之后回来都能继续吗?用户能不能修改 Agent 给出的计划?修改后从哪里恢复?审批记录能不能追溯?

LangChain Runtime 把 interrupt/resume 做成运行时能力,而不是让应用层临时判断。因为 HITL 如果只停留在前端交互层,很容易变成 UI 逻辑;一旦任务跨进程、跨 worker、跨时间,前端就托不住了。

业务 Agent 里有很多场景都需要这种能力:

  • 一个财务 Agent 准备提交报销,需要人工确认。
  • 一个教研 Agent 准备批量生成课件,需要老师选择讲解风格。
  • 一个客服 Agent 准备执行退款,需要主管审批。
  • 一个数据分析 Agent 想访问敏感字段,需要用户临时授权。

这些都不是普通对话体验,而是业务流程。Runtime 如果能原生支持暂停、恢复、审批和状态保存,Agent 的可靠性会明显上一个台阶。

六、权限和多租户:Agent 不能拿着万能钥匙到处跑

业务级 Agent 最大的风险之一,是权限问题。

普通应用里,用户点按钮、调用接口、服务端校验权限,链路相对清晰。Agent 介入后,事情变复杂了:模型会决定调用哪个工具,工具可能访问外部系统,外部系统可能需要用户授权,Agent 还可能把中间结果写入长期记忆。

LangChain 的思路是把身份和权限拆成几层:终端用户是谁,用户能访问哪些 thread 和资源,Agent 能代表用户访问哪些外部系统,团队成员对平台本身有什么操作权限。

在这个设计里,Agent 不是一个后台超级管理员。它更像一个被委托的执行者,只能在当前用户、当前组织、当前任务允许的范围内行动。

如果我们为自己的业务 Agent 设计 Runtime,也应该至少考虑几条边界:

  • 用户身份要进入 run context。Agent 的每次执行都应该知道我正在代表谁行动。
  • 资源访问要按 thread、file、project、organization 做隔离。不能只靠 prompt 告诉模型不要访问别人的数据。
  • 外部工具授权要独立管理。比如 GitHub、Slack、CRM、OSS、数据库,都不应该把长期密钥直接暴露给 Agent 执行环境。
  • 长期记忆要有 namespace。否则 Agent 记住的用户偏好,很可能在多租户场景里变成数据污染。
  • 高风险工具要有审批或策略拦截。删除、发送、支付、发布、批量写入这类动作,不能只靠模型自觉。

Agent 越像人,系统越容易误以为它可以继承人的全部权限。但从工程角度看,Agent 应该拿到的是任务级、时效性、最小化的权限。

七、Middleware:把防护能力放到运行时生命周期里

很多团队会把 guardrails 写进 prompt,比如"不要泄露隐私""不要执行危险操作""遇到不确定要询问用户"。这有用,但不够。

模型会忘、prompt 会被覆盖、工具调用路径会绕开规则,流式输出和后台任务也可能产生不同的行为。业务系统必须要有更硬的防线。

middleware 设计就是它围绕 Agent 生命周期插入控制点:模型调用前、模型调用时、工具调用时、模型调用后,都可以做策略处理。

这意味着很多可靠性能力可以下沉到 Runtime:

  • 调用模型前,裁剪上下文、注入权限信息、检查 token 预算。
  • 调用模型时,做模型 fallback、超时控制、重试策略、成本记录。
  • 调用工具时,做权限校验、参数检查、敏感动作拦截、人工审批。
  • 模型输出后,做 PII 检测、格式校验、结果归档、trace 标记。

这比在每个工具里零散写逻辑要稳定,也更容易统一治理。

对业务级 Agent 来说,middleware 的意义不只是安全过滤,它是 Runtime 可治理性的入口。

八、Streaming 和 double-texting:交互可靠性也要进入 Runtime

很多人把 streaming 当作体验优化。对 Agent 来说,streaming 还有可靠性意义。

长任务如果没有实时反馈,用户不知道系统是否还活着,也不知道执行到了哪一步。尤其是研究、编程、数据分析、课件生成这类任务,用户需要看到中间状态:正在检索、正在调用工具、正在写草稿、正在等待确认。

更复杂的是用户中途插话。Agent 还在跑,用户发来新指令,这被 LangChain 称为 double-texting 一类问题。它不是小问题,而是交互协议问题。

系统要明确:新输入是排队等待,还是直接打断当前任务?是合并到当前上下文,还是撤销后重新执行?是允许用户中途改目标,还是要求当前任务结束后再处理?

业务系统里,不同场景答案不同。

写作 Agent 可以允许用户中途调整方向。

支付 Agent 不能随便中断后继续执行危险操作。

教研课件 Agent 可能适合把新输入加入任务队列。

编程 Agent 可能需要暂停当前命令,等待用户确认是否改计划。

这说明聊天体验其实是 Runtime 设计的一部分。

九、Observability:业务 Agent 不能只靠日志排查

传统应用出问题,日志、指标、链路追踪通常够用。Agent 出问题,单纯日志往往不够。

因为 Agent 的错误很多是过程性错误:第一步理解偏了,第三步用了不合适的工具,第五步接受了低质量检索结果,第七步把中间假设当成结论。最后输出错了,但真正原因埋在执行路径里。

LangChain/LangSmith 强调 trace、time travel、debug,业务级 Agent 需要的不只是调用成功率,还要知道:

  • 这次任务经历了哪些节点?
  • 每一步模型看到了什么上下文?
  • 调用了哪些工具?参数是什么?返回是什么?
  • 中间状态如何变化?
  • 在哪一步发生了分支?
  • 是否触发了 middleware、审批、重试、fallback?
  • 如果把某个 checkpoint 的状态改一下,后面结果会不会变?

这些能力决定了 Agent 能不能被持续优化。否则,团队只能靠看感觉改 prompt。那不是工程闭环。

更进一步说,Observability 还连接 eval。trace 不是只用于排障,也可以变成评估样本、回归测试、成本分析和产品洞察。

十、Agent Runtime 要能横向扩展,也要能控制成本

业务 Agent 一旦上线开始有用户,就需要关心运维问题了。

有些任务很短,有些任务很长;有些只是读数据,有些会调用慢工具;有些用户会连续发消息,有些任务会定时触发;模型调用成本高,工具调用也可能有成本;长任务大量堆积时,API server、queue worker、Redis、Postgres、外部工具都会成为瓶颈。

LangChain Agent Server 有几个值得学习的点:

API server 和 queue worker 分离。 前者负责接收请求,后者负责执行长任务。这能避免长任务拖垮入口服务。

运行状态和持久状态分层。 临时运行状态可以放在 Redis 一类系统里,thread、run、checkpoint、memory 这类数据进入持久存储。

并发能力可配置。 不同 Agent 的任务形态不同,I/O-heavy 和 CPU-heavy 的 worker 并发策略应该不同。

避免前端轮询。 对长任务来说,join/stream 比粗暴轮询更适合,也更节省系统资源。

支持 cron。 很多业务 Agent 不是用户点一下才执行,而是需要定期检查、定期总结、定期同步、定期生成内容。

一个可靠的业务 Agent Runtime,必须同时关心任务语义和基础设施成本。

十一、抽出一份 Runtime 设计清单

如果不照搬 LangChain,而是为自己的业务 Agent 做运行时设计,可以把能力拆成下面这张清单。

第一,任务生命周期。 有没有 thread、run、step 这样的基本抽象?一次 Agent 执行能不能被追踪、取消、暂停、恢复、重试?

第二,持久执行。 每一步关键状态是否 checkpoint?恢复边界在哪里?哪些操作可重放,哪些操作必须幂等,哪些操作只能人工确认后继续?

第三,状态分层。 短期任务状态、长期记忆、业务数据是否分开?是否有 namespace?是否支持清理、迁移、审计?

第四,权限模型。 Agent 是代表谁运行?能访问哪些资源?能调用哪些工具?外部系统授权怎么管理?高风险操作是否需要审批?

第五,工具治理。 工具是否有 schema、权限、超时、重试、限流、审计?工具失败后是重试、降级、跳过,还是中断?

第六,人机协作。 是否支持运行中 interrupt?用户确认后能否 resume?审批内容、审批人、审批时间是否可追溯?

第七,交互协议。 streaming 如何设计?用户中途输入如何处理?排队、拒绝、打断、重启分别适合哪些场景?

第八,观测与调试。 是否有结构化 trace?能否看到模型调用、工具调用、状态变化、middleware 触发?能否把 bad case 转成 eval?

第九,运维扩展。 入口服务和执行 worker 是否分离?队列如何设计?存储瓶颈在哪里?长任务堆积时如何限流?成本如何归因?

第十,部署边界。 哪些能力自己托管,哪些用托管平台?数据是否能留在自己系统里?未来是否会被某个 runtime 绑定太深?

十二、写在最后

Agent 产品不止是追逐更聪明,进入业务系统后,很重要的是更可靠:能恢复、能隔离、能审批、能追踪、能扩展、能控制成本。

这也解释了为什么 Agent Harness 和 Runtime 要分开看。Harness 决定 Agent 的能力上限,Runtime 决定 Agent 的业务下限。没有前者,Agent 不够聪明;没有后者,Agent 不敢上线。

如果我们要做自己的业务级 Agent,Runtime 应该从第一天就进入架构设计。哪怕第一版不做完整系统,也应该先定义好边界:任务状态怎么保存,用户身份怎么传递,工具权限怎么控制,人工审批怎么恢复,trace 怎么沉淀为评估数据。

Agent 的未来不只是模型更强,也会是 Runtime 更成熟。谁能把复杂 Agent 的运行过程做得稳定、可控、可审计,谁才更接近真正的业务落地。

这也是 LangChain 这篇 Runtime 文章最值得学习的地方。

相关推荐
魔乐社区12 小时前
基于昇腾 MindSpeed LLM 玩转 DeepSeek-V4-Flash
人工智能·开源·大模型
传说故事12 小时前
【论文阅读】Code as Policies: Language Model Programs for Embodied Control
论文阅读·人工智能·具身智能
Jurio.12 小时前
AI Daily Paper Reader(ADPR):零服务器搭建个人/团队通用大模型API驱动的论文阅读与推荐平台
论文阅读·人工智能·ai
emfuture12 小时前
国产工控机选型实录:基于龙芯2K3000的中嵌科技EU-7500在边缘计算场景下的适配笔记
人工智能·笔记·边缘计算
IT_陈寒12 小时前
React状态更新后视图不刷新?我差点以为是灵异事件
前端·人工智能·后端
蓦然回首却已人去楼空12 小时前
深度学习进阶:自然语言处理|3.4 QA|共享权重与 `remove_duplicate` 详解
人工智能·深度学习·自然语言处理
searchforAI12 小时前
我用这款本土NotebookLM平替重构了知识库
人工智能·笔记·gpt·ai·音视频·知识图谱
不懂的浪漫12 小时前
01|从 Spring Boot 项目理解 RAG:ingest、query、rerank、trace 到 eval
java·人工智能·spring boot·后端·ai·rag
无心水12 小时前
【分布式利器:金融级】金融级分布式架构开源框架全景解读
人工智能·分布式·金融·架构·开源·wpf·金融级框架