Agent 能力地图,为什么编码 Agent 最先成熟

outlier 15 分钟 5924 字 0 0
系列教程Agent从入门到放弃 第 6 / 19 章
  1. 01Agent 从入门到放弃:教程大纲
  2. 02①大模型、Chatbot、Agent,一次把名字理清楚
  3. 03②Agent 的最小定义,一个 while 循环
  4. 04③Agent 简史,从 ReAct 到 Claude Code
  5. 05④Workflow 还是 Agent?大部分场景你不需要 Agent
  6. 06Agent 能力地图,为什么编码 Agent 最先成熟
  7. 07Token,模型眼里的世界
  8. 08Next-token prediction,一个字一个字地猜
  9. 09采样,temperature、top-p 与"同题不同答"
  10. 10Transformer 与 Attention,不推公式的直觉版
  11. 11Context Window,模型的内存条
  12. 12训练三阶段,能力是怎么被"装"进去的
  13. 13推理模型,让模型先想再答
  14. 14用原理解释怪行为,原理篇结业考
  15. 15从 Prompt 工程到 Context 工程
  16. 16System Prompt 写作,角色、约束与示例
  17. 17Context Rot,为什么长对话越聊越笨
  18. 18项目记忆,CLAUDE.md 与 AGENTS.md
  19. 19检索,RAG 还是 Agentic Search
查看教程目录

开场:同一个下午,两个 Agent

那天下午我同时开着两个 Agent。

一个是浏览器 Agent,我让它帮我在某个网站上订一张下周五去杭州的高铁票。它很努力:打开网站,找到出发地输入框,输入"北京",选日期……然后日历控件弹出来,它点了三次才点中正确的日期;接着要登录,它停下来问我账号;登录完弹出一个滑块验证码,它又停下来了(这一步它本来就不该替你做)。折腾了十分钟,最后选座位的时候,它选了一个靠过道的位置,而我明明说过要靠窗。

另一个是编码 Agent,我让它修一个单元测试。它跑了一遍测试,读了报错,打开两个文件,改了一行,又跑了一遍测试。绿了。前后不到两分钟。

同一个下午,同样是"给 Agent 一个任务",体验差了十万八千里。是浏览器 Agent 背后的模型更笨吗?不一定,它们背后可能就是同一家的模型。

差别不在模型,在任务本身。 这一篇我们画一张 Agent 的能力地图,看看几大方向各自走到了哪一步,以及为什么偏偏是写代码这件事跑在了最前面。读完本篇,你应该能回答这几个问题:

  • Agent 现在主要有哪几个方向?各自卡在哪里?
  • 为什么编码 Agent 最先成熟?
  • 拿到一个任务,怎么快速判断它适不适合交给 Agent?
  • 怎么把一个"不太适合"的任务,改造成"适合"的?

一、四大方向

1.1 一张地图

截至写作时(2026 年 10 月),Agent 的应用大致可以分成四个方向:

flowchart TB A(("Agent")) A --- C["编码
读代码、改代码、跑测试"] A --- B["浏览器操作
点网页、填表单、比价下单"] A --- D["电脑操作
看屏幕、动鼠标、敲键盘"] A --- R["深度研究
搜资料、读网页、写报告"] style C fill:#e8f5e9,stroke:#2e7d32 style B fill:#fff9c4 style D fill:#ffcdd2,stroke:#b71c1c style R fill:#fff9c4

颜色是我主观的"成熟度":绿色是已经有大量开发者每天在用的,黄色是能用、但要看场景、要盯着的,红色是还在"演示很惊艳、日常很费劲"阶段的。

用第 02 篇的眼光看,这四个方向用的是同一个循环,区别只在三件事上:环境是什么、能做什么动作、怎么知道做对了没有。

方向环境(模型看到什么)动作(工具)怎么判断做对了
编码代码、日志、命令输出,全是文本读文件、改文件、跑命令编译器、测试、lint
浏览器操作网页的结构或截图点击、输入、滚动、跳转页面上出现了预期的结果(大多要人看)
电脑操作屏幕截图移动鼠标、点击、按键屏幕上出现了预期的结果(大多要人看)
深度研究搜索结果、网页正文搜索、打开网页、做笔记报告写得好不好(只能人判断)

1.2 编码

代表产品第 01 篇都列过:Claude Code、Codex、Cursor 和 Copilot 的 Agent 模式……它们跑在终端或 IDE 里,能读整个代码库、改文件、跑测试和命令。这是目前最成熟的方向,也是本系列第五部分要亲手造的东西。

1.3 浏览器操作

让 Agent 像人一样用网页:打开页面、找到按钮、填表、提交。环境可以是页面的结构(DOM、可访问性树),也可以是截图。典型场景是比价、填报、在没有 API 的老系统里录数据。

它卡在哪里,开场已经演示过了:

  • 网页是给人设计的:弹窗、动态加载、拖拽控件、无限滚动,对人来说很自然,对 Agent 来说处处是坑;
  • 登录和验证码:这是网站专门用来拦住自动程序的,Agent 本来就不该绕过它们,只能停下来交给你;
  • 有些动作不可逆:下单、付款、发消息,点错了就收不回来。所以靠谱的浏览器 Agent 在这些操作前都会停下来问你。

1.4 电脑操作

比浏览器更进一步:Agent 看的是整个屏幕的截图,动作是移动鼠标、点击坐标、敲键盘。理论上,人能在电脑上做的事它都能做。Anthropic 在 2024 年 10 月推出了 computer use 能力,之后其他家也有了类似的功能。

它是四个方向里最难的:

  • 每一步都要看一张截图:图片很占 token,也很慢。人扫一眼屏幕的事,它要"看"几秒钟;
  • 坐标要猜准:按钮在截图里的位置,要换算成屏幕坐标,差几个像素就点到了旁边;
  • 几乎没有自动验证:点完之后到底成功没有,往往还得再截一张图让它自己判断,自己判断自己,靠不太住。

1.5 深度研究

给 Agent 一个问题,它自己去搜几十上百个网页,读完、整理、交叉验证,最后写出一份带引用的报告。2024 年底到 2025 年初,各家先后推出了这类功能,名字多半叫"深度研究"。

它的体验其实不错,因为它有一个很宽容的使用方式:最终产物是一份报告,由人来读、人来判断。 Agent 写错了一处,人读的时候往往能发现。但这也正是它的局限:

  • 事实难以自动验证:报告里说"某某数据增长了 30%",它真的查到了,还是编的?引用的链接里真的这么写吗?
  • 质量没有标准答案:两份报告哪份更好,见仁见智;
  • 跑偏了不容易察觉:它可能在一个不重要的子问题上挖得特别深,而真正关键的问题一笔带过。

1.6 方向之间正在互相靠拢

这张地图上的边界,其实没有画得那么清楚。

一个很明显的趋势是:编码 Agent 正在"吃掉"其他方向的一部分。 编码 Agent 能跑命令,那它就能用 curl 抓网页、用脚本调 API;接上一个浏览器相关的 MCP server(第 21 篇),它就能打开页面、点按钮、截图看结果。很多原本要用浏览器 Agent 做的事,比如"从这个后台导出数据再整理成表格",如果那个系统有 API,编码 Agent 写一段脚本调 API,比浏览器 Agent 一个按钮一个按钮地点,要快得多、稳得多。

反过来,浏览器 Agent 和电脑操作 Agent 也在往"文本化"的方向靠:能读页面结构就不看截图,能调接口就不点按钮。

背后是同一个规律:能用文本和结构化接口完成的,就别用像素。 像素是最后的手段,是在没有接口的时候才用的。下一节的三个维度,会把这个规律讲得更清楚。

二、三个维度:任务有多"Agent 友好"

把上面四个方向抽象一下,决定一个任务难不难交给 Agent 的,主要是三个维度:

flowchart LR T["一个任务"] --> E["环境
文本 ←→ 像素"] T --> S["动作
少而清晰 ←→ 多而模糊"] T --> V["反馈
可自动验证 ←→ 只能人判断"] E --> E1["文本:模型的母语,便宜、精确"] S --> S1["清晰:read_file、run_bash
参数一目了然"] V --> V1["可验证:结果会告诉它对不对"] style E1 fill:#e8f5e9,stroke:#2e7d32 style S1 fill:#e8f5e9,stroke:#2e7d32 style V1 fill:#e8f5e9,stroke:#2e7d32
编码浏览器电脑操作深度研究
环境纯文本结构化页面 / 截图截图文本
动作少而清晰多、依赖页面无穷多(任意坐标)少而清晰
反馈编译器、测试大多要人看大多要人看只能人判断

编码在三个维度上全部占优。这不是巧合,下面细说。

三、为什么编码 Agent 最先成熟

3.1 原因一:结果可验证

这是最重要的一条,值得多花点篇幅。

回想第 02 篇那个"修复失败测试"的剧本:模型改完代码,再跑一次 go test,结果是 ok,它才说"测试已全部通过"。如果结果还是 FAIL,这个失败信息会作为工具结果回到循环里,模型看到之后会继续改。

sequenceDiagram participant M as 模型 participant H as Harness participant V as 编译器 / 测试 M->>H: 改代码 H->>V: go test V-->>H: FAIL:want 90, got 110 H->>M: 结果追加进上下文 Note over M: 看到了错误,
知道自己没改对 M->>H: 再改一次 H->>V: go test V-->>H: ok M->>H: 完成

测试结果,就是把 Agent 从错误路径上拉回来的那根绳子。 有了它,Agent 不需要一次做对,只需要能根据反馈调整。每一步 70% 的成功率听起来不高,但如果每次失败都能被发现并重来,最终成功的概率会高得多。第 39 篇会用一个蒙特卡洛模拟把这笔账算清楚。

反过来看浏览器 Agent 选错座位那件事:它选完之后,没有任何东西告诉它"选错了"。页面显示"座位已选择",在它看来任务就是成功的。没有反馈的 Agent,它的自信和它的正确率毫无关系。 这句话在第 02 篇的实验 3 里出现过,在这里它变成了一个方向能不能成熟的分水岭。

还有一个容易忽视的点:可验证不只是对 Agent 有用,对你也有用。 Agent 说它修好了,你跑一遍测试就知道是真是假,不用逐行审查。验证的成本低,你才敢放心地把任务交出去。

3.2 原因二:环境是纯文本

代码是文本,报错是文本,日志是文本,配置文件是文本,命令行的输入输出全都是文本。而文本,恰恰是大模型的母语。

对比一下:

  • 编码 Agent 想知道一个函数在哪里定义,跑一下 grep,几十个字符的结果,精确无误;
  • 电脑操作 Agent 想知道一个按钮在哪里,要看一整张截图,在几百万个像素里找它,然后猜一个坐标。

文本环境还有几个附带的好处:

  • 便宜:一屏代码几百个 token,一张截图可能要上千个;
  • 精确:文件路径、行号、函数名,没有歧义;
  • 工具现成:几十年来程序员为自己打造的工具,grep、git、编译器、测试框架,全都是命令行工具,Agent 直接就能用。不用专门为 Agent 造轮子。

3.3 原因三:训练数据极其丰富

模型学写代码,有一座取之不尽的矿:

  • 海量的开源代码;
  • 代码的修改历史:每一个 commit、每一个 diff,都是"把代码从状态 A 改到状态 B"的示范;
  • issue 和 PR 里的讨论:问题是什么、怎么定位、怎么修;
  • 技术问答社区里,数不清的"我遇到了这个报错"和对应的解答。

更重要的是,代码天然适合一种叫"可验证奖励"的训练方式:让模型写代码,跑测试,测试通过就奖励,不通过就惩罚。不需要人来打分,可以大规模地自动进行。第 12 篇讲推理模型时会再提到它:在有标准答案的领域,模型进步得最快,数学和代码就是两个最典型的例子。

3.4 还有两个加分项

  • 出错的代价低,而且能回滚:代码在 git 里,Agent 改坏了,git checkout 一下就回来了。对比一下浏览器 Agent 帮你付错了一笔钱;
  • 用户本身就是开发者:他们能看懂 Agent 在干什么,能容忍它偶尔犯傻,还会主动给它写测试、写说明文档(第 17 篇的 AGENTS.md),帮它变得更好用。

把这几条放在一起:

flowchart TB V["结果可验证
编译器、测试"] --> OK["编码 Agent
最先成熟"] T["环境是纯文本
模型的母语"] --> OK D["训练数据丰富
还能用测试自动打分"] --> OK R["可以回滚
git 兜底"] --> OK U["用户懂行
愿意配合"] --> OK style OK fill:#fff3e0,stroke:#e65100

3.5 编码内部,也分三六九等

说编码 Agent 最成熟,是平均意义上的。把"写代码"再拆细一点,内部的差距也很大,而且差距的来源和上面那三个维度完全一致:

编码任务可验证度为什么
修一个有复现测试的 bug高测试从红变绿,一目了然
按规格加一个纯函数高规格能直接写成测试
重构,保持行为不变中到高取决于现有测试覆盖得够不够
改前端页面的样式低好不好看要人看,Agent 只能截图自己判断
性能优化中有基准测试就高,没有就只能凭感觉
排查偶发的并发问题低问题本身就很难稳定复现
设计模块之间的接口低好坏要等几个月后才看得出来

你会发现,表格上半部分是编码 Agent 真正的舒适区,下半部分其实和"深度研究""电脑操作"一样难。前端样式那一行尤其有意思:它的环境变成了像素,反馈变成了"要人看",于是体验马上就退化成了开场那个浏览器 Agent。

所以,与其说"编码 Agent 最成熟",不如说"有测试的编码任务最成熟"。 这也是误区 5 要说的事。

四、你的任务适合交给 Agent 吗

4.1 两个问题

把上面的分析变成一个能落地的判断方法,只需要问两个问题:

  1. 可验证度:做完之后,有没有编译器、测试、lint、规则这类东西,能自动告诉你对不对?(1 到 5 分)
  2. 重复度:这件事多久做一次?(1 到 5 分)

为什么是这两个?可验证度决定了Agent 能不能做好,以及你能不能放心地把结果用起来;重复度决定了值不值得为它花心思:把一个任务调教到 Agent 能稳定完成,需要写说明、准备验证手段、试错几次。一年只做一次的事,这些投入回不了本。

4.2 四个象限

quadrantChart title 任务四象限 x-axis "重复度低" --> "重复度高" y-axis "可验证度低" --> "可验证度高" quadrant-1 "交给 Agent" quadrant-2 "偶尔交给 Agent" quadrant-3 "自己来,AI 当参谋" quadrant-4 "写成 workflow,人来把关" "补单元测试": [0.75, 0.92] "按 lint 批量修代码": [0.55, 0.9] "升级依赖修编译错误": [0.3, 0.88] "写周报": [0.92, 0.3] "回复客户邮件": [0.78, 0.28] "排查偶发故障": [0.3, 0.5] "技术选型调研": [0.1, 0.25] "设计系统架构": [0.08, 0.08]
  • 右上(可验证 + 高频):交给 Agent,并且把验证命令告诉它,比如"改完跑 go test ./..."。这是 Agent 收益最大的地方;
  • 左上(可验证 + 低频):可以交给 Agent,偶尔用一次。比如升级依赖,一年一两次,但编译器会告诉它哪里没改对;
  • 右下(难验证 + 高频):写成 workflow 或模板,人来把关。比如周报、回复客户邮件,第 04 篇的链式或路由模式就很合适,最后一步由人审;
  • 左下(难验证 + 低频):自己来,AI 当参谋。架构设计、技术选型,你可以和模型讨论、让它列方案,但决策和判断是你的。

4.3 把任务"往上挪"

四象限不是命中注定的。很多任务的可验证度是可以提高的,办法就是给它补上验证手段:

  • 想让 Agent 改一个没有测试的模块?先让它写测试,你审一遍测试,再让它改代码。第 35 篇整篇都在讲这个套路;
  • 想让 Agent 生成配置文件?给它一个能校验配置的命令,比如 nginx -t、terraform validate;
  • 想让 Agent 写文档?给它一个检查清单:"必须包含安装步骤、示例命令要能跑通",再用另一个模型或脚本逐条核对(第 36 篇的 LLM-as-judge)。

给任务补上验证,比换一个更强的模型更有用。 这句话我会在后面反复说。

4.4 一个例子:整理会议纪要

拿实验 2 里那个"整理会议纪要"举例。直接交给 Agent,它的可验证度大概只有 2 分:纪要写得好不好,只能你自己读一遍判断。

但仔细想想,"好的纪要"其实有一些能检查的标准:

  • 结构是固定的:必须有"决定""待办""遗留问题"三节;
  • 待办必须有负责人和截止日期:每一条都能用一个简单的规则检查,有没有人名、有没有日期;
  • 不能编造:纪要里出现的人名,必须在参会名单里;纪要里说"决定了某某",原始记录里要能找到对应的话。

前两条,一段几十行的脚本就能查;第三条,可以让另一个模型拿着原始记录逐条核对,回答"这一条在原文里有没有依据"。

补上这些检查之后,它的可验证度大概能到 3 到 4 分。这时候它就从"自己来"挪到了"写成 workflow,人来把关",甚至可以考虑交给 Agent:让它写完纪要后自己跑一遍检查脚本,不通过就改。你没有换模型,只是把"好"定义得更清楚了。

flowchart LR A["整理会议纪要
可验证度 2"] -->|"固定结构 + 检查脚本"| B["可验证度 3"] B -->|"再加原文核对"| C["可验证度 4"] style A fill:#ffcdd2,stroke:#b71c1c style C fill:#e8f5e9,stroke:#2e7d32

这个思路后面会反复出现:第 35 篇的"先写测试",第 36 篇的"评分细则",本质上都是在把模糊的"好"翻译成可以检查的条件。

五、动手:给你的任务打分

实验 1:跑一遍示例

go run ./examples/ch05-task-score

这个程序不调用任何模型,就是一个打分排序的小工具,也可以在 Playground 的第 05 篇里直接跑。它自带一份示例任务表,输出是这样的:

排名   任务                        可验证     重复     得分  建议
1    给接口补单元测试                    5      4     20  交给 Agent,并把验证命令告诉它
2    按 lint 报错批量修代码              5      3     15  交给 Agent,并把验证命令告诉它
3    升级依赖并修好编译错误                 5      2     10  可以交给 Agent,偶尔用一次
4    写周报                         2      5     10  写成 workflow / 模板,人来把关
5    回复客户邮件                      2      4      8  写成 workflow / 模板,人来把关
6    排查线上偶发故障                    3      2      6  自己来,AI 当参谋
7    做技术选型调研                     2      1      2  自己来,AI 当参谋
8    设计新系统架构                     1      1      1  自己来,AI 当参谋

最值得交给 Agent 的:给接口补单元测试

"建议"那一列的规则写在 advice 函数里,就是上面的四象限:

func advice(t task) string {
    switch {
    case t.verify >= 4 && t.repet >= 3:
        return "交给 Agent,并把验证命令告诉它"
    case t.verify >= 4:
        return "可以交给 Agent,偶尔用一次"
    case t.repet >= 4:
        return "写成 workflow / 模板,人来把关"
    default:
        return "自己来,AI 当参谋"
    }
}

注意第 4 行"写周报":它和第 3 行得分一样,都是 10 分,但建议完全不同。乘积只决定排序,象限决定做法。 可验证度太低的任务,重复得再多也不该直接丢给 Agent。

实验 2:列你自己的任务

建一个 CSV 文件,三列:任务、可验证度、重复度。

任务,可验证度,重复度
给新接口写 handler 和测试,5,4
整理会议纪要,2,4
……

然后在本地跑:

go run ./examples/ch05-task-score my-tasks.csv

(Playground 读不到你电脑上的文件,这一步要在本地或 Codespaces 里跑。)

打分的时候对自己狠一点。"我看一眼就知道对不对"不算可验证,能被程序自动检查的才算。重复度也一样:不要按"理论上会经常做"来打,按过去三个月你实际做了几次来打。打完分,再对照 4.4 节想一想,排在后面的任务里,有没有哪个能补上一个检查脚本,往上挪一格。

实验 3:挑排第一的那个,真的交给 Agent

拿排名第一的任务,交给你手边的编码 Agent(Claude Code、Codex 都行),记得在任务描述里写上验证命令。做完之后记录三件事:它转了几圈、你介入了几次、结果对不对。

到第五部分写完 mini-agent,你可以拿同一个任务再试一次,对比一下自己造的和成品的差距。这也是第 40 篇结业任务的预演。

六、踩坑记录:选任务时的五个误区

误区 1:把"能演示"当成"能用"。
很多 Agent 的演示视频确实惊艳,但演示是挑过的:挑了它擅长的任务,挑了运气好的那一次。判断一个方向成不成熟,要看普通人在普通的一天里,用它干普通的活,成功率有多少。

误区 2:低估验证的成本。
"Agent 写完了"不等于"写对了"。如果一个任务没有自动验证,Agent 写完之后你得逐行检查,那省下来的时间可能还不如你自己写。验证成本是决定用不用 Agent 的关键变量,很多人算账时漏掉了它。

误区 3:把不可逆的操作完全交给 Agent。
发邮件、付款、删数据、改线上配置,这类操作做错了收不回来。不是不能用 Agent,而是这些动作之前必须有人确认。第 27 篇实现权限时,我们会给 mini-agent 加上这道闸;第 38 篇讲安全时,你会看到更多理由。

误区 4:为一年做一次的事情精心调教 Agent。
写详细的说明、准备测试、调试 prompt,这些投入要靠重复使用来摊薄。一次性的任务,直接用、不满意就自己改,往往最划算。

误区 5:以为编码任务都适合交给 Agent。
编码只是"平均来说"最适合。没有测试的老代码、需要理解复杂业务背景的改动、涉及架构取舍的设计,可验证度一样很低。打分要按具体任务打,不要按"是不是写代码"打。

一句话总结

同一个循环,在不同的任务上表现天差地别;编码 Agent 最先成熟,是因为它的结果可验证、环境是纯文本、训练数据丰富;判断一个任务适不适合交给 Agent,先看可验证度,再看重复度。

flowchart LR Q["一个任务"] --> V{"可验证?"} V -->|"能"| R{"高频?"} V -->|"不能"| F{"高频?"} R -->|"是"| A["交给 Agent"] R -->|"否"| B["偶尔交给 Agent"] F -->|"是"| W["workflow + 人把关"] F -->|"否"| S["自己来"] style A fill:#fff3e0,stroke:#e65100 style W fill:#e8f5e9,stroke:#2e7d32

评论

还没有评论,来说点什么吧。

发表评论

Ctrl + Enter 快速提交
Enter 搜索Esc 关闭