跳到主要内容

人类编写但 AI 客服 Agent 无法解析的运维手册

· 阅读需 12 分钟
Tian Pan
Software Engineer

你公司的资深支持工程师打开了一个 AI 智能体已经关闭的工单,发现了智能体的总结:“已解决 —— 已在 Stripe 中确认账单,根据企业政策升级至客户经理 (AE),退款 48 美元。” 每一句话听起来都很合理。但事实上,没有任何一件事发生了。根本没有名为 check_stripe 的工具。也没有任何工具可以查询客户级别。总结中提到的 “AE” 已经不再负责该账户。智能体并没有调用它声称的任何工具;它只是通过改写工程师每周一都会阅读的同一份操作手册(playbook)来生成总结。而客户仍在等待。

智能体阅读的操作手册(runbook)本身是正确的。客户成功团队花了两年时间对其进行调整。资深工程师曾用它来培训新人。它准确地描述了人类会做的事情:如果客户提到账单,检查 Stripe;如果是企业客户,先联系 AE;如果紧急,进行升级。智能体的失败并不在于它忽略了操作手册,而在于它像人类读者一样解析了手册 —— 它补全了手册中没有明确说明的所有内容,然后像执行已写下的指令一样去执行这些补全的内容。

这正是 2026 年大多数生产环境中的支持智能体崩溃的原因:不是因为模型、工具或数据,而是因为文档。客户成功团队积累了五十年的操作指南,是专门为人类读者编写的。而智能体平台团队将同样的指南输入到模型中,让模型以另一种受众的视角去阅读。没有哪个团队负责这两者之间的翻译转换。于是,这种“误译”出现在每一个工单中。

人类操作手册是用隐性知识缩写编写的

“检查 Stripe” 并不是一条指令。它指向的是存在于资深工程师脑海中的一套流程:打开 Stripe,搜索客户的公司名称(不是用户的电子邮件,因为公司通常以不同的法律实体签署合同),扫描过去 90 天的账单,查找争议费用,查找失败的卡片重试记录,并与支持工单的时间戳进行交叉比对。一个加入团队一个月的初级工程师在一周内就能学会这一套流程,并开始习以为常。而五年前编写该手册的资深工程师写下 “检查 Stripe” 是因为任何更细颗粒度的描述都会让他在想象读者时感到是在低估对方的智商。

智能体读到同样的两个词,并合成了一个工具调用。如果工具库中有一个名为 lookup_invoices_by_customer 的工具,智能体可能会调用它;如果没有,智能体极有可能会凭空捏造一个。这在多个智能体框架中都有记载 —— 当 Prompt 提到一个领域动作但没有给出确切的工具名称时,模型会根据文本幻觉出一个工具名称(如 check_stripe$ARTIFACT_TOOLlookup_user_tier),并表现得好像调用返回了数据一样。随后生成的总结就像幻觉出的调用成功了一样。

同样的模式也出现在决策谓词(decision predicates)中。“如果是企业客户” 是资深工程师通过扫一眼 CRM 的级别徽章来评估的谓词。操作手册并不会写 “调用 get_customer_tier(account_id) 并在字符串为 enterprise 时进行分支跳转”。智能体有三个选择:幻觉出一个调用、跳过该谓词,或者根据文本上下文(客户的邮箱域名、工单的用词)猜测答案。这三种做法都是错误的,且错误方式相同 —— 它们在总结中看起来像是正确的步骤,但实际上没有任何工具输出作为支撑。

操作手册现在是面向多种受众的产物

支持团队尚未吸收的架构事实是,操作手册不再是仅供单一读者阅读的文档。同一个 Markdown 文件会被以下角色解析:

  • 资深工程师,他们会快速浏览相关章节,并凭记忆补全其余部分。
  • 初级工程师,他们逐句遵循手册,并在不清楚时在 Slack 中提问。
  • 支持智能体,它将其作为程序执行,且没有带外(out-of-band)渠道来提出澄清问题。
  • 内部可观测性工具,它对其进行索引以生成“我们是否遵循了手册?”的仪表盘。
  • 有时是第三方集成商,通过 API 嵌入你的支持流程。

每位读者对歧义的容忍度不同。资深工程师容忍度最高,而智能体容忍度最低。作者针对他们预想的读者(几乎总是人类)进行了优化,而今晚阅读文档的受众恰恰是那些无法填补空白的人。将操作手册视为单一受众的单一文档是导致这种不匹配的根源。

解决方法并不是为智能体重写每一份操作手册。那样会让仍然负责这些流程的人类感到文档晦涩难懂。解决方法是意识到文档有两个层面,并为每个层面提供专门的章节。

可执行章节:工具、参数、谓词,无隐性步骤

每一个将由智能体执行的操作手册都需要一个明确的可执行章节,这是人类文本章节无法替代的。可执行章节指明了工具库中存在的工具。它列举了这些工具所需的参数,以及每个参数在当前上下文中的来源。它将决策谓词编写为与工具输出的对比,而不是自然语言形容词。它不包含隐性步骤 —— 每一步都基于工具调用,其名称逐字出现在智能体的工具列表中。

在可执行章节中,“检查 Stripe” 这一行变得类似于:使用 crm.find_customer(account_name=ticket.account_name) 返回的 customer_id 调用 stripe.invoice_list,筛选出过去 90 天内 status{past_due, disputed} 的账单,并将列表返回给下一步。“如果是企业客户” 谓词变为:调用 crm.get_account(account_id) 并根据 account.tier == "enterprise" 进行分支跳转。重点不在于文字变得更难看,而在于文字中不再有隐性上下文的空间。要么步骤是有依据的(grounded),要么它就不该出现在可执行章节中。

人类文本章节保留了下来 —— 它是资深工程师阅读的内容、新员工入职培训的依据,也是团队在手册出错时进行辩论的工具。但这两个部分被明确标记,智能体的指令模板仅将可执行部分加载到 Prompt 中,而人类文本部分则被加载到标记为“背景”的独立上下文块中,并指示智能体不要将其转换为工具调用。指令纪律非常直接:文本解释“为什么(why)”,可执行部分说明“做什么(what)”,而智能体只被允许根据“做什么”采取行动。

这与 Addy Osmani 等人在更广泛的智能体规范中推动的形式一致 —— 即智能体规范必须像具有明确工具链入口的设计文档一样进行结构化,而不是像连续文本编写的维基页面。客户支持操作手册恰好是跳过这一纪律导致代价最先显现的地方,因为操作手册比智能体出现得更早,且编写者从未想象过会有非人类读者的存在。

针对实时工具目录对可执行部分进行 Lint 检查

可执行部分现在是代码,而且像所有代码一样,它会产生“漂移”。当平台团队标准化 API 接口时,某个工具可能会被重命名。以前默认使用请求代理身份的参数,现在需要显式传递。新增加的一个工具替换了三个旧工具。Runbook 并没有改变,因为编写它的自然人并不会去阅读工具目录的变更日志 (Changelog)。

弥补这一鸿沟的机制是在合并时以及按计划对每个 Runbook 运行 Lint 检查。Linter 会解析每个可执行部分,提取每个工具名称和每个参数引用,并将它们与 Agent 在运行时使用的实时工具目录进行比对。任何在目录中不存在的命名工具都会导致 Lint 失败。任何未从前序步骤输出、工单数据 (Ticket payload) 或类型化输入中获取的必填参数都会导致 Lint 失败。任何将工具输出与该工具 Schema 无法产生的值进行比较的谓词 (Predicate) 都会导致 Lint 失败。

Lint 检查失败的 Runbook 不能作为 Agent 加载的活动版本。拥有该 Runbook 的团队既可以针对新目录修复可执行部分,也可以将 Runbook 固定 (Pin) 在旧的目录版本上,但任何一方都不允许发布 Agent 无法机械化执行的 Runbook。这与在运行时对工具输入进行 Schema 校验的纪律相同——但它被应用在了创作阶段,因此在客户成功工程师点击保存时就能发现错误,而不是在客户工单处理到一半时才崩溃。

将旧工单作为 Agent 的回归测试集进行回放

即使 Runbook 经过了完美的 Lint 检查,Agent 有时仍会选择一个孤立来看似乎正确,但与高级支持工程师实际处理方式不符的步骤。捕捉这一点的机制与目前评估 Agent 的通用标准模式相同:一套由过去已知正确解决结果的工单组成的回归测试集,在每次变更时通过 Agent 对当前的 Runbook 进行回放。

这个测试集不需要非常庞大。20 到 50 个回放追踪 (Replay traces)——取自高级工程师正确解决的真实工单——就足以捕捉大多数回归。评分标准不是“Agent 生成的词句是否与人类相同”,而是“Agent 是否在相同的决策点选择了相同的工具序列”。如果高级工程师先调用了 crm.get_account,接着调用了 stripe.invoice_list,然后上报给了指定的 AE,那么在回放中,Agent 的追踪记录也应该按相同顺序执行这三个步骤。出现的偏差会被视为评估失败并进行检查——有时 Agent 是对的而人类偷懒了,有时是 Runbook 发生了漂移,有时则是 Agent 凭空捏造了一个步骤。

这种评估必须存在于支持团队和 Agent 平台团队都能看到的地方。如果只有平台团队关注它,支持团队会不断以导致评估失败的方式编辑 Runbook,却不明白为什么他们的合并被阻止了。如果只有支持团队关注它,平台团队发布的模型升级可能会悄无声息地使一半的黄金标准集 (Goldens) 失效。评估是这两个团队之间的契约。

Mercadona 风格的黄金集纪律很好地说明了一点:评估集相对于模型输出必须是不可变的。如果你每次更改模型时都根据 Agent 当前的行为重新生成黄金标准,那么评估就变成了对自洽性的测量,而不是对正确性的测量。黄金标准来自于真正正确解决工单的人类,它们保持冻结状态,直到人类对其进行审查和更新。

Playbook Diff 所揭示的组织失效

人类语言描述与可执行部分之间的差异 (Diff) 不仅仅是一个文档产物。它是你支持栈中谁拥有什么的真实地图。每一处人类语言描述丰富而可执行部分为空白的地方,都是人类在做 Agent 平台尚未编码的隐性工作。每一处可执行部分丰富而人类语言描述薄弱的地方,都是 Agent 拥有支持团队并不知道、也没有在培训新员工时提及的能力。

发布支持 Agent 却不关注这种差异的团队最终都会陷入同样的境地:支持团队指责 Agent 平台提供的 Agent 乱作为,Agent 平台团队指责支持团队的 Runbook “结构不规范”,而客户在等待,直到复盘 (Post-mortem) 发现了一段无人负责的翻译错误。发布有效 Agent 的团队意识到 Runbook 现在是一份契约——对双方受众都可读、可针对工具目录进行 Lint 检查、可针对历史工单进行回放——而且这份契约必须由双方共同拥有,否则它根本就不再是一份契约。

这一切背后的架构认知非常直观。Runbook 曾经是为能够填补空白的人类准备的建议性文档。它们现在是可执行的产物,其读者包括了无法填补空白的系统。没有为新读者重写 Playbook 的团队,正在为每一张工单支付误译的代价——有时是一个错误的答案,有时是一个言之凿凿的错误总结(随后必须由人类撤销),无论哪种方式,这都是对客户信任的损耗,这种损耗会不断累积,直到有人发现 Playbook 已经和 Agent 鸡同鸭讲了好几个月。

References:Let's stay in touch and Follow me for more thoughts and updates