← cd ~/notes

AI / Agent

和编程 Agent 协作两个月:上下文比 prompt 重要

这个站的大部分代码是和 AI Agent 一起写的。记录一些实际踩过的坑,以及慢慢摸索出来的协作方式。

/6 分钟阅读

这个站从搭架子、写工具到前段时间重做界面,大部分代码都是和编程 Agent 一起完成的。两个月下来,最大的体会是:决定效果的不是 prompt 写得多漂亮,而是 Agent 手里有什么上下文、有什么办法验证自己。

下面是一些具体的经验,按我觉得的重要程度排。

1. 给项目写一份“给 Agent 看的说明书”

Agent 每次对话都是从零开始,它不记得上次你说过“别引入新依赖”。我在项目根目录放了一份 CONTEXT.md,写清楚:

  • 这个项目是什么,技术栈是什么
  • 关键的设计决策和为什么(比如“纯静态、零后端,工具全部在浏览器里跑”)
  • 踩过的坑和约束(比如“设计 token 被后台页面引用,只能改值不能改名”)

最后一类最有价值。每次 Agent 犯了一个“不知道背景就一定会犯”的错,我就把这条背景补进去。写了几轮之后,同类错误基本不再出现。

具体怎么组织这类文件,可以看 Skills 那篇 里 Rules 和 Skills 的区分。

2. 让它能自己验证

这是提升最明显的一条。同一个任务:

  • 只说“把这个功能实现了”—— 它写完就说完成了,跑起来可能是错的
  • 说“实现后跑 npm test 和 npm run build,都通过再汇报”—— 它会自己发现问题、自己修

UI 的改动更是如此。能让 Agent 打开浏览器截图看效果的话,它会发现很多光看代码发现不了的问题:元素被裁掉了、动画没生效、手机宽度下挤成一团。

测试本身也是给 Agent 的上下文。有一套靠谱的测试,等于告诉它“这些行为不能被改坏”。

3. 反馈要描述现象,而不只是说“不好”

“这个页面不好看”能用,但“卡片之间移动鼠标有延迟”这种具体的描述,效果好得多。Agent 有了具体现象,就能去找具体原因。

举个真实的例子。重做界面后我反馈“鼠标在卡片间移动有延迟”,Agent 去量了一下,发现是一个跟随鼠标的光晕效果把 CSS 变量写在了 <html> 上 —— CSS 变量会被所有后代继承,于是每次鼠标移动都触发整个页面的样式重算,每帧近 5 毫秒。改成只写在当前卡片上,问题就消失了。

这种问题如果我只说“感觉不流畅”,大概率得到的是“已优化动画性能”加上一些无关痛痒的改动。

4. 让它先找根因,再动手

另一个例子:快捷搜索面板的列表一直没有样式,看上去就是一串裸链接。直觉的修法是“给列表项加点样式”,但其实样式早就写了,只是从来没生效过。

原因是 Astro 的组件样式是作用域隔离的,只作用于模板里写死的元素;而搜索结果是脚本运行时用 innerHTML 插进去的,拿不到作用域标记,样式自然匹配不上。找到这个原因,修复就是一行配置的事;没找到的话,加多少样式都不会生效。

现在我会习惯性地要求“先说明原因,再改”。Agent 把原因讲出来的过程,也是我判断它有没有理解对的机会。

5. 小步走,每步都能看到结果

“重构整个网站”这种任务,一次交出去,回来的往往是一个很大、很难审查的改动。我现在的做法是:

  1. 先让它读代码、提方案,我确认方向
  2. 拆成几块,一块一块做,每块做完都能跑起来看效果
  3. 中途觉得方向不对,随时叫停调整

方向上的问题越早发现越便宜。界面重做时,我中途从“克制的暗色风格”改成了“炫酷科技感”,因为是分步做的,改起来只是调整后面几步,而不是推倒重来。

6. 警惕“过度工程”

Agent 有一个倾向:做得比你要的多。要一个函数,它给你加上配置项、抽象层、各种“以后可能用到”的扩展点。代码看着很专业,但每一行都是未来要维护的。

我的应对办法是在规则里明确写上偏好:能用标准库就不引依赖,能一行就不写十行,不为想象中的需求写代码。审查改动时也优先问“这里能删掉什么”。

7. 审查改动,至少看一眼 diff

Agent 写的代码大部分时候是对的,但“大部分时候”在工程里不够。我不会逐行审查每一处样式调整,但涉及数据、安全、删除操作的改动一定会看。尤其要留意它为了让测试通过而改了测试,而不是改了代码 —— 这种事真的会发生。

写在最后

用 Agent 写代码,越来越像带一个能力很强、但对项目一无所知、而且每天都会失忆的新同事。你要做的不是把每一步都替它想好,而是:

  • 把背景写下来,让它每次都能看到
  • 给它验证结果的手段
  • 描述清楚你看到的现象
  • 在关键节点把关

做到这几点,它能干的活比我预想的多得多。

一句话:prompt 决定 Agent 这一次怎么做,上下文和验证手段决定它能不能每一次都做对。

↑↓ 选择↵ 打开