跳到主要内容

191 篇博文 含有标签「agents」

查看所有标签

提示词契约测试:多智能体团队如何协同而不互相破坏

· 阅读需 11 分钟
Tian Pan
Software Engineer

当两个微服务在API假设上出现偏差时,集成测试会在上线前捕获问题。当两个智能体在提示词假设上出现偏差时,你只会在客户收到自相矛盾的答案——或者整条流水线因级联故障崩溃——时才会发现。多智能体AI系统在生产环境中的失败率高达41%–87%。这些失败中超过三分之一并非模型质量问题,而是协调故障:某个智能体改变了输出格式,另一个智能体仍然期望旧的数据结构,而没有人为此写过测试。

根本问题在于,智能体之间通过隐式契约进行通信。一个研究型智能体——在某人的心智模型中——约定返回带有 sources 数组的JSON对象。编排型智能体依赖这个结构。没有人把它写下来,没有人测试它。六周后,研究型智能体的提示词被优化为返回排名列表而非 sources 数组,编排型智能体就悄无声息地丢失了一半输入。

超时感知的智能体设计:如何返回部分结果而非静默失败

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个智能体成功创建了 GitHub Issue、开启了 Jira 工单,并更新了共享表格。然后在发送 Slack 通知之前超时了。框架将此次运行记录为"已交付"。用户从未收到通知。副作用存在于三个系统中,而对人类真正重要的结果却没有送达。

这是生产智能体系统中最常见的超时失败模式,但几乎从来不是团队预先准备好的那种。大多数智能体实现把超时当作普通异常处理:捕获、记录、返回错误。即使智能体完成了 90% 的工作,用户也什么都得不到。问题不在于是否设置超时——每个生产系统都需要超时。问题在于当时钟走完时,智能体该如何应对。

AI 调试器的陷阱:当 Agent 的补丁速度超过你的诊断速度

· 阅读需 11 分钟
Tian Pan
Software Engineer

一位我上季度合作过的 Staff Engineer 发现了一个在过去六周内已经被“修复”过三次的 bug。由三位不同的工程师处理,涉及三个不同的文件。三次 CI 运行都顺利通过。三次都采用了由 Agent 生成并被接受的补丁。每一个补丁都让失败的测试通过了,也让用户报告的错误消失了。但每一个补丁都只是把 bug 转移到了别处,潜伏在那里,直到被另一个表现面再次触发。当它第四次出现时,它导致的数据损坏已经静默累积了 40 天。

这个 bug 只是分页游标中一个简单的“差一错误”(off-by-one)。Agent 对于“症状会消失”的判断是正确的,但它对“原因”的判断是错误的。而那些优秀的、资深的、动机良好的工程师们,在理解失败机制之前,就各自接受了一个通过测试的补丁。

这就是“智能代理调试陷阱”(agentic debugger's trap):你的 Agent 生成修复方案的速度,超过了你构建评估该方案正确性所需的心智模型(mental model)的速度。补丁速度超过了诊断速度。Bug 数量下降了,CI 面板变绿了,而你交付的代码库,其失败模式你却不再理解。

闭环升级漏洞:当你的专精型智能体陷入循环路由

· 阅读需 13 分钟
Tian Pan
Software Engineer

一个用于市场数据研究的多智能体系统在无人察觉的情况下,在四周内悄悄烧掉了 47,000 美元的推理成本。原本的每周账单仅为 127 美元。原因既不是流量激增,也不是模型升级——而是两个智能体在十一天里来回传递同一个对话,每个智能体都确信对方才是处理该请求的正确位置。没有任何报错。没有任何警报触发。一个机器人的“队列已转移”指标和另一个机器人的“任务已接收”指标都在同步增长,两边的仪表盘看起来都很健康。

这就是闭环升级漏洞 (closed-loop escalation bug)。它是两个热心的同事互相坚持“不,你来处理”的多智能体版本,只不过他们谁都不会感到厌烦并走开。你在设计时画的架构图中,每个专业智能体都拥有一块清晰的问题领域。而运行时实际执行的架构却包含了一个房间里没人能看到的路由循环。

IDE 插件即产品:当你的编程智能体超出了编辑器的插件 API 限制

· 阅读需 13 分钟
Tian Pan
Software Engineer

AI 编程工具的默认思维模型是 VS Code 内部的一个面板。一个对话框,几个行内建议,或许还有一个“应用差异(apply diff)”按钮。这种构想已经过时两年了。该领域的领先产品并不是 VS Code 扩展;它们是完整的编辑器,只是启动时碰巧看起来像 VS Code。Cursor 是一个分叉版本(fork)。Windsurf 是一个分叉版本。Zed 是一个从零开始构建的原生编辑器。这种模式并非巧合 —— 当智能体(agent)的覆盖面最终超过了宿主编辑器的插件 API 所能支持的范围时,必然会出现这种情况。

如果你正在构建一个编程智能体,并且仍然将“发布一个插件”视为理所当然的分发选择,那么你即将撞上那些领跑者在 2024 年左右遇到并选择翻越的那面墙。这面墙有个名字:插件 API 是为了给人类控制的编辑器添加功能而构建的,而不是为了托管一个想要控制编辑器的自主智能体。

智能体管道中的并行陷阱:扇出为何让延迟更糟

· 阅读需 9 分钟
Tian Pan
Software Engineer

你的智能体管道很慢,于是你把任务拆分给五个并行子智能体。p50 下降了,你把它上线了。三天后,告警响了:一批用户请求超时。你挖进去发现 p99 从 4 秒涨到了 22 秒。单个智能体本身没有任何变化。超时是因为编排层在等最慢的那个——它以 1% 的概率遇到了检索抖动,但现在任何触碰全部五条路径的请求都会遇到这个概率。

这就是并行陷阱:这个模式看起来是显而易见的提速方案,实则以一种伤害真实用户更多的方式重构了延迟分布,p50 的改善远不能弥补 p99 的恶化。在生产基准测试中,单个智能体在 64% 的评估任务上能匹配甚至超过多智能体管道。并行扇出奏效的时候,确实奏效得很干净——但仅限于特定类别的问题。把扇出当作默认选项,才是错误所在。

长时 Agent 会话中的人格漂移:为什么你的 Agent 会忘记自己是谁

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数生产环境中的 Agent 故障看起来像是模型错误。Agent 在会话开始时能正确响应系统提示词——维持正确的语气,遵守工具约束,遵循定义的工作流程。然后,在第 30 或 40 轮左右,情况悄然发生变化。Agent 开始在本应直接的地方含糊其辞,调用了它被告知应避免的工具,甚至推翻了它在 15 轮前做出的决定。系统提示词没有改变,但 Agent 的行为已经变了。

这就是人格漂移:由于 Transformer 对越来越深埋的上下文的注意方式,Agent 实际行为与其原始系统指令之间产生的渐进式偏差。研究对此进行了精确量化——经过 8–12 轮对话后,人格自一致性指标下降超过 30%。单轮 Agent 的任务准确率约为 90%;在运行相同任务的多轮 Agent 中则降至约 65%。这 25 个百分点的差距并非一个可以通过调整提示词来解决的模型质量问题,而是注意力机制在长序列上工作方式的架构特性。而大多数团队只有在上线某个功能、该功能悄无声息地降级数小时后才被用户发现时,才意识到这个问题。

并非“全员回复”:智能体出站扇出风险

· 阅读需 10 分钟
Tian Pan
Software Engineer

用户要求智能体(agent)“告知 Karen 我们完成了”。智能体调用了 send_email,收件人字段设置为 karen-team@,这是它的联系人查询工具返回的最合理的地址。这条包含三段内部专用项目状态的信息——其中包括一行关于客户续约风险的坦率描述——最终发送到了四十个收件箱。其中一个收件箱恰好属于该客户。事后分析(postmortem)持续了两周。

没有提示词注入。没有模型越狱。工具完全按照规范运行。团队为 send_email 编写的契约是“向收件人发送消息”。而现实世界强制执行的契约是“广播给一个发送者未审计其构成的群体”。这种差距——即工具的命名与其核心实际能力之间的鸿沟——正是大多数出站智能体事故的源头。

电子邮件是显而易见的例子,但同样的风险潜伏在智能体接触的每一个消息工具中。人类为这些渠道建立的三十年肌肉记忆,并未转移到那些正在通过联系人列表进行模式匹配的规划器(planner)中。

下线一个 Planner 已产生依赖的 Agent 工具

· 阅读需 12 分钟
Tian Pan
Software Engineer

你从工具目录中注销了 lookup_account_v1,换上了 lookup_account_v2,并修改了系统提示词中的一个段落来指向新名称。测试通过了。三天后,支持工单开始提到助手“一直尝试调用不存在的东西”,或者——更令人不安的是——它用自信、看似合理的数字回答客户问题,却根本没有查询数据库。弃用并没有在通信层失败,它在规划器(planner)中失败了。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E4%B8%8B%E7%BA%BF%E4%B8%80%E4%B8%AA%E8%A7%84%E5%88%92%E5%99%A8%E5%B7%B2%E5%AD%A6%E4%BC%9A%E4%BE%9D%E8%B5%96%E7%9A%84%E6%99%BA%E8%83%BD%E4%BD%93%E5%B7%A5%E5%85%B7"]

这是将工具弃用视为语法变更与将其视为行为迁移之间的差距。智能体不仅是在注册表中拥有你的函数;它还拥有数月的计划、多步配方(recipes)以及通过该函数作为检查点的 few-shot 示例。撤掉它更像是停用下游服务非正式硬编码的内部 API——只不过下游服务是一个你无法通过 grep 搜索其习惯的模型,而且当它偏好的工具消失时,它的兜底方案是编造一个。

技能即模块:当你的智能体堆栈需要导入系统时

· 阅读需 12 分钟
Tian Pan
Software Engineer

我上个月交流过的一个团队遇到了一个任何资深包管理器用户都能一眼识破的 Bug。他们的智能体中有两个技能(skills)都提供了相同的 search_orders 能力 —— 一个来自计费工具包(billing toolpack),另一个来自 CRM 工具包。最后添加到清单(manifest)中的那个成了生效者。智能体在三周内都在静默地调用错误的能力。退款发到了错误的客户 ID。他们告诉我,修复方法是召集 CRM 和计费工程师开会以“协商命名”。开会。只为了解决两个可安装模块之间的名称冲突。

就在那一刻,我意识到了当前的智能体运行时(agent runtimes)正在发生什么。运行时加载能力模式 —— 技能、工具包、提示词片段、检索提供程序、MCP 服务器 —— 正汇聚到几十年前编程语言通过导入系统(import systems)解决的相同问题上:名称解析、版本锁定、依赖图、冲突检测、延迟加载。而大多数智能体运行时要么在拙劣地重新发明每一项,要么干脆无视,并以“开会”的形式将账单寄给用户。

工具 Schema 设计即是你的爆炸半径:当函数定义成为安全边界

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的 Agent 代码库中最危险的文件是你一直当作 API 文档来编写的那个。工具注册表(Tool Registry)——即告诉模型存在哪些函数以及它们接受哪些参数的 JSON 或 Pydantic schema —— 不再仅仅是一个 docstring。它是你的授权层(authorization layer)。如果你像大多数团队那样设计它,你就是把万能钥匙交给了大模型(LLM),并称之为优秀的工程设计。

考虑一个典型的工具初步尝试:query_database(sql: string)。初衷是合理的 —— 让模型根据用户的问题制定正确的 SQL。现实情况是,模型现在成了一个不受信任的客户端,拥有连接字符串所指向的任何数据库的无限 DDL 和 DML 权限。系统提示词说“仅在 orders 表上运行 SELECT” 只是一个建议,而不是控制手段。当一个受到提示注入(prompt-injected)的工具结果 —— 比如邮件正文、网页或 PDF —— 告诉模型运行 DROP TABLE users 时,你的授权模型就变成了对模型指令遵循能力的纪律要求。那不是授权。那是祈祷。

Agent IAM 不等于 Service IAM:为什么当意图在运行时构建时 OAuth 会失效

· 阅读需 13 分钟
Tian Pan
Software Engineer

Bearer Token 模型有一个智能体正在悄然违反的假设:调用者在发起请求时知道自己想要什么。OAuth 作用域、IAM 角色和 API 密钥都是围绕一个在身份验证开始前意图就已经确定的主体设计的。你的 CI 运行器意图稳定。你的微服务意图稳定。智能体则不然。智能体的意图是在请求时,由用户提示词、系统提示词、检索到的文档以及可能由攻击者编写的工具输出共同组装而成的。当智能体去获取令牌时,IAM 层必须做的策略决策实际上已经做出了——而决策依据的输入,IAM 层从未见过。

这就是为什么在服务间通信中行之有效的身份验证模式,现在正引发一类没人能准确描述的事故。提示词注入窃取了长效的 Bearer Token。智能体在不同会话间“记住”了权限,因为令牌的寿命超过了用户的意图。一个理应需要三个作用域的多步任务,在整个会话期间都持有所有权限,而不是按步骤获取和释放。严格来说,这些都不是 OAuth 的 bug。它们是试图将假设静态意图的模型扩展到覆盖一个每轮对话都在重构意图的调用者所导致的后果。