AI Coding了大半年,我从执行者变成了决策者

从去年年底到现在,我开始真实使用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 来判断周日。这行代码在默认设置下完全正确,只在用户把周一开始设成一周第一天时出错------而且错得隐蔽,统计数字差一位,不崩溃也不报错。

改完之后,我做了一件事:把这条写进了项目规范。

text 复制代码
不要假设一周从周日或周一固定开始。
必须使用 src/utils/dateUtils.ts 中的工具函数,禁止手动计算日期间隔。
避免使用 date.getDay() === 0 硬编码判断周日。

同一份文件里,还有风格很像的另外几条:

text 复制代码
补卡(日期早于今日)时,总收益减半(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:

text 复制代码
遇到这类错误时,不要只改 preload 路径。应先检查报错资源文件的前几个字节。

后来它再遇到这个报错,会直接去查字节,不用我上手。

写到这里我想说的其实是一个转变:以前这些东西长在我脑子里。我知道"车轮不能转"、知道"补卡要减半"、知道"BOM 会让 Godot 报错"。现在它们长在文件里。

区别在哪?长在我脑子里,我只能在 AI 出错之后才想起来;长在文件里,它在动手之前就能读到。

还没想清楚的地方 :这套 AGENTS.md 的维护本身是有成本的。我现在靠两条腿走------定期回头补,以及 AI 遇到问题时顺手归纳。但"什么时候该归纳、该归纳成什么样",我目前还是靠感觉。


二、管预算:规则写多了,它本身就成了新问题

你为了让 AI 少犯错而写的规则,写到一定量之后,它本身就成了新问题。

原因很朴素:上下文是有预算的。规则文件越写越长,每次对话都被整份塞进去,能留给真正任务的注意力就越少。更麻烦的是,一堆和当前任务无关的规范会干扰它,让它在你没提的地方也"顺手"做点事。

我的解法是分层,并且只把入口塞给它。

第一层,入口只放路由。 根目录那份 AGENTS.md 不写具体知识,只写"遇到什么事去看哪个文件"。我其中一份开头就直说了:

text 复制代码
本文件只提供入口规则和 Skill 路由,不要求一次性读取所有项目 Skill 或 references。

第二层,每个 skill 自带"什么时候该读我"。 它不像文档,更像一组说明书,每份开头写清楚自己适用于什么场景。

第三层,skill 内部再做一次路由。 一份 skill 通常带一堆 references,它会明确写"先判断问题类型,再读取资料。不要每次默认读取全部 references",再列一张对照表------哪类问题读哪几个文件。

三层搭起来之后,效果是:大多数时候它只加载一两个文件,而不是全部。

我后来才知道这种做法有个正式名字,叫"渐进式披露"(progressive disclosure)。但我当时撞上它的原因很实际------上下文被塞爆了。

有个细节我觉得挺重要:分层不只是为了省 token,也是为了减少越界。

比如我在开发游戏时就尝试过:前期它总想在没被要求的地方顺手加东西。后来我把"玩法策划"和"实现"拆成两个 skill,在策划 skill 里写了一句:

text 复制代码
使用本 Skill 时,Codex 先作为本项目的玩法策划协作者,而不是实现工程师。
如果策划结论需要进入实现交接,只输出"实现需求与边界",不要替实现 Agent 设计技术方案。

它甚至把"把策划案写成技术方案"列进了自己的常见误区。

拆开之后,讨论玩法时它不再急着写代码,讨论实现时也不会回头质疑玩法。同一件事被拆成两个角色之后,反而都不越界了。

还有一个更隐蔽的损耗,是我最近才反应过来的:它开始不按约定的格式输出了。

我在交接文档里定过一套固定的汇报结构------改了哪些文件、当前数据流、新增了哪些测试及结果、对原有流程有什么影响、还有什么要确认。条目不多,规则文件也还少的时候,它每次都规规矩矩,一条不落。

等到上下文堆到一定程度,它就开始变了:漏项、把三四条合并成一条、或者干脆按自己觉得顺的方式重写一遍。明明文档还在那儿,它却像没看见。

我一开始以为是它能力不行,后来想明白,这其实是同一个问题的另一面:遵守格式也是要花注意力的。上下文越满,这种"软约束"就越容易被丢掉------它不会报错,只是悄悄退化。

所以我现在又多了一件定期要干的事:回头把这批文档重新梳理一遍。

而且梳理的时候,多数时候不是在加,而是在删 ------把已经内化的条款删掉,把重复的合并掉,把过期的清出去。梳理完最直观的变化不是它变得更聪明了,而是它的汇报格式又正常了。这也算是给我一个信号:当它开始不按格式来,说明文档已经臃肿有一阵了。

还没想清楚的地方:分层解决的是"一次给多少",但没解决"什么时候该整理、什么时候该废弃"。我现在触发梳理的时机基本是"它开始乱来了"------一个明显滞后的信号。另外这些规范文件里,有一些其实已经过期,但我没删------因为不确定删掉之后会不会有东西重新踩坑。


三、会验收:什么能交给 AI 自证,什么必须自己看

做完之后,谁来判它做得对不对。

我一开始的做法是自己看,改一遍看一眼。问题很快就出现了:AI 的产出速度比我 review 的速度快得多,一会儿就堵住了。

后来我把"判定"这件事分成了三档。

第一档:AI 能自己判的

只要判定是客观的,它就能自己闭环。编译过不过、单元测试断言过不过、脚本自检有没有报错、数值有没有越界------这些都可以写成判据交给它。它跑完自己知道对不对,不对自己改。

这一档的成本极低,可以每次改动都跑。我现在会尽量把能挪进来的东西挪进来,因为它是唯一不占我时间的验收方式。

第二档:AI 初判,人抽检

有些东西不算纯粹客观,但 AI 现在能自己看一眼了------比如界面和渲染结果。

比如我在开发游戏时,是固定尺寸的画面,我在项目里加了一个命令行参数,可以按指定条件截图到指定路径:

text 复制代码
--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时就明确强调:

text 复制代码
先实现最小闭环,不主动扩展到 MCP、RAG、Memory、Multi-Agent、Skills、
QuickJS、端侧模型等能力。
任何新增模块如果不是当前里程碑的必要条件,应延后。

另一份里,这个清单列了二十多项具体能力,一条一条写出来。写出来的意义在于------AI 在考虑"要不要顺手做"的时候,能查得到这不在范围内。

我会把"不做什么"放在"做什么"前面写。因为我们讨论需求时注意力都在"要什么"上,但真正决定一个项目会不会失控的,往往是"不要什么"。

另一头是分点验证:一轮只推进一格

这是我试下来收益最高的一条纪律:不把一个大版本交给它一次做完,而是切成能独立验证的小块,一次只做一块。

我其中一个项目的交接文档里,这句话几乎是模板:

text 复制代码
不要一次性实现整个 v0.2。第一轮只执行 v0.2.1。
完成 v0.2.1 后停止开发,并汇报:
1. 修改文件列表;2. 当前数据流;3. 新增测试及结果;
4. 对原有流程的影响;5. 待确认的问题...

关键是"停止"这两个字。不停止,它就会一直做下去;一停,我就有机会看一眼方向对不对,而代价只有这一块的返工。

配套的还有一条:如果发现必须越界才能完成,不要扩范围,回头改设计。

text 复制代码
如果实现过程中发现"必须先实现上述能力才能完成 v0.3",
优先重新检查设计,而不是扩 Scope。

这条我一开始是不信的------都做到一半了,回头改设计成本不是更高吗?实际做下来,回头改设计几乎总是比扩范围便宜。因为扩范围留下的是一堆没人需要的代码,而改设计留下的是一份更清楚的规格。

还没想清楚的地方:这套"一轮一格"的节奏,在需要快速试错的探索阶段会很别扭。有些东西你就是得先随便做出来看看感觉。我目前只能靠"这块是探索还是交付"手动切换,而且我经常切错。


五、落点:判定完之后,才知道该改哪儿

前面四节讲的是怎么和 AI 配合。这一节想聊聊这些做法在我身上留下的东西。

我注意到一件事:"推翻自己"这件事,门槛变低了。

以前我判断一个方向对不对,靠的是做出来之后看一眼感觉。感觉不对,但说不出哪里不对,只能推翻重来------所以我本能地抗拒推翻,因为它太贵。

现在的流程是反过来的:先用测试或者人的体验做一次判定,判定结果决定往哪儿改。

能自动判的交给测试判,判不了的我自己看一遍。判完之后,"该改什么"通常就自己浮出来了。它不再是"我觉得不太行",而是"这一块过不了,其他地方没问题"。

有了这个回路,推翻就不再是一次全盘推倒,而是定向修改。

其实有了AI之后,编码成本大大降低,以前觉得实现麻烦的代码逻辑,AI可以在短时间完成,重要的还是验收。所以转变自己的思路不要以执行者的思维去判定成本高低,因为实际成本可能比你预想的要低得多。


六、让 AI 当导师

最后说一个用法上的转变。

我最近在学习Agent 到底是怎么跑起来的。我不满足于看文章,想自己实现一个 Android 端的 Agent。

但我没有让它直接给我讲原理,而是让它分步实现:先实现 Agent Loop,再实现 Tool Calling,然后是 Context 管理。我在交接文档里写的第一句目标就是"学习与实现":

text 复制代码
不是把某个开源 Harness 移植到 Android,而是提取它的核心架构原则。
第一阶段优先保证可理解性、可测试性和可恢复性,而不是功能数量。

流程就变成了:它写一部分,我读一部分,读不懂的地方问它,问明白了再往下走。

**在这个用法里,代码的角色变了。**前面几节里代码是交付物,这一节里代码是我的教材。同一个 AI、同一份产出能力,只是我换了使用方式。而且因为这个东西是我自己要从头读的,我反而对它的实现质量更挑剔------读不懂的是我自己。

如果你想找一个专门辅助学习的工具,推荐可以试试 Matt Pocock 的 /teach skill,它把学习做成了一个有状态的、跨会话延续的过程,思路挺值得参考。

不过这里有一点我想强调:它教不了的部分,还是得自己补。


最后

附上开头说过的几个小项目

  • 一个心情日记App :Google Play
  • 类幸存者游戏 :
  • 桌面挂机游戏 :
相关推荐
9i编程1 小时前
9. 把 DDD 开源脚手架化为自己的:联调照出的问题与事件重构——租户权限、按钮样式与全局 DomainEvent 反哺 SKILL
人工智能·openai·ai编程
Solara1 小时前
1 条 audit=0 的幽灵记录:我说不清是我删的,还是平台吞的
人工智能·程序员·ai编程
俊哥AI全栈工程师1 小时前
让 AI Agent 替我跑日常重复任务,一周踩坑记录
ai编程
孟健1 小时前
我通过了水星银行美国业务证明审核,交了几轮材料
ai编程
杨杨杨大侠1 小时前
一句“修个 Bug”,AI 编程工具到底怎么扣额度?
人工智能·agent·ai编程
回家路上绕了弯1 小时前
智能体编排平台中,工作流与 Agent 如何分工?
后端·ai编程
桃西西呀1 小时前
给告警加了道 AI 初筛,我终于半夜不用爬起来了看无用告警了
人工智能·llm·ai编程
杨杨杨大侠1 小时前
MCP 到底接在了哪一层?从“Agent 调工具”说起
agent·ai编程·mcp
全栈弄潮儿1 小时前
AI 辅助写单测:如何覆盖边界,而不是凑覆盖率
aigc·openai·ai编程