跳到主要内容

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

查看所有标签

真正的后端是电子表格 —— 而你的智能体刚刚获得了写入权限

· 阅读需 11 分钟
Tian Pan
Software Engineer

问一个工程师他们公司的业务逻辑在哪里,他们会指向一个 Git 仓库。问财务团队、运营团队或销售团队,诚实的回答是一个名为 pricing_model_v7_FINAL_final.xlsx 的文件。定价公式、人员编制计划、佣金计算、月末对账宏 —— 大多数公司的运营核心都运行在 Excel 和 Google Sheets 上。它没有类型,没有测试,没有代码审查,也没有部署流水线。它是像餐巾纸草图一样被维护着的生产基础设施。

三十年来,这套系统基本行得通,因为读取和写入这些文件的只有人类 —— 动作缓慢、谨慎,并且具备“这个数字看起来不对”的直觉。那个时代刚刚结束了。适用于 Google Sheets 和 Excel 的 MCP 服务器现在将完整的“增删改查(CRUD)”权限作为一等公民 Agent 工具开放,而且每个 Agent 平台都提供电子表格连接器,因为那里才是客户数据真正存放的地方。我们将有史以来构建的最快的写入者连接到了有史以来部署的最脆弱的生产系统上,而大多数团队只花了一个下午就完成了这项工作,甚至没有进行过一次设计评审。

无法回滚的回滚:提示词、工具和记忆必须同步版本化,否则满盘皆输

· 阅读需 13 分钟
Tian Pan
Software Engineer

故障频道里传来消息,说新的提示词正在幻觉退款金额,所以你做了一个显而易见的决定:将生产环境标签重新指向到上周的提示词版本。三十秒,无需重新部署,教科书级的回滚。结果 Agent 表现得反而更糟。上周的提示词引用了一个名为 lookup_order 的工具,但平台团队在周二将其重命名为 orders.search。记忆库中充满了由新提示词格式生成的偏好摘要,而旧提示词会将这些内容误读为用户指令。你并没有回滚 Agent,而是制造了一个“奇美拉”——三分之一是上周的,三分之二是今天的——并在从未测试过该组合的情况下将其推向了生产环境。

这是任何人的运维手册中都没有涵盖的失败模式:Agent 的部署不是一个单一的构建产物,而是一个三元组——提示词版本、工具契约、以及累积的记忆状态。回滚其中一个维度,而让另外两个维度保持现状,并不能恢复之前的状态。它创造了一个从未存在过、从未通过评估、且不属于任何团队值班范畴的新状态。

智能体流水线中的“传声筒”游戏

· 阅读需 13 分钟
Tian Pan
Software Engineer

你可能目睹过这样一种失败,只是没有给它命名。你的编排者(orchestrator)读取用户请求并向工作代理(worker agent)下达简报。工作代理运行了十几次工具调用,消化输出,然后汇报一份简洁的摘要。编排者将该摘要并入下一名工作代理的任务简报中,后者如法炮制。五跳(hop)之后,系统给出了一个自信的最终答案——却违反了用户在请求的第二句话中明确提出的约束。没有人故意丢掉这个约束。每一跳只是稍微压缩了一下上下文,方向无人选择,而这些压缩不断叠加。

这就是“传声筒游戏”(the telephone game),而多智能体系统(multi-agent systems)本质上就在玩这个游戏。流水线中的每一次交接都是一个有损压缩步骤:编排者的简报是对用户的转述,工作代理的报告是对其工具输出的转述,而最终答案则是转述之上的转述。问题不在于信息是否丢失——它确实丢失了,而且是可衡量的——而在于你是否决定了哪些信息允许被丢失,还是将这个决定留给了采样温度(sampling temperature)。

千人智能体客户:按席位计费的 SaaS 并非为机器定价

· 阅读需 12 分钟
Tian Pan
Software Engineer

在你公司的某个角落,一名工程师已经将一个智能体集群接入了一个仅获授权 50 个用户席位的 SaaS 产品。这个集群在一夜之间运行了上千个并发会话,通过一个服务账号进行身份验证,并完成了整个部门的工作。没人询问过法务,也没人询问过供应商。如果你仔细阅读合同,很有可能整个工作负载都是未经授权的——这并非因为有人存心欺骗,而是因为这份合同是为一个“用户”意味着“敲击键盘的人”的世界而编写的。

这是智能体时代悄然浮现的合规问题。按席位许可、服务条款中的自动化条款、公平使用率限制以及按用户分析,所有这些设计的初衷都基于一个假设:使用量随员工人数而扩展。智能体从各个方向同时打破了这一假设。运行智能体集群的客户不仅让供应商的定价模型承受压力——他们还经常违反协议的字面规定、其背后的经济逻辑,或者两者兼而有之。

会话记录记住了提交信息遗忘的内容

· 阅读需 11 分钟
Tian Pan
Software Engineer

就在此时,你的笔记本电脑里的某个角落正存放着你的团队有史以来最详尽的工程决策记录,却没有任何人读过其中的一个字。每一个智能体会话 —— 无论是每一次 Claude Code 的运行、每一次 Cursor 对话,还是持续数小时的重构历程 —— 都会被记录成一份转录文本(transcript)。它包含了尝试过又被放弃的三种方案、导致产生这种丑陋临时方案的约束条件,以及你否决模型建议的时刻及其原因。然后会话结束,PR 带着一行 commit message 被合并,所有这些上下文都进入了一个永远不会被打开的 JSONL 文件。

以前,我们丢失这些信息是“理所当然”的。某个设计选择背后的推导过程只存在于某个人的脑子里,随着时间推移而淡忘,并在他们换工作时彻底流失。当时没有什么可以保存的,因为根本没有记录下来。这种借口已经不复存在了。现在的推导过程正被逐字逐句地记录下来,带有时间戳,机器可读 —— 而我们却将其视为随手可弃的废气。

预热沙箱池:当每个智能体任务都拥有专属机器时的基础设施经济学

· 阅读需 13 分钟
Tian Pan
Software Engineer

如果你在任何真实规模下运行编程智能体 (coding agents),你就拥有一支临时虚拟机舰队。你可能并没有主动申请这样做。但在你决定(且正确地决定)不信任的、由模型生成的代码绝不应该在应用程序的信任边界内执行的那一刻,这一切就发生了。每个任务都有自己的沙箱,每个沙箱都是一个微型虚拟机 (microVM) 或硬化容器。突然间,那个自以为在构建“智能体产品”的平台团队,实际上正在运营一些看起来非常像微型 AWS Lambda 的东西:池预热 (pool warming)、快照流水线、装箱调度器 (bin-packing schedulers),以及一个针对无人认领环境的清理进程 (reaper process)。

陷阱在于假设你的容器编排直觉可以无缝迁移。有些确实可以。但 Kubernetes 是为了调度长周期的、同质化的服务而设计的,而智能体沙箱恰恰相反:生命周期短、极度异构,且创建速度之快让部署滚动更新 (rollout) 看起来像是在悠闲散步。那些挣扎的团队往往将沙箱基础设施仅仅视为“步骤更多的容器”。有趣的工程挑战——以及几乎所有的成本——都集中在四个问题上:冷启动、文件系统状态、装箱密度和弃置。

世界没有预发布环境

· 阅读需 12 分钟
Tian Pan
Software Engineer

你的技术栈通常有三个环境。开发环境(Dev)是可抛弃的,预发环境(Staging)是类生产环境,而生产环境(Prod)是神圣不可侵犯的。二十年的工程文化——CI 门禁、金丝雀发布、蓝绿部署——全都建立在这种分层之上。但当你给智能体(Agent)一个调用 Salesforce、QuickBooks 或 Gmail 的工具时,这种分层就悄然消失了。对于客户的组织来说,并没有“预发环境下的 Salesforce”。也没有发票账本的影子副本。一旦工具调用跨越网络边界进入第三方 SaaS,环境就只剩下一个,那就是生产环境。

这是智能体工程(Agent Engineering)中最少被讨论的鸿沟。我们已经擅长对智能体的“计算”进行沙箱化处理——容器、出口白名单、资源配额。我们在评估智能体的“推理”方面也做得还行——离线评估、LLM 作为评委、轨迹评分。但智能体对“外部世界”的操作仍然是在包含真实客户数据的生产系统上运行的,因为对于大多数 SaaS 界面来说,除此之外别无他法。团队只能通过仅有的两种方式悄悄解决这个问题:要么在生产环境中测试,要么根本不测试。

两位写作者,一棵工作树:人机协同编辑的并发控制

· 阅读需 12 分钟
Tian Pan
Software Engineer

你正在重命名一个函数到一半,文件就在光标下重新加载了。你正在暂存的 diff 不再与工作树匹配。你的开发服务器无故热重载了两次,而十分钟前还通过的测试,现在却在你从未打开过的一个文件中报错了。没有崩溃,没有警告。你和你的编程 Agent 刚才一直在同时编辑同一个工作树,而你发现这一点的方式和大多数团队一样:通过那些莫名其妙的 diff。

数据库在五十年前就解决了这个问题,并给它起了一个名字 —— 并发控制 (concurrency control)。两个操作共享可变状态的写入者要么需要一个锁,一个隔离边界,要么需要一个合并协议,而在这些选项中做出选择是一个具有已知权衡的设计决策。然而,大多数采用编程 Agent 的工程团队从未明确做出这个决定。他们将第二个写入者直接扔进一个单一的工作树中,保留着单写入者世界的习惯,然后将产生的怪象归类为 “AI 不稳定”。这不是不稳定,这是一个竞态条件 (race condition),而你正是参赛者之一。

当工单的两端都是 AI Agent 时

· 阅读需 12 分钟
Tian Pan
Software Engineer

在本季度的支持队列中的某个地方,发生了一场没有任何人类参与的对话。你客户的采购智能体发起了一个关于发票差异的工单,你的支持智能体根据退款政策进行了回复,两者往复沟通了 11 次,直到线程终止——问题未解决,没有升级,且对两家公司都是不可见的,直到客户的 CFO 询问为什么退款还没到账。就其自身规则而言,这两个机器人都没有做错任何事。这就是问题所在。

我们为 AI 客户支持构建的一切都假设另一端是人类。情感检测、挫败感阈值、“你是否想与人工通话?”——所有这些都在模拟一个会疲劳、会愤怒或会放弃的客户。而客户的智能体不会做这些事。它具有无限的耐心,程序化的礼貌,并严格遵守剧本。当它遇到同样耐心、同样遵守剧本的支持智能体时,你不会得到解决方案或投诉。你得到的是一个在任何仪表盘上看起来都像健康对话的僵局。

为什么你无法为智能体设置进度条

· 阅读需 11 分钟
Tian Pan
Software Engineer

你发布过的每一个进度条都建立在一个假设之上:你知道分母。上传一个 40 MB 的文件?分母就是 40 MB。安装 212 个包?分母就是 212。进度条是诚实的,因为在工作开始之前,总工作量是已知的。

智能体(Agent)从根本上打破了这个假设。它执行的不是预定的步骤列表——它在执行过程中不断发现剩余的工作。它读取一个文件,结果发现了另外三个值得读取的文件。它运行测试,测试失败了,于是引发了一个谁也没计划过的调试分支。原来的第 4/7 步变成了第 4/19 步,偶尔又会变成第 4/4 步,因为最后三步被证明是不必要的。对于智能体来说,计算完成百分比(Percent-complete)并不难,而是“未定义”。在工作完成之前没有分母,而一旦完成,答案永远是 100%。

然而看看我们发布的产品:预示即将完成的加载动画(spinners)、爬到 90% 就卡住的进度条、在原本需要 8 分钟的任务进行到第 2 分钟时显示“即将完成……”的标签。这些都是小小的谎言,而且用户能识破它们。有趣的交互设计问题不是如何更逼真地伪造进度,而是当工作的持续时间在结构上无法预知时,诚实的安抚(honest reassurance)应该是什么样子的。

你的智能体是一个“话唠”客户端:数据引力开始影响工具循环

· 阅读需 11 分钟
Tian Pan
Software Engineer

15 年前,我们学会了畏惧 N+1 查询:一个在代码审查中看起来人畜无害的 ORM,会针对列表发起一次查询,然后为每一行数据再发起一次查询。一个本该只需要两次数据库调用的页面,最终却发起了两百次。我们通过预加载 (eager loading)、批处理 (batching) 和一代又一代的 Linter 解决了这个问题。然而,现在我们构建了 AI Agent,却在昂贵得多的层级上重犯了同样的错误。

一个单一的 Agent 任务——比如“核对这些发票”或“处理此故障”——通常会进行几十次串行的工具调用。每一次调用都是一次完整的网络往返:从 Agent 到工具,从工具到数据存储,数据返回工具,结果序列化到模型的上下文中,再进行一次推理以决定下一步操作。如果你的推理运行在一个云端,而数据存在于另一个云端,那么每一次跳转都会跨越一个计费且高延迟的边界。此时,Agent 系统成本的主要项不再是模型,而是地理位置。

没有人把这笔账算清楚。延迟预算是按次调用的,出网流量 (Egress) 只是存储账单中的舍入误差,而模型发票则受到了所有的关注。与此同时,工具循环悄然成为了你的基础设施所服务的通信最频繁 (chattiest) 的客户端。

你的 Agent 是别人的 Bot 难题

· 阅读需 12 分钟
Tian Pan
Software Engineer

你构建了一个每天早上检查供应商价格的智能体。它运行真实的浏览器,点击真实的按钮,表现得就像一个勤奋的员工——只是速度更快,而且是在凌晨 6 点。然后有一天,它停止工作了。你的代码没有报错。供应商的网站现在返回一个挑战页面,接着是 403 错误,最后干脆什么都没有了。你的智能体没有坏,它只是被归类了。

这是每个智能体构建者最终都会面临的尴尬对称性:网络防御系统经过了十年的爬虫战争、撞库攻击和囤货机器人的洗礼——从统计学上看,你合法的智能体与这些恶意行为并无二致。2024 年,自动化流量占到了全球网络流量的 50% 以上,其中约 37% 被归类为恶意流量。为了对抗这股洪流而演化出来的免疫系统并不关心你的意图。它关心的是你的指纹,而你的指纹显示为“机器人”。