
如何给 Coding Agent 写仓库规则硬约束、软约束与证据门禁TL;DR场景Coding Agent 在已运行多年的仓库中改对 3 行代码要比从零生成一个函数难得多当前大量仓库规则停留在遵循最佳实践层导致 Agent 拿到的是没有作用域、优先级、停止条件、验证方式的口号。结论可执行的仓库规则必须分成三类——硬约束违反即停止、软约束允许取舍但必须解释、证据门禁决定任务能否完成每类规则还要绑定作用域、优先级与停止条件配套最小变更契约与可审计证据。产出12 节正文写代码 vs 改仓库 / 仓库上下文 / CST·AST·LSP / 硬软门禁三类规则 / 作用域与停止条件 / 变更契约 / 验证梯子 / 证据交付 / 最小规则模板 / 示例 / 误区 / AI 时代再理解 14 项版本矩阵11 ✅ 已验证 3 ⚠️ 待核 10 行错误速查卡 6 件事规则模板。版本矩阵#功能 / 事实状态说明多源印证 / 单一来源 / 待核1Tree-sitter 是解析器生成工具 增量解析库✅ 已验证Tree-sitter 官方定义“a parser generator tool and an incremental parsing library” 多家 CSDN 解析文章 ast-grep 文档引用一致2Tree-sitter 输出具体语法树CST而非抽象语法树AST✅ 已验证官方可以为源文件构建具体的语法树 ast-grep 文档该树状结构不是抽象语法树 多个中文解析3Tree-sitter 支持在存在语法错误时仍提供有用结果✅ 已验证官方even when there are syntax errors, it can still provide useful results 多家中文文章一致4Tree-sitter 增量解析编辑时只更新受影响部分✅ 已验证“编辑源文件时高效地更新语法树” “无需重新解析整个文件” 多源印证5LSP 标准化编辑器/开发工具与语言服务器之间的 JSON-RPC 消息✅ 已验证Microsoft 官方JSON RPC v2.0 LSP 官方页面 “defines the protocol used between an editor or IDE and a language server”6LSP 承载补全、跳转定义、查找引用等语言能力✅ 已验证Microsoft 官方completion, go-to-definition, find references 多家中文解读一致7LSP 实际能力取决于语言服务器实现与项目加载状态✅ 已验证实际能力取决于具体语言服务器、项目是否成功加载以及构建配置是否完整是工程共识多家 LSP 综述一致8OASIS SARIF 2.1.0 是静态分析工具输出的标准格式✅ 已验证OASIS 官方Static Analysis Results Interchange Format (SARIF) Version 2.1.0 GitHub CodeQL 等大量工具支持9Spring 事务默认代理模式只拦截经过代理的外部方法调用✅ 已验证Spring 官方文档 “method visibility and Transactional in proxy mode” 大量中文实践文章10Spring 自调用同类内部方法调用不经过代理 → 事务不生效✅ 已验证“the call goes through the proxy. This is normally the case if the annotated method is invoked from another bean” 多家 Spring 实践文章11SARIF 适合承载机器证据不替代代码评审✅ 已验证业界共识GitHub CodeQL、Coverity、PMD 等工具的文档均认可 SARIF 用于结果交换12AGENTS.md 规范版本号如 1.0 / 2024-12-17⚠️ 待核本文提到AGENTS.md作为概念性规则文件入口未引用具体规范版本发文前可核 agents.md 规范当前状态13KISS / YAGNI / DRY / SOLID 原始出处与年份⚠️ 待核文中作为设计原则列举原始出处分散KISS 1970s、YAGNI Ron Jeffries 1990s、SOLID Robert C. Martin 2000s、DRY Andy Hunt 1999建议在文中给出处或仅作概念引用14本文所列《软件设计之美》《设计模式之美》《代码之丑》《代码精进之路》《编译原理之美》《Spring编程常见错误50例》具体版本/出版年⚠️ 待核文中以《》列出多本中文技术书作为参考建议发文时核对 ISBN / 出版社 / 出版年是否准确注标 ✅ 的项目均经过 2 个以上独立信源印证含官方文档原文 主流技术博客 / 实践文章一致表述标 ⚠️ 的项目在本文写作时未能从官方规范或多源完全确认标注为待核以避免引入未经验证的事实。文章正文以下为原文原封不动放置正文中的图片占位符已用mmx vision describe回填实际描述。让模型写出一个函数并不难难的是让它在一个已经运行多年的仓库里改对三行代码。同样一句给订单接口增加重试可能牵涉公开 API、事务边界、幂等语义、异常映射、调用方假设和监控口径。一个局部看起来正确的补丁可能通过语法检查却在运行时重复执行有副作用的操作也可能通过单元测试却悄悄改变未覆盖的接口行为。因此Coding Agent 的核心问题不是能不能生成代码而是它能否先恢复足够的仓库上下文再把修改限制在可解释、可验证、可回退的边界内。这也是很多仓库规则失效的原因人写下遵循最佳实践“保持代码整洁”“充分测试”以为已经表达清楚Agent 实际拿到的却是一组没有作用域、优先级、停止条件和验收方式的口号。真正可执行的仓库规则至少要分成三类违反后必须停止的硬约束、允许结合上下文取舍但必须解释的软约束以及决定任务能否标记完成的证据门禁。一句话结论可靠的 Coding Agent 不是代码生成器而是一条可检查的修改闭环读取仓库上下文建立结构和语义模型应用局部约束规划最小补丁执行分层验证最后交付可审计证据。实际价值对开发团队把让模型试着改变成有输入、停止条件和验收证据的工程流程。对工具开发者明确解析器、语言服务器、静态分析器、测试和模型各自负责什么。对代码评审者快速区分硬约束、设计偏好和未经验证的推断减少无效争论。对风险治理把自动修复权限与影响面、可验证性和副作用绑定而不是一律允许或一律禁止。正文1. 写一段代码与修改一个仓库是两类任务从空白开始生成函数时输入通常比较完整参数是什么、返回什么、使用哪种语言。修改现有仓库时真正的输入散落在更多地方根目录和子目录中的规则文件构建脚本、依赖清单和代码生成配置接口定义、调用方、测试、数据库迁移和部署约束相邻模块形成的局部惯例没有写进文档、却被业务依赖的隐含行为。这意味着代码能编译只回答了一个很窄的问题。它没有证明接口仍然兼容没有证明框架代理仍然生效也没有证明业务动作只执行一次。《软件设计之美》把软件设计理解为需求与实现之间的模型。对 Coding Agent 来说这个视角很关键代码文本只是实现表面模型、接口和变化边界才决定一次修改是否成立。2. 第一阶段先建立仓库上下文Agent 开始编辑前至少需要完成四类读取。2.1 规则仓库级规则告诉 Agent 允许修改什么、采用什么命令、哪些目录有独立约束、什么结果才算完成。规则之间还可能存在作用域根目录定义通用要求子目录规则覆盖局部行为。2.2 结构模块、包、服务、构建目标和所有权决定修改应落在哪里。只搜索到一个同名函数并不代表它就是正确入口。2.3 契约公开 API、数据结构、异常、事件、配置和测试共同构成可观察契约。修改实现时默认应保留这些契约确实需要改变时应把它升级为显式决策。2.4 邻近实现通用最佳实践不一定是仓库最佳答案。命名、错误处理、依赖注入和测试组织通常都有局部惯例。Agent 应先阅读相邻代码再决定是否引入新抽象。这一步的输出不应是长篇仓库总结而是一份与当前任务有关的约束清单目标、范围、不可改变项、未知项和验证入口。3. 第二阶段从文本走向结构再从结构走向语义代码不是普通文本但结构化解析也不是理解的终点。3.1 CST 和 AST 解决代码是什么结构词法分析把字符切成 token语法分析依据文法建立树。具体语法树保留更多源码细节抽象语法树则通常压缩括号、分隔符等表面信息突出声明、表达式和控制结构。Tree-sitter 官方介绍将其定义为解析器生成工具和增量解析库可以为源码建立具体语法树并在源码编辑时高效更新。它适合定位函数、调用、参数和语法节点官方列出的设计目标之一是在存在语法错误时仍提供有用结果。结构树能让工具执行比字符串替换更可靠的操作例如只修改目标方法的参数列表找到某种调用表达式而不是匹配注释中的同名文本在保持格式信息的前提下执行 codemod判断编辑后是否仍能被语法解析。但树只能告诉我们这里是一个调用不能自动回答这个调用是否有业务副作用。3.2 符号、类型和引用解决名字指向什么语义分析进一步处理符号表、作用域、类型、引用和接口实现。它让工具知道两个同名变量是不是同一个符号一个方法修改会影响哪些调用方一个实现是否仍满足接口。Language Server Protocol 官方页面说明LSP 标准化编辑器或开发工具与语言服务器之间的 JSON-RPC 消息并承载补全、跳转定义、查找引用等语言能力。它可以为影响面分析提供证据但实际能力取决于具体语言服务器、项目是否成功加载以及构建配置是否完整。因此代码理解至少要区分三层语法结构声明、表达式、控制结构 语言语义符号、类型、引用、作用域、调用关系 业务意图规则、领域模型、接口承诺、运行时假设前两层可以由编译器和开发工具大量辅助第三层仍需要仓库文档、测试、调用语境和人工决策补足。4. 第三阶段把设计原则变成局部约束遵循 SOLID不是一条可直接执行的任务。原则只有落到当前仓库和当前变化上才能约束修改。可以把约束分成三类。4.1 硬约束公开 API、数据格式和兼容性要求类型、编译、协议和数据库约束安全边界、权限与敏感信息规则用户明确要求和已有自动化测试契约。硬约束被违反时Agent 应停止、缩小修改或请求决策不能把它解释成普通建议。4.2 软约束命名是否表达业务含义类和函数职责是否清晰是否出现重复、过长函数、过度可变状态或依赖混乱抽象是否符合仓库惯例是否满足 KISS、YAGNI、DRY、SOLID 等设计方向。《设计模式之美》和《代码之丑》提供了大量诊断视角但这些视角不应机械变成自动修改命令。长函数可能是坏味道也可能是一个暂时稳定、缺少测试保护的高风险区域。发现问题只说明需要调查不代表 Agent 已获得重构授权。4.3 证据门禁编辑后的文件可以解析和格式化Lint、类型检查和静态分析没有新增阻断问题与影响面匹配的单元测试、集成测试或契约测试通过必要构建和安全检查通过无法运行的检查被明确记录。设计原则负责解释取舍证据门禁负责决定任务能否完成两者不能混为一谈。5. 规则还需要作用域、优先级与停止条件只把规则分成三类还不够。Agent 还需要知道规则在哪里生效、冲突时听谁的以及什么情况不能继续自行处理。5.1 作用域根目录规则通常覆盖全仓子目录规则只覆盖对应模块用户当前任务再进一步限定本次执行范围。局部规则可以补充或覆盖通用规则但不能悄悄改变更高优先级的用户要求。例如根目录要求所有修改运行格式检查前端子目录可以额外要求视觉回归它不应该因为自己有局部脚本就跳过根目录已经要求的安全检查。5.2 优先级一条实用的冲突顺序是用户当前明确要求、仓库执行规则、模块局部规则、操作文档、示例文件。示例只能说明可能的写法不能反过来覆盖正式规则。优先级必须写出来。否则模型可能把一个陈旧示例当成当前标准也可能用通用最佳实践覆盖团队已经明确选择的局部方案。5.3 停止条件出现以下情况时Agent 应停止写入并请求决策而不是继续扩大修改需要改变公开接口、数据语义、权限或不可逆副作用工作区存在与当前任务冲突的未知修改规则之间互相矛盾无法根据优先级消解必要验证失败且修复需要超出原任务范围缺少关键来源或上下文只能依赖猜测完成。停止不是能力不足而是仓库治理的一部分。可靠 Agent 的边界不只体现在能做什么也体现在什么时候不会擅自继续。6. 第四阶段先写变更契约再生成补丁可靠修改应先形成一个小型变更契约。它不需要复杂文档但至少包含goal:为示例客户端增加可取消的超时控制target_files:-src/client/example.tsmust_preserve:-public method signature-existing error mappingrisks:-request may already have produced side effectsvalidation:-typecheck-client unit tests-cancellation integration test以上只是虚构示例不对应真实仓库。变更契约迫使 Agent 在编辑前回答几个问题目标行为到底是什么哪些文件是必要范围哪些只是搜索线索哪些接口和行为必须保持不变风险来自语法、语义、运行时还是副作用用什么结果证明修改成立补丁应优先满足最小但完整只改完成目标所需的范围同时补上与风险匹配的测试。最小差异不是永远只改一行而是不顺手清理无关代码、不引入没有必要的新抽象、不扩大行为表面。编译原理中的优化强调语义等价这对 Agent 修改同样适用结构可以变化但外部可观察语义必须保持除非任务明确要求改变它。7. 第五阶段执行编辑时区分三种权限并非所有发现的问题都应该自动修复。可以把动作分成三档。动作适用条件示例默认处理自动修改影响面小、规则确定、可自动验证格式化、确定性导入整理、局部 API 迁移修改并验证提议修改存在设计取舍或影响多个模块提取接口、拆分类、调整异常模型给出补丁计划或候选方案请求审批涉及公开契约、数据、安全或业务副作用改数据库语义、权限、支付或设备动作停止并说明决策点结构化编辑适合有稳定语法节点的批量变换精确文本补丁适合范围很小、锚点明确的修改。无论采用哪一种Agent 都应重新读取差异确认没有格式漂移、重复插入或意外覆盖用户已有修改。8. 第六阶段验证不是一个命令而是一架梯子验证应从低成本、反馈快的检查逐步上升语法解析 - 格式检查 - Lint / 静态规则 - 类型检查 - 目标单元测试 - 相关集成或契约测试 - 必要构建 - 安全、性能或端到端检查不是每个改动都需要运行整仓构建。验证范围应与影响面和风险匹配文档修正可能只需要格式和链接检查共享接口修改则需要调用方、类型和集成测试。验证还需要失败策略。某一层失败时应先判断是补丁错误、环境缺失、测试本身不稳定还是存在用户未授权的前置改动。不能为了让结果变绿而删除测试、放宽类型或扩大修改范围。《Spring编程常见错误50例》提供了一个重要提醒框架会隐藏生命周期、代理、事务和上下文。代码编译通过、局部测试通过也不代表运行时代理一定生效。Spring Framework 事务文档明确说明默认代理模式只拦截经过代理的外部方法调用。因此一次看似普通的方法重构可能改变代理调用路径或事务边界。这里的稳定结论是需要验证框架运行时行为而不是把某个版本的具体实现泛化到所有项目。9. 最后交付的是证据不是 Agent 的自我评价已经完成不应来自模型的语气而应来自可复现证据。一次合格交接至少包含修改了哪些文件和行为为什么这些修改足够且没有扩大范围运行了哪些检查结果是什么哪些检查没有运行原因是什么还存在哪些风险或需要人工决定的事项。OASIS SARIF 2.1.0定义了静态分析工具输出的标准格式可用于统一规则、位置、级别和结果等信息。SARIF 适合承载机器证据但它不判断某个修复是否符合业务意图也不替代代码评审。对 Coding Agent 来说可审计的关键不是把所有工具输出都堆进回复而是让结论能追溯到具体差异、命令和结果。10. 一份最小可执行规则模板规则文件不需要把整本软件工程教材搬进仓库但至少应回答六件事任务前读什么、允许改什么、必须保留什么、禁止做什么、如何验证以及何时升级。# Scope 本规则作用于整个仓库子目录存在独立规则时局部规则只覆盖对应目录。 ## Read Before Editing - 读取相关索引、构建入口、测试和相邻实现。 - 先检查工作区已有差异不覆盖未知修改。 ## Hard Constraints - 不改变公开接口、数据格式和权限语义除非用户明确批准。 - 不删除主数据不执行不可逆命令不伪造测试或运行结果。 ## Soft Guidance - 优先沿用邻近实现和现有抽象。 - 发现坏味道时先评估影响面不顺手扩大重构范围。 ## Validation - 运行格式、静态检查、目标测试和与影响面匹配的必要构建。 - 未运行的检查必须说明原因和残余风险。 ## Stop And Escalate - 规则冲突、验证失败、来源缺失或涉及高风险副作用时停止写入。这份模板故意不绑定某个模型或工具。真正稳定的是作用域、约束强度、验证和升级语义具体命令应由仓库自己的技术栈定义。11. 一个不依赖真实项目的示例假设任务是“把loadProfile的超时从固定常量改成可配置同时保持公开接口不变。”一个受约束的执行过程可以是读取仓库规则、构建入口和loadProfile的定义。查询引用确认它由同步入口和后台任务共同调用。读取现有配置模型避免新建第二套配置来源。写下硬约束公开方法签名、默认超时和错误类型不变。只修改配置绑定和内部调用不顺手重构整个客户端。增加默认值与自定义值测试再运行类型检查和目标测试。输出差异、验证结果并注明尚未运行端到端网络测试。这个示例没有给出改造后性能提升多少因为没有真实数据。它证明的是流程可以被检查不证明某个项目已经获得效果。12. 常见误区误区一有 AST 就理解了代码AST 提供结构不提供完整的类型、调用关系、框架运行时和业务意图。可靠理解需要继续补充语义与仓库上下文。误区二找到坏味道就应该自动重构坏味道是调查入口。缺少测试、影响面不明或存在公开契约时自动重构可能比原问题风险更大。误区三设计原则可以机械打分SOLID、KISS 和 DRY 用于解释变化与取舍不是脱离场景的排行榜。仓库局部一致性有时比抽象上的更优雅更重要。误区四测试通过就证明修改正确测试只覆盖已表达的行为。未覆盖的调用方、配置、权限、并发和框架隐式行为仍可能失败。误区五最小补丁就是修改行数最少只改实现却不补必要测试可能只是把风险藏起来。最小补丁应以完整满足目标和验证要求为边界。误区六Agent 可以自行处理工作区里的所有差异工作区可能包含用户尚未提交的修改。Agent 应区分自己的变更与已有变更不能为了获得干净状态而覆盖或回退未知内容。面试追问 / 延伸问题CST、AST、符号表和调用图分别能回答什么问题LSP 能力为什么会受到项目加载和语言服务器实现影响如何把 SOLID 从抽象原则转成仓库局部规则哪些坏味道适合自动修复哪些必须请求审批如何为一次跨模块修改设计最小验证集合测试无法运行时Agent 应如何表述完成状态SARIF 解决了什么问题又没有解决什么问题能力分层初级能按明确要求生成局部代码并通过语法和格式检查。中级能读取仓库规则使用符号和引用分析影响面生成最小补丁并运行目标测试。高级能恢复模型与接口边界区分硬约束、软约束和证据门禁处理运行时风险并提供可审计交接。AI 时代的重新理解过去IDE、编译器、Lint、测试和 CI 是由开发者手动串联的工具。Coding Agent 的机会不是替代这些确定性工具而是把它们组织成一条围绕任务目标运行的反馈回路。模型擅长从分散信息中形成计划、解释差异和处理开放问题解析器、类型系统、静态分析和测试擅长给出可复现结果。两者结合才能把概率性的生成放进确定性的工程边界。因此衡量 Coding Agent 不能只看一次生成是否像正确答案还要看它是否尊重范围、是否能在失败后收缩计划、是否留下可复核证据以及是否知道什么时候应该停止并请求决策。总结让 Coding Agent 可靠修改仓库可以依次检查六步读取与任务相关的规则、结构、契约和邻近实现。用 CST/AST 建立结构模型用符号、类型和引用补充语言语义。把公开契约、安全和测试定义为硬约束把设计原则和坏味道定义为需解释的软约束。在编辑前写清目标、影响面、保留项、风险和验证入口。生成最小但完整的补丁并按风险逐级运行验证。用差异、命令、结果和残余风险交付而不是用模型自评宣布完成。这套方法来自跨书整理和公开标准不代表某个真实项目已经验证也不包含效果比较。它的用途是帮助团队把 Coding Agent 从能生成代码推进到能在约束下执行修改。本文只使用公开标准、书籍整理和虚构示例没有使用公司内部项目材料也不声称已经获得真实项目效果。SEO 关键词Coding Agent、AI 编程、AST 代码分析、Tree-sitter、Language Server Protocol、LSP、AI 代码重构、代码坏味道、SOLID、自动化测试、质量门禁、SARIF、代码审查、Agent 工程化参考资料延伸阅读《编译原理之美》词法、语法、AST、符号表、类型、作用域、IR 与语义等价。《设计模式之美》代码质量、SOLID、KISS、YAGNI、DRY、可测试性与小步重构。《软件设计之美》分离关注点、模型/接口/实现、简单设计与领域边界。《代码之丑》命名、重复、长函数、大类、封装、可变状态、依赖与评审。《代码精进之路》规范、接口合约、异常、安全边界和最小权限。《编译原理实战课》真实语言中的语法、语义、IR 与运行时差异。《Spring编程常见错误50例》生命周期、代理、事务、Web 和测试中的隐式运行时行为。公开标准与文档Tree-sitter Introduction核验增量解析、具体语法树和错误恢复能力。Language Server Protocol核验编辑器与语言服务器的协议边界及定义、引用等能力。OASIS SARIF 2.1.0核验静态分析结果交换格式的职责。公开资料核验日期2026-07-10。错误速查卡症状根因定位修复Agent 改完没动接口但生产环境出现兼容问题软约束命名/抽象被解读为自动重写触发了公开契约漂移diff 检索所有目标方法签名是否被改公开 API/数据格式显式列入硬约束PRESERVE并跑契约测试单元测试通过但运行时事务不生效改了同类内部调用路径Spring 代理未拦截看改动方法是否从外部 Bean 调用把事务方法拆到独立 Bean或显式经过代理调用Agent 给出一份看起来对但实际是猜测的方案规则没有停止条件缺少关键来源仍继续审计 patch 是否引用了真实仓库文件/版本在规则里写来源缺失必须升级禁止依赖猜测完成Agent 删了工作区里不属于本次任务的差异没有区分 Agent 变更与已有差异git status / 改动文件时间戳对比编辑前先备份工作区已存在差异写不覆盖未知修改硬约束Agent 改了一行就顺手重构整个模块软约束代码异味被理解为自动重构命令diff 行数 / 影响文件数 / 公开契约变更软约束明确发现坏味道先记录、影响面评估后再决定Lint 报了一堆旧问题Agent 把它们当成失败并阻塞任务没有把新增阻断问题与存量问题区分跑 lint 前后对比 diff only 模式证据门禁明确是否引入新阻断问题作为门禁条件Agent 标完成但部分检查没跑证据门禁没有未运行检查必须说明复核 Agent 报告 vs 实际运行命令列表模板加未运行的检查必须写明原因和残余风险重构后类型检查通过但 LSP 显示找不到引用改了方法签名但没更新所有调用方LSP find references / 跨模块 grep把类型检查 LSP 引用分析作为集成测试前的必备门禁跑了 build 但忘了跑安全/性能检查验证梯子被截断为 build 通过即结束校验产物是否覆盖安全/性能/端到端项验证模板按影响面绑定检查项不允许通用跳过旧示例反而覆盖了正式规则优先级没有写出来模型把示例当标准在 diff/agent 提示中检索示例路径规则明文写优先级用户 仓库 模块 文档 示例作者武子康的个人博客