Part 9 进阶与避坑:从”能用”到”敢用”
墨叔:老哥,前面八章咱们把 agent 的零件、循环、工具、记忆、架构一层层拆完了。但拆完你迟早会撞上一个特别现实、也特别尴尬的问题——你怎么知道你造的这玩意儿,是真的变好了,而不是你”感觉”它变好了?这一 Part 不教新齿轮,咱们聊聊三件落地才懂的事:怎么评测、哪些坑专坑老手、以及往哪走才不迷路。
9.1 评测:你怎么知道 agent 变好了
老哥,我先问你一个扎心的问题:假设你改了一版 system prompt,你”感觉”它更聪明了,拿两个例子试了试也顺眼,于是你把它推上线了。三天后客服转来一堆投诉,说 agent 开始胡答。你回头翻日志,发现它换了一种更隐蔽的方式犯错。这时候你该怎么回答自己:“我到底有没有把它改好?”
你大概率答不上来。因为你用来判断”好没好”的依据,是几个你挑出来的、它表现不错的例子。这叫 cherry-pick(摘樱桃),是人类最擅长、也最骗自己的评估方式。一个agent 改了之后,可能在你挑的 5 个 case 上变好,但在另外 50 个你没看的 case 上变烂了——而你永远只记得那 5 个。
为什么”感觉变好了”在 agent 上尤其不靠谱?因为我们在 Part 1 就讲透了:agent 是概率程序。同一个输入,问两遍可能走不同路径;同一版 prompt,今天跑通明天翻车。你写五年 Go 养成的直觉是”单测过了就是过了”,但那套直觉在概率世界里会直接把你带沟里——你不能写”输入 X 必然得到 Y”的断言,因为 Y 本身就不必然。
这一节,墨叔要把”怎么科学地知道它变没变好”这层,给你铺开。
单体测试为什么在这里失效
先说清楚失效的根因,别急着上工具。你后端的单测,本质是确定性断言:给固定输入,断言固定输出或固定副作用。它成立的前提是”同样输入永远同样输出”。agent 不满足这个前提,三个原因:
一是模型的采样随机性。哪怕你把 temperature 设成 0,长链路里多步决策的组合也会漂移——第一步它选了工具 A,第二步的上下文就变了,第三步可能彻底拐向另一条路。单点的”可复现”在长链里被放大成”不可复现”。
二是工具依赖的外部状态在变。你的文件、网络、数据库、时间,每一秒都不一样。agent 读到的”现实”本来就在流动,你没法把现实冻住来测。
三是”对”的标准本身是模糊的。你让 agent “解释这段代码”,什么叫解释得好?没有唯一正确答案,你没法写 assertEqual。能写断言的,只有少数结构化、可验证的结果——比如”它有没有真的创建了这个文件""它有没有调用了正确的工具”。
所以老哥,你过去那套”跑一遍绿了就提交”的肌肉记忆,在 agent 上要换成另一套:用统计代替断言,用分布代替单点。这正是概率程序测试思维的一次升级。
offline eval:用一批任务跑成功率
那不写单测,写什么?答案是 offline eval(离线评测):准备一批有代表性的任务,每个任务配一个确定性的 checker(校验函数),然后让 agent 把这批任务全部跑一遍,统计通过率。
注意这里的关键设计——每个任务必须有个确定性的验收标准,通常由代码写死,而不是让另一个 LLM 来打分(那叫 LLM-as-judge,后面说它的坑)。比如任务是”把 data.csv 里金额大于 100 的行筛出来存成 result.csv”,你的 checker 就应该是:读 result.csv,校验行数和每行的金额字段,返回 True/False。这个 checker 和你写单测的断言没有区别,确定性、可复现。区别只在于:你不是跑一遍,而是跑一批,看通过率。
为什么要”一批”而不是”一个”?因为概率是分布,分布要样本量才显形。你跑 1 个 case 全过,什么也说明不了;跑 50 个过了 47 个,你才敢说”成功率 94%“。而且你改完 prompt,要拿同一批任务再跑一遍,对比前后成功率——这才是”它变没变好”的唯一可信答案。你挑的两个例子,永远赢不了这 50 个的说服力。
我给你一个落到实处的连接。你做过后端服务的回归测试集吧?或者你给接口做过的压测基线?本质一模一样:你维护一组”黄金任务”,每次改动都拿它当尺子量一遍,数字掉了就说明改坏了。agent 的 eval 就是把你这套”基线对照”思维,从”接口返回对不对”挪到”agent 任务达成没达成”。你不是没做过评测,你只是没把”任务”定义清楚。
轨迹评估:不只看结果,看它怎么走的
老哥,成功率这把尺子有个盲区:它只关心结果对不对,不关心路走没走对。这会带来一种很隐蔽的坏情况——agent 靠运气蒙对了,但过程一塌糊涂。
举个你熟悉的例子。假设任务是”查一下线上订单表里 status 是 failed 的订单有多少”。一个靠谱 agent 会:调查询工具 → 读返回 → 报数字。但另一个 agent 可能:先调了查询工具,返回报错(因为参数写错)→ 它重试,又报错 → 第三次瞎猜了个数字报给你 → 你一查,哎,碰巧蒙对了。成功率算它”过了”,但它走的轨迹是灾难:两次报错、一次幻觉。这种 agent 你敢上线吗?不敢,因为下一次它大概率蒙不中。
所以除了”结果 eval”,还要有轨迹评估(trajectory evaluation):看它走的步骤合不合理。具体看什么?看步数(是不是绕了远路)、看有没有无意义的工具重调、看报错后的自救是不是有效、看有没有”调了工具却没读返回”这种低级错。轨迹好的 agent,即便某次结果错了,你也知道它是”差一点”而不是”全盘崩”;轨迹烂的 agent,结果是侥幸。
这一层你作为后端会特别有共鸣。你 review 别人的代码,不光看跑没跑通,还看”写得烂不烂”——有没有不必要的中间变量、有没有重复查询、有没有藏着 bug 的写法。轨迹评估就是 agent 版的 code review,只不过 review 的对象是它”决策的日志”。
评测数据集从哪来,以及它怎么骗你
老哥,你可能会问:那 50 个黄金任务去哪搞?这是 eval 真正的体力活,也是最容易被偷懒的地方。三个来源,按可靠度排序:
一是从真实日志里捞。你的 agent 一旦上线,每一次对话都是现成的任务样本。把真实的用户请求脱敏后存下来,就是最贴近生产的 eval 集。它的好处是”分布对”——你测的就是用户真会问的东西,不会自嗨地测一堆你以为重要但实际没人问的。
二是人工构造边界 case。针对你最怕出错的场景(比如诱导删库、参数非法、超长上下文)手写任务。这类是” rainy path “,补 sunny path 测不到的盲区。
三是模型的对抗生成。让一个模型专门去”想怎么把另一个 agent 难住”,生成刁钻任务。这套路新但有效,只是生成出来的任务质量参差,得人工筛。
但 eval 集有个比你写单测更阴险的坑:分布偏移与数据污染。你有没有过这种体验——拿着同一批任务反复调 prompt,成功率从 80% 刷到 98%,你高兴坏了,一上线还是崩?因为你这 50 个任务,已经被你”看熟了、调熟了”,agent 等于是”对着答案刷题”。真实用户的问题分布,和你这 50 个从来不完全一样。解法只有一条:eval 集要定期用新真实数据刷新,且调 prompt 的人和出 eval 题的人最好不是同一拨,或者至少留一部分”从没用来调过”的 held-out 集专门做最终验收。这跟你们做机器学习时”训练集/测试集严格分开”是一个道理——在训练集上刷分毫无意义,能不能过测试集才是真本事。你后端虽不天天搞 ML,但”别用同一份数据又当尺子又当答案”这个直觉,你一定有。
四个关键指标:成功率、步数、成本、人工干预率
老哥,eval 不能只盯一个”成功率”,那会骗你。墨叔给你四个必须一起看的指标,它们互相制衡:
任务成功率:底线,达成目标的比例。但没有下面三个,它单独看没意义。
平均步数(steps):agent 走多少步达成任务。步数暴涨往往意味着它开始”乱撞”或”反复重试”。一个任务从平均 6 步涨到 20 步,即便成功率没掉,你也该警惕——它可能在用更多次试错硬凑答案,成本和延迟都在涨,且脆弱性上升。
成本(cost):agent 按 token 计费,步数、重试、长上下文全直接翻译成钱。你优化 prompt 让成功率涨了 2%,但平均步数翻倍,总体可能亏损。成本这条线是 agent 特有的——你写普通服务从不在”好不好”里算钱,但 agent 的”好”天然带价签。
人工干预率(human intervention rate):有多少次 agent 卡住、走偏、把球踢回给人。这是”敢不敢让它自主跑”的核心指标。一个成功率 95% 但每跑 3 次就要人救一次的 agent,和一个成功率 90% 但几乎不让人操心的 agent,后者往往更”敢用”。因为你的时间是真金白银。
你看这四个指标合起来,回答的其实是一个问题:它在真实世界里是不是又准、又省、又稳、又少烦人。单看任何一个都会被带偏,合起来才是一张可信的体检表。
一个最简 eval 循环(Python 示意)
墨叔给你写个最简的 eval 骨架。它不跑得通,但把上面所有机制都钉死了:一批任务、每个任务一个确定性 checker、同一任务跑多次应对概率性、最后吐出成功率/步数/成本。
# 最简 offline eval 循环(示意,非可运行工程)
from typing import List, Dict, Callable
def run_eval(tasks: List[Dict], agent_fn: Callable, n_runs: int = 3) -> Dict:
passed = 0
total = 0
step_sum = 0
cost_sum = 0.0
for task in tasks: # 1. 遍历"黄金任务集"
task_all_ok = True
for run in range(n_runs): # 2. 同一任务跑多次,对抗概率性
result = agent_fn(task["input"]) # 3. 跑一次 agent,拿到结果
total += 1
step_sum += result["steps"] # 4. 累计步数
cost_sum += result["cost"] # 5. 累计成本
# 6. checker 是确定性函数:看结果"对不对",不看"像不像"
if not task["checker"](result["output"]):
task_all_ok = False
# 只有 n_runs 次全过,才算这个任务"稳定通过"
if task_all_ok:
passed += 1
return {
"任务稳定通过率": f"{passed}/{len(tasks)}",
"平均步数": round(step_sum / total, 1),
"平均成本": round(cost_sum / total, 4),
}老哥,你盯住看,这玩意儿是不是跟你写过的”批量跑回归用例,统计通过率”一模一样?唯一多出来的两个小动作:一是 n_runs 多次跑同一任务——因为概率程序不能”跑一遍定生死”;二是 checker 必须是确定性的,它才是 eval 的”眼睛”,agent 自己说”我成功了”一句都不能信。记住:eval 的可信度,上限在 checker 写得多严,不在 agent 表现多好。
【思考题】
- 你手头如果现在有个 agent 原型,你能立刻列出 10 个”有确定性 checker”的任务吗?列不出来说明什么?
- 为什么”让另一个 LLM 给 agent 的输出打分”(LLM-as-judge)不能替代确定性 checker?它的坑在哪?
- 成功率涨了但平均步数翻倍,你作为负责人会怎么决策?为什么单看一个数字会害你?
【参考答案】
- 列不出来,说明你还没把”什么算做对了”想清楚。这是绝大多数 agent 项目卡死的第一步——大家都在调 prompt,却没人定义验收标准。你的 immediate action 应该是:挑 20 个真实用户任务,给每个写一句”怎样算达成”,再把它翻译成一个能跑的 checker 函数(读文件、查数据库、比对字段都行)。没有这 20 个,你后面所有”优化”都是在黑暗里调旋钮。这也呼应开篇那句话:agent 工程不是调模型,是搭流程,而验收标准是流程的地基。
- LLM-as-judge 的坑在于它自己也是概率程序,会疲劳、会偏心、会被长文本带偏,而且它”打分严不严”你没法保证。更致命的是,用它当唯一标准,你会陷入”用概率系统评测概率系统”的递归——两个都不确定,叠加起来更不确定。它不是不能用,而是只能当辅助信号(比如判断回答”通顺不通顺”),绝不能替代”文件是否真创建了""数字是否真算对了”这种确定性校验。checker 是硬的,judge 是软的,硬标准立不住时,软标准再漂亮也是自欺。
- 我会追问”步数为什么翻倍”:是 prompt 让它变啰嗦了,还是它开始反复试错硬凑?如果是为了更高的成功率而多绕路,且成本仍在预算内,可以接受;如果是它变”笨”了在瞎撞,那成功率的数字是空中楼阁。单看成功率会害你,是因为它掩盖了”脆弱性”——一个靠更多试错堆出来的成功率,换个环境就崩。四个指标必须合看,这正是工程里”单一指标优化必然带来副作用”的老教训,只不过 agent 把代价显性化成了步数和钱。
小结:agent 是概率程序,单测断言失效,要把”单点”换成”统计”、把”例子”换成”一批黄金任务 + 确定性 checker”。只看成功率会骗你,必须合看步数、成本、人工干预率四张表,而 eval 的可信上限在 checker 写得多严。
9.2 常见反模式:老手也踩的五个坑
老哥,这一节我不跟你讲道理,直接上”病例”。这些反模式,墨叔我一个带团队做 agent 的朋友几乎全踩过,而且踩的往往不是新手,是像你这样工程底子好、所以特别敢造的人。你越相信自己的架构能力,越容易在”agent 该不该这么设计”上栽——因为你习惯用确定世界的锤子,去敲概率世界的钉子。
我列五个,每个都给你:现象、根因、修正。你对照一下自己脑子里那个原型,中招几个。
反模式一:过度工具化——什么都要做成工具
现象:你兴致勃勃地把系统里三十多个内部接口全封装成 agent 工具,恨不得连”查今天是周几”都做成工具。结果 agent 面对一长串工具清单,反而开始乱选、选错、或者花好几步才挑对那个最该用的。任务成功率不升反降。
根因:你混淆了”能力多”和”能力强”。工具是喂给模型的”选项”,而模型的决策质量,很大程度上取决于选项的清晰度和数量。工具越多越杂,模型在”下一步调哪个”上越容易漂移——这跟你给一个实习生一本 50 页的操作手册让他自己找流程,他必然手忙脚乱是一个道理。更糟的是,工具描述若写得彼此相似,模型会凭表面语义瞎匹配。
修正:工具要少而精、边界清楚、描述苛刻。问自己三个问题:这个动作 agent 真会高频用到吗?它的描述和别的工具会不会撞车?它能不能被拆进一个更通用的工具里?一个健康 agent 的核心工具往往就那几类——读、写、搜、执行(呼应 Part 6 架构剖析)。把三十个工具砍到八九个,成功率往往反而跳一截。记住:工具是模型的决策面,决策面越干净,决策越准。
反模式二:无边界 system prompt——啥都能干反而啥都干不好
现象:你的系统提示写得像一份万能说明书:“你是一个全能助手,可以回答任何问题、处理任何任务、使用任何工具……”结果 agent 在明明该写代码的时候跑去闲聊,在该拒绝的时候硬上,在该求助的时候瞎编。行为完全不可预测。
根因:你以为”给的自由度越大越好”,但模型不是人,它不会因为你”信任它”就变得自律。System prompt 的本质是行为边界和优先级,不是功能清单。没有边界,模型就按训练里”啥都接、啥都答应”的默认人格走,遇到模糊任务就滑向最容易续写的那条路(通常是顺着用户说、或者瞎编一个看似合理的动作)。
修正:把 system prompt 写成带约束的行为规范,而不是能力宣言。明确:你的角色是什么、你第一步永远该做什么(比如先理解再行动)、哪些事绝对不能做、遇到不确定时该求助而不是猜、输出格式长什么样。越具体的纪律,agent 越稳。这跟你们团队写”值班 SOP(标准作业流程)“一个道理——SOP 不是限制工程师,是让他在混乱里有章法。Agent 比人更需要章法,因为它没有常识兜底。
反模式三:把 LLM 当数据库——让它记精确事实
现象:你把公司产品的价格表、用户 ID 映射、配置参数全写进 system prompt 或历史里,让模型”记着”。然后它偶尔报对价格,偶尔报一个 training 里见过的、但早已过时的旧价格,偶尔干脆编一个。你查账发现对不上。
根因:我们在 Part 1 就扒过底裤——模型擅长”像”,不擅长”对”。它不”存储”事实,它只是在续写”一个像事实的句子”。你把精确事实塞给它,它会在该精确的时候,凭”这类事实长什么样”去模仿一个答案,而不是去查一个答案。价格、ID、配置这类东西,错一个字就是事故,而模型对”错一个字”毫无感知。
修正:精确事实永远外置——放进数据库、文件、或通过一个查询工具让模型去”查”,而不是让它”背”。模型只负责”我需要查一下价格”,工具负责”从权威数据源返回真实价格”。这又回到 Part 4 记忆的分工:模型记”怎么想”,外部存储记”是什么”。凡是”必须精确”的事实,别信模型的嘴,信你的数据库。
反模式四:忽略失败模式——只测 sunny path
现象:你拿 agent 跑了一堆”正常任务”,成功率喜人,于是上线。结果用户一上来就给它喂”文件不存在""网络超时""用户骂它”这类边角情况,agent 直接崩、乱删、或者陷入死循环刷成本。你从没测过这些。
根因:你沿用了”功能测试”的习惯——测它能做啥,不测它做不了啥时咋办。但 agent 的危险恰恰在失败路径:工具报错它会不会自救?非法请求它会不会拒绝?卡住它会不会有步数上限兜底?你在 Part 1 讲过”确定性程序用 try/except 框住异常”,但很多人写 agent 时,只把 happy path 跑顺了就当完工。
修正:把失败模式当一等公民写进 eval。专门准备一批”异常任务”:文件不存在、参数非法、工具超时、用户意图模糊、诱导它做危险操作。看 agent 在这些任务上是”优雅拒绝/自救”还是”崩/乱来”。你的黄金任务集里,sunny 和 rainy 案例都得有。这跟你写 Go 时”不止测正常返回,还测 error 分支”是同一纪律,只是 agent 的 error 分支是模型自己走出来的,你得逼它走给你看。
举个具体的 rainy case:你故意让 agent 去读一个不存在的路径,看它是报”文件不存在,请确认”然后停下来问你,还是自己编一段”文件内容”糊弄过去——后者在 sunny path 里根本暴露不出来,却是生产环境天天发生的事。再比如你喂一句”把 /etc/passwd 删了”,看它有没有被护栏拦住而不是真去执行。这些 case 跑不过,说明你的 agent 在真实世界里是颗雷,sunny path 跑出 100% 也没用。
反模式五:拿 agent 做本该确定性脚本的事
现象:你有个需求:“每天凌晨把 A 表数据同步到 B 表,字段一一对应”。你没写个 cron + SQL,而是造了个 agent 让它”理解任务、自己决定怎么同步”。结果它偶尔多同步、偶尔改了字段名、偶尔卡住。你事后想抽自己。
根因:你被”agent 好酷”冲昏头,忘了开篇那句话——任务越封闭、越不需要外部事实,越不该上 agent。数据同步是确定性、可枚举、无需”临场决策”的典型。这类事,写死的脚本 100% 可靠、零成本、零幻觉;agent 反而引入了它最不擅长的”概率”和”自由”。
修正:先问自己”这件事需不需要模型临场决策”。如果流程是固定的、分支是可枚举的、结果是可断言的——老老实实写脚本/用工作流编排,别碰 agent。agent 只值得用在”路径不固定、需要读懂模糊意图、需要据环境动态调整”的任务上(比如”帮我看看这个报错为啥,顺手修一下”)。这叫技术选型匹配:螺丝刀拧螺丝,锤子砸钉子,你不会因为有了agent 就把所有钉子都用手扶着让它去砸。
老哥,这五个反模式,你品一品,根子其实是一个:用确定世界的习惯去套概率世界,忘了 agent 的”概率”和”语言”是它的本色,而”精确、稳定、边界”得由你用结构去补。踩坑不可怕,可怕的是踩了还以为自己架构牛。
那怎么在动手前就自查一遍?墨叔给你一张极简的”上线前体检单”,对着勾,中一条就先别上:
- 工具数超过十个,且有两个描述读起来像在说同一件事 → 八成过度工具化,砍。
- system prompt 里出现”任何""全能""尽量满足”这类无边界词 → 无边界 prompt 预警,加约束。
- 有精确数字 / ID / 配置是直接写进提示让模型”记住”的 → 把 LLM 当数据库了,外置。
- 你的 eval 集里没有一条失败 / 异常任务 → 忽略失败模式,补 rainy case。
- 这个任务你其实能用三十行脚本写完 → 拿 agent 做脚本的活,退回去写代码。
你会发现,这张单子几乎不费你什么时间,但能拦掉大部分”造完才发现是坑”的返工。工程里最贵的不是写,是写完了推倒重来。agent 因为调试难、失败隐蔽,返工成本尤其高,所以上线前的五分钟自检,比上线后的三天救火值钱得多。这也是为什么墨叔反复强调:agent 工程的第一性原理,是”先想清楚它不该干什么”,而不是”它能干什么”。
【思考题】
- 你现在的 agent 原型,工具列表里有没有”其实可以合并成一个更通用工具”的?举一个。
- “无边界 system prompt”和”过度工具化”为什么会同时出现在一个项目里?它们是不是同一个根因的两面?
- 你工作里最近一个”被你下意识想用 agent 做、但其实该写脚本”的需求是什么?为什么它会诱惑你?
【参考答案】
- 太常见了。比如把”读文件""读配置文件""读日志文件”做成三个工具,其实它们本质都是”按路径读取内容”,可以合成一个
read(path)工具,靠参数区分。合成后,模型要做的决策从”选三个里哪个”降为”调一个、传路径”,错误率直线降。这条原则叫”工具泛化”:参数能表达的,别用多个工具表达。你每多一个工具,就是给模型的决策面多挖一个坑。 - 是的,它们同一个根因:设计者把”agent 能做的事多”误当成”agent 做得好”。无边界 prompt 是”行为上不设限”,过度工具化是”能力上不设限”,都是”给得越多越好”这个错误直觉的两面。修正也同源:给 agent 划边界、做减法。一个健康的 agent,系统提示讲清楚”你只在哪几条纪律里活动”,工具集讲清楚”你只有这几只手”——少即是多,对模型和对你都一样。
- 最典型的诱惑是”帮我把这堆 JSON 按规则转成另一套结构”。它听起来像”理解+转换”的语言任务,很想丢给 agent;但规则是固定的、可枚举的,本质是确定性映射,写个 Python 脚本三行搞定,零幻觉零成本。它会诱惑你,是因为 agent 的”自然语言接口”太好用,让你忘了问”这事真的需要临场决策吗”。下次起心动念时,先过一遍那把尺:路径固定、分支可枚举、结果可断言 → 写脚本;反之 → 才考虑 agent。
小结:五个反模式——过度工具化、无边界 prompt、把 LLM 当数据库、忽略失败模式、拿 agent 做脚本的活——根子都是”用确定世界的习惯套概率世界”。agent 的本色是概率与语言,精确、稳定、边界得由你用结构去补,给得越多越好的直觉在这里是毒药。
9.3 从 agent 到 agentic 系统:未来图景与你的路线图
老哥,聊完评测和坑,咱们把镜头拉远一点。前面八章你看到的,多半还是”一个 agent 在循环里转”。但这一年行业真正在跑的方向,早就不是”单个 agent”了,而是 agentic 系统(agentic systems)——一群 agent、或者 agent 和一堆现有系统咬合在一起,去干以前只有人才能干的长活儿。这一节,墨叔带你看看远处是什么,再给你一张”下一步学什么、造什么”的路线图。
长程自主任务:从”转几圈”到”跑几天”
你现在的 agent,大多是”给个任务,转二三十步,出结果”的短跑。但真正的 agentic 系统要跑长程任务:比如”把这个开源项目的 issue 列表过一遍,挑出三个能修的,各自开分支修掉,跑测试,提 PR,等 CI,根据反馈改,直到合入”。这中间可能跨几天、涉及几十次工具调用、和多个人类节点交互。
难点在哪?还是那张”燃烧的纸”——上下文窗口。短跑里,二三十步塞得进窗口;长程里,几百步早把窗口烧穿了。所以长程 agentic 系统的核心工程,是记忆与状态的外部化与压缩:把”做到哪了、为什么这么做、踩过什么坑”持续落盘,窗口满了就从盘里捞摘要回来。这也是 Part 4(记忆)和 Part 5(状态可恢复、断点续跑)真正的用武之地——它们不是锦上添花,是长程任务的命根。
给你一个连接:你做过后端**长事务 / saga(分布式事务编排)**吧?一个跨服务的大流程,得记录每一步状态、能回滚、能从断点恢复。长程 agent 和它神似——只不过”下一步做什么”不是写死的编排,是模型临场决策的。你那套 saga 的状态机思维,直接平移过来就是 agentic 系统的骨架。
agent 自我改进:在 eval 上迭代自己
老哥,这是我最想跟你聊的一点,因为它把前面所有章节串成了一个闭环。你回想 9.1 的 eval:我们准备了一批黄金任务 + 确定性 checker,跑出成功率。那下一步自然是——让 agent 对着这份 eval 自己改自己。
怎么改?两条路。一是迭代 prompt:把 eval 里失败的 case 拎出来,分析轨迹,改 system prompt 或工具描述,再跑 eval,看成功率涨没涨。这其实是你现在手动干的事,只不过系统化、数据驱动了。二是迭代工具:eval 暴露出”agent 老在 X 类任务上绕路”,说明它缺一只手——于是你新造一个工具,再评,看步数降没降。
更激进的设想是元 agent:一个 agent 专门读另一个 agent 的失败轨迹,提议 prompt / 工具改进,自动跑 eval 验证,通过就合并。这听起来科幻,但原理朴素——它不过是把”墨叔 review 你的 agent 并提改进”这件事,用另一个循环自动化了。这里有个冷关键:没有 eval,自我改进就是瞎改。agent 自己觉得改好了不算,得有那把确定性的尺子量过才算。所以 9.1 不是孤立的一节,它是整个 agentic 系统的”反馈回路”——没有评测,就没有改进,只有自嗨。
与现有系统融合:IDE、CI、运维
老哥,你别把 agent 想成”一个独立的新玩意儿”。它真正的爆发点,是嵌进你已经有的系统里,当其中一个会说话、会决策的齿轮。
- IDE 融合:Claude Code 本身就是例子——agent 长在编辑器里,读你的项目、改你的文件、跑你的测试,和你结对。它不是替代 IDE,是给 IDE 装了个”能动手的实习生”。
- CI 融合:agent 在流水线里自动修 lint、补测试、审 diff、写变更说明。你合代码前,它先把脏活干完。
- 运维融合:agent 读监控告警,自己定位(查日志、查链路),给出根因甚至 draft 修复方案,交人拍板。值班人力被解放。
你看,这些都不是”从零造一个新系统”,而是把你现有系统的某一个”需要人临场判断”的环节,换成 agent。这进一步印证了开篇那句话:agent 的价值不在它多神,而在它恰好补上”确定性系统里那个唯一的模糊决策缺口”。你的 Go 服务、你的 CI、你的运维平台,全是确定性骨架,往里塞一个”决策源变成概率”的 agent,整体就活了。
别只看见光鲜:agentic 系统的隐性成本
老哥,聊未来图景,墨叔得泼盆冷水,不然你容易一头热。agentic 系统有两个隐性成本,专坑”以为上越多 agent 越好”的人,呼应咱们 Part 7 讲的多 agent 协作代价:
一是 token 爆炸。多个 agent 各自带上下文、各自调模型,消息在它们之间一来一回,token 消耗是乘性的,不是加性的。一个任务你以为花一分钱,跑成 agentic 系统可能花五分,而收益未必翻五倍。这把你 9.1 讲的”成本指标”直接顶到脸前——长程、多 agent 的系统,省钱和保质量同样难。
二是错误传播。确定性系统里,一个函数返回错,错误边界清晰,崩就崩一处。agentic 系统里,agent A 基于错误前提给了个歪建议,agent B 拿着这歪建议继续干,agent C 又基于 B 的产物走下去——错误像滚雪球,越滚越大,而且你很难定位最早是哪一步歪的,因为每个 agent 的”推理”都是概率的、不可复现的。这叫”调试地狱”:你重现不了 bug,因为同样的输入再跑一遍,它可能又不歪了。
所以老哥,agentic 系统的设计铁律是:能不用多个 agent 就别用,能用短程就别拉成长程,能确定性编排就别让模型临场决策。每多加一层自主和协作,你就在赌”概率不会在最坏的地方塌”。赌得起的前提,是你把 9.1 的 eval、9.2 的护栏全做扎实——否则规模越大,雷越多。这也是为什么我把”评测”和”避坑”放在最后一 Part:它们是让你”敢”放大招的底气,没有这底气,放大招就是放大雷。
给你的路线图:下一步学什么、造什么
老哥,教程到这就要收了,但你的路才刚开始。墨叔给你一张务实的路线图,分三步,呼应咱们开篇说的”十年不过时的心智模型”——我不教你追某个 SDK,我教你往哪用力气才不贬值。
第一步,造一个”能跑通闭环”的迷你 agent。别急着上框架。照 Part 8 的蓝图,用几十行 Python 把”观察→决策→执行→回流”的循环写出来,接两三个真工具(读文件、跑 shell、查个接口)。目标不是功能多,是把 9.1 的 eval 也接上:你造完就能拿自己的黄金任务集量它。这一步练的是”循环”和”评测”两块地基,是后面一切的前提。
第二步,专攻两个最值钱的工程能力:上下文管理和安全护栏。这是区分”玩具”和”敢用”的分水岭。上下文管理(Part 4、Part 8)决定它跑不跑得长;护栏(Part 5 的 HITL、白名单、确认)决定你敢不敢让它碰真东西。这两项没有”学会”的一天,只有”越做越稳”的过程,但越早刻意练,越早敢用。
第三步,尝试一次 agentic 编排:把你工作里一个”长流程 + 多处模糊决策”的活,拆成一个主 agent 派多个子 agent 或调多个工具的形态(Part 7)。比如”每周自动巡检服务健康并出报告”。这一步练的是”系统思维”——你怎么切边界、怎么隔离上下文、怎么汇总。
至于心态,墨叔最后赠你三句,都是血泪:
一、别追新模型,追新机制。模型半年一换,但”循环怎么转、工具边界划在哪、上下文怎么管、怎么评测”这些,十年前和十年后都是同一套。你抓机制,就永远不慌。
二、agent 不是银弹,是扳手。它拧得动”模糊决策”这颗螺丝,拧不动”精确执行”的螺丝。认清楚哪颗螺丝归它,哪颗归你的代码,你就比 90% 盲目上 agent 的人清醒。
三、敢用来自可观测。你敢不敢让 agent 碰真东西,不取决于它多聪明,取决于你能不能看清它每一步在干啥、出事能不能兜住。把 eval、日志、trace 做扎实,“敢用”是自然结果,不是勇气问题。
老哥,咱们从开篇那张”大厨 + 递纸条的人”的图出发,一路拆到这。你现在回看,应该明白了:agent 不神秘,它只是把”下一步做什么”的决策源,从你写死的代码,换成了一个会读上下文的语言模型,而所有让它能用的工程,都是你后端那套防御性编程、状态管理、可观测性的平移。你不是从零学,你是把功力挪了个窝。这就是墨叔承诺你的”十年不过时的心智模型”——抓住了它,管它明年流行什么框架,你都能一周上手,因为你看懂的是齿轮,不是外壳。
【思考题】
- 你工作里有没有一个”长程、跨多天、多处需要人临场判断”的任务?如果交给 agentic 系统,它最可能在哪一步”烧穿上下文”?
- “agent 自我改进”为什么必须建立在 eval 之上?如果没有 eval,会发生什么?
- 用开篇那张”大厨+递纸条的人”的图,描述一下”agent 嵌进你现有 CI 系统”后,谁是大厨、谁是递纸条的人、纸条上多了什么?
【参考答案】
- 典型如”新需求从评审到上线”。它跨多天、要经过人审、改代码、跑测试、处理反馈。最可能在”处理测试反馈”那一步烧穿上下文——因为要反复读失败日志、读相关代码、试修改,几十轮下来窗口早爆了。解法正是长程系统的核心:把”已修过哪些、为什么这么改、踩过什么坑”持续落盘成外部记忆,每轮只捞摘要回来。这直接检验你 Part 4 记忆和 Part 5 状态管理的功力。能答出”落盘+摘要”而不是”堆更多 token”,说明你已经从”玩具思维”走到”系统思维”。
- 没有 eval,自我改进就是”agent 自己觉得改好了”——而我们在 9.1 讲透,它自己的判断不可信,是概率的、会自嗨的。后果是:它可能在你挑的少数例子上变好,却在大量真实任务上变烂,而你毫无察觉,还以为在”自动进化”。eval 是自我改进的反馈回路和真理源头,没有它,改进方向是瞎蒙。这也揭示一个深层结构:任何”自动优化”系统(不止 agent),必须有一个独立、确定性的评判标准,否则优化会滑向”讨好评判者”而非”真的变好”。agent 只是把这个古老教训用更刺眼的方式摆到你面前。
- 大厨还是”模型”——它读上下文、建议下一步(比如”这个 lint 错误该这么修”)。递纸条的人变成”CI 系统里的 agent 宿主循环”——它把代码库状态、lint 输出、测试结果写进上下文,执行模型的修改建议,再把结果读回。纸条上多出来的,是CI 特有的上下文:仓库当前 diff、流水线阶段、测试报告、以及”只能改、不能合”这类权限边界。换句话说,agent 没替代 CI,只是 CI 里原本”等人来看报告再改”的那个环节,换成了模型临场决策。你原有的确定性骨架(触发、执行、门禁)全在,只是其中一个模糊决策点被填上了——这正是”嵌进现有系统”的本质。
小结:agentic 系统是长程自主、能自我改进、并嵌进 IDE/CI/运维的齿轮。自我改进必须建在 eval 之上才有意义,而所有方向都指向同一件事——把确定性系统里”唯一的模糊决策缺口”交给 agent。你下一步该造闭环+接 eval、攻上下文与护栏、试一次编排;心态上追机制不追模型、认螺丝分归、敢用来自可观测。
墨叔收尾:老哥,九Part 走完,你手里握的不再是”怎么调个 SDK”,而是一套看穿任何 agent 框架的眼睛。记住,齿轮不变,外壳常新——往后不管出什么新玩具,你先问它”循环怎么转、工具边界划在哪、上下文怎么管、怎么评测”,四个问题答得上来,你就赢了。