跳到主要内容

209 篇博文 含有标签「agents」

查看所有标签

长时 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。它们是试图将假设静态意图的模型扩展到覆盖一个每轮对话都在重构意图的调用者所导致的后果。

Brownout 模式:当你的 LLM 供应商响应迟缓而非宕机时

· 阅读需 12 分钟
Tian Pan
Software Engineer

凌晨 3 点因为宕机而把你吵醒的告警其实是简单的。供应商返回了 40 分钟的 503 错误,你的回退机制生效了,运维手册(runbook)启动了,复盘报告(post-mortem)几乎可以自动完成。而那些没有吵醒你的告警——那些在所有仪表盘都显示绿色的情况下,让你的支持队列在 6 小时内堆满的告警——才是渐变故障(brownout)。供应商的 API 仍然有响应。状态页依然显示“运行正常(operational)”。你的 p99 延迟已悄然从 2.1 秒漂移到 14 秒,错误率从 0.1% 上升到 4%,而唯一察觉到的人是那些已经流失的用户。

供应商的可用性并不是非黑即白的二元状态。大多数团队编写的回退逻辑——“如果供应商宕机,则切换到备用方案”——本质上是用一个只有两种状态的状态机去应对一个连续变量,当供应商处于“惨淡运行”而非“彻底宕机”的状态时,这种机制根本不会触发。为渐变故障(brownouts)而设计是一个与处理宕机完全不同的设计问题,我所见过的几乎每一个生产环境中的 Agent 调度框架在发布时都没有解决这个问题。

澄清预算:你的智能体何时应该询问而非猜测

· 阅读需 12 分钟
Tian Pan
Software Engineer

智能体最糟糕的两种失败模式看起来截然相反,但它们其实源于同一种失效的策略(Policy)。第一种智能体在执行任何操作前都会先问四个后续问题,这让它的用户因为繁琐而最终放弃使用。第二种智能体从不提问,它自信地生成用户不得不推倒重做的输出,这让它的用户对其产生不信任感。同样的策略,只是一个缺失参数的不同设置:即提问的成本相对于错误答案成本的比例。

大多数智能体根本没有任何策略。模型只是被要求“提供帮助”,然后被留下来独自应对模糊性。因为下一个 Token 预测(next-token prediction)机制奖励对答案的确定性,所以智能体倾向于猜测。又因为 RLHF 奖励礼貌,智能体偶尔会为了安全而过度纠偏并提出问题。其结果就是一种毫无原则的行为,这种行为在不同会话之间波动不定,团队层面也无法直观地判断智能体何时会暂停、何时会盲目推进。

澄清预算(Clarification budget)正是那个缺失的参数。它是针对每个任务制定的、允许智能体施加摩擦力的配额,并配有一套判断何时值得花费预算去提问的决策规则。你可以把它看作是对话领域的“延迟预算(latency budget)”——每个产品都有一个,即使没人把它写下来;而那些把它写下来的团队,就能停止交付那种让人困惑的智能体。

多步 Agent 的延迟预算:为什么 P50 会说谎,而 P99 才是用户的真实感受

· 阅读需 12 分钟
Tian Pan
Software Engineer

仪表盘显示智能体很快。P50 停留在 1.2 秒,团队开会庆祝,然后放弃率却在持续攀升。没有人关注用户真正体验到的那个图表。

!["https://opengraph-image.blockeden.xyz/api/og-tianpan-co?title=%E5%A4%9A%E6%AD%A5%E6%99%BA%E8%83%BD%E4%BD%93%E7%9A%84%E5%BB%B6%E8%BF%9F%E9%A2%84%E7%AE%97%EF%BC%9A%E4%B8%BA%E4%BB%80%E4%B9%88%20P50%20%E4%BC%9A%E8%AF%B4%E8%B0%8E%EF%BC%8C%E8%80%8C%20P99%20%E6%89%8D%E6%98%AF%E7%94%A8%E6%88%B7%E7%9A%84%E7%9C%9F%E5%AE%9E%E6%84%9F%E5%8F%97"]

这是生产环境中多步智能体可靠的失效模式:中位数是你能够达到的指标,而尾部延迟才是你用户感受到的指标。随着你在流水线上不断增加子调用,这两者之间的差距会呈非线性增长。一个包含四个步骤的智能体,即使每一步在“中位数表现”上都很快,其 P99 通常也会比任何单步操作糟糕 6 到 8 倍。用户体验到的不是中位数,而是他们那次特定请求中最慢的一步。

如果你的团队优化了错误的分位线,你交付的系统将拥有出色的基准测试表现和精美的演示效果,但在你从未监测的长尾场景中,用户正不断流失。

工具调用顺序是偏序,而非集合

· 阅读需 12 分钟
Tian Pan
Software Engineer

“先创建后通知”的序列在开发阶段运行良好。而“先通知后创建”的序列则会为一个尚不存在的实体触发 webhook,导致消费者返回 404,接着你的团队会花上一周时间来调试这个看起来像是不稳定的集成测试。这种不稳定并非随机。它是确定性的,源于你的工具集拥有而你的规划器(planner)却不知晓的隐藏排序不变性。

这就是生产环境中 Agent 工具调用排序 bug 的常见形态:工具集在底层以偏序(partial order)方式组合——某些操作必须先于其他操作执行,而另一些则可以按任意顺序运行——但在规划器看来,它们只是一个无序的能力集合。模型选择了一个昨天行之有效的顺序。而明天,一次提示词修改、模型升级,甚至只是不同的 temperature 采样,都会选出另一个顺序。对于阅读追踪记录(trace)的人来说,这两种顺序看起来都很合理。但其中只有一个是正确的。

如果不声明顺序,团队交付的就是一个最终会被模型的提示词敏感性(prompt sensitivity)触发的 bug 隐患。

弃权作为一种路由决策:为什么“我不知道”应该属于路由层,而不是提示词

· 阅读需 12 分钟
Tian Pan
Software Engineer

大多数团队通过在系统提示词中加入一句话来处理弃权(abstention)问题:“如果你不确定,就说你不知道。”模型偶尔会遵守,但经常不遵守,而且这种失败模式是不对称的。一个自信的错误答案会以全速发布——它直接落入用户手中,在 Slack 讨论串中被引用,在下游摘要中被采纳。而一个诚实的弃权则会触发客户成功(CS)升级,因为用户期望智能体处理请求,而现在必须有人解释为什么它没有处理。六个月后,团队已经了解到哪种失败的发布成本更低,而那个名义上控制弃权的系统提示词修改,已经被悄悄地调整为倾向于顺从,而非诚实。

解决这个问题的准则不是寻找更好的措辞。而是要认识到,弃权是一个路由决策,而不是一种提示词模式。它理应拥有一个一等公民级别的输出通道、自己的 SLO、自己的评估套件,以及在系统拓扑中的独立位置——位于提示词之外,可以被测试、维护和扩展。

Agent 降级模式规范是你没有撰写的文档

· 阅读需 12 分钟
Tian Pan
Software Engineer

当搜索索引失效、供应商 API 对你限流、数据库只读副本出现延迟,或者下游微服务开始返回 503 错误时,你的智能体(agent)必须决定该做什么。在大多数生产环境的智能体系统中,这个决定从未被真正做出。它是被“默默继承”下来的——往往来自于编写工具封装(tool wrapper)的工程师在项目第三周周二下午 4 点随手写下的代码。

其结果就是你的客户最终替你写出的内容:一个 Reddit 帖子、一份客服对话记录,或者是新闻稿中的一段引述。“助手告诉我余额是 0 美元,但其实我的账户没问题——结果发现是他们的查询服务挂了。”那段话就是你的团队没写的降级模式规范。现在它公开了,它属于客户了,而且你的工程部门在接下来的整个季度里都将忙于应对它。