跳到主要内容

191 篇博文 含有标签「agents」

查看所有标签

双跳工具链:为什么 95% 的工具组合会变成 80% 的流水线

· 阅读需 13 分钟
Tian Pan
Software Engineer

你的可观测性技术栈中的单工具仪表盘讲了一个令人宽慰的谎言。search_listings 的成功率是 96%,显示为绿色。book_appointment 是 95%,也是绿色。而连续调用这两个工具的智能体(agent)三周以来的成功率一直只有 78%,却没人能解释原因。原因不在任何一个工具内部,而是在它们之间的缝隙里——那个没有任何仪表盘面板覆盖的地方。

组合不是加法。当工具 A 的输出流入工具 B 的输入时,故障面并不是 B 对“有效调用”的狭隘定义下的 1 - (0.96 × 0.95)。它是 A 在 B 的标准下所有微妙偏差方式的完整笛卡尔积:A 返回的日期格式是 MM/DD/YYYY,而 B 期望的是 ISO 8601;返回的价格单位是分,而 B 解析的是元;分页游标指向了最后一个结果之后的一项;或者上游服务昨天重命名了一个实体 ID。这些情况都能顺利通过 A 自身的契约测试(contract tests),但每一个都会导致 B 崩溃。团队的单工具可靠性指标永远看不到这一点,因为按各自的标准来看,每个工具都运行良好。

升级率:离线测试遗漏的评估信号

· 阅读需 11 分钟
Tian Pan
Software Engineer

每个智能体(agent)功能都有一个“后门”。有的团队称之为“转人工支持”,有的称之为“路由至人工审核员”,还有的则使用模板化的回复:“我无法处理此事——让我为你联系能提供帮助的人。”无论标签是什么,每个生产环境中的智能体都有一条放弃用户请求并将其移交给人工的路径。而生产流量采取该路径的比例,是少数几个不依赖标注员、评审员或手动构建测试集的信号之一。这是系统在生产环境中告诉你,模型无法处理用户实际发送的请求。

这个信号几乎总是被错误的团队读取。在大多数公司中,转人工率(Escalation rate)是一个劳动力规划指标:它决定了下一季度排队系统需要多少人工客服。它存在于运营团队审查的仪表板上,其审查频率与 AI 团队读取评估分数(eval scores)的频率完全不同。30% 的周环比转人工增长在周一的运营审查中表现为一个人员配备问题,而 AI 团队的评估套件依然显示绿色,领导层的报告也显示功能状态良好。两个团队看着同一个生产系统,却得出了截然相反的结论:运营团队认为他们需要更多人手,而 AI 团队认为模型运行良好。

智能体内存驱逐:为什么 LRU 在模型升级中屹立不倒,而显著性评分却不行

· 阅读需 11 分钟
Tian Pan
Software Engineer

那些发布了带有显著性加权内存驱逐(salience-weighted memory eviction)功能智能体的团队,在不知不觉中,已经为每一次模型升级预订了一个内存迁移项目。驱逐策略表面上看起来是一个质量杠杆——选择最聪明的评分方法,获得最好的召回——但它实际上是一个隐秘的版本契约。当评分模型发生变化时,智能体实际上的“过去”也会随之改变。现有的围绕提示词和评估(evals)构建的工具链都无法捕捉到这一点,因为发生漂移的产物既不是提示词也不是评估,而是几个月前由一个已经不存在的模型做出的一系列关于“该忘记什么”的决定。

LRU(最近最少使用)和 LFU(最不经常使用)没有这个问题。它们是确定性的、与模型无关的,并且可以干净利落地在升级中幸存。但它们也会丢弃掉那些审慎的裁判模型会保留的信息。这是大多数团队在第一天——当 Demo 的召回率指标是衡量一切的唯一标准时——会做出的妥协。然而,这种妥协在智能体余下的生命周期里,每季度都会反噬你一次。

浏览器 Agent 会话泄漏:当单个 Profile 服务于多个租户时

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个计算机使用型智能体(computer-use agent)在客户的 CRM 上完成了一项任务,工作线程池将浏览器返回到空闲环中,几百毫秒后下一个请求到达,仪表板导航成功——唯一的问题是,它是作为错误的用户登录成功的。前一个会话的 OAuth cookie 仍留在配置文件(profile)中。追踪记录显示 navigation succeeded(导航成功)、screenshot captured(截图已捕获)、action performed(操作已执行)。运行日志中没有任何内容表明,智能体正在以一个从未授权过它的用户身份进行操作。

这是浏览器智能体从其构建所用的库中悄然继承的一类故障。无头浏览器(headless browser)框架被设计为每个配置文件仅供一个用户使用,因为这是浏览器三十年来的工作方式。当工作池为了摊销全新的 Chromium 实例长达八秒的冷启动时间而重用配置文件时,这种“单用户”假设就破裂了,而且这种破裂对于团队通常信任的每一层遥测数据来说都是不可见的。

凭证残留:你已停用的智能体仍处于生产环境登录状态

· 阅读需 11 分钟
Tian Pan
Software Engineer

在你关停(sunset)一个智能体(agent)六个月后,一名安全审计员在团队的 Slack 上发消息问:“为什么这个 OAuth 应用仍然拥有公司 Google Workspace 的读取权限?”没人认得这个应用名称。有人 grep 了代码库——没有匹配项。有人检查了部署清单——也没有匹配项。最终,一位前任产品经理(PM)想了起来:那是会议摘要原型,一个在第三季度被砍掉的产品。面向用户的界面早已被删除。但 OAuth 授权、BigQuery 中的服务账号、Pinecone 索引、Slack 告警路由、Datadog 仪表盘、Splunk 保存的搜索、充满客户转录文本的评估数据集——所有这一切依然存在,依然已授权,也依然在计费。

这就是凭证残留问题,它是智能体时代最主要的运营失效。你发布的每一个智能体都会在各供应商、内部服务和数据系统中创建出一圈资源。当你通过删除代码来退役一个智能体时,你移除的可能仅占其创建内容的五分之一。剩下的部分作为“幽灵基础设施”留在生产环境中,无人认领、无人负责,而且最危险的是,它们依然持有凭证。

评估选择偏差:为什么你的测试集会对那些导致用户流失的失败视而不见

· 阅读需 11 分钟
Tian Pan
Software Engineer

在生产级 LLM 评估中存在一种悄无声息的失败模式,这是任何排行榜都无法捕捉到的:你的测试集是基于留存用户构建的,因此它永远不会提出那些让其他用户离开的问题。季度复季度,评估分数攀升,仪表板一片绿,但净留存率(net retention)依然在下滑。团队在追问“评估是否可被操纵?”,而真正的故事更简单也更残酷:评估分布向幸存者偏移了,而幸存者恰恰是你最不需要其反馈的人群。

这是换了装束的二战轰炸机装甲问题。Abraham Wald 观察了返回的飞机,注意到弹孔聚集在哪里,并指出你应该加固的地方是那些没回来的飞机上的弹孔。把轰炸机换成用户,把弹孔换成失败的交互轮次,你就得到了从生产追踪(production traces)中提取评估集的中心病理。

MCP 冷启动税:工具服务器开销如何在智能体第 7 步发生累加

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个 200 毫秒的工具调用在火焰图(flame graph)上看起来就像是杂音。但在 Agent 循环中堆叠七个这样的调用,杂音就变成了信号 —— 模型在 800 毫秒内完成了思考,但用户却等待了 4.5 秒,因为每一次工具调用都在重新支付首个调用已经吸收掉的启动成本。残酷之处在于,这种成本在任何单一的追踪(trace)中都不会显示为异常。它表现为干脆利落的 Demo 与反应迟缓的生产环境 Agent 之间的差异,而大多数团队会将其归咎于模型。

Model Context Protocol (MCP) 已成为 Agent 工具链的默认集成界面,这意味着它也成了延迟(latency)堆积的重灾区。MCP 的设计 —— 基于 stdio 或可流式 HTTP 的 JSON-RPC、能力协商(capability negotiation)、动态工具发现 —— 对于一个必须桥接任意客户端和服务器的协议来说是正确的。但它隐含的单次调用成本结构对于 Agent 实际的访问模式并不友好。Agent 的模式不是“每个会话调用一次工具”,而是“每轮对话调用七个工具,每个会话进行四十轮对话”。

这篇文章将探讨这种错配:冷启动税究竟存在于何处,为什么它在长生命周期的 Agent 中是叠加而非被摊销(amortize)的,以及如何通过“预热池”(warm-pool)规范将数秒的惩罚降低到 100 毫秒以下。

多维 Agent 二分查找:当回归出现在交互中时

· 阅读需 12 分钟
Tian Pan
Software Engineer

质量在一夜之间下降了。值班工程师打开仪表盘,追踪了几个异常会话,并开始进行显而易见的二分定位:模型提供商在 UTC 时间 02:00 切换到了新的快照,于是将模型回退到固定的旧别名。评估套件仍然显示红色。回滚昨天的提示词更改。仍然是红色。将检索索引固定回上周的版本。仍然是红色。每个负责团队都在孤立地回滚自己的维度,并报告“不是我们的问题”。三个小时过去了,没有人负责诊断,因为没有人负责回归真正存在的交互面(interaction surface)——新模型以一种旧模型绝不会采取的方式,解释了新的工具描述。

这就是单轴工具无法解决的失败模式。git bisect 之所以有效,是因为搜索空间是一维的:提交记录的线性序列。而 Agent 没有单一的时间线。它有四到五个并行运行的时间线——模型快照、系统提示词、工具目录、检索索引、采样配置——每个都有自己的负责人、自己的部署节奏,以及自己的“回滚”按钮,只能将其自身的轴恢复到已知状态。你正在追踪的回归通常是一个双因素交互作用,沿着任何单一轴进行二分都会返回假阴性结果,因为该 bug 仅在“新模型遇上新工具描述”的交叉乘积单元格中触发。

多模态通道冲突:当模型在视觉与文本之间自我矛盾时

· 阅读需 12 分钟
Tian Pan
Software Engineer

这张图片是一张红色八角形停止标志的照片。有人在中间的单词上贴了一张小贴纸,上面写着“YIELD”(让行)。你问多模态模型:“这个标志写了什么?”模型回答:“该标志指示驾驶员在交叉路口让行给迎面而来的车辆。” 表现得既自信又流利,却既不忠实于视觉证据,也不忠实于文本证据。它是一个混合体,在产生分歧的真相通道之间采取了折中方案。

这种故障模式目前还没有一个统一的名称。研究多模态幻觉(multimodal hallucination)的研究人员将其称为“语义幻觉”(semantic hallucination)、“跨模态偏差”(cross-modal bias)或“模态主导”(modality dominance),具体取决于撰写论文的细分领域。交付文档 AI、截图智能体和缺陷检测系统的从业者每周都会遇到这种情况,并在事故复盘中将其描述为“模型只是在瞎编”。它不是瞎编的。这是一种在最终层融合了两个通道、却没有任何原语来表示通道意见不一情况的架构的可预测输出。

静默工具截断:你的智能体在不知情下进行推理的默认限制

· 阅读需 12 分钟
Tian Pan
Software Engineer

一个工具调用返回了 142 KB 的 JSON 数据块。你的智能体框架丢弃了 8,192 字节之后的所有内容,将前缀交给模型,而模型根据一个它从未意识到是不完整片段的内容写出了一个自信的答案。三周后,一名客户升级了投诉。你翻看追踪记录(trace),看到“工具返回成功”,随后的复盘变成了寻找哪一步“忽略”了证据——然而没有哪一步忽略了它。证据在到达推理引擎之前就被裁剪掉了。

这并非假设。Codex 将工具输出截断硬编码为 10 KiB 或 256 行。Claude Code 的工具结果默认为 25,000 个 token,并且带有一个单独的显示层限制,曾在 2025 年短暂地将 MCP 响应裁剪到 700 个字符左右。OpenAI 的工具输出提交上限为 512 KB。每个框架都选择了一个看起来安全的数字,对于短工具调用确实如此。当单步输出越界时,故障模式就出现了——悄无声息地,没有异常,也没有模型可见的标记。

当工具撒谎时:智能体默认信任的“伪成功”失败模式

· 阅读需 12 分钟
Tian Pan
Software Engineer

智能体自信地告诉用户:“我已经发送了确认邮件,并将退款退回到你的账户。”追踪记录很干净:两次工具调用,均返回 {"success": true},模型生成了精练的摘要,对话在 3.2 秒内结束。一周后,客户发起投诉,因为邮件从未送达,退款也从未入账。审计日志中全是绿色的勾选标记。没有任何环节失败——除了实际的工作本身。

这就是在大多数智能体技术栈中尚未被命名的故障模式:撒谎的工具。这里的“撒谎”并非恶意——它们返回了其契约规定的响应。这种谎言是结构性的。HTTP 层返回 “200 OK” 是因为请求被接受了,而不是因为操作完成了。邮件服务商返回 success: true 是因为消息进入了发送队列,而不是因为它已经发出了。数据库写入返回且无报错,是因为它写入了一个从未同步的副本。被训练成“乐于助人”且在“绿色代表完成”的示例上训练过的模型,将这些信号编织成一份自信的摘要,然后继续下一步。

挂钟时间截止日期漂移:为什么你的智能体认为它还有时间但实际上没有

· 阅读需 11 分钟
Tian Pan
Software Engineer

用户点击发送。智能体被配置了 30 秒的时间配额。规划器(planner)检查任务,发现一条耗时约 12 秒的“深度研究”路径和一条耗时 3 秒的“快速查询”路径,并自信地选择了深度路径,因为“我们有充足的时间”。28 秒后,响应返回,比团队上季度发布的 SLA 晚了 2 秒。仪表盘显示,智能体的推理是正确的,重试逻辑是正确的,工具调用也成功了。没有人能解释为什么用户的加载动画转了 46 秒。

这个 bug 不在任何单一组件中。它存在于组件之间的缝隙中,存在于一个系统从未想过要刷新的值里:智能体对于还剩多少时间的认知。在请求受理与模型的下一个规划步骤之间,发生了一次透明重试,挂钟时间在流逝,但截止时间的元数据却没有更新。模型现在正根据它在 15 秒前就已经花掉的预算进行推理,而它自己对此一无所知。