从全局记忆到收束工作流:我用 AI 写代码这一年的心法
一年多用 AI 写代码下来,最深的体感不是「AI 越来越强」,而是——AI 的能力上限是固定的,真正决定效果的,是你给它的边界。
下面分五段讲我怎么一步步把这些边界搭起来:从全局记忆,到按需加载的 Wiki,到把流程固化成 Skill,再到写代码前的「收束工作流」。
第一层:三大 CLI 的全局记忆文档
主流的命令行 AI 编码工具,都默认会在每次会话启动时自动加载一个「全局记忆文档」。这是我们调教 AI 的第一道阵地——它决定了 AI 一上来对「我是谁、项目长什么样、我们怎么协作」的基础认知。
三家对照如下:
| CLI 工具 | 全局记忆文件 | 默认路径 | 项目级覆盖 |
|---|---|---|---|
| Claude Code(Anthropic) | CLAUDE.md | ~/.claude/CLAUDE.md | 项目根目录 CLAUDE.md |
| Codex CLI(OpenAI) | AGENTS.md | ~/.codex/AGENTS.md | 项目根目录 AGENTS.md |
| openCode(sst) | AGENTS.md | ~/.config/opencode/AGENTS.md | 项目根目录 AGENTS.md |
这些文件应该写什么
不是说明书,是给 AI 的「入职手册 + 工位便签」。建议覆盖几类:
- 语言与沟通偏好:例如「所有对话用中文」「commit message 用中文」
- 代码规范红线:例如「禁止使用全限定类名」「禁止
--no-verify跳过 hook」 - 技术栈与工具链:项目用什么框架、构建命令、测试命令
- 不要做的事:踩过的坑、被 review 打回过的写法
- 协作约定:什么时候该问、什么时候直接干、commit 粒度怎么切
一个最小可用模板:
# 个人偏好
- 使用中文交流,代码标识符保留英文
- 回答简洁,不要总结废话
# 代码规范
- Java 中禁止使用全限定类名,必须 import
- 提交前必须通过本地测试,禁止 --no-verify
# 项目背景
- 这是一个 XXX 系统,技术栈:Spring Boot + MyBatis + Vue3
- 构建命令:mvn clean package
- 测试命令:mvn test
关键认知
全局记忆不是万能咒语。它解决的是「AI 不知道我是谁、项目是什么样」的问题,不能解决「AI 在写代码时跑偏、过度发挥」——那是后面要讲的事情。
第二层:LLM Wiki —— 按需加载,而不是全量塞
第一层的隐患
第一层我们说全局记忆是「入职手册」。但实际用一段时间后,一定会遇到:
- 协议文档想塞进去 → CLAUDE.md 涨到 2000 行
- 需求背景想塞进去 → 每次会话先吃掉几万 token
- 待办清单想塞进去 → 改一次就要 review 一次全局文件
全局记忆是常驻内存,往里塞东西就像在给 AI 灌「开机自检脚本」——每次会话都要全文读一遍,又贵又慢,还容易污染上下文。
Karpathy 的「LLM Wiki」模型
Andrej Karpathy 提过一个非常优雅的心智模型:
把 LLM 当成一个会查 Wiki 的实习生,而不是一个被迫背完整本百科的考生。
核心机制只有两步:
- 会话启动时只加载「索引(index)」——一份精简目录,告诉 AI「有什么、在哪里、什么时候该看」
- 当任务关键词命中索引项时,AI 才主动读对应「页面(page)」——具体的协议、需求、文档全文
┌───────────────────────────────┐
│ SessionStart │
│ ↓ 加载 index.md(轻量索引) │
│ ↓ 100 行,几百 token │
└──────────────┬─────────────────┘
│
用户:"对接支付协议这块怎么改?"
│
▼
AI 在 index 里命中关键词「支付协议」
│
▼
按需读取 wiki/payment-protocol.md(完整页)
为什么这个模型这么香
| 维度 | 全塞 CLAUDE.md | LLM Wiki 模型 |
|---|---|---|
| 首 token 成本 | 高(每次都全量加载) | 低(只加载索引) |
| 上下文污染 | 严重(无关内容也在里面) | 几乎没有(用到才读) |
| 更新成本 | 改一次全员重新训练心智 | 改具体页面,索引几乎不动 |
| 可扩展性 | 上限两三百行(再多就被截断) | 几乎无上限(按需读取) |
| 协作友好 | 多人改同一个文件容易冲突 | 一人一页,天然分文件管理 |
适合放进 Wiki 的内容
- 协议规范:HTTP 接口约定、字段命名、错误码表、签名算法
- 需求背景:业务语境、为什么这么设计、踩过的坑
- 待办清单:长期 TODO、技术债、未完成的迁移
- 架构决策:ADR(Architecture Decision Records)
- 环境信息:测试账号、灰度开关、各环境的特殊配置
不适合放进 Wiki 的(应该留在全局记忆):
- 始终生效的代码规范红线
- 团队语言与沟通风格
- 永远不许做的事
一个最小可用的目录结构
.wiki/
├── index.md # SessionStart 加载这个
├── protocols/
│ ├── payment-protocol.md # 支付对接协议
│ └── auth-jwt-spec.md # JWT 鉴权规范
├── requirements/
│ ├── 2026Q2-flight-booking.md
│ └── 2026Q2-iot-rules-engine.md
└── todos/
├── tech-debt.md
└── migration-mybatis-plus.md
index.md 只需要一句话标签 + 路径:
# 项目知识索引
## 协议
- **支付协议** → protocols/payment-protocol.md :与第三方支付网关对接的字段、签名、回调约定
- **JWT 鉴权** → protocols/auth-jwt-spec.md :Token 结构、刷新机制、黑名单
## 需求
- **机票预订(2026Q2)** → requirements/2026Q2-flight-booking.md
- **IoT 规则引擎(2026Q2)** → requirements/2026Q2-iot-rules-engine.md
## 待办
- **技术债清单** → todos/tech-debt.md
- **MyBatis-Plus 迁移** → todos/migration-mybatis-plus.md
在 CLAUDE.md / AGENTS.md 里加一句:「当任务涉及上述索引项时,主动 Read 对应文件再回答」——AI 就会照做。
OMC 已经内置了这套机制
如果你用的是 oh-my-claudecode(下文简称 OMC),它本身就提供了一组 Wiki 工具(wiki_ingest / wiki_query / wiki_read / wiki_list / wiki_lint),自动维护 index、按 tag 检索、定期 lint 失效页面,开箱即用。
关键认知
全局记忆 = 常驻内存(小而精) Wiki = 外挂硬盘(大而全,按需调)
成熟的 AI 工作流是两者搭配:用全局记忆定原则,用 Wiki 存细节。AI 既懂规矩,又能在需要时翻到正确那一页。
第三层:Skills —— 把反复用到的提示词固化下来
什么是 Skills
Skills 是 Claude Code 提供的一种可复用的工作流封装。可以这么理解:
- 全局记忆告诉 AI「我是谁」
- Skill 告诉 AI「这件事要怎么做」
一个 Skill 通常包含:
- 触发条件(关键词或显式调用
/skill-name) - 一段精心编写的提示词,定义流程、产出格式、检查清单
- 可选的脚本、模板、参考文档
简单来说:把「反复要给 AI 解释一遍的流程」固化下来,下次喊一句指令就能跑。
一个例子:Apifox Skill
背景痛点:
- 后端写完接口,要去 Apifox 录入文档
- 字段、参数、示例响应一个个手填,重复枯燥
- AI 直接写又容易瞎编字段类型、漏掉必填项
我写了一个 Skill 来解决:
- 输入:一段 Controller 代码 / DTO 类
- AI 自动解析出接口路径、请求方法、入参出参结构
- 按 Apifox 的 OpenAPI 规范生成可直接导入的 JSON
- 内置字段类型校验、必填项检查、示例数据生成规则
收益很直接:单个接口的录入时间从 5 分钟压到 30 秒,字段类型、required、描述一次到位,几乎不用回炉。团队里任何人喊一句 /apifox 就能用,不用再问我「你那个咒语怎么写来着」。
过程不重要。重要的是这个心智模型:把每个「重复 3 次以上的提示词」,都升级为一个 Skill。
什么时候应该写 Skill
适合写:
- 同一个流程,写过 3 次以上提示词
- 流程有明确的输入/输出,能写出 checklist
- 团队里别人也会用到
不适合写:
- 一次性需求(不要过度工程化)
第四层:写代码前的「收束工作流」
这是最想讲的一段,也是我用 AI 一年多最大的体感。
AI 的「原罪」是发散
LLM 的本质是概率续写。当你给它一个模糊的任务,它会基于训练数据里「最常见的写法」来生成代码。这意味着:
- 你让它修一个 bug,它顺手给你重构了三个文件
- 你让它加一个字段,它顺便改了校验逻辑、加了缓存、写了 README
- 你让它优化一个函数,它「贴心」地引入了一个新的工具库
所有这些「贴心」,本质上都是思维发散——它在用大概率的「通用最佳实践」,污染你具体场景下的最优解。
我们做的所有努力,都是为了「收束」
回头看前三层在干嘛:
| 手段 | 收束的是什么 |
|---|---|
| 全局记忆文档 | 约束 AI 的风格、规范、底线 |
| LLM Wiki | 约束 AI 看到的信息范围(按需加载,不污染) |
| Skills | 约束 AI 在特定流程里的步骤和产出 |
| 写代码前的工作流 | 约束 AI 在具体任务里的思考边界 |
一句话总结:
写好提示词的本质,不是教 AI 做更多事,而是阻止 AI 做你没让它做的事。
一个可以落地的工作流:写代码前先跑两个阶段
为了让 AI 在执行任务时不发散,可以实现这样一个工作流——它在写代码之前运行,跑完之后才允许动键盘。
由两个阶段组成:
| 阶段 | 核心问题 | 关键动作 |
|---|---|---|
| ① 调研 Trace | 为什么会是这样? | 多假设 + 证据 + 反驳 |
| ② 定义 Interview | 那我们到底要做什么? | 苏格拉底提问 + 模糊度打分 |
| ③ 写代码 | —— | 前两步跑完才允许动键盘 |
阶段一:Trace —— 像侦探一样调研
面对一个模糊问题(比如「线上接口偶发超时」),AI 第一反应往往是「我去看看代码」——然后就开始改了。这是发散的起点。
收束的做法是强制 AI 走完一套侦探流程:
① 多假设并行(而不是一条道走到黑)
让 AI 一次性给出 3 个不同方向的可能解释,互相不能重叠。常用的三个分区:
- 代码路径假设:是不是某段实现写错了?
- 环境/配置假设:是不是部署、配置、资源限制造成的?
- 测量/假设错位:是不是我们以为的「现象」本身就是误判?
关键点:AI 必须先列假设让你确认,而不是自己挑一个就开始查。这一步把「AI 凭直觉判断」的环节交还给人。
② 每个假设都要找正反两方面证据
这是工作流最反直觉、也最有效的一步:
- 不允许只找支持当前假设的证据
- 必须同时主动找反对自己假设的证据
- 找不到反对证据?那就降低这个假设的置信度
证据要分级,从最可信到最不可信:
可复现实验 > 日志/Git 历史 > 代码静态推断 > 纯逻辑猜测
AI 最大的毛病就是把「逻辑猜测」包装成「我看到了」。逼它分级,谎就站不住。
③ 找出每个假设的「关键未知」
每个假设走完后,问 AI 一个问题:「还差哪一个事实,能让这个假设被确认或推翻?」
这个事实就叫 critical unknown。它是阶段二的提问素材,也是判断「该继续查还是动手」的标尺。
④ 一轮反驳
把当前置信度最高的假设,和置信度第二的假设拉出来对线:
- 「如果假设 1 是对的,假设 2 的证据怎么解释?」
- 「假设 2 的反对证据,是否同时也削弱了假设 1?」
只有撑过反驳的假设,才有资格被采纳。
⑤ 收敛检测
如果两个看起来不同的假设,最后都指向同一个根因(比如「代码 bug」和「配置问题」其实都是因为同一个并发竞态),显式合并它们,不要假装还有三条线。
跑完阶段一,你会拿到一份这样的调研报告,而不是 800 行的 diff:
最可能的解释:
数据库连接池被打满(高置信,证据:监控曲线 + Tomcat 线程堆栈)
次要候选:
下游 RPC 超时传染(中置信,缺少链路追踪数据)
关键未知:
连接池上限是按业务峰值还是默认值配置的?
建议下一步实验:
把连接池上限调到 2 倍,观察 24 小时
到这里,AI 一行业务代码都还没改。
阶段二:Interview —— 苏格拉底式提问
调研只回答了「WHY」。要不要修、修到什么程度、什么算修完——这是阶段二的事。
把 AI 切换到「提问者」的角色,规则是:
① 一次只问一个问题
不允许 AI 一次抛 5 个问题给你选。一次一个,问完等回答,再问下一个。
② 每轮给当前需求打一个「模糊度分数」
按维度拆开打分:
- 目标(Goal):要达到的状态清楚吗?
- 约束(Constraints):什么不能动?时间/资源边界?
- 验收标准(Acceptance Criteria):怎么算「做完了」?
每轮结束 AI 都要明确告诉你:现在最模糊的是哪一维,下一个问题就主动针对最弱的那一维提问——而不是问那些它自己已经知道答案的「凑数题」。
③ 模糊度不到阈值,禁止开工
设一个硬性门槛,例如模糊度 ≤ 20% 才允许进入写代码阶段。没到?继续问。
这个数字是关键。它把「差不多就开始吧」这种诱惑彻底封死。
④ 当 AI 自己开始飘,召唤「挑战角色」
跑到第 4 轮还没收敛?工作流自动召唤几个角色来挑战当前需求:
- 杠精(Contrarian):故意给出反向意见,看用户怎么回
- 简化派(Simplifier):质疑「是不是过度设计了」
- 概念派(Ontologist):检查关键名词每轮含义有没有偷偷漂移
这些角色专治 AI 和人之间「互相点头但其实理解错位」的尴尬。
最终产出一份 spec,至少包含:
目标: …(一句话)
非目标: …(明确不做什么——这条最重要)
约束: …(不能动哪些文件 / 不能引入哪些依赖)
验收标准: …(可验证的具体条件)
关键假设: …(前提一旦不成立要立刻停下)
两阶段之间的「注入」
阶段一的成果不能扔掉。它必须显式注入到阶段二的开场:
- 结论注入:阶段一的「最可能解释」,作为阶段二第一个问题的前提条件
- 背景注入:阶段一已经摸清的代码结构,直接给阶段二,省掉一次重复探索
- 问题队列注入:阶段一识别的「关键未知」,作为阶段二最先提问的 Top 3
没有这一步,两个阶段就是两个独立流程;有了它,调研真正变成需求定义的「前置弹药」。
这套工作流为什么能「收束」
把它和「直接让 AI 写代码」对比一下:
| 自由度 | 直接动手 | 走完两阶段工作流 |
|---|---|---|
| 假设是谁定的 | AI 凭直觉 | 你从 3 个候选里选 |
| 证据可信吗 | AI 说有就有 | 强制分级 + 反对证据 + 反驳轮 |
| 需求是谁写的 | AI 替你脑补 | 你被精准提问后亲口说出 |
| 何时开始写 | 立刻 | 模糊度 ≤ 阈值才允许 |
| 改动范围 | 「顺手」扩散 | spec 里的「非目标」明文挡住 |
当 AI 终于开始写代码时,它面对的是一份你亲自审核过的、几乎没有歧义空间的 spec——再想自由发挥,也找不到缝。
案例对比
反例(直接动手):
> 帮我看看这个登录接口有没有问题,能优化就优化下
AI 顺手改 JWT、加 Redis 缓存、重写参数校验、调整异常体系……800 行 diff,不知道从哪 review 起。
正例(先跑工作流):
阶段一跑完,AI 给出:
最可能问题:UserController.login 第 47 行字符串拼接(高置信,SQL 注入)
次要候选:缺少限流(中置信) / JWT 过期时间偏长(低置信,可能预期)
关键未知:JWT 过期时间是否符合业务安全策略?
阶段二从模糊度 60% 开始追问,三轮后冻结:
目标: 修复 login 接口的 SQL 注入风险
非目标: 限流、JWT 配置(识别但本次不处理)
约束: 只能改 UserController 和 UserMapper,不引入新依赖
验收: 恶意 phone 入参不再触发 SQLException,已有功能用例全绿
到这一刻,AI 才开始写代码——产出 5 行 PreparedStatement 修复,干净利落。
团队怎么落地
- 把这套工作流封装成 Skill——一句话触发,一线不用每次自己组织
- 把「高频翻车场景」写进全局记忆——例如「禁止主动重构」「禁止主动加依赖」
- 把模糊度阈值写死——不要让一线「为了快」自行降标准
- Code Review 时关注 diff 的「意外项」——不在 spec 里的改动一律打回
- 形成口头禅:写提示词前多问自己一句——「我这句话,会不会让 AI 顺手干点别的?」
我的日常工作流:OMC 四件套
前面四段讲的是心法——记忆、Wiki、Skills、收束。这一段讲手法:每天真正在键盘上敲的命令是哪几个。
我用的插件是 oh-my-claudecode,一套构建在 Claude Code 之上的多智能体编排层,把第二章的 Wiki、第三章的 Skills、第四章的收束工作流全部预制好了,开箱即用。我目前的日常开发,几乎都是围绕它的四个命令在转:
| 场景 | 命令 | 一句话定位 |
|---|---|---|
| 开发整个新模块(重活) | /deep-dive | 先调研 → 再问需求 → 模糊度合格才生成计划 |
| 日常零碎修改(小活) | /autopilot | 一句话描述需求,全自动跑完到工作代码 |
| 找 bug / 理解逻辑 | /trace | 把错误日志直接糊上来,多假设并行追因 |
| 提交代码前自检 | /simplify | code-review:空指针、重复代码、可复用点 |
下面分别讲一下。
/deep-dive —— 新模块的「启动仪式」
适用场景:一个完整模块/新功能的从 0 到 1(比如「做一套机票退改签的状态机」)。
为什么不直接 /autopilot?因为新模块的需求模糊度通常很高,AI 越自动跑得越远。/deep-dive 强制走第四章那个两阶段流程:
/deep-dive 退改签状态机
│
▼
阶段一:Trace(调研)
- 现有订单状态怎么管的?
- 哪些地方依赖订单状态?改了会炸什么?
- 三个并行假设:现有架构能复用 / 需重构 / 需独立服务
│
▼
阶段二:Deep Interview(苏格拉底提问)
- 一次只问一个问题
- 每轮给当前需求打一个「模糊度分数」
- 模糊度 < 阈值(默认 20%)才允许生成计划 ← 关键
│
▼
生成 spec → 交接给 /autopilot 执行
这就是「模糊度评分」机制。它不是花架子,是一个硬门槛——AI 自己判断「现在还有多少没问清楚」,没到阈值就绝对不让自己开工。
我的实际感受:用 /deep-dive 做的功能,PR 出来基本没有「AI 顺手干了一堆没让它干的事」。因为它亲口逼我把「非目标」说清楚了。
/autopilot —— 日常零碎修改的「主力」
适用场景:已经清楚要改哪个文件、要做什么的小活。例如:
- 给某个接口加一个字段
- 改一个枚举值
- 把某段重复代码抽成方法
用法极简:
/autopilot 给 OrderController.cancel 加一个 reason 入参,必填,透传到 Service 和 DAO
它会自动跑完:分析需求 → 写代码 → 跑测试 → 多视角 review → 收尾。
经验:
- 描述里带上文件名/方法名,效果显著好于「加个取消原因字段」
- 如果需求一句话讲不清楚,说明这个活该用
/deep-dive,不要硬塞给/autopilot
/trace —— 排查 bug 的「侦探」
适用场景:
- 线上日志里报了个错,不知道根因
- 想搞懂一段陌生代码到底在干嘛
- 性能问题、偶发问题、玄学问题
最舒服的用法:把错误日志直接粘进去就行。
/trace
[ERROR] 2026-04-29 14:23:11 NullPointerException at FlightOrderService.calcRefund:127
at ...
at ...
它会按第四章的「侦探流程」自动跑:
- 多假设并行(一次给 3 个不同方向的可能根因)
- 每个假设都找正反两方面证据,按可信度分级
- 找出关键未知——还差哪个事实就能定案
- 反驳轮:把 Top1 和 Top2 对线,撑过反驳的才被采纳
关键:它不会直接动手改代码,而是给你一份调研报告。你看完报告再决定要不要进 /autopilot 或 /deep-dive 修。
这条命令我用得最多。遇事不决先 /trace——比起让 AI 凭直觉乱改,先弄清楚「到底是怎么回事」性价比高得多。
/simplify —— 提交代码前的「最后一道闸」
适用场景:写完代码、提交之前,必跑一遍。
它做的事情其实就是自动 code-review:
- 空指针检查:可能 NPE 的地方有没有判空 / Optional / 默认值
- 重复代码检查:本次新增的代码,项目里有没有现成的工具类/方法可以复用
- 质量与简化建议:能不能写得更短、更清楚、更一致
- 发现问题直接修(不只是报告)
为什么必须有这一步?第四章讲了那么多收束手段,但 AI 写代码时偶尔还是会:
- 自己造轮子(项目里有
StringUtils.isBlank它非要if (s == null || s.isEmpty())) - 漏掉边界(链式
.get().getXxx()没判空) - 写得啰嗦(5 行能搞定的写 15 行)
/simplify 就是兜底网。它把「AI 自己写的代码」再过一遍 AI,专门挑这些毛病。
我的硬性纪律:未经 /simplify 的 diff,不准 commit。
四件套之间的关系
把上面四个串起来,就是我每天的标准流程:
按场景选入口(三选一):
- 新模块 →
/deep-dive - 小修改 → 直接进
- 出 bug →
/trace(先拿调研报告,再决定是否进入修复)
之后都汇入同一条主线:
→ /autopilot → /simplify → commit
四个命令各司其职:
/deep-dive管「要做什么」(需求收束)/autopilot管「怎么做出来」(执行)/trace管「为什么会这样」(追因)/simplify管「做得到底好不好」(质检)
关键认知
不要把 AI 当成「一个全能助手」,要把它当成「一支分工明确的小队」。
第三层我们说每个反复 3 次以上的提示词都该升级为 Skill。OMC 已经把「开发一个完整功能」这件事拆成了调研 / 设计 / 执行 / 追因 / 质检五个角色,每个角色都有自己的提示词、流程和检查清单。
我们要做的,是学会调度它们——而不是每次都从零跟 AI「商量该干啥」。
写在最后
我们对知识的要求,正在从深度转向广度。
AI 只能写出它认知范围内的代码——而它的认知范围,就是你的提问范围。你懂得越广,它能帮你的就越多。
也许未来,我们不再是写代码的人,而是决策者:判断代码对不对、架构合不合理、边界画在哪里。