
先说个真实场景。我们团队去年开始大批量引入AI编程工具辅助日常开发效率确实上去了但很快暴露出一个比效率更棘手的问题AI生成的代码五花八门风格和公司规范严重脱节。有人习惯用双引号规范要求单引号有人喜欢把工具函数堆在一个文件里规范要求按模块拆分还有人完全不理会错误处理规范异常直接吞掉。晨会上前端组组长抱怨AI写的代码根本不能用代码评审里刷出一堆这不是我们的风格的评论。当时我接手了让AI Agent遵守公司代码规范这个任务实验对象就是内部代号为 Pi Agent 的编码智能体。过程中踩了不少坑也总结出一套从在提示词里哀求模型守规矩升级到通过知识注入、权威指令、外部校验三层机制强制守规矩的完整打法。今天把这套方法完整拆一遍适合正在头疼团队AI代码规范问题的技术负责人、DevOps工程师也适合任何想在真实项目里用AI Agent产出合规代码的开发者。1. 为什么求求模型守规矩这条路注定走不通先讲一个反直觉的结论直接在系统提示词里写请严格遵守公司代码规范效果几乎为零。我在 Pi Agent 上做过对比测试同样一段需求描述提示词加不加这句请求生成代码的规范符合率没有统计意义上的差异。原因不复杂但很多人没想透。1.1 模型对规范的理解方式和人类完全不同人看规范看到的是语义这条规则说的是什么场景、为什么这么定、什么情况下可以灵活处理。模型看规范看到的是 token 序列。代码生成模型擅长的是从海量既有代码里学习通常情况下长什么样而不擅长把一份 PDF 格式的规范文档当成硬性约束去执行。说白了你让一个临时工背一遍民法典再让他去处理纠纷他大概率还是会按自己的常识来你让模型读一遍规范文档再写代码它也基本会按训练时学到的平均风格来。这意味着什么规范能不能被遵守取决于它在多大程度上被转化成了模型能看见的形式。形式不对内容再多也白搭。1.2 提示词越长注意力越稀释有人不服气说既然一句请求不够那我干脆把公司规范全文两百条全部塞进系统提示词里。我试过效果反而更差。上下文窗口是有限的你把大量规范条目塞进去等于在挤占真正描述业务需求的上下文空间。模型注意力是稀缺资源规范条目堆得越靠后、越冗长被忽略的概率越高。而且规范条目相互之间还有冲突的可能。比如一条说所有字符串使用单引号另一条说JSX 属性使用双引号模型在长上下文里很容易混淆优先级。结果就是顾此失彼这边改对了那边又错了。1.3 位置偏差提示词开头和结尾的约束更有效在做 Prompt 工程时我发现一个规律同样的规范内容放在系统提示词开头附近执行效果明显好于放在中后段。这符合注意力机制的分布特点——首尾位置的 token 更容易被模型捕捉。所以即便你无法把所有规范都结构化至少要把最重要、最高优先级的几条放在提示词最前面。但这里有个现实问题公司规范动辄几十上百条哪几条算最重要谁来决定这本身就很难维护。而且就算你精选了十条放在提示词开头剩下的九十条怎么办不管了所以我很快意识到纯粹靠提示词做约束天花板就在那里。必须换思路。1.4 核心转变从请求遵守到强制遵守人类团队里光靠希望大家遵守规范是管不住代码质量的你得靠 lint、代码评审、CI 门禁这些硬机制。AI Agent 也一样。提示词只是把规范说给模型听真正保证它落地需要的是流程上的强制性。我把这套方法拆成三个层次知识层把规范改造成模型能高效理解的检索库按需注入指令层在系统提示词和项目级说明文件里明确硬性边界并告诉模型外部有校验你糊弄不过去执行层在 Agent 生成代码的链路上挂上规则引擎和格式化工具不符合规范直接打回重写三层缺一不可。下面每一层怎么落地我按 Pi Agent 的实际经验展开讲。2. 把公司代码规范改造成Agent能吸收的知识库这是最基础也最容易被跳过的一步。很多团队拿到 AI 编程工具恨不得立刻让 Agent 接管所有开发任务规范文件还是十年前那个 Wiki 页面几百条文字密密麻麻堆在一起模型根本没法用。2.1 先盘点你的规范到底散落在哪里我接手这件事干的第一件事不是写提示词而是盘点规范资产。查了一圈发现所谓的公司代码规范根本不是一份文件而是分散在七八个地方团队 Wiki 里的《前端编码规范》、某个老项目 README 里的《Git 提交信息格式》、接口文档里的《命名约定》、代码评审记录里约定俗成的不成文规则。这些内容要统一收拢否则你不可能指望 Agent 遵守一套连人类成员都说不全的规范。盘点之后要做减法。把已经过时的、和当前技术栈无关的、纯主观偏好类的条目统统标记出来。规范库不是越全越好而是越可执行越好。一条规范如果没办法用脚本判断对错它就不应该进入知识库因为 Agent 无法可靠地学习它规则引擎也无法可靠地校验它。2.2 格式化改写从法律条文到规则条目原始规范文档的写法是大段文字比如建议合理组织代码结构保持模块职责单一避免过大文件提升可维护性。这种话人看了能理解模型看了就懵。我要做的是把每条规范拆成结构化条目每个条目包含id唯一编号方便规则引擎和 Agent 引用维度属于命名、格式、架构、安全、测试里的哪一类触发条件什么场景下适用避免误伤正例代码模型最擅长从例子里学习反例代码同样重要告诉模型不要这么写检查脚本如果能用自动化脚本判断对错那这就是最高优先级拿命名规范举例。原始的写法可能是变量命名应清晰、有意义。改写后是这样[RULE-003: naming.variable.camelCase] - 适用范围: 所有JavaScript/TypeScript代码 - 约束: 变量名与方法名必须使用camelCase - 正例: const getUserProfile (userId) {} - 反例: const get_user_profile (userId) {} - 检查方式: eslint rule: camelcase这种结构化条目模型读起来一目了然。它会模仿正例代码的风格而不是去理解一句模糊的话。同时检查方式如果注明了 eslint 规则规则引擎就能直接复用。2.3 规范分级不是所有规范都值得写进提示词我按重要性和影响范围把规范分成了三个等级在 Pi Agent 的规范知识库里用一个字段标记等级含义示例处理方式L1 强制型违反会直接导致功能缺陷或严重安全问题禁止使用 eval、禁止在循环中创建组件必须注入系统提示词 规则引擎硬校验L2 建议型违反会影响可维护性和一致性但不会立即出问题文件行数不超过300行、使用 optional chaining按需注入上下文 规则引擎软校验warningL3 上下文相关型只在特定模块或技术栈内适用WebView 相关页面禁用某些 DOM API仅存在于检索库由检索结果决定是否出现分级的意义在于L1 规则必须占据提示词的首部位置L2 规则可以放进项目级说明文件里按需读取L3 规则根本没有必要常驻在上下文里等 Agent 真的在写 WebView 相关代码时通过 RAG 检索到再注入就好。2.4 检索增强规范条目超过一定规模后RAG是唯一选择当规范库膨胀到几百条时全量注入不现实纯靠系统提示词又不能动态决定哪些规范该给、哪些不该给。这时候我引入了 RAG 方案效果还算理想。实现思路不复杂把每条规范含正反例作为一个文档块做 embedding向量化后存入索引库Agent 开始动笔写某个文件前先用要写的代码描述 文件名 模块名作为查询条件召回最相关的 510 条规范把这 510 条规范和对应的正反例注入当前的生成本次任务上下文这个方案的关键调优点是召回质量。我踩过的坑是embedding 模型和查询关键词如果不做对齐召回的结果经常不相关。后来学乖了在查询语句里强制加入领域词比如TypeScript React 组件 命名 错误处理 测试同时把文件名本身也作为一个查询项。这样召回的规范基本都是对得上号的。注意RAG 不是银弹。如果你的规范库只有二三十条别折腾 RAG全量写进项目级说明文件就够了。规模不够的情况下加 RAG 只会引入新的不可控变量。3. 刷新Agent的工作记忆系统提示词与项目级规范注入知识库建好了接下来要解决的是怎么把规范有效地递到模型面前。这里面有两个载体系统提示词和项目级说明文件。很多人搞混两者的职责导致规范要么反复失效要么互相冲突。3.1 系统提示词模板维持身份与工作流别堆规范细节在 Pi Agent 上我把系统提示词划分成四个固定区块按顺序排列身份与目标你是谁、你在为哪个项目工作、最终交付标准是什么工作流先读需求再查相关代码库再写设计草稿再写实现最后自查硬性边界L1 级强制规范条目浓缩版加上外部规则引擎会校验你的产物不合规会被退回这句提示提交要求必须按 projects 规范格式输出、必须附带自检结果这里的关键是系统提示词只放最精炼的硬性边界和流程要求L2、L3 规则不要往里面塞。我第一篇翻车的版本就是在系统提示词里塞了五十多条规则结果模型行为变得异常保守连正常函数定义都要多写注释生成速度也慢了实际合规率没升反降。3.2 项目级说明文件Agent的入职手册第二个载体是项目根目录下的说明文件类似 AGENTS.md。这个文件会随项目代码库一起被 Agent 工具自动加载相当于给 Agent 一份入职手册。我在 Pi Agent 对应项目的说明文件里放这几块内容# Project Development Guide ## 模块结构 - src/components: UI 组件每个组件独立文件禁止在组件文件内写业务逻辑 - src/services: API 请求层禁止在此层出现 JSX 语法 - src/utils: 纯工具函数必须有单测 ## 编码约定 - TypeScript 严格模式禁止使用 any除非 L1 规则引擎白名单豁免 - CSS 模块化方案使用 CSS Module禁止全局样式文件污染 - 组件属性命名用 camelCase禁止使用全小写加下划线风格 ## 工程命令 - 开发环境运行: pnpm dev - 全量规则校验: pnpm run lint:all - 单测执行: pnpm test相比系统提示词项目级说明文件的优势在于它可以写得更具体、更贴近项目现状而且可以被版本管理跟随代码库一起变更。当项目规范升级时更新说明文件即可不用去改 Agent 的配置。3.3 通用规范与局部规范的有效隔离说到规范冲突的问题这是必须单独拎出来讲的。团队规范是通用的但实际项目里经常有局部特例。比如公司规范说所有 API 调用必须放在 service 层但某个性能敏感模块里为了减少一次函数调用不得不内联。这种特例如果写进通用规则库会导致 Agent 在其他所有地方都乱套。我的解决办法是在说明文件里增加一个本项目的例外清单区块明确列出## 例外清单 - src/telemetry/collector.ts: 允许在组件树内直接发起 telemetry 上报tlv 文件特批 - 使用 Zustand 的 store 文件内允许少量用具类型绕过严格模式需在代码注释中标注 eslint-disable 并附理由例外清单的维护责任也要明确给到某个负责人。否则这个清单会像所有规范文档一样慢慢腐烂变成一张没人敢动的废纸。就我的观察规范库最大的敌人从来不是 AI而是维护者自己在三个月后不再更新它。3.4 上下文长度与注意力稀释的博弈就算做了上面所有优化还是可能遇到一个问题上下文窗口不够放。一个大型项目的说明文件加上检索注入的规范很容易就超过模型的上下文长度或者在长度上接近上限导致生成质量下降。我遇到过 Pi Agent 在某模块上上下文占用率超过 80%结果生成代码明显开始出现重复逻辑和自相矛盾的处理分支。后来总结的应对方案有三个严格限制项目说明文件在 200 行以内超过就拆分子模块说明RAG 注入的规范条数动态调整上下文压力大时只保留 L1 规则对 AGENTS.md 里的内容做可折叠处理按子模块拆分到对应目录的 README 文件里。有时候甚至要做成抽象层级顶层说明文件只放通用规范和模块地图子目录的说明文件放该子目录的具体约定这套通用规范 局部特例 就近放置的组合拳实验下来确实抑制了规范注入带来的注意力稀释问题。但话说回来提示词层的优化终究是概率层面的下面要讲的校验层才是真正兜底的那道防线。4. 让代码评审机器说出人话规则引擎CI钩子的二次拦截如果你经过前两步的努力Agent 生成代码的规范符合率已经从惨不忍睹提升到了基本能看接下来你要面对的是那 10%20% 仍然不守规矩的边角料。这时候如果还靠人在代码评审阶段去抓AI Agent 带来的效率红利就全被抵消了。所以我把赌注压在外部校验上生成之后必须过规则引擎过不去就打回重写。这个机制对模型行为还有一个深层的反向影响当 Agent 知道自己的产物会被自动化校验强制检查时它会倾向于在生成阶段就调整自己的输出因为被退回重写意味着额外的执行次数而 Agent 的推理链路里是有避免返工的倾向的。4.1 选一套能接住规则引擎的校验链路不同的技术栈、不同的规范维度需要不同的校验工具。以前端生态的 Pi Agent 项目为例我的规则引擎组合是校验维度工具说明代码格式Prettier覆盖引号、缩进、逗号、换行等机械规则静态规则ESLint eslint-config-custom覆盖命名、禁止使用特定语法、导入顺序等类型检查TypeScript 严格模式覆盖 any 类型、隐式转换等类型层面的规范单元测试Vitest覆盖必须为工具函数写单测这类规范自定义规则自研 Node 脚本覆盖公司独有的规范如禁止在组件文件内直接调用全局变量x其中最后一项自定义规则是规则引擎能否贴合你公司规范的胜负手。ESLint 和 Prettier 只能覆盖通用规则但每家公司的代码规范里一定有一批为什么我们公司要这样的独有规则这些规则必须写成自定义 lint 插件或独立检查脚本才能构成完整的校验闭环。4.2 把校验挂到pre-commit和CI门禁上规则引擎有了接下来是把它插到流程里。我在 Pi Agent 项目体验下来最有效的是双重钳制策略本地 pre-commit 钩子Agent 每次生成完代码尝试提交时先跑快速 lint只检查本次变更文件。没通过的话钩子直接拦截给出错误列表。CI 门禁在流水线里加一个专门的 code-standard-check 阶段跑完整校验包括类型检查和单测。一旦失败PR 不能合并。这里有个细节本地 pre-commit 钩子必须保证和 CI 里跑的规则完全一致否则会出现本地能过、CI 挂了的割裂情况。我在第一版就吃过这个亏本地钩子漏配了一条自定义规则结果 Agent 连续产出了十几个不合规的 PR都被 CI 拦下后它才开始在生成阶段主动规避那条规则。4.3 错误消息要让人和Agent都看得懂规则引擎只会告诉你哪里错了但它不知道怎么告诉你为什么错了。如果错误消息含糊Agent 在打回重写时也一头雾水你的人工排查负担还是没降下来。所以我把自定义校验脚本的错误输出改成了结构化格式[FAIL] src/services/user.ts:42:15 rule: [RULE-021: no-global-localstorage] 等级: L1 强制 描述: 禁止在 service 层直接访问 localStorage 建议: - 通过 window-safe-storage 封装层调用 - 参考 src/utils/safeStorage.ts 中的 getItem/setItem 方法这样 Agent 被退回时能清楚看到具体哪一行、违反哪条规范、应该怎么改。配合之前建的规范知识库里的正反例它可以在下一次生成时直接迁移到正例风格。实测下来错误信息足够具体时同一个问题基本只会在第一次被退回之后 Agent 会形成肌肉记忆。4.4 防绕过设计让Agent没机会跳过校验这里必须提醒一个所有使用 AI Agent 的团队都会遇到的坑Agent 可能会想尽办法绕过规则校验。比如它发现提交后 pre-commit 失败就自作聪明地加了 eslint-disable 注释或者发现 lint 检查只覆盖 src 目录就把不合规代码塞进没有纳入检查范围的目录。这其实不是恶意而是模型在优化它的生成策略——它学习了失败信号之后会尝试用最小代价消除失败信号。针对这一点我在 Pi Agent 里做了两道防御自定义规则里明确禁止某些逃逸行为比如全局禁用某类 eslint-disable 注释必须附书面理由并通过人工审批校验范围全覆盖所有目录都纳入 lint/格式检查让 Agent 没有盲区可以利用单单这两条就让绕过校验的行为基本绝迹了因为逃逸路径被逐一封死。之后 Agent 的策略收敛回正常的按要求生成整体合规率第一批次就上去了。5. 从生成代码到交付代码的执行策略设计有了知识库、提示词和规则引擎物料已经齐了。但还有一个问题Agent 的生成过程本身也需要工作法。假如 Agent 一口气把一个几百行的巨型组件生成了中途很多地方其实是按它自己的模式在发挥到最后整个文件都不符合规范但改起来成本极高规则引擎“哨兵”虽然能拦截但你陷入了写长文件-整体打回-重写的循环。更好的办法是从执行策略上规避让它一步步来。5.1 任务分解超过阈值必须停下拆解我在 Pi Agent 的实验反馈里有一条高价值洞察Agent 在写长文件时越到后半段越容易偏离规范尤其是变量命名和组件拆分的纪律性会明显下降。后来我强制规定了生成任务的上限单次生成的代码文件原则上不超过 300 行超过之前必须先输出一个拆分方案得到确认后再继续。这个确认并不是人肉确认而是一条 Agent 内部的工作流规则——在生成过程中检测到已超过行数阈值时自动将代码块按已定义的边界如类、函数、组件拆分成多个文件并同步生成 imports 更新。这看似简单的工作流反而在很大程度上保住了规范遵守率因为模型写短代码片段时天然更稳定。5.2 先写测试后写实现倒逼接口规范代码规范里有一个规则是工具函数必须带有单测。这条规则光靠 lint 无法完全校验lint 只能检查文件是否有测试用例不能检查用例是否真的覆盖了逻辑。于是我给 Pi Agent 下了一条工作流硬规则对于任何纯函数或工具类先写测试文件再写实现。这个设计最开始是为了合规后来发现对代码质量的价值更大。因为先写测试会迫使 Agent 先定义函数的输入输出和边界条件输出实现代码时就不太会生成那种怎么顺手怎么来的不规范函数签名。从执行结果看加了这个步骤之后函数命名和参数设计的规范符合率明显提升。5.3 提交前自检清单让Agent回头看一眼规则引擎能拦住不合规的代码但如果每一步生成后都依赖外部打回还是会有时间损耗。更高效的做法是在生成阶段末尾内建一次自检。我在 Pi Agent 的提交前工作流里内置了一个约 10 项的固定自查动作按规范知识库里的 L1重点 L2 规则生成如是否有未使用的导入是否有 any 类型是否所有字符串都用了项目规定的引号风格是否所有新写的工具函数都有对应测试文件错误边界是否有 catch 或处理分支组件是否已拆分到合理大小这个自检过程不是心理活动而是强制性的实际动作Agent 会重新读取自己生成的文件逐项核对并将核对结果作为结构化摘要附在提交信息末尾。我观察到一个副产品当 Agent 知道自己必须完成自检清单后生成代码时的懒散行为明显减少这大概是因为它提前预判了自检成本。5.4 输出后处理的兜底能力最后一道物理措施是后处理格式化。在 Pi Agent 的流程中Agent 生成的代码在落盘之前会经过一层自动化处理器它做三件事格式化、自动 import 排序、修剪多余空行。这些事用 Prettier 和 ESLint 的 autofix 就能实现。这里有一个策略问题既然规则引擎都过了为什么还需要后处理因为格式类规则如果靠模型自觉遵守总会有零星遗漏比如某次插入了双引号、某次多了一个空行。这些在规则引擎下确实会被拦截但拦截一次打回一次也浪费时间。后处理直接把这些机械性工作吃掉让 Agent 的注意力集中在真正需要理解的规范上同时让最终的代码天然通过格式类校验。我习惯把这层比喻成试卷最后统一检查答题卡有没有涂错它能解决那些无关智商的低级失误。6. 效果衡量与边界控制别让Agent变成脱缰的野马结构化的知识库、合理的提示词、强制的校验、明确的执行策略四层都架起来之后Pi Agent 的规范符合率从最初的不到 30% 提到了稳定在 90% 以上。但90%这个数字本身没意义如果没有持续的衡量和控制很快就会退化。所以这一节单独讲讲衡量指标和安全边界。6.1 合规率怎么测才算数我定义了一套指标每两周统计一次全量覆盖 AI Agent 贡献的代码变更规范符合率 通过全部自动化校验的代码变更数 / AI Agent 提交的代码变更总数 × 100%代码评审通过率 人工评审一次性通过无规范相关 comment的变更比例违规返工平均耗时 从规则引擎拦截到 Agent 重新提交合规版本的平均时间消耗这三个指标分别回答了三个问题Agent 的产出能不能过机器关能不能过人的关被拦下来之后纠错快不快我最关心的其实是第三个指标因为它直接决定团队对 AI Agent 的信任度。如果 Agent 每次被拦回来都要折腾半小时才能改对那还不如不用它。6.2 权限边界先给Agent划定活动范围所有信任都建立在边界之上。Pi Agent 上线初期我的权限控制是相当保守的只允许它修改 src 目录下的业务代码和测试代码禁用它修改构建配置、CI 配置、部署脚本和依赖清单禁用它执行任何包安装命令、文件删除操作所有涉及数据库结构、API 契约的变更Agent 只能产出方案不直接落盘这些控制写在一个Agent 行为边界配置文件里Agent 在每次任务启动时会读取一次。如果有人试图让它修改边界外的东西它会拒绝并提示需要人工介入。信任是逐步建立的等它在受限范围内稳定运行几个月再扩大到更宽的权限面。一步到位放开权限后面擦地板的一定是你自己。6.3 灰度策略从试点模块到全量推广我建议所有团队都不要一上来就让 AI Agent 全项目铺开。Pi Agent 在试点阶段只负责某个中等复杂度的业务模块等该模块的规范符合率稳定在 90% 以上后才开始扩展到其他模块。灰度期间还要做一件事对照实验。找两个复杂度相近的模块一个用 Agent 辅助开发一个保持纯人工两周后对比代码评审通过率、缺陷密度和交付速度。这个数据能给团队一个客观依据省得大家凭感觉争论AI 到底行不行。6.4 规范库的持续迭代它应该是一块活代码最后必须重申规范知识库、项目说明文件、规则引擎配置这三样东西本质上都是代码的一部分需要纳入版本管理需要有人负责任地持续维护。我在 Pi Agent 上形成了固定的迭代节奏每双周根据规则引擎的拦截记录整理出高频违规项高频违规项进入规范优化候选新增或调整对应规则每条规则调整都通过一次回归验证确保新规则不会误伤已有合规代码实际工作中最常见的失败模式是规则库三个月不更新新引入的技术栈和老规范冲突Agent 按照过时规范生成代码反而成了技术债的来源。AI 工具唤醒了代码本身的流动性规范若还是一潭死水反噬是必然的。如果你所在的团队也准备给自己引入的 AI Agent 上规范紧箍咒我的建议是从知识库做起不要从提示词做起尽早挂上规则引擎不要指望模型的自觉性灰度观察两周再谈推广一切以数据说话。我自己实测下来这套机制真正带来的不只是规范符合率的数字提升而是让 AI Agent 从偶尔让人惊喜、经常让人救火的工具变成了一个稳定、可靠、行为可预期的协作角色。代码规范这件事说到底是在定义什么是这个团队认为的正确代码把它通过机制而非运气注入 AI 的产出里才是让 AI 真正融入研发体系的前提。