资料库 · Agentic 编程实践
第 ① 卷,条目 1–20。全部来自 simonwillison.net。
按时间正序排,从 2025 年 3 月到 2026 年 8 月。这个排法在这一卷是刻意的:你能看到一个持续做一手实验的人,在一年半里认知是怎么变的——从"LLM 辅助写代码"到"agent 自己跑循环"到"并行开几个 agent",每一步都有具体的转折点。
读的时候留意日期。这一卷里越早的条目,具体操作层面越可能过时,但方法论层面越经得住看。
2025 上半年:先把话说清楚
1. Hallucinations in code are the least dangerous form of LLM mistakes
来源:Simon Willison,2025 年 3 月 2 日。
读它解决什么:LLM 写代码会"编造"不存在的库和方法,这件事到底有多严重。
要点:
- 论点是代码中的幻觉是危害最小的一类 LLM 错误
- 理由与"代码可以被执行验证"有关
我的补充:这一条是结构性的,不会过期。 论证很简洁:编造一个不存在的库,import 就失败了,你立刻知道。这类错误自带检测机制。
真正危险的是看起来对、跑得通、但语义错的代码:
- 边界条件处理错了(空列表、单元素、最大值)
- 并发下不安全,但单线程测试全绿
- 错误被静默吞掉(
except: pass) - 用了正确的 API 但语义理解偏了(比如
sorted()的稳定性、浮点比较、时区处理) - SQL 逻辑对但没走索引,数据量小时看不出来
这个判断直接决定了你的注意力该放哪:不用花时间检查"这个方法存在吗"(跑一下就知道),要花时间检查边界条件和语义。
我自己形成的具体习惯是:AI 给的代码,先读它的错误处理和边界分支,再读主逻辑。主逻辑通常是对的(那是训练数据里最常见的部分),边界和错误处理是最常出问题的地方——恰好也是人类 review 时最容易跳过的部分。
2. Here's how I use LLMs to help me write code
来源:Simon Willison,2025 年 3 月 11 日。
读它解决什么:一个高产的开发者具体怎么把 LLM 接进日常工作。
要点:
- 详细的个人工作流说明
- 2025 年 3 月,属于 agent 工具成熟之前的阶段
我的补充:这一篇现在读要注意时代背景——2025 年 3 月还是"人在循环里每一步"的阶段,Claude Code 那种自主跑的 agent 刚出现。所以具体操作已经变了,但里面几条原则我认为仍然成立:
一、给足上下文。 把相关代码、错误信息、你的约束一次贴全,比来回问五轮快。这一条在 agent 时代变成了"写好 CLAUDE.md",本质没变。
二、要求它给可运行的完整代码,而不是片段。 片段需要你自己拼,拼的过程就是出错的地方。
三、把它当结对编程的对象,不是搜索引擎。 具体差别是:搜索引擎你问一次拿走答案;结对对象你会说"不对,因为 X"然后它调整。后者的产出质量高得多,但需要你真的读它的输出并给出具体的反驳。
四、明确说你不要什么。 "不要用第三方库"、"不要改这个函数的签名"、"保持现有的错误处理风格"——这类约束不说它就自己发挥。
我要补充一条他当时没强调、现在很关键的:给它验证手段。让它能跑测试、能看到报错、能执行代码。有验证手段的 AI 编程和没有的,产出质量差一个档次——因为它能自己发现第 1 条里说的那类"自带检测机制"的错误,不用你来当传话筒。
3. Not all AI-assisted programming is vibe coding (but vibe coding rocks)
来源:Simon Willison,2025 年 3 月 19 日。
读它解决什么:"vibe coding" 这个词到底指什么,为什么它被滥用了。
要点:
- 澄清 vibe coding 的原始定义(Andrej Karpathy 2025 年初提出)
- 区分它和一般的 AI 辅助编程
我的补充:这个区分很重要,因为混用会导致严重的判断错误。 原始定义的 vibe coding 是:你不读生成的代码,只看结果对不对,不对就让它再改。关键在"不读代码"这四个字。
所以:
- 用 Copilot 补全然后 review 每一行 —— 不是 vibe coding
- 用 Claude Code 写完然后自己读一遍 —— 不是 vibe coding
- 让 AI 写个小工具,跑起来能用就行,代码看都不看 —— 是 vibe coding
为什么这个区分重要:两者的适用场景完全不同。
vibe coding 合适的场景:一次性脚本、原型验证、个人小工具、你完全不在乎可维护性的东西。风险边界清楚——出问题最多是这个东西不能用。
不合适的场景:任何要长期维护的、任何处理真实用户数据的、任何有安全边界的。因为**"不读代码"意味着你不知道它做了什么**——它可能把密钥打进日志、可能有 SQL 注入、可能在某个分支里删了东西。
我见过最糟的情况是有人对生产代码做 vibe coding,然后说"这是 AI 写的,我不知道为什么这样"。这个说法在工程上是不可接受的——见第 16 条。
4. Two publishers and three authors fail to understand what "vibe coding" means
来源:Simon Willison,2025 年 5 月 1 日。
读它解决什么:术语被误用到什么程度,以及为什么作者要反复纠正。
要点:
- 指出出版物中对 vibe coding 的误用
- 是上一条的后续
我的补充:这一条本身是个小事,但它指向一个真实的问题:这个领域的术语正在以极快的速度被稀释,而术语被稀释之后,技术讨论就没法进行了。
"vibe coding" 已经从"不读代码"漂移成"用 AI 写代码"的泛称。同样的漂移发生在:
- "agent" —— 从"能自主循环调工具"漂移成"任何带 LLM 的产品"(见第 6 条,作者后来给了个可用的定义)
- "RAG" —— 从特定的检索增强架构漂移成"任何往 prompt 里塞文档的做法"
- "MCP" —— 从一个具体协议漂移成"任何工具集成"
- "reasoning" —— 从特定的训练/推理方式漂移成营销词
实用建议:跟人讨论这类话题时,先花三十秒对齐定义。"你说 agent 的时候,指的是能自己决定调哪个工具、并且循环执行的东西吗?" 这个问题能省掉后面十分钟的误解。
我在技术方案评审里养成的习惯是:看到这类词就要求写出具体行为。"用 agent 处理工单" → 它具体能调哪些工具?循环上限是多少?失败怎么处理?谁来审?把这几个问题问完,方案的可行性就清楚了,而术语本身怎么用已经不重要。
5. Building software on top of Large Language Models
来源:Simon Willison,2025 年 5 月 15 日。
读它解决什么:在 LLM 之上做产品,工程上要处理哪些事。
要点:
- 讲把 LLM 作为组件构建软件的方法
- 2025 年 5 月,是从"用 LLM 帮我写代码"转向"把 LLM 写进产品"的一篇
我的补充:这一篇讲的是一件和前四条不同的事——LLM 作为你产品的一个组件,而不是你的编程助手。这个转换带来一批新问题,而它们全部是工程问题,不是 AI 问题:
一、它是个不确定的、会变的、可能挂的远程服务。 所以要有超时、重试、降级、熔断——就是第五卷 HTTP 客户端那一套(专题库第 98 条)。很多人在这一点上完全没设防,然后模型 API 抖动的时候整个产品挂掉。
二、成本和延迟是设计约束,不是实现细节。 一次调用几秒钟、几分钱,这两个数字直接决定你的产品形态能不能成立。要在设计阶段算,不是上线后优化。
三、输出格式不可信。 要求返回 JSON 它也可能返回带解释的 JSON、markdown 包裹的 JSON、或者截断的 JSON。必须有解析失败的处理路径。 现在有结构化输出/工具调用能大幅缓解,但不是零风险。
四、你需要 eval。 改了 prompt、换了模型,怎么知道变好还是变坏?没有 eval 就是靠感觉,而感觉在这件事上极不可靠(见第二卷 39、40 条)。
五、prompt injection。 只要有用户输入进入 prompt,就有这个问题。见第三卷。
这五条都是结构性的,一年多之后仍然全部成立。我认为其中第四条是最容易被跳过、代价最大的——没有 eval 的 LLM 产品,每次改动都是赌博。
2025 下半年:agent 成型
6. I think "agent" may finally have a widely enough agreed upon definition
来源:Simon Willison,2025 年 9 月 18 日。
读它解决什么:agent 这个词能不能用了,指什么。
要点:
- 认为 agent 终于有了足够共识的定义
- 2025 年 9 月
我的补充:那个逐渐成为共识的定义大意是:一个 LLM 在循环里调用工具以达成目标。三个要素——LLM 做决策、能调工具、循环执行直到完成或放弃。
这个定义的好处是它能划清界限:
- 聊天机器人 —— 不是(没有工具,没有循环)
- 一次性调用工具的 LLM 调用 —— 不是(没有循环)
- 固定流程的工作流,每步调 LLM —— 不是(决策不在 LLM 手里,是你写死的)
- Claude Code / Codex CLI —— 是
第三条最值得注意,因为它区分了 "agent" 和 "workflow",而这个区分有实际的工程后果:
| Workflow(固定流程) | Agent(LLM 决策) | |
|---|---|---|
| 可预测性 | 高,路径固定 | 低,每次可能不同 |
| 调试 | 容易,能定位到步骤 | 难,要看完整轨迹 |
| 成本 | 可预估 | 上限难控 |
| 适用 | 流程已知的任务 | 流程不确定的任务 |
实用的判断规则:能写成 workflow 的,就别用 agent。 如果你已经知道该怎么做(先查库、再算、再发通知),那就把它写成代码,每步该调 LLM 的地方调 LLM。这样可预测、便宜、好调试。
agent 的价值在于你不知道该走哪条路——比如"排查这个 bug",路径取决于中间发现了什么。这种情况下 workflow 写不出来,才需要 agent。
7. Designing agentic loops
来源:Simon Willison,2025 年 9 月 30 日。
读它解决什么:怎么设计一个 agent 的工作循环,让它能自己跑到结果。
要点:
- 讲 agentic loop 的设计方法
- 2025 年 9 月底,紧接 agent 定义那篇
我的补充:这一条是这一卷里最实用的,而且是结构性的。 核心问题是:agent 要能自己跑,就必须能自己判断做对了没有。所以设计一个 agentic loop,本质是给它一个可以自己验证的反馈信号。
好的反馈信号的特征:自动、快、明确。
| 任务 | 好的反馈信号 | 坏的反馈信号 |
|---|---|---|
| 修 bug | 那个失败的测试变绿 | "看起来对了" |
| 加功能 | 新写的测试通过 + 旧测试没坏 | 手动点一遍 |
| 性能优化 | benchmark 数字 | 感觉快了 |
| 重构 | 测试全绿 + 行为没变 | 代码更好看了 |
| 改 UI | 截图对比 | 需要人看 |
所以我的实际做法是:动手让 agent 干活之前,先花五分钟建立反馈信号。 没有测试就先写一个能复现问题的失败测试,然后让它去修——它自己就能知道什么时候完成了。这五分钟的投入回报极高,因为它把"我要审查每一步"变成了"我审查最终结果"。
反过来,没有反馈信号的任务不适合交给 agent。比如"改善这段代码的可读性"——没有客观信号,agent 只能自我评价,然后你会拿到一堆改动,还得自己判断好不好,等于没省事。
几个补充的实践细节:
- 给循环设上限(迭代次数、token、时间)。没有上限的 agent 可能在一个死胡同里烧掉几十块钱。
- 让失败可见。agent 卡住时应该报告"我试了 X 和 Y 都不行",而不是交一个悄悄绕过问题的实现(比如把断言删了让测试通过——这个真的会发生)。
- 验证要独立于 agent 的实现。它自己写测试自己跑,可能会写一个恒真的测试。测试最好由你提供,或者你至少要读一遍。
8. Embracing the parallel coding agent lifestyle
来源:Simon Willison,2025 年 10 月 5 日。
读它解决什么:同时开多个 agent 干不同的活,实际体验和管理方式。
要点:
- 记录并行使用多个编码 agent 的工作方式
- 2025 年 10 月
我的补充:并行 agent 的瓶颈不在工具,在你。一个 agent 跑起来之后你要等,等的时候可以开第二个——听起来是免费的加速,实际上有个硬约束:你的审查带宽是固定的。
三个 agent 同时交出结果,你要审三份代码。审查质量会随并行度下降,而审查是 AI 编程里唯一不能省的环节。所以我的实际做法是控制并行度:
并行度以 2–3 为上限,而且必须是不相关的任务。相关的任务并行会撞车(同一个文件、同一个接口),合并的成本超过并行的收益。
用 git worktree 隔离(见专题库第 49 条),这是让并行真正可用的关键。每个 agent 在自己的工作目录,改动互不干扰:
git worktree add ../proj-taskA main
git worktree add ../proj-taskB main任务粒度要能独立验证。 "加一个 API 端点"可以并行,"重构整个数据层"不行。
一个我自己踩过的坑:并行 agent 会重复劳动。两个 agent 各自发现同一个辅助函数不存在,各自写了一个,最后合并时有两个功能相同名字不同的函数。缓解办法是任务描述里明确划定边界("只改 src/api/ 下的文件"),并且在合并前扫一遍新增的文件。
我的结论:并行 agent 是真实的效率提升,但提升幅度远小于"agent 数量"的倍数。从 1 到 2 收益明显,从 3 往上基本是给自己制造审查债。
9. Vibe engineering
来源:Simon Willison,2025 年 10 月 7 日。
读它解决什么:给"认真地用 AI agent 做工程"这件事一个名字,和 vibe coding 区分开。
要点:
- 提出 vibe engineering 这个说法
- 与 vibe coding 相对:同样重度用 AI,但工程标准不降低
我的补充:这个概念我认为是这一卷里最有价值的一个,因为它填了一个真实的空白:重度用 AI agent 写代码、但完全保持工程标准的做法,之前没有名字,所以经常被误当成 vibe coding。
区别很具体:
| vibe coding | vibe engineering | |
|---|---|---|
| 读生成的代码 | 不读 | 读,而且改 |
| 测试 | 通常没有 | 必须有,往往先写 |
| 责任 | 能跑就行 | 你对代码负全责 |
| 适用 | 一次性、原型 | 生产系统 |
vibe engineering 需要的技能反而更高,不是更低。 因为你要:
- 有能力审查大量代码(产出速度上去了,审查压力跟着上去)
- 知道怎么建反馈循环(第 7 条)
- 能判断一个实现是不是"对但不合适"(比如它用了正确但过度复杂的方案)
- 有扎实的测试和 CI 基础(这是让 agent 能自主工作的前提)
这解释了一个现象:AI 工具让资深工程师的产出提升远大于新手。不是因为资深的人更会写 prompt,而是因为他们有审查能力和判断力——而这恰好是 AI 目前给不了的部分。新手用 AI 能更快产出代码,但没有能力判断那些代码对不对,于是产出的是债而不是资产。
我的判断:这个差距短期内不会缩小,因为它不是工具问题。工具能帮你写,不能帮你负责。
10. Claude Skills are awesome, maybe a bigger deal than MCP
来源:Simon Willison,2025 年 10 月 16 日。
读它解决什么:Skills 是什么,为什么作者认为它比 MCP 更重要。
要点:
- 对 Claude Skills 机制的评价
- 与 Anthropic 同期发布的 Agent Skills 相关(见第二卷第 30 条)
我的补充:这一条的核心论点是关于复杂度的,而这个论点是结构性的,值得记住。
MCP 是协议:要跑一个 server、要处理连接和认证、要定义 schema、要维护版本。Skills 是一个 markdown 文件:写清楚"遇到这类任务时这样做",放进目录里。
两者解决的问题有重叠,但成本差一个数量级。而大部分场景需要的其实是后者:
- "生成报表时用公司的模板,格式是这样" → Skill 就够
- "查询内部订单系统" → 需要 MCP(要真的调 API)
判断标准很简单:需要访问外部系统就用 MCP,只是"告诉它怎么做"就用 Skill。
我自己用 Skills 的实际收获是:它把重复的上下文固化下来了。以前每次开始一个任务都要交代一遍项目约定(用什么风格、测试怎么跑、不要碰哪些文件),现在写成 Skill 一次,之后自动生效。
一个实践建议:Skill 要写得像给新同事的交接文档,不是像 prompt。具体、有例子、说明为什么。我见过写得像咒语的 Skill("你是一个专业的 X,你必须……"),效果明显不如平实地写"这个项目里我们这样做,因为……"。
注意这一条会部分过期:Skills 的具体格式和加载机制在演进(第 19 条提到 OpenAI 也开始采纳类似机制)。但"低成本的上下文固化比重型协议更常用"这个判断不会过期。
11. Living dangerously with Claude
来源:Simon Willison,2025 年 10 月 22 日。
读它解决什么:放宽 agent 的权限限制,风险和收益分别是什么。
要点:
- 讨论以较少限制的方式使用 Claude 的体验
- 2025 年 10 月
我的补充:这一条讲的是每个用 agent 的人都会面对的取舍:每一步都确认(安全但慢到没法用) 还是 放开权限(快但可能出事)。
我自己的分层做法,按"出错的代价"划:
完全放开 —— 一次性容器、临时目录、我随时能整个删掉重来的环境。这种地方没有什么可失去的,确认每一步纯属浪费。
放开但有边界 —— 本地项目目录、干净的 git 状态。前提是三条:代码已提交(能 git reset --hard 回去)、没有生产凭据、不能直接 push。这是我的日常模式。
逐步确认 —— 任何碰生产的、碰真实数据的、能发出网络请求改变外部状态的。
永不放开 —— 有生产凭据的环境。这里的风险不只是"agent 犯错",还有 prompt injection(第三卷):agent 读到的任何内容——issue、网页、日志、依赖包的 README——都可能包含指令。有凭据的环境里,一次成功的注入等于凭据泄露。
具体的边界设置手段:
# git 是最好的安全网:动手前确认干净
git status --porcelain | grep . && echo "先提交或 stash"
# 用容器隔离(推荐)
docker run --rm -it -v "$PWD:/work" -w /work --network=none <image>
# 环境里不要有真凭据
env | grep -i 'key\|token\|secret\|password'最重要的一条:--network=none 或者出站白名单。没有网络出口,注入攻击就无法把数据传出去——这是 lethal trifecta(第三卷第 53 条)里最容易切断的一条边。
12. Code research projects with async coding agents
来源:Simon Willison,2025 年 11 月 6 日。
读它解决什么:用异步 agent 做"研究型"任务(读代码、搞清一个系统怎么工作)而不是写代码。
要点:
- 讲用 Claude Code、Codex 这类 agent 做代码研究
- 2025 年 11 月
我的补充:这是我认为 agent 目前最被低估的用法。 大家都盯着"让它写代码",但"让它读代码然后告诉我这个系统怎么工作"的价值可能更高,原因有三:
一、风险为零。 只读操作,不改任何东西,不用审查代码,不用担心它写错。 二、正好是它的强项。 快速通读几万行代码、找到所有相关位置、总结调用关系——人做这个慢得多。 三、结果容易验证。 它说"认证逻辑在 auth/middleware.py:45",你去看一眼就知道对不对。
我实际常用的几类研究任务:
- "这个项目的请求是怎么从入口走到数据库的?把关键文件和行号列出来"
- "找出所有直接拼 SQL 字符串的地方"
- "这个配置项
FOO_TIMEOUT在哪些地方被读到,默认值是多少,改了会影响什么" - "对比这两个版本的行为差异,重点看破坏性变化"
- "这个依赖库的这个函数,实际实现里有哪些我文档上看不到的行为"
关键技巧是要求它给出文件和行号。这把"它说的"变成了"我能验证的"——没有行号的总结你没法核对,有行号的三十秒就能确认。这一条同时也大幅降低了它编造的空间。
另一个用法是入职新代码库。以前接手一个陌生项目要花几天摸清结构,现在可以让 agent 先给一份带行号的导览,然后你按着它去读关键部分。我自己用这个方法接手项目,时间大概能省一半。
13. Useful patterns for building HTML tools
来源:Simon Willison,2025 年 12 月 10 日。
读它解决什么:用 AI 快速做单文件 HTML 小工具的模式。
要点:
- 总结构建 HTML 工具的实用模式
- 2025 年 12 月
我的补充:单文件 HTML 工具是 AI 编程时代性价比最高的产出形态,我自己做了不少。特征是:一个 .html 文件,没有构建步骤,没有依赖安装,双击就能用,也能直接扔到任何静态托管上。
为什么它和 AI 特别配:
- 一个文件,AI 能一次生成完整的,不用管项目结构
- 零构建,所以零环境问题——不会有"我这里跑不起来"
- 立刻能验证:打开浏览器就看到结果,反馈循环极短(第 7 条)
- 无状态无后端,所以没有安全边界要担心(数据不出浏览器)
我做过的实际例子:JSON 格式化+差异对比、时间戳/时区换算、正则测试、CSV 转 Markdown 表格、批量文件重命名预览、Base64/URL 编解码、颜色对比度检查(用于无障碍检查)。这些都是那种"网上有现成的,但我不想把公司数据贴到别人的网站上"的工具——自己做一个,数据不出本机。
几个实践模式:
- 状态存 URL hash,这样能分享带数据的链接,也能刷新不丢
localStorage存配置,不用做设置界面- 拖拽读文件(
FileReader),比 input 好用 - CDN 引入依赖(
<script src="https://cdn.jsdelivr.net/...">),仍然是单文件 - 一开始就说"不要构建步骤、不要 npm、单个 HTML 文件",否则 AI 默认会给你搭一个 Vite 项目
这一条不会过期,因为它讲的是产出形态的选择,而这个形态的优势(零依赖、零构建、可验证)与模型能力无关。
14. JustHTML is a fascinating example of vibe engineering in action
来源:Simon Willison,2025 年 12 月 14 日。
读它解决什么:一个真实项目怎么在 vibe engineering 模式下做出来。
要点:
- 分析 JustHTML 这个项目作为 vibe engineering 的案例
- 呼应第 9 条提出的概念
我的补充:案例研究的价值在于它给出了可核对的证据,而不是"我觉得 AI 很有用"这类无法验证的说法。
读这类案例时我关注四个具体的量:
- 实际花了多久(和不用 AI 的估计对比)
- 代码量和质量(有测试吗?覆盖率?有文档吗?)
- 人在哪些环节介入(这是最有信息量的部分)
- 哪里失败了、返工了(成功案例里最有价值的部分,也是营销稿里一定没有的部分)
第 4 点是我判断一篇 AI 案例是否可信的主要标准。任何只讲成功不讲返工的案例都要打折看——真实的 AI 辅助开发一定有返工,一定有它绕了远路你不得不干预的地方。不写这些的文章,要么是没做过,要么是在卖东西。
下一条(第 15 条)给了一个带具体数字的对照,那类数据更有参考价值。
15. I ported JustHTML from Python to JavaScript with Codex CLI and GPT-5.2 in 4.5 hours
来源:Simon Willison,2025 年 12 月 15 日。
读它解决什么:一次跨语言移植的完整过程和实际耗时。
要点:
- 用 Codex CLI 把一个 Python 项目移植到 JavaScript,耗时 4.5 小时
- 标题给出了明确的工具、模型和时间
我的补充:跨语言移植是 AI 目前最擅长的任务类型之一,值得单独说清原因:
- 规格是完全明确的 —— 目标就是"行为和原来一样",没有设计决策要做
- 验证信号极强 —— 原项目的测试可以一起移植,跑绿了就是对了(第 7 条的理想情况)
- 工作量大但认知负担低 —— 这正是人类觉得枯燥、AI 不觉得的部分
- 两种语言的惯用法都在训练数据里,翻译的质量有保证
所以移植类任务是我推荐给"想试试 agent 但不知道从哪开始"的人的首选。
实际操作上我的建议:
- 先移植测试,再移植实现。 测试是规格,有了它 agent 就有了反馈信号。
- 分模块做,不要一次全上。 一个模块跑绿了再下一个,出问题时范围小。
- 明确指出目标语言的惯用法要求。不说的话,Python 移到 JS 会得到一份"用 JS 语法写的 Python"——能跑,但不像 JS 代码,后续维护难受。
- 留意语义差异:整数除法、浮点精度、字符串编码(Python 的
str是 Unicode 码点,JS 是 UTF-16)、Nonevsnull/undefined、可变默认参数、异常层级。这些地方测试如果没覆盖,就会静默出错,而这是移植类任务唯一真正的风险点。我会专门要求它列出"这次移植中语义不能一一对应的地方"。
16. Your job is to deliver code you have proven to work
来源:Simon Willison,2025 年 12 月 18 日。
读它解决什么:AI 写了代码之后,你的职责是什么。
要点:
- 标题即论点:你的工作是交付你已证明可以工作的代码
- 2025 年 12 月
我的补充:这一条是整个第一卷的落点,也是我认为整库里最重要的几条之一。它完全不会过期。
论点简单到无法反驳:"AI 写的"不是免责声明。 代码交出去,署你的名,出问题是你的责任。这件事在 AI 之前是这样,在 AI 之后一模一样。
而"证明它能工作"是个有具体内容的要求,不是态度问题:
- 跑过了(不是"看起来对")
- 测试覆盖了主要路径和边界
- 异常路径试过(不只是快乐路径)
- 你能解释它为什么这样写——这一条是分水岭
最后那条值得展开。如果你无法解释某段代码为什么这样写,你就无法在它出问题时修它,也无法判断它在别的输入下会怎样。这不是道德要求,是可维护性的硬约束。 一个团队里如果有相当比例的代码没人能解释,那这个代码库的实际状态就是"不可维护",不管它现在跑得多好。
我自己的做法是设一条最低线:任何要合并的代码,我必须能对每个非平凡的决策说出理由。 说不出来就去读、去问 agent 为什么、或者重写成我理解的版本。这一步花的时间,比后面维护一堆看不懂的代码便宜得多。
顺带说,这条标准还有个副作用:它天然限制了你的产出速度到你的理解速度。这是对的——理解不了的产出不是资产。
2026:软件工厂与新的困惑
17. How StrongDM's AI team build serious software without even looking at the code
来源:Simon Willison,2026 年 2 月 7 日。
读它解决什么:一个团队声称不看代码也能做正经软件,他们的流程是什么。
要点:
- 介绍 StrongDM 的 AI 团队的开发方式
- URL 里的说法是 "software factory"
我的补充:这一条和上一条(第 16 条)表面上直接冲突——一个说"必须证明代码能工作",一个说"不看代码"。值得仔细想清楚这两者怎么共存,因为这是 2026 年这个领域最实际的争论。
我的理解是它们并不真的矛盾,关键在于验证发生在哪一层:
- 第 16 条的"证明能工作",没有规定必须靠人读代码来证明
- 如果你有足够强的自动化验证——完整的测试套件、属性测试、模糊测试、契约测试、端到端验证、形式化规格——那么"证明"可以由这套机制完成
换句话说,"不看代码"的前提是"验证体系强到不需要看代码"。 这个前提极高:
- 测试要覆盖到你敢在没人读过实现的情况下上线
- 要有性能和安全的自动化门禁
- 要能快速回滚
- 关键路径可能需要形式化方法
所以这条路的门槛比"读代码"高,不是低。 它把审查的成本从"每次改动都要人读"前移到了"一次性建立极强的验证体系"。对于改动频繁、规模大的系统,这个交换可能划算;对于大多数团队,那套验证体系本身就是他们没有的东西。
读这一条时我建议的态度:把它当成一个方向上的探索,而不是可以直接照搬的做法。先问"我的验证体系够强吗",答案通常是不够——那就还得读代码。
18. Writing about Agentic Engineering Patterns
来源:Simon Willison,2026 年 2 月 23 日。
读它解决什么:agentic 编程有哪些成型的模式,作者在系统整理什么。
要点:
- 作者关于 agentic engineering patterns 的写作说明
- 2026 年 2 月
我的补充:一个领域开始出现"模式语言"(pattern language)是它走向成熟的标志——就像 1994 年设计模式那本书之于面向对象。模式的意义在于给反复出现的解法一个名字,之后讨论就能在更高的层次进行。
从我自己的使用中已经能认出来的几个模式(用我自己的命名):
- 验证优先 —— 先建反馈信号再动手(第 7 条)
- 研究再实现 —— 先只读地摸清系统,再改(第 12 条)
- worktree 隔离 —— 并行任务各自独立工作区(第 8 条)
- 上下文固化 —— 重复的约定写成 Skill 或
CLAUDE.md(第 10 条) - 子 agent 分治 —— 把大范围搜索交给子 agent,主上下文只收结果
- 失败要响 —— 让 agent 卡住时明确报告,而不是绕过(比如删掉断言让测试通过)
- 一次性沙箱 —— 危险操作在能整个丢掉的环境里做(第 11 条)
这一条是这一卷里唯一我建议"持续关注"而不是"读完就行"的。 模式还在成型,一年后这份列表会不一样。
顺带一个判断:这类模式的价值高于任何具体工具的使用技巧。工具一年换一轮,"先建立反馈信号"这个模式换工具也成立。所以如果你时间有限,学模式而不是学某个工具的参数。
19. Vibe coding and agentic engineering are getting closer than I'd like
来源:Simon Willison,2026 年 5 月 6 日。
读它解决什么:随着模型变强,"不看代码"和"认真做工程"的边界在模糊,这带来什么问题。
要点:
- 作者对两种模式趋同的担忧
- 2026 年 5 月,是他提出 vibe engineering(第 9 条)七个月后的反思
我的补充:这一条讲的现象我自己也感受得很明显:模型变强之后,"不读代码也基本能跑"的比例在上升,于是读代码这件事的即时收益在下降——你读一百次,可能只有三次发现问题。
这是个典型的风险稀释陷阱:出问题的概率降低了,但单次出问题的代价没有降低,而你的警惕性会随着"一直没出事"而下降。这个模式在别的领域也有——安全带用了很久没出车祸,不代表可以不系。
我的应对是把审查从"依赖自觉"变成"结构性要求",因为自觉在概率降低时一定会失效:
- CI 门禁是不可绕过的。 测试、lint、类型检查、依赖审计、密钥扫描——这些不依赖人的注意力。
- 按风险分级决定审查强度。 改文案和改支付逻辑不该是同一套流程。前者可以放,后者必须逐行读。
- 有些东西列入"永远人工审查"清单:认证授权、支付、数据删除、权限判断、加密相关、任何处理钱和个人数据的地方。这个清单要明确写下来,不能靠记。
- 抽样审查。 即便低风险改动,也随机抽一部分读。这是维持"我知道代码库里在发生什么"的手段。
第 4 条是我认为最容易被跳过、但最重要的。 因为如果你完全不读,你会逐渐失去对代码库的心智模型,而那个模型是你判断第 2 条的"风险等级"的依据。失去它之后,你连"这个改动重要不重要"都判断不了了。
20. Conceptual integrity and counting lines of code
来源:Simon Willison,2026 年 8 月 19 日。
读它解决什么:AI 让写代码变便宜之后,代码量和"概念完整性"之间的关系变了吗。
要点:
- 讨论概念完整性(conceptual integrity)与代码行数
- 2026 年 8 月 19 日,是本卷收录的最新一篇(截止日期前一天)
我的补充:"概念完整性"这个词出自 Fred Brooks 的《人月神话》(1975),意思是一个系统应该体现一个连贯的设计思想,宁可少几个功能,也不要让设计变得东拼西凑。Brooks 当年的论证是:不一致的设计带来的理解成本,超过多出来的功能带来的价值。
AI 时代这件事变得更重要,不是更不重要,理由是:
代码写起来便宜了,但读起来、理解起来没有变便宜。 阻止代码库膨胀的主要力量一直是"写代码很累",这个力量正在消失。于是:
- 三个 agent 各自实现了一个功能相似但接口不同的工具函数(第 8 条的坑)
- 同一个概念在系统里有四种叫法
- 每个新功能都新起一套模式,因为让 AI 顺着现有模式写比让它随便写更费口舌
- 代码量翻倍,但理解这个系统的难度翻了不止一倍
"行数"作为指标的意义也变了。 以前行数勉强能当工作量的代理指标,现在完全不能——生成一万行的成本可能低于认真设计一千行。反过来,"删掉了多少行"现在是个比"写了多少行"更有信息量的指标。
我自己的应对:
- 明确写下项目的设计约定(放进
CLAUDE.md/ Skill),包括命名、分层、错误处理、什么情况下允许新增依赖。让 AI 顺着已有的模式走,比事后统一便宜得多。 - 定期做"概念审查",不看代码质量,只看:有没有重复的概念?命名一致吗?分层清楚吗?
- 对"新增抽象"保持怀疑。 AI 很擅长造抽象层,而多余的抽象是概念完整性的主要杀手。
- 把删代码当成正经工作。 定期找出无人调用的函数、重复的实现、只用了一次的抽象。
本卷小结:1–5 条是 2025 上半年的基础认知(第 1 条"该检查什么"和第 3 条"vibe coding 的准确定义"是地基);6–16 条是 2025 下半年 agent 成型期(第 7 条 agentic loop 设计和第 16 条"交付你证明过能跑的代码"是这一卷最实用的两条);17–20 条是 2026 年的争论与反思。
这一卷里最不会过期的四条:第 1、7、16、20 条。 具体工具和模型会换,这四条讲的是判断标准和工程责任,换几轮模型都成立。
上一页: 工具资料库总览 · 下一卷: ② Anthropic 的 Agent 工程方法 →
