从去年年底到现在,我开始真实使用Coding Agent进行编码,无论是工作上还是私下学习,AI已经很大程度接管了我的代码工作,甚至是日常的一些事情。
私下我也自己琢磨一些小项目,用来更好的理解和使用Agent:
- 一个已经上架的 Android App:像素风的日记 + 数值养成,React Native 开发,目前已上架 Google Play。ps:只是没怎么维护😂
- 一个 Godot 实现的幸存者类肉鸽原型:用来验证AI + Godot制作游戏,以及如何使用AI在人不参与代码阅读的情况下使用知识库的方式进行管理。
- 还是一个 Godot 实现的桌面挂机陪伴游戏:这个体量最小,重点其实是想尝试给AI提供一个想法,AI怎么自己输出资源并完成一个游戏效果。
- 一个 Android 端的 Agent Runtime:为了搞明白 Agent 到底怎么跑起来而自己实现的项目,还在持续迭代。
代码加起来四万多行,其中绝大多数不是我敲的。
但这篇不是"AI 帮我提效 N 倍"的文章,也不是工具评测。我更想聊聊这半年里我自己身上发生的变化。
变化其实只有一句话:我从一个执行者,变成了一个决策者。
以前我的产出是代码。现在我的产出是判断——判断该做什么、不该做什么、怎样算做对了、做到哪一步就该停。这些判断得被写成 AI 能读懂、能执行、甚至能自己验证的东西,否则我就得一遍遍回到现场。而这半年我大部分的时间,其实花在了后面这件事上。
下面是我攒下来的一些做法和感受。它们不一定对,只是我目前的状态。
一、留判据:把踩过的坑,写成 AI 读得懂的约束
一开始我以为,AI 写代码快是因为它知道得多。后来发现不是。它知道得很多,但它不知道我这个项目哪里会塌。
有个很典型的例子。我做了一个带打卡功能的小 App,用户可以选择"一周从哪天开始"。AI 写周统计的时候,很自然地写了 date.getDay() === 0 来判断周日。这行代码在默认设置下完全正确,只在用户把周一开始设成一周第一天时出错——而且错得隐蔽,统计数字差一位,不崩溃也不报错。
改完之后,我做了一件事:把这条写进了项目规范。
不要假设一周从周日或周一固定开始。
必须使用 src/utils/dateUtils.ts 中的工具函数,禁止手动计算日期间隔。
避免使用 date.getDay() === 0 硬编码判断周日。
同一份文件里,还有风格很像的另外几条:
补卡(日期早于今日)时,总收益减半(x0.5)。
修改记录时,仅增加差额部分 XP,防止刷分。
这些条款有个共同点:它们不是通用最佳实践,而是"我这个项目特有的坑"。date.getDay() === 0 本身没毛病,问题只在"用户可以自定义一周起点"这个前提下才存在。
后来我慢慢摸出一个判断标准。一个坑值不值得写成约束,我大致看四条:
- AI 会重复踩的,写。同一个错改过两次以上,就说明它会一直犯。
- AI 缺的领域常识,写。比如一个游戏项目的车轮贴图不能靠旋转变形来做——那张图的手绘高光和阴影是固定的,一转就全错。这种事 AI 不可能"想到",因为它没有画过画。
- 通用最佳实践,不写。公开资料里到处都是的东西,写进去只是白占上下文。
- 一次性的业务特例,不写。只在一个地方成立的规则,留在代码注释里比写进
AGENTS.md更合适。
最后这条标准看起来简单,但它帮我省掉了大量"看起来很负责、实际上在浪费 token"的规则。
我写的这些东西大致分两类。一类是 AGENTS.md,放在项目根目录,管的是全局纪律。
另一类是 skill,按主题拆分,每个管一块具体知识:这一个管数值设计规范,那一个管 UI 色板和间距规范。它比 AGENTS.md 轻,只在相关任务里被加载。
还有一类坑属于工具链,我印象最深的一个是:Godot 的文本资源文件如果带 UTF-8 BOM,加载时会报一个完全看不懂的错——Parse Error: Expected '['。第一次遇到时我改了半小时的 preload 路径,全无用处,真正的原因在文件的前三个字节。这条也被写进了 AGENTS.md:
遇到这类错误时,不要只改 preload 路径。应先检查报错资源文件的前几个字节。
后来它再遇到这个报错,会直接去查字节,不用我上手。
写到这里我想说的其实是一个转变:以前这些东西长在我脑子里。我知道"车轮不能转"、知道"补卡要减半"、知道"BOM 会让 Godot 报错"。现在它们长在文件里。
区别在哪?长在我脑子里,我只能在 AI 出错之后才想起来;长在文件里,它在动手之前就能读到。
还没想清楚的地方:这套 AGENTS.md 的维护本身是有成本的。我现在靠两条腿走——定期回头补,以及 AI 遇到问题时顺手归纳。但"什么时候该归纳、该归纳成什么样",我目前还是靠感觉。
二、管预算:规则写多了,它本身就成了新问题
你为了让 AI 少犯错而写的规则,写到一定量之后,它本身就成了新问题。
原因很朴素:上下文是有预算的。规则文件越写越长,每次对话都被整份塞进去,能留给真正任务的注意力就越少。更麻烦的是,一堆和当前任务无关的规范会干扰它,让它在你没提的地方也"顺手"做点事。
我的解法是分层,并且只把入口塞给它。
第一层,入口只放路由。 根目录那份 AGENTS.md 不写具体知识,只写"遇到什么事去看哪个文件"。我其中一份开头就直说了:
本文件只提供入口规则和 Skill 路由,不要求一次性读取所有项目 Skill 或 references。
第二层,每个 skill 自带"什么时候该读我"。 它不像文档,更像一组说明书,每份开头写清楚自己适用于什么场景。
第三层,skill 内部再做一次路由。 一份 skill 通常带一堆 references,它会明确写"先判断问题类型,再读取资料。不要每次默认读取全部 references",再列一张对照表——哪类问题读哪几个文件。
三层搭起来之后,效果是:大多数时候它只加载一两个文件,而不是全部。
我后来才知道这种做法有个正式名字,叫"渐进式披露"(progressive disclosure)。但我当时撞上它的原因很实际——上下文被塞爆了。
有个细节我觉得挺重要:分层不只是为了省 token,也是为了减少越界。
比如我在开发游戏时就尝试过:前期它总想在没被要求的地方顺手加东西。后来我把"玩法策划"和"实现"拆成两个 skill,在策划 skill 里写了一句:
使用本 Skill 时,Codex 先作为本项目的玩法策划协作者,而不是实现工程师。
如果策划结论需要进入实现交接,只输出"实现需求与边界",不要替实现 Agent 设计技术方案。
它甚至把"把策划案写成技术方案"列进了自己的常见误区。
拆开之后,讨论玩法时它不再急着写代码,讨论实现时也不会回头质疑玩法。同一件事被拆成两个角色之后,反而都不越界了。
还有一个更隐蔽的损耗,是我最近才反应过来的:它开始不按约定的格式输出了。
我在交接文档里定过一套固定的汇报结构——改了哪些文件、当前数据流、新增了哪些测试及结果、对原有流程有什么影响、还有什么要确认。条目不多,规则文件也还少的时候,它每次都规规矩矩,一条不落。
等到上下文堆到一定程度,它就开始变了:漏项、把三四条合并成一条、或者干脆按自己觉得顺的方式重写一遍。明明文档还在那儿,它却像没看见。
我一开始以为是它能力不行,后来想明白,这其实是同一个问题的另一面:遵守格式也是要花注意力的。上下文越满,这种"软约束"就越容易被丢掉——它不会报错,只是悄悄退化。
所以我现在又多了一件定期要干的事:回头把这批文档重新梳理一遍。
而且梳理的时候,多数时候不是在加,而是在删——把已经内化的条款删掉,把重复的合并掉,把过期的清出去。梳理完最直观的变化不是它变得更聪明了,而是它的汇报格式又正常了。这也算是给我一个信号:当它开始不按格式来,说明文档已经臃肿有一阵了。
还没想清楚的地方:分层解决的是"一次给多少",但没解决"什么时候该整理、什么时候该废弃"。我现在触发梳理的时机基本是"它开始乱来了"——一个明显滞后的信号。另外这些规范文件里,有一些其实已经过期,但我没删——因为不确定删掉之后会不会有东西重新踩坑。
三、会验收:什么能交给 AI 自证,什么必须自己看
做完之后,谁来判它做得对不对。
我一开始的做法是自己看,改一遍看一眼。问题很快就出现了:AI 的产出速度比我 review 的速度快得多,一会儿就堵住了。
后来我把"判定"这件事分成了三档。
第一档:AI 能自己判的
只要判定是客观的,它就能自己闭环。编译过不过、单元测试断言过不过、脚本自检有没有报错、数值有没有越界——这些都可以写成判据交给它。它跑完自己知道对不对,不对自己改。
这一档的成本极低,可以每次改动都跑。我现在会尽量把能挪进来的东西挪进来,因为它是唯一不占我时间的验收方式。
第二档:AI 初判,人抽检
有些东西不算纯粹客观,但 AI 现在能自己看一眼了——比如界面和渲染结果。
比如我在开发游戏时,是固定尺寸的画面,我在项目里加了一个命令行参数,可以按指定条件截图到指定路径:
--day-night-hour=<0..24> --scene-variant=<0|1> --capture-path=<absolute PNG path> --capture-quit
于是流程变成:AI 改完 → 用固定参数截一组图 → 存进按阶段命名的目录 → 它自己先看一遍。这个项目里这样攒下来的验收截图有 106 张。
它的价值有两层。一层是 AI 可以先筛掉明显不对的。另一层是——这些截图变成了可回看的证据。
不过标准还是得我定。它能看出"这跟上一版不一样",但它不知道"哪一版才是对的"。
第三档:只能我自己判的
这是范围最窄、但也最不可替代的一档:业务逻辑对不对,交互体验有没有达到预期。
AI 可以高正确率地写出可用代码,但它判不了这个。它能告诉你"这个按钮点下去会跳转到 A 页面"——这没错,可是"用户在这个位置期待的是不是跳到 A",只有做产品的人知道。
我后来想明白一件事:在这一档里,我的角色不是验收者,而是"提前把预期讲清楚的人"。
因为如果你不提前讲,就只能事后反复自己看——而反复自己看,是整个流程里最贵的一件事。所以现在我会尽量在动工前把"什么样算做对了"先写出来,哪怕写得不够精确。写得越清楚,能挪进第一档的东西就越多。
还没想清楚的地方:让 AI 参与大量验证,本质上是在烧 token。第一档可以每次都跑,因为它便宜;但如果让它自己截图、自己看、自己反复调,成本会上得很快。"验证力度该给多大",我到现在还在摸索。
四、控偏移:先把需求收敛,再分点验证
怎么让 AI 别在实现的过程中跑偏?
我用 AI 最常遇到的问题,不是写错,而是顺便做多了。你让它加一个功能,它会顺手把相关的、相似的、可能以后用得上的都做了。听着像好事,实际是灾难:改动面失控,review 成本爆炸,而且它做的那些"以后可能用得上"的东西,往往正好是你现在不想要的。
我摸索出的做法是两头夹住。
一头是收敛需求:先写"不做什么"
我现在的每个项目都有一份明确的"不做清单"。有一份写得很直白,比如我在学习Agent时就明确强调:
先实现最小闭环,不主动扩展到 MCP、RAG、Memory、Multi-Agent、Skills、
QuickJS、端侧模型等能力。
任何新增模块如果不是当前里程碑的必要条件,应延后。
另一份里,这个清单列了二十多项具体能力,一条一条写出来。写出来的意义在于——AI 在考虑"要不要顺手做"的时候,能查得到这不在范围内。
我会把"不做什么"放在"做什么"前面写。因为我们讨论需求时注意力都在"要什么"上,但真正决定一个项目会不会失控的,往往是"不要什么"。
另一头是分点验证:一轮只推进一格
这是我试下来收益最高的一条纪律:不把一个大版本交给它一次做完,而是切成能独立验证的小块,一次只做一块。
我其中一个项目的交接文档里,这句话几乎是模板:
不要一次性实现整个 v0.2。第一轮只执行 v0.2.1。
完成 v0.2.1 后停止开发,并汇报:
1. 修改文件列表;2. 当前数据流;3. 新增测试及结果;
4. 对原有流程的影响;5. 待确认的问题...
关键是"停止"这两个字。不停止,它就会一直做下去;一停,我就有机会看一眼方向对不对,而代价只有这一块的返工。
配套的还有一条:如果发现必须越界才能完成,不要扩范围,回头改设计。
如果实现过程中发现"必须先实现上述能力才能完成 v0.3",
优先重新检查设计,而不是扩 Scope。
这条我一开始是不信的——都做到一半了,回头改设计成本不是更高吗?实际做下来,回头改设计几乎总是比扩范围便宜。因为扩范围留下的是一堆没人需要的代码,而改设计留下的是一份更清楚的规格。
还没想清楚的地方:这套"一轮一格"的节奏,在需要快速试错的探索阶段会很别扭。有些东西你就是得先随便做出来看看感觉。我目前只能靠"这块是探索还是交付"手动切换,而且我经常切错。
五、落点:判定完之后,才知道该改哪儿
前面四节讲的是怎么和 AI 配合。这一节想聊聊这些做法在我身上留下的东西。
我注意到一件事:"推翻自己"这件事,门槛变低了。
以前我判断一个方向对不对,靠的是做出来之后看一眼感觉。感觉不对,但说不出哪里不对,只能推翻重来——所以我本能地抗拒推翻,因为它太贵。
现在的流程是反过来的:先用测试或者人的体验做一次判定,判定结果决定往哪儿改。
能自动判的交给测试判,判不了的我自己看一遍。判完之后,"该改什么"通常就自己浮出来了。它不再是"我觉得不太行",而是"这一块过不了,其他地方没问题"。
有了这个回路,推翻就不再是一次全盘推倒,而是定向修改。
其实有了AI之后,编码成本大大降低,以前觉得实现麻烦的代码逻辑,AI可以在短时间完成,重要的还是验收。所以转变自己的思路不要以执行者的思维去判定成本高低,因为实际成本可能比你预想的要低得多。
六、让 AI 当导师
最后说一个用法上的转变。
我最近在学习Agent 到底是怎么跑起来的。我不满足于看文章,想自己实现一个 Android 端的 Agent。
但我没有让它直接给我讲原理,而是让它分步实现:先实现 Agent Loop,再实现 Tool Calling,然后是 Context 管理。我在交接文档里写的第一句目标就是"学习与实现":
不是把某个开源 Harness 移植到 Android,而是提取它的核心架构原则。
第一阶段优先保证可理解性、可测试性和可恢复性,而不是功能数量。
流程就变成了:它写一部分,我读一部分,读不懂的地方问它,问明白了再往下走。
**在这个用法里,代码的角色变了。**前面几节里代码是交付物,这一节里代码是我的教材。同一个 AI、同一份产出能力,只是我换了使用方式。而且因为这个东西是我自己要从头读的,我反而对它的实现质量更挑剔——读不懂的是我自己。
如果你想找一个专门辅助学习的工具,推荐可以试试 Matt Pocock 的 /teach skill,它把学习做成了一个有状态的、跨会话延续的过程,思路挺值得参考。
不过这里有一点我想强调:它教不了的部分,还是得自己补。
最后
附上开头说过的几个小项目
- 一个心情日记App:Google Play
- 类幸存者游戏:
- 桌面挂机游戏: