1 分钟

Claude Code 风格指南提示,帮助实现一致的代码审查

学习如何撰写 Claude Code 风格指南提示,强制命名、分层、错误处理和日志规则,通过简单检查尽早发现违规。

Claude Code 风格指南提示,帮助实现一致的代码审查

为什么风格违规会迅速蔓延

风格违规很少以一次严重错误出现。它们通常从微小的“差不多”选择开始,在一次拉取请求中看起来无害,然后逐渐堆积,直到代码库显得不一致、难以阅读。

风格漂移常常表现为:一个文件使用 userID,另一个使用 userId,第三个使用 uid。一个 handler 返回 { error: "..." },另一个抛出错误,另一个记录日志后返回 null。每次改动都很小,但合在一起就会让仓库中的模式变得不可预测。

快速迭代和多人协作会让问题更严重。人在时间压力下会复制他们看到的东西。如果仓库中最新的代码使用了一个快捷写法,下一个改动很可能以该写法为模板。几周后,“默认风格”不再是你写下的指南,而是最后发生的事情。

因此目标必须是保持一致的约定,而不是个人偏好。问题不该是“我喜不喜欢这个名字?”,而是“这是否符合我们约定的规则,以便下一个人可以无需思考就能遵循?”

及早发现违规意味着在坏模式成为复制粘贴的源头前就阻止它。把注意力放在新增和修改的代码上,修复新不一致的首次出现,并阻止合并引入新的漂移。当你标记一个问题时,附上一个简短的首选示例,供下次模仿。

举个现实的例子:某个开发者新增了一个 API 端点并为了调试而记录了原始请求体。如果这段代码合并了,下一个端点会复制它,很快敏感数据就会出现在日志中。第一次在 PR 中捕获它代价很低;等它扩散后再处理既痛苦又危险。

把风格指南变成清晰、可测试的规则

风格指南只有在审查中能像检查表一样被读取时才有效,而不是一堆偏好。把每条准则重写为可在 diff 上检查的规则。

把规则按四类组织,便于抓住:命名、分层、错误处理和日志。对每一类写两件事:必须满足的条件和禁止项。

事先决定每条规则的强度:

  • 必须(Mandatory):不满足则阻止变更合并。
  • 建议(Recommended):除非有明确理由,否则应修复。
  • 可选(Optional):可加分,绝不阻塞合并。

设置作用范围以避免审查变成无尽的重构。一个简单的规则很好用:“新增和修改的代码必须符合规范;未触及的现有代码不必重写,除非它阻碍了修复。”如果你想要清理工作,把它作为单独的有时间限制的任务。

还要定义你期望审查产出的格式,便于落地:通过/失败的结论、带文件与行号的违规清单、以具体改动形式给出的建议修复,以及在可能导致漏洞或泄露时的一句话风险说明。

举例:如果一个 PR 在日志中记录了原始用户令牌,审查在“日志:禁止记录秘密”这一项下应判为不通过,并建议改为记录请求 ID。

强制规则而非意见的提示结构

风格提示失败的原因通常是听起来像偏好。好的审查提示应像一份合同:明确列出不可协商的项、清晰命名的例外,以及可预测的输出。

以两个短块开头:必须为真(必须满足的项)和可放宽之处(可例外的项)。然后加上一条决策规则:“如果不明确,标记为需要澄清。不要猜测。”

强制要求证据。当工具标记违规时,要求引用确切的标识符和文件路径,而不是模糊描述。这个单一限制可以减少大量来回沟通。

把作用范围限定得很紧:只对变更的行和直接受影响的代码路径发表评论。如果允许无关的重构,风格执行就会变成“重写整个文件”,人们会停止信任这些反馈。

这里有一个可以复用的结构:

Role: strict style guide reviewer.
Input: diff (or files changed) + style guide rules.
Non-negotiables: [list].
Allowed exceptions: [list].
Scope: ONLY comment on changed lines and directly impacted code paths. No unrelated refactors.
Evidence: Every finding MUST include (a) file path, (b) exact identifier(s), (c) short quote.
Output: structured compliance report with pass/fail per category + minimal fixes.

要求报告每次都保留相同的章节,即便某些章节写上“No issues found”:命名、分层、错误处理、日志。

如果报告写着“service 层泄露了 DB 细节”,它必须引用类似 internal/orders/service/order_service.go 的文件路径和确切调用(例如 db.QueryContext),这样你就能在不争论意图的情况下修复泄露。

步骤:构建风格检查提示工作流

风格指南之所以能坚持,是因为流程可重复。目标是让模型检查规则,而不是争论喜好,并且每次都用同样的方式执行。

使用一个简单的两遍工作流:

  1. 把你的标准粘贴成紧凑的编号规则列表(10–25 行)。保持每条规则可测试。
  2. 添加变更的上下文:diff、被触及的文件,以及一句话的意图说明。
  3. 首先要求生成违规报告。要求包含文件和行引用、简短理由以及确切的规则编号。
  4. 只有在得到报告后,要求给出达到合规的最小补丁。
  5. 在更新代码后,用完全相同的提示重新运行以确认没有遗留问题。

举例:一个 PR 添加了新端点。第一遍会标出 handler 直接访问 PostgreSQL(分层违规)、请求结构体命名混用(命名违规)、以及日志记录了完整邮箱(日志违规)。第二遍给出最小修复:把 DB 调用移到 service/repository,重命名结构体,并在日志中对邮箱做脱敏。其他内容不变。

命名约定:捕捉那些看似微小的问题

命名问题看起来微不足道,但它们会带来真实成本:人们误读意图、搜索变困难、以及“几乎相同”的名字会成倍增长。

明确说明审查者必须在整个变更中执行的命名规则:文件名、导出类型、函数、变量、常量和测试的命名。明确大小写(camelCase、PascalCase、snake_case),并选定一个缩写规则(例如 APIClient vs ApiClient)。然后在所有地方强制执行。

还要统一共享词汇:错误类型、日志字段和配置键。如果日志用 request_id,就不要允许某处使用 reqId,另一处使用 requestId

一个实用的审查指令:

Check every new or renamed identifier. Enforce casing + acronym rules.
Flag vague names (data, info, handler), near-duplicates (userId vs userID), and names that contradict behavior.
Prefer domain language: business terms over generic tech words.

要求一份简短报告:三处最令人困惑的名称、任何近似重复项以及应保留的那个名称,还有任何不符合标准的日志/配置/错误名称。

分层规则:防止职责混淆

把团队带入统一流程
邀请团队成员在同一流程中工作,并保持审查一致性。

分层规则用简单语言表达效果最好:handlers 处理 HTTP,services 保存业务规则,repositories 访问数据库。

锁定依赖方向。Handlers 可以调用 services;services 可以调用 repositories。Repositories 不应调用 services 或 handlers。Handlers 不应引入数据库代码、SQL 助手或 ORM 模型。如果使用共享包(config、time、IDs),保证它们不含应用逻辑。

把横切关注点固定到一个“家”:校验通常属于边界(请求形状),而业务规则的校验属于 service。授权通常从 handler 开始(身份、权限),但 service 应当强制执行最终决定。映射应发生在层的边界:handler 将 HTTP 映射到领域输入,repository 将 DB 行映射到领域类型。

把下面这段放入提示以保持审查具体:

Check layering: handler -> service -> repository only.
Report any leaks:
- DB types/queries in handlers or services
- HTTP request/response types inside services or repositories
- repository returning DB models instead of domain objects
- auth/validation mixed into repository
For each leak, propose the smallest fix: move function, add interface, or rename package.

让报告具体:列出文件、它属于哪个层、哪个 import 或调用破坏了规则,以及防止该模式扩散的最小改动建议。

错误处理约定:在压力下保持一致

大多数风格争论在生产出现问题时最激烈。明确的错误处理策略能让修复保持冷静,因为大家都知道“好的做法”是什么。

写下哲学并执行它。例如:“包装错误以添加上下文;只有在改变语义或映射到用户消息时才创建新错误。在系统边界外返回原始错误。” 这一句话能防止随机模式蔓延。

把面向用户的文本和内部细节分开。用户消息应简短且安全。内部错误可以包含操作名和关键标识,但不能包含秘密。

在审查中检查几个常见失误:吞掉错误(记录但不返回)、含糊的返回(在失败后返回 nil 值且 error 也是 nil)、以及向用户暴露堆栈跟踪、查询文本、令牌或 PII 的信息。如果支持重试或超时,要求显式声明它们。

举例:结账调用超时。用户看到“Payment service is taking too long.”。内部则应包装超时并包含 op=checkout.charge 和订单 ID,以便可搜索和可操作。

日志约定:可读、可搜且安全

只有大家以相同方式写日志时,日志才有用。如果每个开发者选择自己的用语、级别和字段,搜索会变成猜测。

把日志级别设为不可协商:debug 用于开发细节,info 用于正常里程碑,warn 用于意外但已处理的情况,error 用于用户可见的失败或需要关注的情况。把“fatal”或“panic”保持稀少并与明确的崩溃策略绑定。

结构化日志比完美句子更重要。要求稳定的键名以免仪表盘和告警破裂。决定一小套核心字段(例如 event、component、action、status、duration_ms)并保持一致。

把敏感数据视为硬性终止条件。明确列出绝对禁止记录的内容:密码、认证令牌、完整的信用卡号、秘密和原始个人数据。点出那些看起来无害但其实不安全的项,比如密码重置链接、会话 ID 和完整请求体。

关联 ID 使跨层调试成为可能。要求每条与请求相关的日志都包含 request_id。如果要记录 user_id,定义允许的场景以及如何表示缺失或匿名用户。

下面是一段可复用的提示块:

Review the changes for logging conventions:
- Check level usage (debug/info/warn/error). Flag any level that does not match impact.
- Verify structured fields: require stable keys and avoid free-form context in the message.
- Confirm correlation identifiers: request_id on all request-bound logs; user_id only when allowed.
- Flag any sensitive data risk (tokens, secrets, personal data, request/response bodies).
- Identify noisy logs (in loops, per-item logs, repeated success messages) and missing context.
Return: (1) violations with file/line, (2) suggested rewrite examples, (3) what to add or remove.

在合并前做一次快速“安全检查”:任何新日志缺少 request_id(针对请求工作)、任何改变现有键名的新键(userId vs user_id)、任何错误日志缺少失败的描述(操作、资源、状态)、任何会在每个请求触发的高频日志,以及任何可能在字段或消息中出现秘密或个人数据的情况,都应被标记。

如何在问题扩散前捕捉违规

安全快速地发布
快速部署应用,以便在不匆忙把凌乱修复推到主分支的情况下测试行为。

把风格漂移当作构建失败,而不是建议。加一个严格的门禁,在合并前运行并返回明确的通过或不通过。如果违反了必须的规则(命名、层边界、日志安全、错误处理)则判为不通过并指出确切的文件和行。

把门禁保持简短。一个实用技巧是要求每条规则给出 YES/NO 检查表,只要有任何一项为 NO 就拒绝批准。

一个能捕捉大多数问题的 PR 大小检查表:

  • 命名:文件、类型和函数名符合批准的模式。
  • 分层:没有直接跳层的调用(例如 handlers 直接调用 DB)。
  • 错误:返回时带有上下文,未被静默丢弃。
  • 日志:字段一致、无秘密、级别与影响相符。
  • 测试/文档:当行为或公共 API 改变时已更新。

当工具建议修复时,要求为它触及的每条规则提供一小段合规代码片段。这能避免模糊的反馈,如“重命名以提高清晰度”。

使用提示进行风格执行时常见的陷阱

风格指南失败最快的方式是留下解释空间。如果两个审查者读同一条规则会得出不同结论,工具就会在执行品味而不是标准。

命名就是一个常见例子。“使用清晰名称”不可测试。把它收紧为可验证的语言:“函数用动词(例如 createInvoice),布尔值以 is/has/can 开头,导出类型用 PascalCase。”

另一个陷阱是一次性要求所有内容。当一个提示尝试涵盖命名、分层、错误、日志、测试和性能时,反馈往往泛泛。需要深度时把审查拆成有重点的几遍,或者把门禁提示限制在必须的规则上。

最常导致执行漂移的问题:

  • 模糊规则:把“干净”和“一致”替换为可衡量的语言。
  • 把样式修复和重设计混淆:不要让风格提示提出新架构。
  • 无引用证据:要求每条评论引用确切的标识符或片段。
  • 无声的例外:如果允许例外,要求写一条简短说明解释为什么以及何时应移除。

如果你把提示当作测试,就能获得可预测的执行;如果把它当成建议,违规就会潜入并扩散。

每次变更可以运行的快速检查表

把规范变成计划
在编码前在 Planning 模式下起草命名、分层、错误和日志规则。

对 diff(而不是整个仓库)做一次快速检查并确认:

  • 命名: 新标识符遵循你的模式(大小写、前缀、后缀)。同一概念在各文件中使用同一名称。
  • 分层: 依赖只朝允许的方向流动。下层绝不导入上层。
  • 错误: 失败返回时带上下文。没有被静默忽略的错误。
  • 日志: 级别正确、字段稳定、无秘密或个人数据。
  • 最终结论: 审查者明确声明:“no mandatory violations found” 或列出必须在合并前修复的违规项。

保留一个简短的提示模板,并在每次变更时粘贴:

Review ONLY the changed code against our rules for naming, layering, errors, and logging.
List mandatory violations first (with file + line if available). Then list optional suggestions.
End with either: “no mandatory violations found” or “mandatory violations found”.

举例:在 handler 中新增一个 procUsr() 函数并直接写入 PostgreSQL,即使功能可用也应因命名和分层违规而失败。在这里捕获它能防止复制粘贴把错误扩散开来。

示例:一个现实的审查流程,在早期修复问题

一位同事新增了端点:POST /v1/invoices/{id}/send。它触及了 handler、service 和 storage。

第一遍你想要的是报告而不是重写:

Pass 1 (report only)
You are a strict style checker. Read the patch.
Rules: naming must match our guide, handlers call services only, services call storage only, no SQL in handlers,
errors must be wrapped with context, logs must be structured and not leak PII.
Output: a numbered list of violations with file:line, rule name, and one-sentence impact. Do not propose fixes.
If a rule might be intentionally broken, ask one clarification question.

典型发现包括:SendInvoiceNow()SendInvoice 的命名不一致、handler 直接调用 db.QueryRow、返回原始 err 且未加上下文、以及像 log.Printf("sending invoice %v", invoice) 这类会转储完整对象的噪声日志。

第二遍要求最小且安全的改动建议:

Pass 2 (minimal fix suggestions)
Using the violations list, propose the smallest code edits to comply.
Constraints: keep behavior the same, no refactors beyond what is needed, show suggested function names and where code should move.
For each fix, include 1-2 lines of example code.

如果允许破坏规则,需要先说明:“仅在添加一条短注释解释原因并添加后续任务以移除例外时才允许例外。”

修复后,handler 变得瘦小,仅作适配;service 负责工作流;storage 负责查询;错误变为 fmt.Errorf("send invoice: %w", err);日志变为一行干净的、只记录安全字段(如发票 ID,而不是完整发票)。

接下来的步骤:常态化而不拖慢节奏

选一个团队认可的提示并把它当作共享工具开始使用。从审查中最常惹你麻烦的点开始(命名漂移、层泄露、不一致的错误、不安全的日志)。仅当你在真实代码中看到实际违规时才更新提示。

在提示顶部保留一小段规则块,并在每次审查时不变地粘贴它。如果每次人人都编辑规则,你得到的就不是标准,而是辩论。

一个简单的节奏有帮助:每周由一人收集最常见的风格错误,并恰好添加一条更明确的规则或一个更好的示例。

如果你在像 Koder.ai (koder.ai) 这样的聊天驱动构建流程中工作,值得在变更过程中而不是仅在结束时运行相同的门禁检查。规划、快照和回滚等功能可以帮助你在导出源代码前把风格修复保持小且可撤回。

常见问题

为什么细小的风格指南违规会迅速蔓延?

风格指南违规之所以传播得很快,是因为开发者会复制附近的代码,尤其是在赶进度时。把第一个不一致的模式视为需要审查的问题,避免它成为下一个人的范例。

如何让风格指南规则可测试?

规则应当能让人根据 diff 进行检查。例如,写明“处理程序只能调用服务”或“绝不记录令牌”,而不是要求代码整洁或一致。

哪些风格规则应该阻止拉取请求?

使用三个级别:强制规则会阻止合并,推荐规则需要说明跳过的理由,可选规则永远不会阻止合并。这样能避免审查者把每项偏好都当成同样紧急的问题。

Claude Code 风格审查提示词应包含哪些内容?

包括变更的 diff、精简的编号规则列表、变更意图和固定的报告格式。要求每项发现都注明文件、准确的标识符或代码引用、规则编号,以及最小的合规修复方案。

如何避免风格审查变成全面重写?

将审查限制在变更的行和直接受影响的路径内。先要求提供违规报告,只有在你认同这些发现后,再请求最小补丁。

审查应发现哪些命名问题?

选择一条大小写规则和一条首字母缩略词规则,然后将其应用于文件、类型、函数、变量、测试、日志字段和配置键。还应拒绝同一概念的近似重复命名,例如 userIDuserIduid

审查应如何强制执行层级边界?

清楚说明允许的方向:处理程序到服务再到仓储。标记处理程序中的数据库查询、服务或仓储中的 HTTP 类型,以及返回数据库模型而非领域对象的仓储。

错误处理审查应查找什么?

要求错误携带有用的操作上下文,但不要在用户消息中暴露内部细节。标记被吞掉的错误、失败后含糊的成功返回,以及泄露查询、令牌、堆栈跟踪或个人数据的消息。

哪些日志规则应当是强制性的?

使用稳定的结构化字段,并让日志级别与影响相匹配:debug 用于开发细节,info 用于正常里程碑,warn 用于已处理的意外情况,error 用于失败的用户操作。每条与请求相关的日志都应包含 request_id,日志绝不能包含密钥、令牌、完整请求体或原始个人数据。

如何在违规成为常态之前发现它们?

在每次合并前运行同一道简短检查,并明确给出通过或失败的结果。检查命名、允许的依赖关系、错误处理、日志安全性,以及受公共行为变更影响的测试或文档。

Related posts