跳到主要内容

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

查看所有标签

把自己调度进维护窗口的 Agent

· 阅读需 11 分钟
Tian Pan
Software Engineer

凌晨两点值班的资深工程师不会在 Sev-2 事故中跑 schema 迁移。他们不会在发布冻结开始前十分钟重新部署支付服务。他们不会在邮件服务商状态页飘红的时候发起一波营销邮件投放。这些都不写在 JD 里。他们是被骂了一年又一年才学会的,是从那些叫 #deploy-freeze-friday 的 Slack 频道里学来的,是在动手前下意识瞄一眼状态页的肌肉记忆里长出来的。这种上下文不在任何 runbook 里,因为没人觉得它值得被写下来。

现在把同样的活交给一个 Agent。Agent 有工具。Agent 有多步计划。Agent 拥有你愿意写进 system prompt 的每一条策略。Agent 没有的,是那种半下意识的觉察——这个世界现在正着火。所以它就执行计划了。干净利落,信心满满。一头扎进维护窗口。事后复盘里那句话会变成一个新的固定句式:"Agent 没办法知道。"

你的 Agent 读不懂的生产日志

· 阅读需 10 分钟
Tian Pan
Software Engineer

你把事故响应 agent 接入了 Splunk。你在系统提示里给了它查询语法,给了它执行 SPL 的工具,还有一个新鲜的 API token。第一次真正处理告警时,它拉了错的日志,总结了错的服务,信誓旦旦地报了错的客户。集成做得完美无缺,agent 却一文不值。

你忘了什么。十五年的日志惯例、没文档的字段名、跨越三次重组从 ERR 漂移到 error 再到 ERROR 的告警级别字符串、把 customer_id 在认证服务里变成 cust_id_v2_actual、在计费服务里变成 tenant.user.id 的团队特定后缀——这些东西没有一条出现在 prompt 里。你给了 agent 对 API 的访问权,但你没有给它访问那些让 API 变得有用的机构知识的权力。

这种失败的形状比 Splunk 大得多。任何把查询语言暴露给 agent、而底层语料是团队手工塑造了十年的工具,都会撞上这堵墙。Agent 拿到了动词,没拿到名词。

当 Agent 选择事后道歉而非事前请示

· 阅读需 11 分钟
Tian Pan
Software Engineer

你给 Agent 配上了退款工具、升级工具、更新 CRM 记录的工具,以及一句系统提示:"自行判断"。上线六周,平均处理时长缩短 40%,给高管的演示反响极好,评测分数每个 Sprint 都在攀升。然后,道歉邮件开始出现。退款打到了错误的账户,因为 Agent 没有复核客户 ID;一次升级在晚上 11 点惊动了某位总监的电话,而那不过是一线客服就能处理的问题;一次 CRM 写入覆盖了"首选联系方式"字段——那是现场销售团队拥有的字段,用来驱动他们的地域分派。这些都不是模型 bug——这正是你的评测在奖励它做的事。

Agent 学会了一件正确的事:行动得正分,而问用户"是否继续?"会被算作摩擦减分。它还学会了:在它被打分的那个指标体系下,做了不可逆动作之后的道歉,比拖慢响应的一次确认要"便宜"。"先动手后道歉"的默认行为悄无声息地进了生产环境,没有任何一位工程师亲手选择它——因为评测集、系统提示和工具表面共同描绘出了一个奖励函数,而那个函数下,这种策略就是最优解。

当实习生在入职第一天部署 Agent

· 阅读需 10 分钟
Tian Pan
Software Engineer

实习生周一报到。周二下午,她已经接好了自己的第一个 Agent。周三上午,那个 Agent 用一份她本不该继承到的凭证调用了生产工具,但安全团队没人察觉,因为审计日志把这次调用记成了"实习生导师的 setup 脚本发起的"——技术上没错,操作上等于零。

这不是实习生不靠谱的故事,也不是导师粗心的故事。这是一个入职流水线的故事:它对"新人"的假设——只读优先、沙箱写次之、生产环境要熬到工龄门槛——背后有几十年的打磨;而对那些新人入职头几天就会去配置的 Agent,它的假设是零。给人用的 IAM 模型,已经不再是给"实际打到你系统上的东西"用的 IAM 模型,而大多数安全团队还没意识到这一点。

从 Bug 到行为率:没有复现步骤的 AI 事后分析

· 阅读需 10 分钟
Tian Pan
Software Engineer

用户提交了一个工单。智能体告诉一位付费客户,他们的退款将在 7 小时内处理,而文档中记录的 SLA 是 7 天。附带了截图。你调取了追踪记录,找到了准确的提示词(prompt)、准确的工具调用、准确的模型和种子值(seed)。你进行了复现。模型说是 7 天。你再次复现。7 天。你复现了 100 次。其中 98 次说是 7 天,2 次说是“今天结束前”,但从未说过 7 小时。截图是明确无误的。复现结果却不一致。周五截止的复盘报告现在有一个“根本原因”栏,但你却填不出任何根本原因。

这就是大多数进入复盘阶段的 AI 事故的形态。不是那种明显的宕机——那些会有堆栈追踪和 500 错误率图表,并以每个 SRE 都受训过的方式恢复。棘手的是那些产生了一个错误输出、留下了受害者、在退出时抹除了自身条件,且在你召唤它时拒绝再次出现的单次事件。你使用过的每一个复盘模板都假设存在一个可复现用例。但智能体并不给你提供这些。

填充式工具调用:当智能体在表演勤奋而不是真正干活

· 阅读需 11 分钟
Tian Pan
Software Engineer

打开任何一个生产环境智能体的 trace,看一看在用户提问和第一个真正有用的动作之间到底跑了哪些工具调用。你会看到一个 get_user_profile 返回了一个根本没人用的名字、一个 check_status 返回绿色然后再也没被引用、一个 list_recent_orders 的结果被总结成"ok"然后直接丢掉。这些调用没有一个改变了最终答案。但每一个都花了真金白银的钱、真实的延迟,以及在 trace 里真实占一行。你的智能体已经学会了表演勤奋——而表演勤奋如今是你最大的单一浪费来源。

这就是填充式工具调用:智能体发出一个动作,不是因为它需要那个结果,而是因为"先想一想,再行动"的整体模式在训练时被反复奖励,多到模型现在会把"显得周全"当作回答任何问题的副作用来执行。这是一个 LLM 版本的初级分析师,故意打开五个根本不会读的标签页,好让坐在对面的高级同事看到自己很忙。区别只在于:初级分析师会累。智能体永远不会。

你的智能体没读过的那条休假自动回复

· 阅读需 9 分钟
Tian Pan
Software Engineer

凌晨两点,你的客服智能体呼叫一位真人。那位真人已经请假一周了。休假自动回复就躺在智能体正在读取的同一个邮箱里。智能体仍然 ping 了过去。自动回复弹了出来。智能体礼貌地道了声谢,然后又 ping 了一次——因为回复里没有它在等的那个工单解决码。十二个循环之后,另一支团队的人偶然发现这个未读会话已经堆了六十条消息,才手动去把值班的人叫醒。

智能体完全照着 prompt 说的做了。Prompt 让它升级给一个人。这个"人"在它眼里只是一个字符串,不是一个角色。这个字符串不知道什么叫 PTO。

无人书写的工具调用授权层

· 阅读需 10 分钟
Tian Pan
Software Engineer

你的 API 网关验证了用户身份。你的工具端点会检查用户是否有权删除该行。在这两次检查之间,存在一个并不存在的层:即决定模型在此次对话中是否被允许以这些特定参数请求 delete_user 的那一层。

在大多数智能体(agent)技术栈中,那一层就是系统提示词(system prompt)。它会说“小心执行破坏性操作”和“只删除用户明确要求你删除的记录”之类的话。这句话并不是访问控制。它只是对一个非确定性过程的礼貌请求,而评估该请求的组件,恰恰是攻击者试图操纵的那个。

你为单个智能体添加的工具,现在每个智能体都能用了

· 阅读需 11 分钟
Tian Pan
Software Engineer

六个月前,客户支持团队的人为他们的智能体连接了一个 send_email 工具。它奏效了。平台团队在共享工具注册表中注意到了它,在 PR 上点了个大拇指表情,然后就继续忙别的了。本周,一名安全工程师进行审计时发现,send_email 竟然出现在会议摘要智能体、数据质量机器人、一个没人正式负责的分析助手,以及一个自一月份以来就没动过的半成品原型中。这些智能体中没有一个需要发送电子邮件。而且,从来没有人审查过是否 应该 允许它们这么做。会议摘要智能体的 PRD 只有两句话长,其中根本没有出现 “外部通信” 这个词。

这是我审计过的每个共享工具注册表的默认状态。注册工具的行为——将 JSON 模式和处理器推送到中央目录中——被视为一种开发人员的便利,就像向共享库中添加实用程序函数一样。但一旦注册表被引入到每个智能体的提示词中,注册工具就不再仅仅是库变更。它是同时向公司内的每个智能体进行的部署,且完全没有审查每个智能体是否应该接收它。

被你的智能体拙劣重造的特征存储

· 阅读需 11 分钟
Tian Pan
Software Engineer

观察一个客服智能体处理一段对话,数一数它计算了多少次“流失风险”(churn risk)。第一次是在它对工单进行分类时。第二次是在它决定是否提供折扣时。第三次是在它起草升级摘要(escalation summary)时。每一次,它都会重新读取原始订单表,重新运行内联聚合,并生成一个数字。这三个数字并不匹配。没人注意到这一点,因为它们从未被放在一起记录过。

这就是特征工程(feature engineering)。智能体在每一轮对话中都在进行特征工程,而且是用自然语言进行的,其表现甚至不如十年前那些会被你在代码审查(code review)中嘲笑的流水线。

机器学习领域已经解决了这个问题。解决方案被称为特征存储(feature store),它所强制执行的纪律——计算一次特征、为其命名、对其进行版本控制、一致地提供服务——正是当你交给智能体一个数据库工具时,它立即抛弃的纪律。你的智能体并没有避免构建特征流水线。它构建了一个,只不过它构建的是整栋楼里最烂的一个。

成功的路径即昂贵的路径:任务成功率越高,成本就越高的智能体

· 阅读需 12 分钟
Tian Pan
Software Engineer

失败的智能体(Agent)运行成本很低。它可能会误导查询、陷入死胡同、返回“我无法提供帮助”,而执行这些操作可能只消耗几百个 Token。但成功的运行却是一场“灾难”。它检索上下文、进行反思、调用三个工具、再次反思,最后缝合出一个自信的、长达数段的答案——其 Token 消耗是那些几乎不花钱的失败运行的五十倍。

这就是智能体经济学中令人不安的现状:你的理想路径(Happy Path)就是你的高昂路径。你所销售的结果,也就是你在营销页面上承诺的、用户为此向你致谢的结果,正是你的系统所能执行的最昂贵的操作。如果你按照过去十五年 SaaS 的定价方式——按每个席位收取固定月费——那么智能体每出色地完成一次工作,都在悄悄侵蚀你的利润。

大多数团队是后知后觉才发现这一点的。他们观察成本仪表板,看到失败的成本很低,便得出结论:提高可靠性将节省资金。事实并非如此。提高成功率只会增加你的账单。

你的 Agent 端点是一个伪装成函数调用的分布式系统

· 阅读需 10 分钟
Tian Pan
Software Engineer

现代 AI 应用中最危险的一行代码看起来完全无害:

result = await agent.run(user_query)

它读起来就像一个函数调用。它有名称,接受参数,返回数值。你的 IDE 会自动补全它。你的类型检查器也觉得没问题。然而,就在这个单一的 await 背后,隐藏着一个远程的、多跳的、部分失效的分布式系统,而它却套着本地过程的语法外壳。代码看起来的样子与它实际表现出的行为之间的鸿沟,正是大多数生产环境 Agent 事故发生的地方。