2 分钟

设计在生产中不会崩溃的智能体系统

为什么许多智能体系统在生产中失效,以及如何通过状态机、明确的工具契约、重试策略和深度可观测性来设计可靠的智能体。

设计在生产中不会崩溃的智能体系统

从令人印象深刻的演示到脆弱的生产智能体

智能体系统是指那种 LLM 不仅回答提示,而是决定下一步要做什么的应用:调用哪个工具、获取哪些数据、执行哪些步骤,以及何时“完成”。它们将模型、一组工具(API、数据库、服务)、一个规划/执行循环和把各部分连接起来的基础设施组合在一起。

在演示中,这看起来很神奇:智能体制定计划、调用几个工具,然后返回完美结果。快乐路径短、延迟低,并且没有多个环节同时失败。

为什么演示能行而生产会崩溃

在真实负载下,同样的智能体会遭遇演示从未暴露的压力:

  • API 超时、返回部分数据或更改契约。
  • 多个请求争用共享资源并破坏状态。
  • 长期会话膨胀上下文并超出限制。
  • 细微的模型错误在多次工具调用中复合放大。

结果是:难以复现的间歇性行为、静默的数据损坏以及偶尔挂起或无限循环的用户流。

真正的业务影响

间歇性智能体不仅影响“用户体验”。它们:

  • 触发事故与值班告警。
  • 产生错误答案并流入下游系统。
  • 侵蚀用户信任:人们悄悄停止依赖该功能。
  • 通过重试与失控循环推高云端费用。

本指南关注什么

本文讲述的是工程模式,而不是“更好的提示”。我们将探讨状态机、显式工具契约、重试与失败处理策略、内存与并发控制,以及让智能体在高负载下变得可预测而不仅是舞台上令人惊叹的可观测性模式。

为什么大多数智能体架构在规模化时会失败

大多数智能体系统在单次快乐路径演示中看起来没问题。但当流量、工具与边缘情况一同到来时,它们就会失败。

脆弱行为:循环、阻塞、部分工作、静默错误

天真的编排假设模型会在一两次调用中“做对事”。在真实使用下,你会看到反复出现的模式:

  • 循环:智能体不断重新规划或重复调用同一工具,因为它从未识别出完成或失败。
  • 阻塞:智能体在某个工具或子任务上等待却没有超时,导致用户会话挂起。
  • 部分工作:智能体完成了工作流的一半(例如写好了邮件草稿却从未发送,生成了计划却没有执行步骤)。
  • 静默错误:工具失败或 schema 不匹配,但智能体自信地返回看似合理但缺失或错误的数据。

没有显式状态与结束条件,这些行为几乎不可避免。

隐含的非确定性与工具不可靠性

LLM 采样、延迟变化与工具时序带来隐含的非确定性。相同输入可能走不同分支、调用不同工具或对工具结果有不同解读。

在规模化时,工具问题占主导:

  • 上游 API 与数据库的超时与不稳定
  • 工具契约与服务实际返回之间的schema 漂移
  • 智能体从未学会处理的不一致错误格式

每一个都会演变成多余的循环、重试或错误的最终答案。

并发放大了边缘案例与产品不匹配

在 10 RPS 很少出问题的场景,在 1000 RPS 下会频繁失败。并发揭示了:

  • 共享状态或缓存上的竞态条件
  • 用尽的速率限制导致级联工具故障
  • 单个依赖抖动触发的大规模重试

产品团队通常期望确定的工作流、清晰 SLA 与可审计性。未经约束的智能体提供的是概率性、尽力而为的行为,保证很弱。

当架构忽视这种不匹配——把智能体当传统服务而不是随机规划器来对待——系统在可靠性最重要时段会变得不可预测。

面向生产的智能体系统设计原则

面向生产的智能体更依赖严谨的系统设计,而非“聪明的提示”。一种有用的思路是:把智能体看作偶尔调用 LLM 的小型、可预测的机器,而不是偶尔触碰你系统的神秘 LLM 大块头。

什么使智能体具备生产就绪性?

四个属性最关键:

  • 安全:智能体必须尊重数据访问、副作用与对用户承诺的约束。这要求显式权限、工具的护栏以及对不可信输出的谨慎处理。
  • 可预测性:给定相同输入与状态,智能体应在狭窄、预期的范围内行为。你应能解释它能做什么与不能做什么。
  • 可调试性:当出现问题时,你能追踪路径:哪个状态、哪个决策、哪个工具、哪次模型调用。没有隐藏循环,没有没有结构的“思考”片段。
  • 变更容忍性:你能够在不重写全系统的情况下升级模型、工具或策略。

这些属性不是靠提示获得,而是靠结构获得。

更偏向显式工作流而非自由循环

许多团队默认模式是:"while not done, call the model, let it think, maybe call a tool, repeat"。这方便原型开发但难以运维。

更安全的模式是将智能体表示为显式工作流

  • 定义有限的状态集(例如 COLLECTING_INPUT, PLANNING, EXECUTING_STEP, WAITING_ON_HUMAN, DONE)。
  • 定义允许的状态转移。
  • 把 LLM 主要用于局部决策:选择下一状态、选择工具或填充参数。

这将智能体变为一个状态机,每一步都可检查、测试和重放。自由形式的循环看起来灵活,但显式工作流才是让事故可调试、行为可审计的关键。

把“万能智能体”拆分为模块化技能

一体化的万能智能体虽然诱人,但会把无关职责紧耦合:规划、检索、业务逻辑、UI 协调等。

相反,组合小而明确职责的智能体或技能

  • 一个负责分解任务的规划器。
  • 一个负责运行具体步骤的执行器。
  • 针对各领域(计费、支持、分析等)的专家模块。

每个技能可以有自己的状态机、工具与安全规则。组合逻辑成了更高层的工作流,而不是单个智能体内不断膨胀的提示。

这种模块化让每个智能体足够简单以便推理,并允许你在不破坏其他部分的情况下进化单个能力。

分离策略、状态和工具

一个有用的思想模型是把智能体拆成三层:

  1. 决策策略(LLM 提示 + 模型)
    封装智能体如何选择下一步行动,并在严格约束下解释。你应能在不改系统连线的情况下替换模型、调整温度或细化提示。

  2. 状态机 / 工作流引擎
    负责当前处于流程何处、哪些转移可行以及如何持久化进度。策略提出动作;状态机验证并应用它。

  3. 工具层
    实现现实世界中能发生的操作:API、数据库、队列、外部服务。工具暴露窄且类型化的契约,并执行授权、速率限制与输入校验。

通过强制这些分层,你就避免把业务逻辑藏在提示或工具描述里。LLM 成为清晰确定性外壳内的一个决策组件,而不是整个外壳本身。

设计的简洁与明确性

最可靠的智能体并不是最令人惊艳的演示,而是那些你能在白板上解释其行为的系统。

具体做法:

  • 让每个智能体专注于一项工作和一个主要成功指标。
  • 用显式编码的工作流和状态转移代替散文式说明。
  • 让 LLM 在若干明确定义的选项之间做选择,而不是从零发明整个过程。

这种偏向小、可组合、结构良好的智能体设计,能使系统在范围扩大时不被自身复杂性压垮。

将智能体工作流建模为显式状态机

大多数智能体实现开始于一个“思考—行动—观察”的循环,围绕 LLM 调用。这对演示可以,但很快变得不透明且脆弱。更好的方法是把智能体当作显式状态机:一组有限状态,以及由事件触发的明确定义的转移。

将工作流表示为状态与转移

不要让模型隐式决定下一步做什么,而是定义一个小型状态图:

  • PLAN — 解析用户请求、分解步骤、选择工具。
  • CALL_TOOL — 使用验证过的输入执行单次工具调用(或批量)。
  • VERIFY — 将工具输出与简单不变式或额外模型检查比对。
  • RECOVER — 处理错误:重试、回退或上报。
  • DONE — 返回最终答案并结束工作流。
  • FAILED — 带明确原因与上下文的终态错误。

这些状态之间的转移由类型化事件触发,例如 UserRequestReceived, ToolCallSucceeded, ToolValidationFailed, TimeoutExceededHumanOverride。每个事件加上当前状态决定下一状态与动作。

这让重试与超时变得直接:你可以把策略附加到单个状态(例如 CALL_TOOL 可重试 3 次并使用指数退避,PLAN 则可能不重试),而不是把重试逻辑散落在代码库各处。

将状态外部化以增强弹性与扩展性

将当前状态与最小上下文持久化到外部存储(数据库、队列或工作流引擎)。这样智能体就成了纯函数:

next_state, actions = transition(current_state, event, context)

这带来好处:

  • 弹性 — 若工作进程在运行中意外挂掉,另一个进程可从最后持久化的状态继续恢复。
  • 横向扩展 — 无状态工作进程消费事件、更新状态并发出下一个事件。
  • 重放与补偿 — 你可以重建一次运行、从任一状态重驱它,或在必须回滚流程时运行补偿动作。

推理与审计的好处

有了状态机,智能体行为的每一步都是显式的:它处于哪个状态、发生了哪一事件、哪个转移触发、产生了哪些副作用。这样的清晰度让调试更快,简化事故调查,并为合规审查创建自然的审计轨迹。你可以从日志与状态历史中证明:某些高风险操作仅在特定状态且满足既定条件时才被执行。

为智能体设计可靠的工具契约

当工具更像“有明确保证的接口”而不是“埋在散文里的 API”时,智能体的行为会更可预测。

定义契约,而不仅仅是提示

每个工具应包含契约,涵盖:

  • 输入 schema:必需字段、类型、枚举、约束、默认值。
  • 输出 schema:成功载荷、可空字段以及“无结果”代表何意。
  • 错误模型:类型化错误(如 InvalidInput, NotFound, RateLimited, TransientFailure)并赋予明确定义。
  • SLA:延迟期望、可用性目标与速率限制。

把这些契约以结构化文档的形式暴露给模型,而不是一墙文字。智能体规划器应该知道哪些错误可重试、哪些需要人工干预、哪些应终止工作流。

严格的 JSON 与严格校验

把工具的输入输出当作生产 API:

  • 使用严格的 JSON schema(例如 OpenAPI、JSON Schema)来描述输入与输出。
  • 在调用之前校验(以捕捉模型错误),并在调用之后再次校验(以捕捉工具回归)。
  • 对轻微问题自动修复(如类型强制转换),但要记录以便后续调整。

这能让提示更简短:与其用冗长指令,不如依赖 schema 驱动的引导。清晰的约束能减少幻觉式的参数和荒谬的工具序列。

版本化与兼容性

工具会演进;智能体不应在每次演进时都崩溃。

  • 对工具契约进行版本化(v1, v1.1, v2),并把智能体锁定到某一版本。
  • 逐步弃用字段;保留旧字段一段时间以便读取。
  • 以向后兼容的方式新增字段;避免悄然改变语义。

规划逻辑随后可以安全地混合不同成熟度的智能体与工具。

处理失败与降级模式

在设计契约时就考虑部分失败

  • 允许带有每项错误详情的部分结果。
  • 定义降级响应(例如:缓存的、近似的或过期的数据),而不是硬性失败。
  • 标注哪些字段是“尽力提供”的,哪些是“必须有”的。

智能体据此可适应:用受限功能继续工作、向用户确认或切换到回退工具。

安全与授权边界

工具契约是编码安全限制的天然位置:

  • 规定工具允许读取或修改的范围。
  • 对敏感操作要求显式参数(例如 confirm: true)。
  • 区分用户作用域与系统作用域操作。

并在服务端做校验;不要仅仅依赖模型“自觉守规矩”。

为何良好契约能简化智能体

当工具拥有清晰、已校验、版本化的契约时,提示可更短,编排逻辑更简单,调试更容易。你把复杂性从脆弱的自然语言说明迁移到确定性的 schema 与策略,从而减少幻觉式工具调用与意外副作用。

重试、幂等性与失败处理模式

从构建到部署
工作流稳定且测试通过后,部署并托管你的代理应用。

可靠的智能体系统假定“万物终将失败”:模型、工具、网络,甚至你自己的协调层都会失败。目标不是避免失败,而是让失败代价低且安全。

幂等性:安全重试的基础

幂等性意味着:重复同一请求的对外可见效果应与只执行一次相同。这对经常在部分失败或不确定响应后重新发起工具调用的 LLM 智能体至关重要。

通过设计让工具具备幂等性:

  • 请求 ID:每次工具调用包含稳定的 request_id。工具记录该 ID,并在再次看到时返回相同结果。
  • Upsert 而非 Insert:使用基于自然键或合成业务键的“创建或更新”语义,而非自增 ID。
  • 校验和与版本化:附加内容哈希或版本号,使工具能检测重复、过期写入或冲突更新。

不致成本爆炸的重试策略

对瞬时错误(超时、速率限制、5xx)使用结构化重试:指数退避、抖动以避免群体效应,并设定严格的最大尝试次数。用相关 ID 记录每次尝试以便追踪智能体行为。

对于永久性失败(4xx、校验错误、业务规则违背)不要重试。将结构化错误暴露给智能体策略,让其重规划、询问用户或选择其他工具。

断路器与回退

在智能体与工具层实现断路器:在连续失败后暂时阻止对该工具的调用并快速失败。配合明确定义的回退策略:降级模式、缓存数据或替代工具。

避免在智能体循环中盲目重试。没有幂等工具与清晰失败分类,你只会放大副作用、延迟与成本。

管理智能体的内存、状态与数据一致性

可靠的智能体始于对“什么是状态”与“它在哪里”这两个问题的清晰思考。

短期状态 vs 长期记忆

把智能体当作处理请求的服务看待:

  • 短期状态:完成当前任务或子任务所需的一切,包括活跃目标、当前步骤、工具输出、部分决策与控制变量(剩余重试次数、所选分支等)。它应当是有界的,工作完成后可丢弃。
  • 长期记忆:应在多次运行与会话间存活的信息:用户偏好、以往决策、项目历史与学习到的捷径。

混用会导致混乱与缺陷。例如,把短期工具结果放进“记忆”会让智能体在未来会话中重复使用过时上下文。

状态存储位置

你有三种主要选择:

  1. 上下文内(仅提示) — 简单、低延迟,但容量有限且不持久。适用于单次运行的短期状态。
  2. 外部存储 — 数据库、缓存或向量库。用于长期记忆与需在重启间存活或跨 worker 协调的状态。
  3. 混合 — 权威状态存外部;仅把下一步所需加载到上下文中。

一个好的规则:把 LLM 当作对显式状态对象的无状态函数。把该对象持久化到模型外,并从它重生成提示。

避免“把日志当记忆”的反模式

一个常见失败模式是把对话日志、追踪或原始提示当做事实记忆。

问题包括:

  • 检索变得随意且脆弱。
  • 重要事实埋在长文本中。
  • 多次运行可能产生相互矛盾的记录且没有明确的“最后写入获胜”规则。

相反,定义结构化记忆 schema:user_profile、project、task_history 等。从日志派生记录,而不是反过来。

与共享数据和工具的一致性

当多个工具或智能体更新同一实体(例如 CRM 记录或任务状态)时,需要基础一致性控制:

  • 为关键实体使用单一事实源(例如订单、工单、文档)。
  • 优先采用幂等工具契约:工具应通过稳定 ID 与 upsert 语义安全地处理重试。
  • 在可能出现并发更新时使用乐观并发控制(版本号、时间戳)。

对于高价值操作,记录一份与会话日志分离的决策日志:记录是什么被改变、为什么、基于哪些输入。

快照与可恢复执行

为了在崩溃、部署与速率限制下存活,工作流应可恢复

  • 在每个重要步骤后持久化状态快照:当前步骤、输入、工具结果与待处理动作。
  • 使状态机的每个转移都可从快照重放。
  • 在失败或重启时,从最后快照加载并继续,而不是从头开始。

这也支持时间旅行调试:你可以检查并重放导致错误决策的确切状态。

隐私、保留与最小记忆原则

记忆既是资产也是负担。生产智能体应:

  • 明确哪些内容绝不存储(例如机密、原始文档、敏感 PII)。适当时使用脱敏或哈希。
  • 为每种记忆类型定义保留策略(会话级、30 天、法律保留等)。
  • 给用户查看与删除长期记忆的控制权。
  • 避免在可用更小结构化摘要时存储完整提示或工具输入。

把记忆当作一个产品面:被设计、版本化与治理——而不是附着在智能体上的不断增长的文本堆栈。

智能体系统中的并发、速率限制与背压

智能体在白板上看似顺序,但在真实负载下表现为分布式系统。只要有大量并发用户、工具与后台作业,你就要处理竞态条件、重复工作与顺序问题。

智能体工作流中的并发危害

常见失败模式:

  • 竞态条件:两个智能体执行并发更新同一工单、购物车或文档,互相覆盖。
  • 重复工作:重试调用或错误配置的 worker 导致同一任务被处理两次(例如重复扣款)。
  • 乱序影响:工具调用按非预期顺序完成,旧结果覆盖新状态。

这些问题通过幂等工具契约、显式工作流状态和数据层的乐观/悲观锁来缓解。

队列 vs 同步流

同步的请求—响应流程简单但脆弱:每个依赖都必须在线、在速率限制内且快速。一旦智能体扇出到多个工具或并行子任务,就应把长时间运行或有副作用的步骤移到队列之后。

基于队列的编排让你:

  • 使用工作池控制并发
  • 集中处理重试与去重
  • 将慢或不可靠的工具从用户可见延迟中隔离

速率限制与背压

智能体通常会触及三类限额:

  • 模型:每分钟令牌数、每分钟请求数、上下文大小
  • 工具:内部服务的 QPS 或 CPU 限额
  • 上游 API:第三方配额与硬性上限

需要显式的速率限制层,包含按用户、按租户与全局的节流策略。使用令牌桶或漏桶算法执行策略,并返回明确错误类型(例如 RATE_LIMIT_SOFT, RATE_LIMIT_HARD),以便智能体优雅退避。

背压是系统在压力下保护自身的方式。策略包括:

  • 先舍弃非关键流量
  • 降级功能(更小的上下文、更少的工具调用)
  • 在保持关键流量运行的同时暂停低优先级队列

监控饱和信号:队列深度、工作进程利用率、模型/工具错误率与延迟分位数。当队列深度上升且延迟或 429/503 错误增加时,是智能体超载环境的早期预警。

可观测性:智能体行为的追踪、指标与日志

构建时赚取积分
发布你的作品,并因创作关于 Koder.ai 的内容获得积分。

如果你不能快速回答两个问题:“它做了什么?”与“为什么这么做?”,就无法让智能体可靠。智能体的可观测性就是让这些答案便宜且精确。

你需要看到什么

设计可观测性,使单个任务有一条追踪,串联起:

  • 每个智能体步骤与状态转移
  • 每次工具调用与响应
  • 每次模型调用与提示变体

在追踪中,附加关键决策的结构化日志(路由选择、计划修正、护栏触发)和用于容量与健康的指标

一个有用的追踪通常包含:

  • 任务元数据:租户、用户、渠道、优先级
  • 智能体状态:当前状态名、下一个状态、重试计数
  • 工具 I/O:输入、输出、延迟、错误、断路器状态
  • 模型调用:提示模板 ID、模型名、令牌数、延迟

日志与脱敏

以结构化形式记录提示、工具输入与输出,但先通过脱敏层

  • 屏蔽 PII 与密钥
  • 截断超大载荷并用哈希以便关联
  • 为字段标注敏感度以控制保留与访问

在低环境中可以开放未脱敏的原始内容;生产默认应展示脱敏视图。

真正重要的指标

至少要跟踪:

  • 按智能体与用例划分的任务成功 / 失败率
  • 每任务的平均与 P95 步数
  • 延迟:端到端以及按工具 / 模型分解
  • 每次任务的成本(令牌、工具开销)以及每次成功的成本

发生事故时,良好的追踪与指标能把“智能体看起来不稳定”转为精准的陈述,例如:“P95 任务在 ToolSelection 状态在 2 次重试后失败,原因是 billing_service 的新 schema”,把排查时间从小时缩短到分钟,并给出可操作的调优手段。

智能体系统的测试与评估策略

测试智能体意味着既要测试工具,也要测试把一切串在一起的流程。把它当作分布式系统测试,而不仅仅是提示微调。

单元测试:针对工具契约,而不是提示

从工具边界的单元测试开始:

  • 校验 schema:必需字段、枚举、范围与不变式。
  • 检查幂等性与错误语义(哪些错误、哪些代码、哪些可重试)。
  • 断言工具对畸形输入有良好处理并返回结构化失败。

这些测试不依赖 LLM。直接调用工具并用合成输入断言精确输出或错误契约。

集成测试:工作流与多步行为

集成测试应端到端地检验智能体工作流:LLM + 工具 + 编排。

将它们建模为基于场景的测试:

  • 关键用户旅程的快乐路径(预约、退款、升级等)。
  • 边缘情况:缺失数据、部分工具失败、超时、速率限制。
  • 跨工具交互:工具 A 的输出如何喂入工具 B。

这些测试断言状态转移与工具调用,而不是 LLM 每个令牌的措辞。检查:调用了哪些工具、传入了哪些参数、顺序如何、以及智能体最终达到的状态/结果。

为 LLM 与工具使用确定性的夹具

为保持测试可重复性,要对 LLM 响应与工具输出做夹具(fixture):

  • 为每个提示 + 模型 + 配置记录一次 LLM 响应并以 JSON 夹具存储。
  • 在工具背后 mock 外部系统,避免测试击中真实服务。
  • 在测试中使用显式种子与固定温度配置。

典型模式:

with mocked_llm(fixtures_dir="fixtures/llm"), mocked_tools():
    result = run_agent_scenario(input_case)
    assert result.state == "COMPLETED"

针对提示与 schema 的回归套件

每次提示或 schema 变更都应触发不可妥协的回归运行:

  • 保留一组精心挑选的输入与预期状态、工具调用或分类作为样例库。
  • 将它们锁为黄金文件;差异突出行为改变。
  • 对关键流的任何漂移都需显式批准或回滚。

schema 演进(新增字段、收紧类型)应有专门回归用例,以捕捉仍假定旧契约的智能体或工具。

上线前的离线评估

切勿把新模型、策略或路由策略直接推到生产流量中。

相反:

  • 在新配置下离线重跑回归语料库。
  • 在抽样历史交互上运行回放测试。
  • 自动计算指标(任务成功率、工具错误率、延迟、成本)并在必要时对抽样做人工评分。

只有在通过离线门禁后,新变体才应进入生产,且最好在功能开关与逐步发布下进行。

测试数据管理与匿名化

智能体日志常包含敏感用户数据。测试必须尊重这一点:

  • 匿名化或合成输入构建测试数据集。
  • 在存储日志或夹具前剥离或哈希标识符、自由文本 PII 与密钥。
  • 分段访问:工程师可见行为痕迹,但不可见原始用户密钥。

把这些规则写入 CI 流程,确保没有未经匿名化检查的测试工件被生成或存储。

在生产中运行、监控与演进智能体

保留完整代码所有权
导出源代码并接入现有仓库和流水线。

在生产中运行智能体更像是在运维分布式系统,而不是发布静态模型。你需要发布控制、明确的可靠性目标与严格的变更管理。

安全的发布策略

逐步引入新智能体或行为:

  • 影子模式:并行运行智能体,但不影响用户,记录其决策并进行离线比对。
  • 金丝雀:把少量流量(例如 1–5%)暴露给新版本,观察错误率、延迟与质量再扩大。
  • A/B 测试:对用户可见流程,用业务 KPI(而不仅是模型指标)比较新版与旧版。

所有这些应由功能开关与配置驱动策略支持:路由规则、启用的工具、温度、安全设置。变更应以配置可下发、而非必须改代码,并能即时回滚。

SLO 与事故工作流

定义反映系统健康与用户价值的 SLO:

  • 可靠性:任务、工具调用与端到端工作流的成功率。
  • 延迟:关键路径的 p50 / p95。
  • 质量:自动评估分数、人工评分分布或特定任务的成功率。

把这些接入告警系统,按常规服务处理事故:明确归属、排查运行手册与标准缓解步骤(回滚标志、抽流、进入安全模式)。

持续改进与变更控制

用日志、追踪与会话记录来改进提示、工具与策略。把每次变更视为版本化工件并通过审核、批准与回滚机制管理。

避免无声的提示或工具更改。没有变更控制,你无法把回归与具体编辑关联起来,事故响应会变成猜测而非工程化的过程。

一个用于可靠智能体系统的参考架构

生产就绪的智能体系统受益于清晰的关注点分离。目标是让智能体在决策上智能,但在基础设施上“愚笨”。

核心组件

1. 网关 / API 边缘
客户端(应用、服务、UI)的单一入口。负责:

  • 认证与授权(用户、服务、租户)
  • 速率限制与配额
  • 请求整形(schema、大小限制、基本校验)

2. 编排器
编排器是“脑干”,而非大脑。它负责协调:

  • 规划器:将用户意图翻译为工作流或状态机
  • 状态编排器:执行该工作流、跟踪状态、处理重试与超时
  • 策略引擎:执行安全、合规、允许工具、PII 规则与成本预算

LLM 位于编排器后面,被规划器与需要语言理解的特定工具使用。

3. 工具与存储层
业务逻辑保留在现有微服务、队列与数据系统中。工具是对这些资源的薄封装:

  • 内部 HTTP/gRPC 服务
  • 数据库、向量存储、缓存
  • 外部 API

编排器通过严格契约调用工具,而存储系统保持事实源头。

集成、控制与遥测

在网关处强制执行认证与配额;在编排器处强制执行安全、数据访问与策略。所有调用(LLM 与工具)向结构化遥测管道发出数据,供:

  • 覆盖每步行为的追踪
  • 用于 SLO 与速率限制的指标
  • 用于安全与合规的审计日志
  • 按用户、项目与工具的成本核算

更简单的架构(网关 → 单一编排器 → 工具)更易运维;增加独立的规划器、策略引擎与模型网关能提升灵活性,但成本是更多的协调、延迟与运维复杂性。

将所有要点整合并为团队的下一步

现在你已有让智能体在真实负载下可预测的核心要素:显式状态机、清晰的工具契约、纪律化的重试与深度可观测性。最后一步是把这些理念变成团队可复用的实践。

核心模式一张图概述

把每个智能体想象成一个有状态的工作流

  • 状态机 定义合法步骤(plan → gather → act → summarize 等)与它们之间的转移。
  • 工具契约 定义每个动作能做什么,带严格的 schema、超时与错误面。
  • 重试与幂等性 保护每次外部交互,使重放安全且副作用不会重复应用。
  • 可观测性(追踪、指标、日志)使每次决策与工具调用可解释且可调试。

当这些部分协同工作时,系统会优雅降级,而不是在边缘情况下崩溃。

将智能体投入生产前的轻量检查表

在把原型智能体发布给真实用户之前,请确认:

  • 工作流:状态与转移显式;没有隐藏循环或无界的工具链。
  • 契约:每个工具有类型化的输入/输出、清晰的失败模式与超时。
  • 安全:对输入、输出与动作有护栏(速率限制、白名单、配额)。
  • 重试:为每个工具定义策略;所有有副作用的调用都有幂等键。
  • 状态:记忆与持久化状态有边界、版本化并可恢复。
  • 可观测性:你能在一条追踪中回答“发生了什么?”
  • 测试:有基于场景的测试和提示/工具/策略的回归套件。

如果任何项缺失,你仍处于原型阶段。

团队如何分工与承担责任

可持续的设置通常分离职责:

  • 产品团队:负责智能体行为、提示、领域相关工具与评估数据集。
  • 平台 / 基础设施团队:负责状态机框架、通用工具 SDK、日志与追踪、策略执行与共享评估基础设施。

这样既能让产品团队快速迭代,又能让平台团队强制保证可靠性、安全与成本控制。

未来扩展与安全迭代

在打好基础后,你可以探索:

  • 基于日志的学习策略:用记录的追踪改进路由、工具选择与回退策略。
  • 强化学习:以长期目标(任务完成率或收入)而非单次响应来优化策略。
  • 自调流程:根据观测到的性能自动调整温度、工具或子流程。

在此方向上应采取渐进式引入:把新学习组件置于功能开关后面,进行离线评估并加上强力护栏。

贯穿始终的主题是:为失败而设计,偏好清晰而非聪明,并在可观测且可回滚的前提下迭代。在这些约束就位后,智能体不再是可怕的原型,而是组织可依赖的基础设施。

常见问题

什么是智能体系统?它与普通的 LLM 应用有什么不同?

智能体系统是一类应用,LLM 不只是回答单次提示,而是决定下一步做什么:调用哪个工具、检索哪些数据、执行工作流中的哪一步以及何时结束。

与简单的对话补全不同,智能体系统由以下部分组成:

  • 决策策略(LLM + 提示)
  • 跟踪进度的工作流或状态机
  • 一组工具(API、数据库、服务)
  • 用于重试、状态持久化、日志和可观测性的基础设施

在生产环境中,LLM 成为更大确定性外壳内的一个决策组件——而非整个系统的全部。

为什么在演示中表现良好的智能体在生产中常常失败?

演示通常只覆盖“快乐路径”:单个用户、理想的工具行为、没有超时、没有模式漂移、对话很短。生产环境下,智能体会遇到:

  • 不稳定的工具:超时、5xx 错误和返回格式变化
  • 并发:大量用户竞争共享资源与速率限制
  • 长时间会话:上下文膨胀、记忆混乱、状态漂移
  • 模型错误累积:在多次工具调用中小错误逐步放大

如果没有显式的工作流、契约和故障处理,这些因素会引发循环、阻塞、部分完成和沉默错误,而这些在演示环境中往往看不到。

怎样让智能体可预测且易于调试?

让 LLM 在一个清晰结构内运行,而不是自由循环:

  • 将智能体建模为具有有限状态和允许转移的状态机
  • 仅在局部决策使用 LLM(例如:接下来调用哪个工具,如何填充参数),而不是让它发明任意流程。
  • 将状态持久化到外部,这样每次转移都可重放和审计。
  • 保持智能体小而专注:一个主要职责,一个主要成功指标。

这让你能逐步解释、测试和调试行为,而不是追着不透明的“智能体思路”跑。

把智能体建模为状态机是什么意思?

把智能体建模为带名称状态和类型化事件的工作流,而不是 while not done: call LLM

典型状态可能包括:

  • PLAN — 解析请求并生成逐步计划
  • CALL_TOOL — 调用具体工具或一组工具
  • VERIFY — 根据简单不变式或附加模型检查输出
  • RECOVER — 通过重试、回退或升级处理错误
  • DONE / FAILED — 终态

事件(例如 ToolCallSucceeded, TimeoutExceeded)加上当前状态决定下一步状态。这使得重试、超时和错误处理变得显式,而不是隐藏在提示或胶水代码中。

我应如何为智能体设计工具契约?

把工具设计成真正的生产 API,而不是埋在提示里的散文说明。每个工具应包含:

  • 输入 schema:必需字段、类型、约束与默认值
  • 输出 schema:成功结构、部分结果和“无结果”的含义
  • 类型化错误:例如 InvalidInputNotFoundRateLimitedTransientFailure
  • 运行期预期:延迟目标与速率限制

在调用前验证输入,调用后验证输出。对工具契约进行版本化,并将智能体固定到具体版本,以免模式变动悄然破坏流程。

如何在智能体工作流中处理失败、重试和幂等性?

假设所有外部调用都会在某个时刻失败,并据此设计:

关键模式:

  • 幂等性:有副作用的工具接受稳定的 request_id 或业务键,重复调用应返回相同结果。
  • 有针对性的重试:对瞬时错误(超时、5xx、速率限制)使用指数退避与抖动,并设置最大尝试次数。
  • 断路器:在连续故障后暂时阻断对该工具的调用,并切换到回退或降级模式。
  • 结构化失败面:返回显式错误类型,让智能体决定是重试、重规划还是询问用户。

这样能在不产生失控循环、重复副作用或成本暴涨的前提下保持高可用性。

管理智能体的记忆与状态应该怎么做?

短期状态长期记忆分离,并让 LLM 本身保持无状态。

  • 短期状态用于完成当前工作流所需的一切:当前目标、步骤、工具输出与重试计数。任务结束后应可丢弃。
  • 将长期记忆(用户档案、项目历史)存储在外部,使用结构化 schema而非原始对话文本。
  • 把 LLM 当作对显式状态对象的纯函数:加载相关状态,构建提示,调用模型,然后持久化更新后的状态。

避免用原始日志或完整会话历史作为“记忆”;应从中派生简洁的结构化记录并制定明确的保留与隐私规则。

我应该如何处理并发、速率限制与系统的背压?

把你的智能体系统当作在负载下运行的分布式系统来设计,即使每个流程在白板上看起来是顺序的。

要保持可靠:

  • 将长时间运行或有副作用的步骤放到队列后面,用工作池控制并发。
  • 对模型和工具实施基于用户、租户与全局的速率限制
  • 使用背压策略:丢弃非关键流量、降级功能或在饱和时暂停低优先级队列。
  • 结合幂等工具契约与乐观/悲观并发控制,以避免双重工作和竞态条件。

监控队列深度、延迟分位数与 429/503 错误率,以便在过载成为故障前检测到问题。

在生产中安全运行智能体需要哪些可观测性?

你需要能回答“该智能体做了什么?”和“为什么这么做?”两个问题。

实用需求:

  • 追踪(traces):每个任务的一条端到端追踪,覆盖状态转移、工具调用与模型调用。
  • 结构化日志:记录关键决策(工具选择、计划修正、护栏触发),并带上关联 ID。
  • 指标:任务成功率、按状态划分的失败率、延迟(总体和按工具/模型)、每次成功的成本。
  • 脱敏:在记录提示、工具输入与输出前屏蔽 PII 与密钥;按敏感度控制保留期。

有了这些,事件响应就能从“智能体很不稳定”变为定位具体状态、工具或变更的精确陈述。

团队应该如何长期、安全地发布和运维智能体系统?

把智能体当作不断演进的服务来管理,而不是静态的提示,采用与其他生产系统同样严谨的管理方式。

建议做法:

  • 使用 影子模式、金丝雀和功能开关(feature flags)逐步发布新智能体或模型版本。
  • 为可靠性、延迟与质量定义 SLO,并把它们与告警和事故处置书(runbooks)挂钩。
  • 对任何提示、工具或策略的更改保留回归套件与离线回放。
  • 拆分责任:产品团队负责行为、提示与领域工具;平台团队负责状态机框架、共享工具、可观测性与策略执行。

这样既能让产品团队快速迭代,又能保证故障被限制、可诊断且可回滚。

Related posts