跳到主要内容

842 篇博文 含有标签「ai-engineering」

查看所有标签

当两个 Agent 共享一个工具:多 Agent 系统中的并发 Bug

· 阅读需 11 分钟
Tian Pan
Software Engineer

当你输入“启动另一个智能体来并行处理”的那一刻,你就已经成为了一名分布式系统工程师。你可能没有注意到。框架让它变成了一行代码的改动,演示运行良好,延迟也降低了。但在底层,你刚刚引入了两个在没有协调的情况下读写共享状态的进程 —— 而困扰了数据库领域五十年的每一个竞态条件 (race condition)、更新丢失 (lost update) 和脏读 (dirty read),现在都潜伏在你的智能体堆栈中,伺机而动。

这种情况之所以棘手,是因为故障看起来不像并发 Bug,而像是某个智能体出错了。输出在语法上是有效的,流水线显示绿色,没有抛出异常 —— 然而,客户被收取了两次费用,或者文件丢失了一半预期的内容,又或者一个智能体自信地根据另一个智能体已经覆盖的数字采取了行动。你去调试那个“愚蠢的智能体”,发现它的提示词 (prompt) 没有任何问题,因为提示词根本就不是问题的症结所在。

你的向量索引是一个没有失效策略的缓存

· 阅读需 11 分钟
Tian Pan
Software Engineer

向量索引感觉就像一个数据库。你向其中写入文档,查询它,它返回结果。但它并不是数据库——它是存储在其他地方的数据的“派生、非规范化副本”。你的事实来源是 wiki、工单系统、CRM 或 PDF 文件夹。嵌入 (embeddings) 是这些事实的投影,冻结在你运行摄取任务 (ingestion job) 的那一刻。

这使得你的向量索引变成了一个缓存。就像所有缓存一样,它会失效。不同之处在于,大多数团队是有意识地构建缓存层,带有 TTL 和失效钩子 (invalidation hook),而几乎没有人会有意识地将向量索引作为缓存来构建。他们将其构建为“知识库”,然后在它提供三周前就已经过时的知识时感到惊讶。

当廉价模型变得更昂贵时

· 阅读需 11 分钟
Tian Pan
Software Engineer

财务团队指出,本季度的 LLM 账单上涨了 18%。一名工程师调出使用情况仪表板,发现 70% 的流量现在流向了经济型模型(budget model)而非前沿模型(frontier model),他感到有些困惑:路由更改本应是为了削减开支。每 token 价格确实如电子表格预测的那样下降了。但账单还是上涨了。

这不是计费错误。这是成本优化在悄无声息中发生逆转的最常见方式。证明降级合理的电子表格衡量的是一件事——token——而生产系统支付的是完全不同的另一件事:完成的任务。较弱的模型不仅仅是产生更便宜的 token。它还会改变其周围每个组件的行为,而这些二阶效应最终都会反映在同一张发票上。

这个陷阱非常诱人,因为一阶数学逻辑确实是正确的。经济型模型的每 token 价格可能比前沿模型便宜 10 到 30 倍,且对于大部分流量,它返回的答案在质量上是难以区分的。错误不在于路由决策。错误在于在错误的边界衡量路由决策。

你的提示词专家只有 14 个月的半衰期

· 阅读需 11 分钟
Tian Pan
Software Engineer

每一家在生产环境中上线 AI 功能的公司,都有那么一两个无法承受其离职损失的工程师,而大多数公司直到收到辞职邮件时,才意识到这些工程师是谁。

那个关键人物很少是办公室里嗓门最大的。他们是那个记得在第二季度的问题升级后,通过三行系统提示词(system-prompt)修改修好了客服摘要语气的人;是那个在模型供应商悄悄更改默认采样(sampling)的那周,在评估套件(eval suite)中添加了六个案例的人;也是那个在上次有人“清理”评分细则(rubric)时,发现评判标准校准(judge calibration)发生偏移的人。这些内容都没有被记录在继任者能找到的地方。它只存在于一个人的脑子里,而这个人的脑子大约每两周就会收到一次猎头发来的加薪 25% 的消息。

置信度分数税:为什么询问模型它有多确定比直接出错成本更高

· 阅读需 12 分钟
Tian Pan
Software Engineer

在每个 AI 功能的演进过程中,审阅者总会提出一个听起来很合理的问题:“我们能不能让模型告诉我们它的置信度(confidence),这样我们就可以把低置信度的回答路由给人工或备选方案?”这听起来像是一份免费保险。你在输出 schema 中添加一个 confidence 字段,模型尽职尽责地填好它,现在你就有了一个可以调节的旋钮。发布吧。

那个旋钮并不是免费的,更糟糕的是,它通常没有连接到任何实际逻辑上。置信度数字只是模型乐于生成的一个 token 序列,模型并没有义务让它具有实际意义。团队支付真实的 token 和延迟来获取它,却从不检查它是否与正确性相关,然后根据它路由生产环境的流量,就好像 “0.9” 真的代表 90% 的可靠性评估一样。它就像一个用螺栓固定在仪表盘上的压力表,但玻璃后面其实什么也没连。

这篇文章讨论了两个没人定价的成本:生成置信度字段本身的单次请求税,以及信任一个未校准的数字来做路由决策所带来的更巨大的成本。

PM 与评测之间的翻译鸿沟:当发布决策超越了词汇表

· 阅读需 9 分钟
Tian Pan
Software Engineer

AI 功能的上线决策会议(go/no-go meeting)表面上是一个数据驱动的仪式。工程团队会带来一系列评估数字——评测专家分数变化(judge score deltas)、切片准确率(slice accuracies)、相对于基线的回归百分比(regression-against-baseline percentages)——然后由与会者做出决定。这看起来非常严谨。但通常并非如此。

一句话概括这种失败模式:有能力解读评估切片权重的人没有决策权,而有决策权的人看不懂切片。产品经理(PM)主导发布决策。工程师掌握数字背后的含义。在这两者之间存在着翻译鸿沟,谁在会议上表现得最自信,谁就能填补这个鸿沟。

问题的征兆在于,“87% 准确率就发布”和“87% 准确率不发布”都可以基于同一份评分卡找到依据,这取决于你更看重哪个切片。当同一份数据集支持截然相反的结论,且决定性因素是辞令上的自信而非证据时,你拥有的就不是一个数据驱动的流程,而是一场以电子表格为背景的辩论。

改变答案的重试:针对非确定性 LLM 调用的幂等键

· 阅读需 10 分钟
Tian Pan
Software Engineer

你构建过的每个分布式系统都依赖于一个隐形的假设:超时后的重试是安全的。操作是幂等的,因此如果客户端放弃等待并重新发送,最坏的情况也只是重复工作,并最终收敛到相同的状态。两个 PUT 请求落地同一行。两个 DELETE 请求留下同样的空缺。重试只是伪装成第二次尝试的“无操作”(no-op)。

LLM 调用打破了这一假设,而且是悄无声息地打破。重试并不会重新获取相同的答案 —— 它会采样一个新的答案。当客户端因为响应在传输中丢失而在网络层超时,但提供商实际上已经完成了生成时,重试会产生第二个、不同的答案。现在,对于一个逻辑请求,存在两个不同的输出,而你的技术栈中没有任何部分知道哪一个是权威的。

这并非罕见的极端情况。在模型背后运行超时机制的从业者报告称,即使底层调用最终成功,仍有 5–10% 的请求会触发完整的超时加重试循环。其中的每一次重试都是一次抛硬币,而你的系统从未被设计成去裁定这种结果。

当“智能体能做 X 吗?”演变为交付承诺时

· 阅读需 11 分钟
Tian Pan
Software Engineer

一个工程师花了一个下午钻研一个问题:智能体 (agent) 能否根据合同条款核对客户的发票?他们编写了一个简单的提示词,在五份真实发票上运行,结果三份是正确的。另外两份的错误方式他们还没完全搞清楚——于是他们关上电脑,继续做别的事。在第二天早上的站会上,他们说:“是的,发票核对基本上能用了。”房间里的 PM 记下了这一点。两周后,它成了 Q3 路线图上的一个项目。一个月后,一位销售代表在续约电话中向一家大客户承诺了这项功能。

没有人撒谎。没有人孤立地做出错误决定。但团队现在已经在合同上承诺了一种行为,而这种行为的评估集 (eval set) 并不存在,其失败模式从未被记录,其可靠性预算是由一位看了演示并将其解读为正式合同的总监设定的。这是 AI 功能获取范围 (scope) 最常见的方式:不是通过规划会议,而是通过一个从未被明确提升地位的能力探索 (capability probe)。

行业对这种下游症状有一个称呼——“POC 炼狱” (POC purgatory),即 70% 到 80% 的 AI 项目在可运行的沙盒和可交付的产品之间停滞不前的状态。但“炼狱”是一个错误的比喻,因为它暗示项目被困住了。它们并没有被困住。它们在移动——在有人检查它们是否准备好之前,它们就被承诺了,现在团队正试图将可靠性强行填补到一个承诺中。

Agent 调试器没有断点:为什么追踪优先工作流正在取代单步执行

· 阅读需 11 分钟
Tian Pan
Software Engineer

当你第一次尝试像调试服务那样调试 Agent 时,你会发现以往的肌肉记忆完全派不上用场。你设置了一个假设的断点——虽然 IDE 中没有面板可以放置它,但你在脑海中想象了一个——就在 planner 选错工具的那一步。你使用相同的输入重新运行。这一次,planner 选择了正确的工具。你再次运行。它又选了一个你从未见过的第三种工具。Bug 是真实存在的,你的同事今天早上复现了两次,而你用了十五年的调试器突然间变成了博物馆里的陈列品。

这里失效的心智模型并不是“使用调试器”,而是背后更深层的假设:即一个程序在给定相同输入的情况下,会产生相同的执行过程。现代调试器中的每一项功能——断点、单步跳过 (step-over)、观测表达式 (watch expressions)、条件断点、热重载——都是建立在这种确定性之上的。你暂停执行是因为暂停是有意义的。你向前单步执行是因为下一步是可预知的。你检查一个变量是因为它的值是一个事实,而不是从某种分布中随机抽取的结果。

没人做的 AI 无障碍审计

· 阅读需 12 分钟
Tian Pan
Software Engineer

打开你的智能体产品,开启 VoiceOver,然后发送任意提示词。如果你使用的是典型的带有内联推理过程的流式 UI,那么你在接下来的 30 秒内听到的内容并非你的产品。那是一股汹涌的局部 token 流、单词中间的重排、无人播报的状态变化,以及一段视力正常的用户选择查看、但盲人用户却无法逃避的推理独白。在舞台上演示效果极佳的界面,对于屏幕阅读器来说,是一场以语音形式发起的拒绝服务攻击。

这是 AI 团队中没有人会运行的审计。设计评审批准了流式动画。评估套件测量了回答质量。延迟仪表盘追踪了首个 token 响应时间。但这些工具都没有注意到,让某一群体感到产品快速且贴心的功能特性,却让另一群体完全无法使用。这种疏忽正开始出现在亲自诉讼申请中——过去十年一直在处理针对电商网站无障碍投诉的联邦法院,现在看到的 AI 界面相关投诉正急剧增加,据一家追踪机构报告,仅在 2025 年,同比增幅就达到了 40%。

没人写的 AI 功能下线指南

· 阅读需 14 分钟
Tian Pan
Software Engineer

每个 AI 组织都有一个坟场。不是服务的坟场——服务会有操作手册(runbook)、弃用横幅、30 天的迁移窗口,以及在平台团队季度路线图上的位置。这个坟场是属于 功能 的:从未转正的智能摘要 Beta 版、两个大客户据此构建了工作流的自动分类器、演示效果极佳但在灰度发布后无人问津的 Agent 流程。弃用一个端点很容易。但与之关联的其他四个东西——提示词(prompt)、评测员(judge)、回归测试集(regression set)和事故记忆(incident memory)——才是真正需要一个季度才能搞定的,而且团队中没人写过这种手册,因为没人会因为下线某个功能而获得晋升。

这就是差距。大多数关于“模型弃用”的公开讨论都是针对供应商侧的下线:GPT-4o 在某天停止服务,Assistants API Beta 版在 8 月 26 日下线,DALL-E 3 在 5 月 12 日退休,而你的平台团队有一个通知期来进行迁移。这个问题有现成的手册,因为供应商发布了日期,迁移是被迫的,而且工作量可以塞进一个 Sprint 中。而“内部”版本——当你决定你构建的一个功能未能转正并必须将其撤除时——则没有任何这类强制因素。弃用日期由你说了算。迁移路径由你来构建。而且你必须退役的产物不是单个端点,而是一堆纠缠在一起的、与模型相关的资产,你的监控系统几乎感觉不到它们的存在。

“AI 让我这么做的”辩护:当代码审查悄然停止提出异议

· 阅读需 12 分钟
Tian Pan
Software Engineer

在 2026 年的代码审查(Code Review)讨论串中,最昂贵的一句话莫过于“这是 Agent 这么写的”。这并非因为它本身是错的——有时它确实没错——而是因为它终止了本该由此开启的对话。审查者输入一个问题,作者直接引用模型的推理作为回复,讨论在任何人真正开始争论这项变更之前就结束了。反对一个自信且谈吐得体的模型的社交成本,已经悄然高过了合并一个隐蔽 Bug 的成本,而大多数团队在未来两个季度内都无法在指标中察觉到这种权衡。

这不是一个关于 AI 写代码好坏的故事。它会写代码,其中有些还写得不错。这是一个关于当编写代码的摩擦消失时,质量关卡(Quality Gate)会发生什么的故事。审查速度上升,缺陷率也随之同步上升,而这种关联并不明显,因为没有人在追踪审查耗时与缺陷时会关联作者的类别。曾经是代码库品味核心的资深工程师,在一个悄然转向“模型盲从”的文化中,变成了孤独的坚持者。