资讯详情

让AI编程助手守住代码规范:Pi Agent规则配置实战

📅 2026/10/17 12:00:40 | 华诺云谱 👁 阅读
让AI编程助手守住代码规范:Pi Agent规则配置实战
我大概是在第八次被代码评审打回PR之后才下决心去解决一个看起来很“软”的问题怎么让AI生成的东西别跟公司代码规范对着干。我们组的主力编程助手是Pi Agent它写通用逻辑又稳又快但一旦代码量上来就原形毕露——目录一会儿是utils一会儿是lib日志中英混杂异常处理有时候吞掉有时候自己编一个新的。复盘之后我发现根子不在模型能力而是Agent的运行机制天然偏向“近因优先”和“通用优先”。这篇文章就从Pi Agent的实际配置出发聊清楚怎么利用规则挂载、命令执行和自动检查把公司规范从口头约定变成Agent的硬约束。如果你也在被AI写的不规范代码折磨这篇应该能给你一套能直接抄走的方案。1. 先看清问题本质Agent不是不听话而是“记不住”1.1 规范在处理层面分为“硬规则”和“软约定”很多人以为“遵守代码规范”就是把lint的规则全开着。实际上公司规范里能靠工具自动检查的只占一部分比如缩进、引号、禁止通配符导入这类。真正难住AI的是另一类软约定模块边界怎么划分、错误上报走什么通道、日志上下文要带哪些字段、接口返回结构怎么设计。这类规范无法被eslint --fix一把梭Agent只能靠上下文里的描述去猜。而问题是你给它的上下文描述往往只覆盖了“它正在写的那个函数”没覆盖“你所在团队的长期约定”。Pi Agent这类工具的好处是支持在不同层级注入规则可以把软约定也变成显式指令。但前提是你得先分清哪些规范是机器可判断的哪些是上下文相关的。分不清这个后面配置规则文件就是堆字而已。1.2 Agent“忘事”的机制近因效应和上下文稀释我一开始很纳闷明明系统提示词里写了“禁止使用any”为什么它写不了几行就给我甩出一个const data: any ...后来观察多了才明白Agent生成每一段代码时能参考的信息是有限窗口内的上下文。随着对话变长、文件内容变多早期出现的规则会被后续任务指令、报错信息、用户补充内容层层稀释。说白了它像个记性不好的实习生入职培训你讲了半小时规范它当时听得频频点头结果中午让它改个接口它满脑子都是刚看到的那段老代码早就把上午的“不要怎么做”忘干净了。系统提示词虽然优先级高但当前轮用户消息如果特别长或者中间穿插了大量文件内容它的“注意力”也会被带偏。这不是Pi Agent独有的毛病是所有上下文语言模型共通的近因效应。1.3 一个反直觉事实让Agent抄老代码是最快的失控方式很多团队的“规范传承”靠的是“让AI参考现有实现”。我当时也这么干过结果翻车惨烈。比如我给它看了一个老模块的Service层写法希望它照着这个风格写新模块。它确实模仿了——但把老模块里过时的依赖注入方式、被废弃的日志工具、甚至当年临时注释掉的兜底逻辑一并学了去。原因很简单对模型来说具体示例的参考权重远高于抽象规则。你写“请保持分层清晰”远不如给它一个符合规范的真实文件来得有效。但反过来如果示例本身是坏味道样本它就会学到坏味道。这解释了为什么“让Agent参考现网代码”需要筛选样板而不是随手丢一个目录路径过去。2. 给Pi Agent装上“规范记忆”的三种办法2.1 全局指令最直接但最容易被覆盖的方式Pi Agent的全局指令相当于给所有会话预设一个“总纲”适合放那些无论如何都不能破的红线规则。比如“禁止提交包含console.log的代码”“禁止使用var”“错误处理必须显式捕获不允许静默吞掉”。但全局指令有明显的天花板它的字数是有限的而且会跟用户每条消息叠加。一旦任务描述复杂起来全局指令的权重会被逐渐稀释。我见过有人把整本团队规范几千字全塞进去结果Agent反而开始“选择困难”该触发哪条都不确定。所以我对全局指令的建议是只放“一票否决”级别的规则控制在十到二十条以内每条都用祈使句别写解释。规则文件解释得越详细Agent越容易把注意力放在故事上而不是要求上。2.2 放在项目根目录的规则文件每轮会话都在场比全局指令更可靠的是项目级规则文件。Pi Agent支持在项目根目录放置约定文件比如.agent/rules.md或PROJECT_GUIDE.md它在每次读取项目文件时都会把这个文件带进上下文。这相当于给Agent配了一本“项目当地法律”只要它在这个项目里工作就绕不开这些条目。这里的核心技巧是规则文件要克制。它不需要覆盖所有场景只要覆盖这个项目里最容易犯错的区域。比如你们项目是Node.js后端那就重点写模块分层、错误处理、日志规范、API参数校验前端项目就重点写状态管理边界、组件命名、样式规范。写多了文件太长反而会造成上下文浪费——每次读文件都消耗token还挤占了真正重要的代码内容的空间。我再给个实操细节规则文件的入口可以只写索引。比如规则文件里说“TypeScript规范见.agent/ts-rules.md错误处理规范见.agent/error-rules.md”让Pi Agent按需去读具体文件。这样每轮上下文里只有几百字节的索引Agent真正处理该模块时再去加载完整规则省token又不稀释注意力。2.3 示例代码与其讲道理不如给它抄作业规则文件写再多也不如“给一个正确范例”来得快。因为Agent本质上是个概率生成器它对模式的捕捉能力远超对抽象描述的理解。与其在规则文件里写“缓存键必须包含业务前缀防止跨业务冲突”不如给它一小段示例// 正确示例缓存键带前缀 const cacheKey order:price:${orderId}_${currency};Pi Agent对这样的示例非常敏感。你甚至可以在项目里放一个samples/目录里面存几个“黄金样板文件”在规则文件里写明“当你有疑问时先看.agent/samples/order-service.ts的写法”。这比在规则里反复强调“不要怎么做”高效得多。我把这种方式总结成一句话规则文件负责说“不能做什么”示例代码负责说“应该长什么样”。两件事配合才算是把规范讲透。3. 一份可以直接抄走的Pi Agent规范配置3.1 从公司规范到Agent指令三段式翻译法我在第一次配置时就踩了坑把公司wiki里的开发规范整章复制进规则文件结果Agent根本不知道哪些条目是重点生成时东一榔头西一棒子。后来我把所有规范统一翻译成“场景—禁止—替代”的三段式- 当处理外部接口返回时禁止直接用 any 声明响应体 替代方案先定义接口的 Response 接口用 zod 或 interface 做运行时/编译期校验。这种三段式的信息密度很高Agent无需推断就能执行。它对规则的识别率远高于“应保证接口类型安全”这类模糊描述。我见过一份写得很好的规则文件里面全是这样的短句没有一句废话Agent遵守率肉眼可见地高。3.2 规则清单的优先级与分层Pi Agent的规则注入路径大致有三级全局指令、项目规则、本次任务指令。它们同时在场时Agent会把“更靠近当前任务的指令”放在更高优先级。如果你在项目规则文件里写了“模块命名用短横线”但当前任务指令里恰好写“请把文件命名为camelCase”它大概率会照任务指令执行。这不是bug是特性。利用这个特性我们可以做一个简单的优先级设计优先级层级适合放置的内容高当前任务指令本需求特有的约束例如“这次只改缓存模块不要动Service层”中项目规则文件该项目的工程约定、模块边界、错误处理规范低全局指令所有项目通用的硬性红线例如禁止任何匿名函数缩写之类实际配置时需要保证规则本身不冲突。团队规范里最常见的问题就是“新旧两版规范并存”比如旧的允许var新的禁掉了如果两句话都写进规则文件Agent会无所适从。项目规则文件一定要以当前生效版本为准别把历史规范留作参考。3.3 一个可落地的规则文件结构下面是我给某个模拟项目X配置Pi Agent时实际在用的结构供你参考.agent/ ├── rules.md # 总入口索引各专项规则 ├── typescript.md # TS/Node 专用规则 ├── frontend.md # 前端组件与状态管理规则 ├── error-handling.md # 错误处理与日志规范 └── samples/ ├── service.ts # 黄金样板Service 层 └── controller.ts # 黄金样板Controller 层rules.md不需要长篇大论它起索引作用。真正的规则写在各专项文件里每个文件二三十行即可。规则文件里我还会留一个小节叫“常见误用”把开发中反复踩的坑写成反例。比如// 反例吞掉异常 try { await save(data); } catch (e) { console.error(e); }再附上正例// 正例包装后抛出到上层统一处理 try { await save(data); } catch (e) { throw new PersistenceError(save failed, { cause: e }); }Agent读完正反例对比之后写出来的代码质量明显提升。反例特别重要因为模型很容易“生成它见过最多的写法”而大部分老代码里就是反例居多。你给它一个反例加正例的组合等于帮它分清“常见”和“正确”的差异。4. 从“口头约定”到“硬性约束”把静态检查塞进Agent的工作流4.1 让Agent在收尾阶段自动执行lint与format提示词是软约束命令是硬约束。Pi Agent支持在对话中执行终端命令这给了我们一个很实用的思路让它生成完代码后自己跑一遍lint和format看到报错就修修完再跑直到全绿。我在项目规则文件里加了一条固定流程完成代码修改后依次执行 1. pnpm lint 2. pnpm format:check 3. pnpm typecheck 如果任何一项失败请从报错信息中定位问题修复后重新运行直到通过。第一次跑通这个流程后Agent产出的代码直接从“看起来能用”变成了“能过流水线”。很多规范问题命名、引号、缩进、未使用的变量根本不需要写进规则文件lint就可以挡住。这大大减少了规则文件需要管的范围。4.2 把CI失败信息同步回Agent实现“被现实纠偏”lint能抓语法格式但抓不到业务规范。比如“接口响应必须包在统一结构里”“异常必须走Sentinel上报”这类规则我选择不重复写进规则文件而是等CI失败时把日志喂给Agent。做法是在Pi Agent里新建一个“修复CI失败”类型的任务把CI日志文件的路径粘贴进去让它先读日志再定位问题。CI里跑的是公司统一的规范检查Agent看了真实报错之后会比自己脑补规则学得更快。有一次它反复犯同一个“禁用any”的错误我在会话里直接甩了三条CI报错给它再让它总结规律之后新代码就没再踩同一个坑。这个思路的本质是让Agent不只在生成时遵守规则还能在“被外部工具否定后”自我修正。经历几次失败-修正循环后Agent在后续生成中对这类问题的敏感度会明显提高。4.3 生成后即刻检查一个轻量卡点脚本最后一道防线我建议做成脚本放在项目根目录。脚本不必复杂能检查几个最容易反复的点就行。我写过这样一个简单的shell脚本卡在git commit前自动执行#!/bin/bash # commit前合规检查 failed0 # 检查是否残留 TODO 未处理 if rg TODO|FIXME --glob !*.md src/ /dev/null; then echo 发现未处理的 TODO/FIXME请先清理 failed1 fi # 检查业务代码是否出现 any if rg \: any\b src/ --glob *.ts /dev/null; then echo 发现 any 类型请改为具体类型或 unknown 收窄 failed1 fi # 检查是否直接 console.log应采用统一 logger if rg console\.(log|debug) src/ /dev/null; then echo 请改用统一 logger failed1 fi if [ $failed -ne 0 ]; then exit 1 fi这个脚本其实就是把公司规范里最常翻车的几条变成自动化检查。它不需要覆盖所有规范只抓最高频的几条就够了。真正的完整规范还是交给CI阶段的全量lint和评审去兜底。5. 实测翻车现场四类“规范失效”的真实案例与修复过程5.1 长对话后段规范被越聊越弱大约第三周我在Pi Agent里开了一个需求会话连续改了七八轮。前半程它还很规整后半程新增的一个接口却推开规范自己玩文件名用了下划线参数校验缺失错误处理只打日志不抛异常。我看了一下上下文发现前面几轮用户补充的任务细节、报错信息加在一起已经很长规则文件的索引早就被挤出有效上下文了。解法很朴素长任务分段。不要太相信一个会话能从头撑到尾。我会在需求进行到明显阶段边界时主动开新会话并让新会话先读规则文件再继续。这虽然损失了一点上下文连续性但换来了稳定性和规范一致性值得。5.2 多语言项目记住了主规范忘掉了副规范后来有个模拟项目X是前后端同仓TS后端加Python脚本。Pi Agent对TS部分的规范执行得很好但写Python脚本时又开始放飞文件名camelCase、变量命名用了orderList而不是order_list和团队Python规范完全反着来。原因是我当时的规则文件只写了typescript.mdAgent认为“项目规范”只约束TS文件。修复方法是在rules.md里按文件类型分开指示处理 .ts/.tsx 文件时遵守 typescript.md 处理 .py 文件时遵守 python.md。加了这么一行之后Agent会自己按扩展名加载对应规范。这个“按文件类型切换规范”的做法比把所有规范堆在一个文件里更精准也更容易维护。5.3 代码补全Agent“自作主张”用了通用写法有一次让它实现一个带缓存的数据查询方法它“贴心地”在模块顶层加了一个全局Map作为缓存容器。单看代码本身没毛病但我们的规范要求缓存走统一的Redis客户端且禁止模块级共享可变状态。这就是典型的“通用写法”与“团队约定”打架。单靠规则文件里写“不允许模块级可变状态”这种抽象描述Agent很难在所有生成路径里都主动触发。我这里用了一个组合拳规则文件里写反例正例同时在samples/目录里放了一个包含缓存逻辑的黄金样板文件。它一看样板里用的是redisManager.getClient().set(...)后续生成时就自动照着那个写了。说到底示例代码在“纠正Agent的审美”这件事上比十条抽象规则都管用。5.4 规范更新后Agent还在执行旧规约第四类翻车发生在团队规范更新之后。我们把单引号规范改成了双引号同时废弃了旧的moment时间库统一改用date-fns。结果我发现Pi Agent的新会话里依然在旧规则上打转生成单引号字符串时间格式化还在用moment。排查原因很简单项目里的规则文件、示例代码都还是旧版。Agent的上下文里没有“规范已经更新”的信号它当然按旧习惯生成。自那以后我建立了两条规矩一是规则文件更新后一定要新建会话来验证Agent能识别新规则二是规则文件头部写一行“生效时间”并让Agent在开始任务前先确认自己读取的是最新版本。步骤很不起眼但确实避免了“AI一直用上季度规范写代码”的尴尬。6. 边界与取舍让AI遵守规范的天花板在哪里6.1 规范文件不是越长越好token是硬成本规则文件写太长的代价是实打实的每轮读取都占用上下文窗口挤掉真正需要的代码信息规则条目太多时模型对每条规则的置信度还会互相稀释最后哪些都没记住。我现在控制项目规则文件的总体量在200行以内每一条都有明确的“触发场景”不写废话。更底层的规范细则留在wiki里Agent需要时再让它去查而不是全量塞进上下文。这个思路叫“宽进严出”让Agent先掌握精简版高频规范细节规范通过检索按需获取而不是让它每轮都背着整本手册。6.2 哪些规则适合交给Agent哪些必须留在人手里就我的实践来说适合交给Agent的是确定性规则类型定义、命名规范、模块边界、资源释放、错误传播路径、日志格式。这些规则有明确的对错模型能稳定执行。不适合交给Agent的是判断性规则公共API的抽象粒度、跨模块的边界划分、性能方案的取舍、用户交互行为的合理性。这些需要产品语感和全局视野即便模型拍脑袋做了也不该放它乱来。所以我的流程是让Agent负责“按规范写好代码”我来负责“判断代码是否值得进主干”。规范执行可以自动化设计判断必须有人在场。6.3 从试点项目到团队习惯的落地顺序最后聊聊落地。我建议别一上来就把所有项目接入Pi Agent规范系统先拿一个中型项目试点把规则文件整理好跑一个月统计评审里由Agent引发的规范问题再反推规则文件哪里写得不清不楚。我这边第一个月把“日志规范”从一句话扩成了带正反例的一整节因为Agent反复在这个点上翻车第二个月又因为“事务边界”问题新增了一个专项规则。规则文件是活的得跟着团队的实际痛点进化。我现在每周都会把评审里新出现的共性问题翻译成一条Agent规则扔进规则文件里。三个月下来Agent生成的东西基本不用改风格了。这个过程没有玄学就是让规范以Agent能理解的形态存在再不断修剪而已。
📝

华诺云谱内容团队

资深建站顾问 · 行业研究员

10年+企业数字化服务经验,专注智能建站、SEO优化与品牌营销,持续输出建站技巧、行业洞察与营销干货,已帮助5000+企业实现数字化增长。

你可能需要的服务

订阅华诺云谱资讯周报

每周一封,精选建站技巧、SEO与营销干货,直达邮箱。已有 8,000+ 企业主订阅,助你少走弯路。

↑