1. 从“能跑就行”到“意图驱动”AIcoding 落地内部项目的真实起点去年下半年开始团队里几乎每个人都在聊 AIcoding。一开始大家的兴奋点很朴素——让模型帮忙补全几行代码、写个正则、生成一段样板逻辑确实能省不少时间。但真正把 AIcoding 往内部项目里推的时候问题很快就暴露了模型生成的代码风格飘忽、边界条件经常漏、改完一处又崩另一处最要命的是你很难跟它讲清楚“这个模块到底要干什么”。后来我们才意识到AIcoding 落地的瓶颈从来不是模型够不够聪明而是你有没有把“意图”讲明白。这篇文章我想聊的就是这件事在一个真实的内部项目改造里我们怎么用intent.md把需求意图固化下来又怎么用持续评测把 AIcoding 的输出质量管住。顺带会讲到它和CLAUDE.md、SDLC 之间的关系以及所谓 ai-native SDLC playbook 到底在说什么。如果你正在团队里推 AIcoding或者被“aicoding 笔试题怎么写”这类问题困扰过这篇应该能给你一些能直接抄作业的思路。先说清楚适用人群这篇文章不是给完全没碰过 AIcoding 的人看的入门科普也不是给只写 demo 玩票的人看的。它面向的是那些准备把 AIcoding 引入真实项目、需要可维护、可评测、可交接的工程同学和技术负责人。核心关键词就几个AIcoding、intent.md、持续评测、CLAUDE.md、SDLC。下面我会一层层拆开讲。2. 为什么是 intent.md把“口头需求”变成模型能读的契约2.1 传统 SDLC 在 AIcoding 场景下的失灵传统 SDLC 的链路是需求文档 → 设计文档 → 编码 → 测试 → 上线。这条链路默认了一个前提——执行者是人。人会读需求、会追问、会凭经验补全那些文档里没写清楚的隐含约束。但 AIcoding 的执行者是模型它不会追问它只会根据你给的上下文“猜”。你给的信息越模糊它猜得越离谱。我们内部项目改造初期就吃过这个亏。一个订单状态流转的模块需求文档里写的是“状态变更需要记录日志”。人看了会自然想到记录哪些字段、日志级别是什么、失败要不要回滚、并发下怎么保证顺序。模型不会想这些它给你生成一行log.info(status changed)就交差了。结果就是代码能跑但完全不能用。问题的根子在于需求文档是写给人看的而 AIcoding 需要的是写给模型看的“意图契约”。这就是intent.md出现的背景。2.2 intent.md 到底是什么和 CLAUDE.md 有什么区别很多人第一次听到intent.md会把它和CLAUDE.md搞混。我用一句话区分CLAUDE.md解决的是“怎么干活”——项目结构、编码规范、命令怎么跑、依赖怎么装它是给模型的操作手册。intent.md解决的是“要干成什么样”——这个模块的业务目标、边界条件、验收标准、不允许出现的行为它是给模型的意图契约。打个比方CLAUDE.md像是新员工入职时拿到的《办公指南》告诉你打印机在哪、报销怎么走intent.md像是这个季度的 OKR 拆解告诉你这个岗位到底要交付什么结果。两者缺一不可但职责完全不同。在实际项目里我们的目录结构大概是这样project/ ├── CLAUDE.md # 全局操作规范 ├── src/ │ ├── order/ │ │ ├── intent.md # 订单模块的意图契约 │ │ └── ... │ └── payment/ │ ├── intent.md # 支付模块的意图契约 │ └── ...intent.md放在模块目录下模型在处理这个模块时优先读取它。这样做的原因是意图是有作用域的。全局的操作规范可以共用但业务意图必须就近放置否则模型很容易把 A 模块的约束套到 B 模块上。2.3 一份能用的 intent.md 应该包含哪些字段我见过太多人把intent.md写成第二份需求文档洋洋洒洒几千字结果模型读完还是抓不住重点。经过几轮迭代我们沉淀出一个相对稳定的模板字段不多但每个都直击要害字段作用是否必填模块目标一句话说清这个模块存在的意义必填输入输出明确的入参、出参、数据结构必填边界条件空值、超限、并发、异常的处理约定必填禁止行为明确不允许模型做的事必填验收标准可执行的判定条件必填参考实现指向已有的相似代码选填这里我要重点说禁止行为这个字段。它是intent.md区别于普通需求文档的核心。模型有个通病你让它实现 A它顺手把 B 也“优化”了。比如你让它加个字段校验它可能顺手把整个方法重构成流式写法。禁止行为就是给模型划红线明确告诉它“只做这些别动其他”。一个真实的intent.md片段长这样## 模块目标 处理订单从创建到完成的全部状态流转保证状态机的一致性。 ## 边界条件 - 状态只能按 CREATED - PAID - SHIPPED - COMPLETED 单向流转 - 任何逆向流转必须抛出 IllegalStateException - 并发更新同一订单时使用乐观锁版本号不匹配则重试最多 3 次 ## 禁止行为 - 禁止修改 OrderStatus 枚举的已有取值 - 禁止在状态流转方法内直接操作数据库必须通过 Repository - 禁止吞掉异常所有异常必须向上抛出或记录 ERROR 日志 ## 验收标准 - 给定非法流转方法抛出 IllegalStateException - 给定并发场景最终状态一致且无脏写这份文件不到 40 行但模型读完之后的输出质量比给它一份 2000 字需求文档要稳定得多。原因很简单它把“意图”从“描述”变成了“约束”。描述是开放的约束是封闭的模型在封闭空间里发挥出错概率自然低。3. 持续评测让 AIcoding 的输出质量可量化、可回归3.1 为什么一次性评测不够用很多人做 AIcoding 评测的方式是改完一个模块跑一遍测试过了就完事。这在项目初期没问题但一旦项目进入持续迭代问题就来了——模型是会“漂移”的。同样的intent.md今天生成的代码和下周生成的代码可能完全不一样因为模型版本在更新、上下文在变化、甚至你intent.md里加了一句话都可能影响输出。我们内部就遇到过一次某个模块的intent.md只改了一个措辞从“记录关键日志”改成“记录必要日志”结果模型把日志级别从 ERROR 降到了 INFO导致线上排查问题时关键信息全丢了。如果只做一次性评测这种回归根本发现不了。所以持续评测的核心不是“测一次”而是“每次改动都测、每次模型调用都测、每次 intent 变更都测”。它本质上是一套回归机制。3.2 评测集怎么建从真实 bug 里长出来评测集不是拍脑袋想出来的最好的来源是真实发生过的 bug。我们的做法是每修复一个 AIcoding 引入的缺陷就把它抽象成一个评测用例沉淀进评测集。这样评测集会随着项目推进越来越厚覆盖的坑也越来越全。一个评测用例的结构大概是{ id: order-state-003, intent_ref: src/order/intent.md, input: 订单状态为 COMPLETED请求再次流转到 PAID, expected: 抛出 IllegalStateException且不产生任何数据库写入, tags: [边界条件, 状态机, 并发] }注意expected字段的写法——它必须是可判定的。“正确处理”这种描述是没用的必须是“抛出 X 异常”“返回 Y 值”“不产生 Z 副作用”这种机器能验证的表述。3.3 评测的执行时机与自动化接入持续评测要真正落地必须挂到自动化流程里否则没人会手动跑。我们把它接在了三个节点上提交前开发者本地跑一遍轻量评测集只覆盖改动模块相关的用例几十秒出结果。CI 阶段全量评测集跑一遍任何用例失败直接阻断合并。模型调用后每次 AIcoding 生成代码后自动触发对应模块的评测结果附在 PR 描述里。这里有个经验评测集要分层。轻量层跑得快用于本地快速反馈全量层跑得慢但覆盖全用于 CI 把关。如果只有一层要么太慢没人跑要么太快覆盖不够。3.4 评测结果怎么读别只看通过率新手最容易犯的错是只看通过率。通过率 95% 听起来不错但如果失败的 5% 全是核心路径那这个版本根本不能上。我们看评测结果时会分三个维度通过率整体健康度。失败用例的分布是集中在某个模块还是散落各处集中说明该模块的 intent 有问题散落说明模型整体不稳定。与上一版的对比哪些用例从通过变失败这些是回归必须优先处理。提示评测结果一定要和具体的intent.md版本绑定。否则你根本不知道是代码变了还是意图变了导致的结果波动。4. 实操全流程一次真实的模块改造记录4.1 改造前的准备梳理现状与划定范围我们选的改造对象是一个内部使用的库存扣减模块。选它的原因很典型逻辑不算复杂但边界条件多历史代码里藏着不少“祖传逻辑”正好用来验证 AIcoding 在真实场景下的表现。改造前第一步是划定范围。我们没有一上来就全量重构而是先圈定三个核心方法deduct、rollback、query。范围划小的好处是intent.md能写得更聚焦评测集也更容易建。第二步是梳理现状。把这三个方法现有的行为、被谁调用、有哪些隐含约定全部列出来。这一步很关键因为很多“意图”是藏在代码里的不梳理出来就写不进intent.md。比如我们发现deduct在库存不足时返回的是-1而不是抛异常这个约定文档里从来没写过但调用方全都依赖它。4.2 编写 intent.md从模糊到精确的三轮迭代第一轮我们写得很粗基本就是把需求复述一遍。结果模型生成的代码虽然能跑但边界处理一塌糊涂。第二轮我们加入了边界条件和禁止行为输出质量明显提升但还是有遗漏。第三轮我们引入了验收标准把每个边界条件都翻译成可判定的表述这才稳定下来。三轮迭代下来我最大的体会是写 intent.md 的过程其实是在逼你把需求想清楚。很多你以为自己清楚的地方一落笔就发现根本说不明白。说不明白的地方模型一定做不对。4.3 用 AIcoding 生成代码提示词与上下文组织有了intent.md提示词反而可以写得很简单。我们的模板是请阅读 src/inventory/intent.md 和 CLAUDE.md 实现 deduct 方法满足 intent.md 中的所有约束。 只输出方法实现不要修改其他文件。关键点有三个明确指向 intent 文件、限定输出范围、强调约束优先。不要试图在提示词里重复 intent 的内容那样只会造成信息冲突。上下文组织上我们只喂三类文件intent.md、CLAUDE.md、以及被改造方法的现有代码。不要喂整个项目模型会被无关信息干扰。4.4 评测与回归一次真实的失败排查改造过程中有一次典型的失败。评测集里有个用例是“并发扣减同一商品库存不能为负”。模型生成的代码用了synchronized单机测试全过但我们的评测环境是多实例的结果直接失败。排查过程是这样的先看评测输出发现失败用例集中在并发标签下再看生成的代码发现用了 JVM 级别的锁最后对照intent.md发现我们只写了“并发安全”没写“分布式场景下并发安全”。问题定位到 intent 的表述不够精确。修复方式很简单把intent.md里的“并发安全”改成“多实例部署下的并发安全禁止使用 JVM 级别锁”。改完之后重新生成模型用了数据库乐观锁评测全过。这个案例后来被我们当成典型写进了团队的 AIcoding 规范里。5. 常见问题与避坑清单5.1 intent.md 写多长合适这是被问得最多的问题。我的答案是能短则短但边界条件一个都不能少。我们内部的经验值是 30 到 80 行。低于 30 行通常约束不够高于 80 行模型容易抓不住重点。如果确实内容多就拆成多个模块的 intent而不是堆在一个文件里。5.2 模型总是不遵守禁止行为怎么办先检查禁止行为的表述是不是可判定的。“不要过度设计”这种表述模型根本没法执行。改成“禁止新增除 X、Y 之外的任何类”就有效得多。另外禁止行为最好放在 intent 文件靠前的位置模型对开头内容的注意力更高。5.3 评测集维护成本太高怎么破两个思路一是自动化生成从历史 bug 和代码变更里自动抽取候选用例人工确认后入库二是分层维护核心用例长期保留边缘用例定期清理。不要追求评测集只增不减那样迟早跑不动。5.4 常见问题速查表问题现象可能原因排查方向生成代码风格飘忽CLAUDE.md 缺失或过时检查全局规范是否覆盖当前技术栈边界条件频繁遗漏intent.md 边界字段不完整对照历史 bug 补充边界用例评测通过但线上出问题评测集覆盖不足把线上问题抽象成新用例模型改动范围过大禁止行为未明确补充“只做 X禁止 Y”类约束同一 intent 输出不稳定模型版本或上下文变化绑定 intent 版本固定上下文范围5.5 几个我踩过的坑第一个坑是把 intent.md 当成一次性文档。写完就不管了结果代码在演进intent 还停在原地模型读到的意图和实际需求早就脱节了。后来我们规定任何需求变更必须先改 intent.md再改代码。第二个坑是评测集和 intent 脱钩。评测用例没有标注它对应哪个 intent 版本导致 intent 改了之后不知道哪些用例需要同步更新。现在每个用例都强制带intent_ref字段。第三个坑是过度依赖模型自评。我们一度让模型自己判断“是否满足 intent”结果它永远说满足。评测必须用外部可执行的判定不能靠模型自说自话。6. 从 intent.md 到 ai-native SDLC这套方法能走多远聊到这里其实已经能看出这套方法和传统 SDLC 的区别了。传统 SDLC 的核心资产是需求文档和设计文档而 ai-native SDLC 的核心资产变成了intent.md和评测集。前者定义“要什么”后者验证“做到了没”。代码反而成了中间产物可以随时由模型重新生成。所谓 ai-native SDLC playbook说的其实就是这套东西意图先行、评测驱动、代码可再生成。它不是把 AI 塞进旧流程里而是围绕 AI 的能力重新设计流程。CLAUDE.md管操作规范intent.md管业务意图评测集管质量回归三者配合起来才算是真正把 AIcoding 落到了工程上。我们内部现在推新模块的标准动作是先写intent.md再建评测集最后才让模型生成代码。顺序反过来返工率会高得离谱。这个顺序上的调整看起来只是流程变化实际上是整个研发心智的转变——从“写代码”变成“定义意图和验证意图”。至于“aicoding 笔试题怎么写”这类问题我的建议是别把它当成八股来背。真正理解 intent 和评测的关系笔试题里那些场景题自然就有思路了。面试官想看的不是你会不会用某个工具而是你有没有把 AIcoding 当成一件需要工程化对待的事。最后分享一个我们内部一直在用的小技巧每次模型生成的代码合并前让作者在 PR 里贴一句话——“这次改动对应 intent.md 的哪几条约束”。贴不出来说明要么 intent 没写清楚要么这次改动根本不该由模型来做。这一句话的约束力比任何规范文档都管用。