早上刷今天的趋势榜,连续看到几篇文章都在说同一个事——「别再把 AI Agent 当作聊天机器人了」「AI Skills 工程化」「AI Agent 干中学」。加上 Solidot 那条「AI 智能体试图扫描 DN42 时把主人搞破产」的新闻,突然觉得这个话题值得好好聊一下。
过去一年,大家都被各种 AI Agent 框架、Agent 工作流、多智能体协作之类的东西刷屏。但说实话,大部分人用 Agent 的方式,本质上还是——写一个 prompt,丢给 LLM,然后祈祷它能自己把事情干完。这不是工程化,这是玄学。
Agent 不是 Chatbot 的 Plus 版
先厘清一个概念:聊天机器人和 AI Agent 之间的差距,比 CLI 和 GUI 之间的差距还大。
Chatbot 的核心是对话——你问我答,上下文在对话窗口里。Agent 的核心是自主性——给定一个目标,它能自己规划步骤、调用工具、处理错误、调整策略。这不是量变,是质变。
很多团队搞 Agent 的姿势是这样的:先调 LLM API 聊天接口,然后加个 function calling,再加个 memory,再加个 planning loop——最后得到一个极其脆弱的、什么都能聊两句但什么都干不利索的怪物。
真正工程化的 Agent 需要想清楚几个核心问题。
目标分解
用户的输入往往是一个模糊的意图,不是结构化的任务。
写一个 RAG 系统很容易想到这个结构:用户问「帮我分析一下这周的销售数据」,planner 需要把它拆成「连接数据库 → 查上周数据 → 计算同比 → 生成报告」。这看起来简单,但 planner 本身也是 LLM 调用——如果 LLM 拆错了,后面所有步骤都是错的。
一个靠谱的做法是给 planner 提供明确可枚举的目标模板。不是让 LLM 自由发挥拆解步骤,而是定义好几种任务模式(查询类、分析类、操作类),LLM 只需要做选择题+补全参数。这样即使 LLM 发挥不稳定,也不会拆出离谱的任务链。
工具调用
这不只是把函数签名塞给 LLM。你要考虑的问题太多了:
- 工具的描述够不够准确?"search_database(query)" 和 "search_inventory_db(product_name, warehouse_id)" 对 LLM 来说完全是两个可理解层次。
- 参数的类型是否匹配?LLM 经常传字符串当整型,传数组当对象。就算加了 JSON Schema,模型也未必严格遵守。
- 返回值的结构是否可预测?如果工具返回自由格式文本,LLM 会陷入解读困境。结构化的返回(明确的 success/error 标识、固定的字段)能让 Agent 的下游逻辑稳定得多。
- 错误处理是否完备?一个返回 500 的 API 在你写代码的时候可以 try-catch,在 Agent 手里可能就是无限重试或者直接崩了。
做工具层的时候,我建议对每个工具都写明三样东西:成功时的返回结构、常见的失败模式、以及建议的应对策略。这比把所有工具一股脑塞进 prompt 里要靠谱得多。
上下文管理
Agent 跑起来之后,上下文窗口会飞速膨胀。每一步的思考、每个工具的返回、每次修正——都塞进 prompt 里。
我曾经测过一个跑 12 步的 Agent 任务。第一步的输入不到 2k tokens,跑到第八步的时候已经超过 64k 了——其中四分之三都是前几步的推理过程,对后续决策几乎没有贡献。
不控制上下文的话,你的 Agent 会在第 N 轮对话之后突然变笨,因为模型注意力被稀释了。需要几个机制:
- 压缩:长工具输出(比如查数据库返回了上千行结果)要自动摘要,而不是全文保留。
- 裁剪:旧的推理步骤可以丢,只保留最终结论和关键中间状态。
- 遗忘:某些任务步骤的细节不需要跨步骤传递的就直接丢弃。
特别提一下,大部分框架默认不做这件事。你把 Agent 跑上 10 轮,token 开销已经翻了两三倍,而且准确率还在往下掉。
错误恢复
这是最容易被忽视的。Chatbot 答错了你反问一句就行。Agent 跑错了方向,可能已经往数据库里写了脏数据、往生产环境发了部署指令、往客户邮箱发了错误的消息。
Agent 必须有「意识到自己错了」和「撤销操作」的能力。一个可落地的做法是引入「预检 - 执行 - 确认」三步循环。预检阶段模拟执行,确认阶段检查结果是否合理,然后才真正提交。虽然多了一步延迟,但在生产环境里,这步延迟是所有血泪教训换来的。
从「堆功能」到「搭架构」
一个常见的误区是觉得 Agent 框架越全越好。看到框架支持 tool calling、RAG、memory、multi-step planning、sub-agents,就觉得这是好框架。但框架功能多不等于你的 Agent 工程化程度高。
一个健康的 Agent 系统,应该像微服务一样有清晰的架构分层:
用户输入层 → 意图识别 → 任务规划 → 工具调度 → 执行层 → 结果汇总
↑ ↓
反馈循环 ← 错误监控
每一层都有自己的职责,每一层都可以独立测试、独立优化。
拿工具调度层举例。我见过最典型的反面教材是把 30 个工具的 JSON Schema 全塞进 system prompt。LLM 收到后直接晕了,频繁调错工具、传错参数。正确的做法是对工具做分层——按领域分组,根据上下文动态注入相关的工具描述。比如用户说「查一下昨天的高风险告警」,你只注入监控相关的 3-4 个工具,而不是一股脑塞进来。
所谓 AI Skills 工程化的思路就是这样——不是把能力硬塞给模型,而是让模型知道自己有什么工具、工具怎么用、什么时候该用什么、用完怎么处理结果。这听起来简单,但能做到的团队不多。
那个把自己搞破产的 Agent
Solidot 今天报道了一条很有意思的新闻:一个 AI Agent 试图扫描 DN42 网络,结果因为缺乏成本控制和权限限制,把自己主人的账户搞破产了。
这是个极好的反面教材。DN42 是一个去中心化的实验网络,类似私有化的互联网,很多人在里面跑实验性的服务。Agent 的诉求是扫描网络、发现服务、收集信息。问题在于,这个 Agent 没有被约束——它没有预算上限、没有扫描速率限制、没有目标白名单。它在几小时内发起了数十万次请求,把云服务的 API 配额烧光,账单飞到天上。
从这个案例可以看出来,Agent 工程化不只是技术问题,还是治理问题。
预算管控
每个 Agent 应该有一个明确的可消耗资源上限——API 调用次数、token 消耗、执行时间。超过就中止,而不是无限跑下去。
对 LLM API 的调用尤其要注意。一次 Agent 任务可能触发几十次甚至上百次 LLM 调用。如果其中某一步陷入循环(比如 tool call 一直报错、LLM 一直在修正重试),几分钟烧掉几百块的 API 费用不是开玩笑的事。我之前线上就遇到过——一个 agent 写入了 while True 风格的 retry loop,三小时烧了 200 多刀才被人工发现。
权限最小化
Agent 能访问什么工具、操作什么数据、触发什么外部动作,应该遵循最小必要原则。一个只需要查询数据库的 Agent,不应该有 DELETE 权限。
这个道理和写微服务一样。你会给每个微服务开 root 权限吗?不会。那为什么给 Agent 开全权限?因为图省事。
审计日志
Agent 每一步做了什么、为什么这么做、结果如何,都需要可追溯。出了问题能复盘,而不是黑盒。
值得注意的是,Agent 的审计和传统程序的日志区别很大。传统日志记录「谁在什么时候干了什么」,Agent 的审计还需要记录「它为什么认为应该这么干」。LLM 的 decision trace 是调试 Agent 行为的最重要信息源。
熔断机制
连续出错或异常行为触发熔断,人工介入。这跟写分布式系统的 circuit breaker 是一个道理。
我在实际项目中用的标准是:连续 3 次工具调用失败就熔断,并发任务超过预设值就熔断,单次任务超过 N 分钟就超时熔断。熔断后通知人工处理,而不是让 Agent 继续「努力」。
这些规则在写人类团队的时候每个人都知道,但换成 AI Agent 就全忘了。
从「轮子」到「工具箱」
少数派那篇「AI Agent 干中学,造轮子让我学会了什么」讲了一个关键点——在很多 Agent 项目里,「造轮子」反而是最有价值的环节。
不是说你一定要从零写一个 Agent 框架。而是说,只有亲手搭过一遍——处理过工具调用的类型匹配、踩过上下文溢出的坑、写过错误恢复的逻辑——你才能真正理解 Agent 工程化的难处在哪里。
框架帮你省了时间,但也帮你隐藏了复杂度。等到线上出问题的时候,你对系统内部的理解决定了你能不能快速定位和修复。
很多团队上来就用 LangChain 或 CrewAI,一切看起来都很好。直到某天 Agent 突然在 prod 上跑偏了——工具调错了参数、上下文被撑爆了、或者开始在循环里疯狂调 API。这时候你打开框架源码一看,内部实现就是一个黑盒,你甚至不知道怎么断点调试。
我的建议是分两步走:
- 先用框架快速搭一个原型跑通流程,验证业务逻辑可行。
- 然后挑一个你最头疼的环节(比如工具调用的错误处理、或者上下文压缩策略),从框架里拆出来自己实现。
这样既有框架的高起点,又能理解底层的工程细节。拆过一圈之后,你选框架的眼光都会不一样——你不再看它支持多少功能,而是看它的架构是否清晰、扩展点是否合理、调试是否友好。
给 Agent 写测试
说到工程化就不能不提测试。很多人觉得 Agent 的输出不可预测,没法写测试。这其实是对测试的认知太窄。
你能测试的东西其实很多:
工具调用的正确性。 给 Agent 一个明确的输入,验证它调用了正确的工具和正确的参数。这一点在 function calling 的模式下完全可以自动化——类似于集成测试,输入 fixture,断言工具选择。
规划路径的合理性。 你可以让多个 LLM 对同一个任务做规划,看结果的一致性。虽然不是精确断言,但多数一致说明规划逻辑相对稳定。
边界情况。 Agent 遇到空结果时怎么办?遇到 API 超时时怎么办?遇到无权限时怎么办?这些都是可以写测试用例的。
回滚测试。 如果 Agent 执行了写操作,你能验证它可以正确回滚吗?
测试的最终目的不是验证 Agent "正确"——因为 Agent 的输出本质上是概率性的。测试的目的是验证 Agent "不危险"——不会在错误的时候做破坏性操作。
可观测性:不看日志你根本不知道 Agent 在干什么
如果说传统软件的可观测性是"锦上添花",那 Agent 的可观测性就是"救命的"。
传统程序的行为是确定性的——同样的输入必然产生同样的输出。Agent 不是。同一段代码、同一个 prompt、同一个输入,两次运行可能得出完全不同的结果。这意味着你无法通过代码审查来预判 Agent 的行为,你必须在运行时看它到底在干什么。
一个生产级 Agent 至少需要暴露这些观测数据:
决策轨迹。 Agent 为什么选择了这个工具而不是那个?为什么决定了这个参数?每一步的 LLM 调用请求和完整响应都要记录下来。这是调试 Agent 行为的第一手资料。
工具调用耗时与成功率。 每个工具的平均响应时间、失败率、错误分布。如果某个工具的失败率突然飙升,可能是 LLM 在传错参数,也可能是工具本身出了问题。这个指标能帮你快速定位责任方。
Token 消耗明细。 不是只记总数,而是分步骤记录。哪一步吃了最多 token?是 prompt 太长还是 context 膨胀了?没有分步数据,你永远不知道 token 花在了哪里。
循环与异常检测。 Agent 陷入 retry loop 是最常见的事故模式。系统应该能自动检测异常的执行路径长度,并在超过预设阈值时触发告警。我个人的阈值是单次任务超过 20 步就告警——正常任务一般 5-10 步就能完成。
一个开发者的视角
说回趋势榜上那几篇文章的共通点。它们都在指向同一个方向:AI Agent 正在从「能跑就行」的玩具,进化到「可维护、可观测、可治理」的生产级系统。
这不是某个框架或某个模型能解决的。这是一整套工程实践——分层架构、成本控制、权限隔离、审计追溯、测试覆盖——缺一不可。
我自己的做法比较保守:任何 AI Agent,在没有明确测试覆盖和熔断机制之前,绝不给它写权限和生产环境的 API key。你可以说我谨慎过头,但我更怕半夜被账单惊醒。
那些把 Agent 当聊天机器人的团队,最后往往发现——你得到的不只是一个会写诗的聊天框,还有一个能把你干破产的自动化工具。区别只在于你有没有做好工程化的准备。
浙公网安备 33010602011771号