跳到主要内容

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

查看所有标签

评分了每一轮对话却错过了整个交流:聊聊多轮评估的陷阱

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的评估仪表盘是一片绿色。单轮准确率(turn-level accuracy)保持在 95%,LLM 裁判(LLM judge)与你的标注人员意见一致,每一项回归测试在上线前都顺利通过。然后,一名用户提交了一个 bug:在第九轮对话中,智能体推荐了一个 Postgres 索引,但这直接违反了用户在第一轮中设定的“我们使用的是 DynamoDB”这一约束。你调出对话记录。每一轮对话如果拆开来看,都是合理的回复。但如果把整个对话作为一个整体来看,那就是一场灾难。

这是单轮评估(turn-level evaluation)的核心谎言。它对“请求-响应”对进行评分,因为这是标注成本最低的单位,并且它默认假设一段对话仅仅是你可以取平均值的独立轮次的组合。事实并非如此。第九轮的响应是以之前发生的一切为条件的,而那些真正触达用户的失败几乎从未存在于单轮对话内部——它们存在于轮次之间的缝隙中,在那里状态丢失、假设变得僵化,微小的错误复合成一个完全错误的最终答案。

你的智能体对话记录是可被取证的,且法务从未批准过

· 阅读需 10 分钟
Tian Pan
Software Engineer

你按照每一份可观测性指南的要求对代理(agent)进行了插桩。每一个回合都有一个 span:完整的 prompt、检索到的块(chunks)、模型的思维链、它考虑过的工具调用、它起草随后又放弃的计划,以及最终的行动。存储费用是每 GB 三分钱,而在事件响应期间,这些追踪(traces)已经救了你十几次。你保留了一切,因为保留一切几乎是免费的,而且偶尔还能立大功。

这是平台团队中没人建模过的部分:那个追踪记录是用流畅的英语写成的,它点名道姓地揣测你的客户,还起草了你从未实际执行的操作。它是你公司产生的最容易被引用的制品,而原告律师会对着幻灯片上印着的你公司 Logo,向陪审团宣读其中最“精彩”的 200 个单词。让你的系统具备可调试性的推理追踪(reasoning trace),正是让它承担法律责任的推理追踪。

对你的工具接收的内容保持严格:波斯塔尔法则在智能体系统中失效

· 阅读需 12 分钟
Tian Pan
Software Engineer

“发送时要保守,接收时要开放。”波斯塔尔法则(Postel's Law)无疑是网络历史上最成功的设计原则——正是依靠它,来自不同厂商的 TCP 实现才得以在 20 世纪 80 年代实现互操作,并塑造了四十多年来的协议和 API 设计。然而,根据 IETF 自身的判断,这一原则会随着时间的推移而变质:RFC 9413 源于一份标题直白为《稳健性原则的有害后果》(The Harmful Consequences of the Robustness Principle)的草案,认为开放式的接收在短期内有助于互操作性,但从长远来看,却在悄悄腐蚀整个生态系统。

智能体(Agent)系统将这种长期的腐蚀缩短到了几周。当“发送者”是一个发出工具调用(tool calls)的大语言模型时,每一次开放式的接收——将 "5" 强制转换为 5、丢弃未知字段、对枚举拼写错误进行模糊匹配——都会破坏维持系统健康所需的精确信号。在智能体架构中,工具边界是唯一一处“大声报错”即是可靠性特性的地方,而大多数团队却反其道而行之。

舰队级 CODEOWNERS:当作者是 AI Agent 时的评审路由

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的 CODEOWNERS 文件编码了一个古老到没人记得当初为何制定的假设:代码变更(diff)的作者知道自己身处谁的领地。一名修改计费服务的工程师深知自己进入了计费业务的领地。他们有目的地将变更范围限制在自己团队的目录内,如果必须触碰其他团队的代码,他们会亲自或在 Slack 上打个招呼,在发出评审请求之前先进行沟通。基于路径的评审路由之所以奏效,是因为人类作者会预先为自己的变更选择路由。

Agent 不会这样做。如果要求一个 Agent “迁移所有弃用的日志调用”,它会在一个下午横扫整个代码库,并生成一个涉及 400 个目录的 diff。GitHub 尽职尽责地查询 CODEOWNERS,匹配每一个通配符(glob),并同时向 40 个团队发出评审请求。

没有人询问过这些团队是否想要这种变更。没有人预警过变更即将到来。而且请求批准的“作者”并不是一个可以随时抓来了解背景信息的同事——它是一个代表其他部门某人行事的机器人账号,而那个人甚至可能都不知道哪些团队收到了通知。

当你最大的客户端是 Prompt 时,如何弃用 API

· 阅读需 12 分钟
Tian Pan
Software Engineer

你完美地执行了弃用指南。提前六个月发布公告邮件。包含四种语言代码示例的迁移指南。在每个 v1 响应中添加了 Sunset 响应头。开发者仪表板上的横幅。两封提醒邮件。然后你关闭了 v1 —— 但结果并非指南所承诺的安静切换,你的错误率直线飙升并维持在高位。流量没有迁移。它只是不断涌入、失败并重试,且容量比以前更高,因为每一次失败都触发了另一次尝试。

指南之所以失败,并不是因为你执行得不好。它的失败是因为它假设另一端是一个人类 —— 一个会阅读邮件、浏览变更日志并在截止日期前提交 Jira 任务进行迁移的人。你很大一部分流量背后已经没有这样的人了。它来自智能体 (Agent),它们对你 API 的认知被冻结在系统提示词、工具 schema 以及散布在成千上万个你看不见也永远无法触达的代码库中的模型训练数据里。你的停用通知是写给读者看的。而你的最大客户端是一个 Prompt。

内部试用 (Dogfooding) 你的 Agent 并不等于 QA

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 Agent 内部指标看起来棒极了。任务完成率达到了 94%。#agent-feedback Slack 频道已经安静了三周。领导层正准备将其推向客户。接着外部用户进场了,不到一个月,数据全线崩溃:工单量激增,信任度降至冰点,复盘时每个人都会问:“Dogfooding 怎么会漏掉这些问题?”

Dogfooding 并没有漏掉问题,而是掩盖了问题。内部用户并不是客户群体的缩影 —— 他们是一群专家级操作员,在无声地修补 Agent 的错误,学习避开哪些提示词(Prompt),并在私信里分享变通方案而不是提交 Bug。每一次修补都让仪表盘(Dashboard)看起来更好,却让产品变得更难理解。你读到的清晰信号并非质量,而是补偿(Compensation)。

不稳定的测试毒化 Agent 循环的速度比伤害人类时快得多

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个人类工程师在看到一个明明不可能由改动引起的测试失败时,会做一件智能体做不到的事:耸耸肩。他们会点击重新运行,对着 CI 大神嘀咕几句,然后继续工作。这种耸肩行为包含了多年积累的上下文 —— 这个测试从 3 月份开始就一直不稳定(Flaky),那个服务的预发布环境每逢周一就会崩溃,没人信任 WebSocket 的测试套件。而编码智能体完全没有这些。它看到一个红色的 X,就将其视为绝对真理,因为它的所有训练和提示词都在告诉它:测试失败意味着代码是错误的。

接下来的环节才是最昂贵的部分。智能体不会耸耸肩 —— 它会采取行动。它会“修复”那些从未损坏的代码。它会因为应用改动后测试套件变红而回滚一个正确的改动。它会消耗大量的 Token 预算去追赶一个幻影,在原本正常的代码路径中添加重试、等待和防御性检查,直到那个不稳定测试碰巧通过,智能体便得出结论:它最后的突变就是解药。测试基座中的非确定性一直是人类注意力的一种负担。而对于智能体循环来说,它更糟糕:它是直接注入到决策系统中的受损训练信号,而系统正以机器速度基于此做出反应。

Agent 的演练日:排演那些无法复现的故障

· 阅读需 11 分钟
Tian Pan
Software Engineer

传统的混沌工程建立在一个默认的假设之上:如果你两次注入同样的故障,你会得到两次同样的失败。停掉 pod,观察故障转移,修复漏洞,再次停掉 pod 以进行确认。整个学科——假设、爆炸半径、稳态指标——都假定系统具有足够的确定性,使得实验是可重复的。

智能体系统从根本上打破了这一假设。在智能体运行过程中注入工具超时,模型会重新规划路径——有时它会重试,有时它会换一个工具,还有时它会自信地编造一个从未获取到的结果。针对相同的提示词运行相同的故障,你最终会得到不同的轨迹,因为故障路径是通过一个随机规划器(stochastic planner)运行的。上周二你在生产环境中看到的故障永远不会以完全相同的形式再次发生。而这恰恰就是你必须对其进行演练的原因。

GraphQL 终于找到了它的客户端,而且它不是人类

· 阅读需 12 分钟
Tian Pan
Software Engineer

GraphQL 的核心赌注是客户端应该能够自主组合其数据需求。在过去的十年里,这个赌注大体上是输了——因为客户端是由人类团队组成的,而他们根本不想组合任何东西。前端工程师想要的是一个可以调用后就不用管的稳定端点。GraphQL 推销的灵活性是以解析器复杂度(resolver complexity)、缓存变通方案和安全审查为代价的,而换取的收益——按请求进行字段选择——对于已知的、变化缓慢的 Web 应用来说几乎毫无必要。到 2024 年,从业者的共识已明显降温:大多数内部 API 只服务于两三个已知客户端,一个设计良好的 REST 端点或 BFF 层就能很好地覆盖这些需求。

接着,一种新型的客户端出现了。AI 智能体没有固定的一套屏幕。它根据每个任务决定自己需要什么数据,并且它为响应的每一个字节付费——字面意义上是在为 Token 付费,而在认知意义上,随着上下文窗口被没人要求的字段填满,推理能力也会随之下降。真正能够自主组合数据需求的客户端终于出现了。只是它不是人类。

让 Agent 先接警:AI 故障响应的信任阶梯

· 阅读需 10 分钟
Tian Pan
Software Engineer

几乎每起事故的前 15 分钟都是机械式的。拉取每个人都会拉取的那四张图表。对比事故开始时的部署差异。检查今天翻转了哪些功能标志(feature flags)。在运行手册(runbook)维基中搜索错误字符串。这些都不需要判断力——它只需要你保持清醒,而在凌晨 3 点,你的值班工程师正把这些时间花在找笔记本电脑、加入语音会议(bridge),以及回忆哪个仪表盘才是真正有用的那个。在人类解锁屏幕之前,智能体(agent)就可以完成这一切。

然而在大多数组织中,关于 AI 在事故响应中应用的讨论往往止于一个段子:“我们听说有个团队的自动修复脚本搞垮了生产环境。”于是,整个想法就被禁绝了——不是限制范围,不是分阶段实施,而是直接禁绝。这是一个范畴错误。那些恐怖故事讲的是自主权阶梯的最顶层,而团队的反应却是拒绝踏上最底层。在最底层,智能体没有任何写入权限,它能做的最坏的事情也就是在 Slack 里发了一段错误的话。

无代码是一场赌注,赌代码成本将维持在高位。这场赌局刚刚输了

· 阅读需 12 分钟
Tian Pan
Software Engineer

你用过的每一个无代码平台,其定价基准都是相同的:雇佣工程师的成本。这就是其核心卖点。编写真正的软件需要稀缺且昂贵的人才,因此这些平台向你推销了一种交易——牺牲灵活性,接受沙箱的限制,作为交换,你的运营经理可以自己发布库存仪表盘,而不必在工程积压名单中等待六个月。这笔交易在过去十五年里是合理的,因为基准一直成立。代码始终是昂贵的。

然后,基准崩溃了。当一个编程智能体能够以低于 Retool 一个席位的月费,构建并维护一个真正的应用程序——即托管在仓库中、拥有你自主掌控 Schema 的真实代码时,拖拽式抽象就不再是捷径,而变成了天花板。你现在是在支付溢价,只为了被“阻止”拥有真正的软件。

但这是大多数“讣告”都搞错的地方:这些平台并不会消亡。聪明的平台已经在向那些与代码成本无关的方向转型——受监管的数据访问、经过验证的集成,以及成为 IT 部门已经批准的沙箱。内部工具的限制因素正从“谁能构建它”转向“谁被允许构建它”,这一转变重写了你评估整个内部工具栈的方式。

Notebook 对编程智能体来说是“敌对领域”

· 阅读需 12 分钟
Tian Pan
Software Engineer

给编程智能体一个 Python 模块,它是在坚实的基础上运行的:磁盘上的文件就是程序。阅读它,编辑它,运行它,观察结果 —— 闭环达成。给同一个智能体一个 Jupyter notebook,所有这些假设都会悄然瓦解。智能体充满信心地编辑第 12 个单元格,却不知道你一小时前曾用不同的数据重新运行过第 3 个单元格,也不知道一个在早已删除的单元格中定义的变量在内核中仍然处于活跃状态,更不知道它刚刚在第 7 个单元格下读取的输出是三次内核重启前由一段已不存在的代码生成的。

Notebook 是一个披着文件外衣的 REPL。磁盘上的 .ipynb 看起来像源代码,但真正决定行为的东西 —— 内核累积的内存 —— 是不可见的、未序列化的,并且是由产生它的那一连串人工点击所塑造的。智能体是基于“代码决定行为”这一契约训练出来的。Notebook 废除了这一契约,而大多数智能体框架甚至对此一无所知。