跳到主要内容

311 篇博文 含有标签「ai-agents」

查看所有标签

没有模型推理项的故障复盘模板

· 阅读需 11 分钟
Tian Pan
Software Engineer

第一次智能体导致我们团队出现真正的停机事故时,复盘报告的作者打开模板,划过时间线,盯着“根因”字段沉思了良久,然后输入:“队列阻塞恢复的操作指南 (runbook) 有误。” 但实际上操作指南没问题。智能体阅读了指南,认定队列的症状符合另一种场景,并针对该场景运行了恢复脚本。那份文档产生的改进措施——“细化操作指南用词”、“在恢复脚本中增加确认提示”——对于实际的故障模式完全无用。实际情况是一个推理系统推导错误,而模板中没有任何字段知道该如何表达这一点。

自那以后,我看到同样的失败在不同团队中反复上演。模板是为确定性系统设计的。代码做错了,你就修复代码;配置设错了,你就修复配置。复盘文档的模式 (schema) 就是团队关于故障理论的模式,当这个理论无法表达“智能体的计划错了”时,文档就会将实际故障强行降维成模板表达的最接近的事物——通常是文档缺失或缺乏护栏——从而导致改进措施试图用确定性的修复方案去解决概率性的故障。然后,同一类事故会再次发生,团队下次依然会以同样的方式记录它。

你为人类设置的速率限制,AI 智能体三秒钟就会让其饱和

· 阅读需 11 分钟
Tian Pan
Software Engineer

速率限制从来就不是一种公平性原语。它只是一个逐渐“演化”而来的销售工程指标——是三年前某个解决方案工程师在客户接入期间随手写进文档、被复制到套餐定义中,且由于从未有人触发过而从未被重新审视的一个数字。这个限制写着“每分钟 100 次请求”,其真实含义是“超出了任何理性的集成方案的需求”,因为当时平台上的每一个集成都是由人类在键盘前驱动的后端服务,而人类每分钟敲不了 100 次字。

然后,一个付费租户将一个智能体(agent)指向了该端点。智能体不会打字。它不会为了阅读响应而停顿。它没有需要在请求之间渲染的 UI。它执行一个规划循环,每一个推理步骤调用一次 API,而模型制定一个推理步骤只需要大约 30 毫秒的实际时间。智能体在 3 秒内就触及了每分钟的限额,在 3 分钟内触及了每小时的限额,而在轮值工程师的咖啡还没变凉之前,它就已经耗尽了每日配额。在限流仪表盘更新之前,技术支持的升级请求就已经送达了。

智能体安排的无人继承的周期性任务

· 阅读需 10 分钟
Tian Pan
Software Engineer

用户输入:“每周二提醒我检查那个集成。”Agent 创建了一个 cron 条目,返回礼貌的确认,随后会话关闭。六个月后,用户调换了团队。该集成在上个季度已被弃用。Cron 仍在运行,调用着在 4 月份轮换过的 API 密钥,发送到在 5 月份归档的 Slack 频道,费用计入无人查看的项目预算。Agent 完全按照要求执行了操作。出问题的是那个“要求”,它随着时间的流逝变得不再适用。

这不是某个特定 Agent 的 bug。它是这类事物的共性。当我们赋予 Agent 调度持久副作用的能力时——如 cron 任务、Webhook、轮询循环、工作流触发器、日历邀请、定期查询——我们就创建了一类生来就没有生命周期的基础设施。“创建”原语显眼且容易,“删除”原语、“审计”原语、“继承”原语——它们并不具有同等的地位,因此未被使用。

除非你主动去寻找,否则代价是隐形的,而此时恰恰没有人会去寻找。

你的定时 Agent 有四个时钟,而你信任的是错误的那一个

· 阅读需 14 分钟
Tian Pan
Software Engineer

一个每日站会总结被安排在 UTC 时间 09:00。定时任务(Cron)准时触发。两秒钟后,一个工作节点容器组(Worker pod)启动。LLM 调用又耗费了四十秒的往返时间。模型在撰写总结时认为现在是去年的 2 月,因为那是其训练数据最后确信的时间点。工具层在 UTC 时间 09:00:42 根据挂钟时间(Wall clock)发送了 Slack 消息,模型从未提及具体日期,因为没人要求它这样做。消息进入了正确的频道,昨天的站会笔记被总结成了“今天的”,而且整整三周都没有人察觉。

这并不是任何单一组件的 bug。这是一种在四个不同的时钟之间、谁也没有写下来的契约,而这四个时钟都认为自己知道“现在”是什么时候。

你没列进预算的"弃答税"

· 阅读需 12 分钟
Tian Pan
Software Engineer

你教会了 Agent 在上下文不足时说"我不知道",然后把这当成一次安全胜利。OpenAI 账单确实降了。所有人都同意这是负责任的做法。三个月后,你的客服 VP 在追问为什么人头预算偏差 40%,AI 团队里没人答得上来——因为你跟踪的指标是弃答率,而真正动起来的指标是每周工单数,而那条把它们加起来的曲线没有任何 owner。

这就是弃答税。它不是一种模型成本。它不会出现在推理账单上。它出现在下游:出现在每接住一句"我无法回答"就要排队处理的人工团队队列深度里,出现在针对人工额外补足后的上下文再跑一次的第二次模型调用里,出现在等待期间流失掉的客户身上。只看模型成本的那张账面,悄悄把它藏了起来。再加上 AI 团队负责弃答、运营团队负责队列的那道组织接缝,意味着没有人有动力去看清这件事。

那个用一小时反复重试同一个 400 错误的 Agent

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个 agent 调用了某个工具。工具返回 400 Bad Request,错误体结构清晰得无可挑剔:{"error": "missing required field", "field": "email"}。Agent 的推理链一字不差地复述了错误,说"我需要在请求里加上 email 字段",然后发出了下一个工具调用——负载和上一次一模一样。框架的重试策略是多年前为不稳定 HTTPS 连接写的,把这个 400 当成瞬时错误,又发了一次。三次。八次。十五次。一小时后,这个 agent 烧掉了上下文、烧掉了预算、烧掉了限流额度,却从未发出过一个工具能接受的请求。

这种失败看起来像是模型的问题。其实不是。模型把错误读对了。是包在它外面的框架,没有给"修正"留任何落脚点。

无法说出"等一下"的智能体

· 阅读需 10 分钟
Tian Pan
Software Engineer

随便挑一个过去两年里搭建的生产级智能体,清点它在某一轮里实际能做的事。清单很短:发起一次工具调用、给出最终答案,或向用户提一个澄清问题。这就是整个动作词汇表。注意一下缺了什么。没有动词表达"我想在决定之前多花点时间";没有动词表达"我足够不确定,所以希望暂停并重新考虑,而不立刻承诺";没有动词表达"我想在采取任何行动之前先在这件事上多停留一会儿"。智能体在字面意义上无法说出"等一下"。语法里压根没有这个词。

这并不是表面打磨的问题,而是结构性的问题。一旦智能体的全部输出都是动作,任何内部状态都必须经由一个动作来表达。犹豫变成多余的工具调用,怀疑变成自信的承诺。只设计了动作动词的团队,实际上发布了一个唯一的语言就是"做事"的智能体——然后又奇怪它怎么从来不像在思考。

当昨天的进度本身就是谎言:AI 时代的站会怎么开

· 阅读需 10 分钟
Tian Pan
Software Engineer

团队上午十点开站会。第一位工程师开始汇报他的 Agent 们昨晚完成了什么——只是,早上七点启动的评测套件还没跑完,Agent 凌晨三点开的那个 PR 正在等另一个 Agent 评审、而后者的队列深度无人知晓,长跑的重构 Agent 已经进入第十一个小时(预估是四小时),既没有卡住的信号、也没有健康的信号。昨天的状态既不是"已完成",也不是"进行中"。从会议室里看,昨天的状态根本无从得知。

![](https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E5%BD%93%E6%98%A8%E5%A4%A9%E7%9A%84%E8%BF%9B%E5%BA%A6%E6%9C%AC%E8%BA%AB%E5%B0%B1%E6%98%AF%E8%B0%8E%E8%A8%80%3AAI%20%E6%97%B6%E4%BB%A3%E7%9A%84%E7%AB%99%E4%BC%9A%E6%80%8E%E4%B9%88%E5%BC%80

站会本来是一种为同步人类工作量身定做的同步仪式。每个人做一件事、完成它、睡一觉、第二天早上汇报。工作的最小单位是一个工作日。汇报的最小单位是一个人。节奏匹配的是底层介质。现在这些前提全都不成立了。今天工作的最小单位是一次 Agent 运行,它在你上床前就启动了,可能在会议进行中或会议后三小时收工。汇报的最小单位是一支集群,而不是一个人。而那个节奏——上午十点准时开始、9 到 15 分钟一轮的轮流播报——是底层介质根本不会按这个频率产出事件的节奏。

把沉默当作同意的 ChatOps 机器人

· 阅读需 11 分钟
Tian Pan
Software Engineer

你的部署机器人已经上线九个月了。仪表盘显示消息量持续上扬,负面反馈率稳定在 2% 以下。负责它的团队把这解读为"已被采用"。然后,一位资深工程师顺口提了一句:他那个小组的人早在二月份就把那个频道静音了——他们对机器人发出的每小时摘要的信任程度,跟对厂商邮件 newsletter 差不多;他们受不了那种持续的嗡嗡声。机器人在对一个空房间说话,而指标却称之为"势头"。

这就是大多数 ChatOps 团队都会撞上、却几乎没人去度量的失败模式。当 Slack 或 Teams 里的机器人不再收到回复时,最轻松的解读是"智能体进入稳态了——用户不再需要跟它争论了"。诚实的解读通常恰好相反:用户在绕开它、把它静音,或者认定忽略提示比读它更省事。参与度图表无法分辨这两者。仪表化必须围绕一个前提重新设计:沉默是默认状态,而正确解读这种沉默才是真正的工作。

你的 Agent 没有留下的那本证据档案

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的调用链路会记录每一个 token。它记录每一次工具调用、每一次重试、每一次检索延迟、每一个模型 id。看起来无所不包。然后,某个监管机构、某个客户、或者你自己内部的 incident 频道,抛出一个本该轻松回答的问题:模型在决策那一刻究竟看到了什么? 你这才发现,调用链路记下了"问题",却没记下模型当时正在看着回答的"答案"。

那次检索命中的 chunks 早就因为上周二的重建索引轮换出了向量存储。那次工具响应是一段流式 payload,你只保留了最终态摘要,因为完整流会让账单翻三倍。那段 system prompt 是运行时按一个 feature flag 拼装出来的,而那个 flag 此后又翻转了两次,你的 flag 服务并不按时间戳保留历史值。你对发生了什么有完整的可观测性——调用图、token 数、延迟。但你对模型当时在针对什么作答,一无所知。这道缺口,就是调用链路与决策记录之间的差别。大多数团队没意识到自己只造了两者中的一个。

把每个工具都当作 O(1) 的规划器

· 阅读需 9 分钟
Tian Pan
Software Engineer

你的规划器输出了五次工具调用。从纸面上看,这是一个干净的解决方案:lookup_usersearch_documentscall_external_apispawn_sub_agentrequest_human_approval。轨迹优雅、逻辑自洽,智能体最终也会给出正确答案。可在生产环境中,这五个步骤分别耗时 12 毫秒、800 毫秒、4 秒、2 分钟和 6 小时。规划器从未察觉,它这五步计划在成本上跨越了九个数量级。

![](https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E6%8A%8A%E6%AF%8F%E4%B8%AA%E5%B7%A5%E5%85%B7%E9%83%BD%E5%BD%93%E4%BD%9C%20O(1%29%20%E7%9A%84%E8%A7%84%E5%88%92%E5%99%A8)

这并不是幻觉。模型选对了工具,顺序也合理。它做不到的——工具模式根本没给它做这件事的途径——是去推理:计划的最后一步在性质上和第一步完全不同。在规划器眼里,工具就是工具,计划图中每个节点的权重都是 1。

你的智能体无法穿透推理的脱敏层

· 阅读需 10 分钟
Tian Pan
Software Engineer

一次隐私评审批准了你的脱敏层。姓名、邮箱、账号、电话——所有这些都在提示词送达模型之前被清理掉了。你的单轮分类器仍然能跑到 94% 的准确率。六周后,你的多步骤智能体开始对类似"Sarah 用于登录的邮箱和她账单记录里的邮箱是同一个吗?"这样的问题给出自信但错误的答案,而且没人能在开发环境里复现。

脱敏层做到了 infosec 团队要求它做到的一切。它同时也悄悄地摧毁了你的智能体推理所依赖的性质:在不同轮次中出现的两个实体指代是同一回事。这个智能体并没有产生幻觉,它读到的是一份转录文本,其中 Sarah 变成了三个不同的人,"同一个"邮箱地址变成了两个互不相同的占位符。