security-guidance 插件对 end-of-turn 评审和 commit review 明确声明”不使用编写代码的同一 Claude 实例进行自我评审”,这一约束在生产评估中关键——自我评分容易陷入”先合理化、再打勾”的偏差。落地方式是用 Claude Agent SDK 启动一个独立的子代理实例,把评审上下文与作者上下文物理拆开,再喂入独立的安全提示词。下面拆解这个机制。
一、为什么要做独立评审
让同一个模型对刚写完的代码再做一次安全评审,形式上合规,本质上无效。模型对自己的产物天然有”维护合理化”的倾向,简单的字符串匹配能挡住 eval 这类明显危险模式,但拦不住”把用户输入直接拼进 SQL”这种需要换视角才看得出的漏洞。
插件官方文档写得很直接:”The plugin does not ask the same Claude instance that wrote the code to grade itself.” 这条声明不是宣传话术,是插件设计的第一原则。围绕这条原则,end-of-turn 评审和 commit review 都必须把”作者 Claude”和”评审 Claude”放到两个互不可见的上下文里。
二、Agent SDK 在 commit review 中的角色
commit review 是三层防御里最深的一层,也是唯一调用 Agent SDK 启动子代理的层。/plugin install security-guidance@claude-plugins-official 装好之后,插件首次运行会在 ~/.claude/security/ 下创建虚拟环境,并把 claude-agent-sdk 安装进去。Claude Code 通过这个 SDK 启动一个拥有独立上下文窗口的子代理,子代理拿到一段”安全评审提示词”作为系统提示,再读取作者 Claude 这一回合产生的 git diff、调用方、sanitizer 等周边代码做判断。
三个细节决定它能真隔离:
- 子代理上下文是全新的——没有作者 Claude 的会话历史、推理草稿、目标函数继承;
- 系统提示是一份安全专用 prompt,与作者 Claude 的角色 prompt 完全独立;
- 工具调用、权限模式、模型选择都可在子代理里重新配置,例如用
SG_AGENTIC_MODEL覆盖默认模型。
这套机制的副作用是耗时:commit review 是 agentic 的,子代理会读多个文件。文档给出的节流是 1 小时滚动窗口最多 20 次 commit 评审。
三、end-of-turn 评审的实现路径
end-of-turn 评审跑在每回合结束之后,作者 Claude 把回合内所有改动(含 edit、Bash、子代理产生的修改)打成 git diff,再把 diff 送到一个独立的 Claude 实例。这一层不调用 Agent SDK,因为它不需要跨文件读上下文,只做 diff 级别的安全分析。
| 维度 | end-of-turn 评审 | commit review |
|---|---|---|
| 触发时机 | 回合结束 | git commit / git push 落点 |
| 评审深度 | diff 级别,串行逻辑审查 | 跨文件阅读,判断是否为误报 |
| 隔离手段 | 新建独立 Claude 实例 | 通过 Agent SDK 启动子代理 |
| 评审 prompt | 安全专用 prompt | 安全专用 prompt(含周边代码读取) |
| 默认模型 | 独立模型选择 | 独立模型选择 |
| 节流 | 单回合最多 3 次连续触发 | 1 小时滚动窗口最多 20 次 |
| 文件上限 | 单回合最多 30 个改动文件 | 无单独上限 |
两个评审的共同点是:评审提示词与作者 Claude 的系统提示互相独立。差异在于 commit review 让子代理去翻上下文(callers、sanitizers、相关配置),以减少误报;end-of-turn 评审只看 diff,速度快但容忍一定误报。
四、独立 prompt 是怎么写出来的
隔离了上下文还不够,prompt 本身也要换身份。官方文档没把完整 prompt 公开,但可以从插件行为反推几个稳定要素:
- 角色声明:评审者是”独立安全审计员”,不是”作者协作者”;
- 任务定义:只关注 OWASP 常见类别(注入、不安全反序列化、IDOR、SSRF、弱加密、授权绕过);
- 输出格式:每条 finding 包含文件路径、行号、风险描述、修复建议,便于作者 Claude 二次处理;
- 决策边界:要求评审者区分”理论风险”与”已被 sanitizer 抵消的风险”,避免空喊狼来了。
# .claude/claude-security-guidance.md(项目级自然语言补充规则示例)
- 所有路由必须在数据库访问前调用 require_role 进行权限校验
- 使用 timingSafeEqual 比较 token,禁止使用 === 直接比较
- 不得在 INFO 及以上级别日志中输出 customer_id
这段配置会被合并进评审 prompt,文件搜索顺序为:用户级 ~/.claude/claude-security-guidance.md → 项目级 .claude/claude-security-guidance.md → 本地覆盖 .claude/claude-security-guidance.local.md,合并后总大小限制为 8 KB。
五、把独立评审落到生产
按下面五步把插件装好并启用独立评审:
- 在 Claude Code 会话里执行
/plugin marketplace add anthropics/claude-plugins-official,把官方市场加进 sources; - 执行
/plugin install security-guidance@claude-plugins-official,按提示选择 user scope,让插件在每台机器的本地会话自动加载; - 执行
/reload-plugins应用新插件,不重启会话; - 第一次 commit 触发时观察
~/.claude/security/是否自动创建、Agent SDK 是否安装成功;若失败,commit review 会自动回退到 single-shot 模式; - 在项目根的
.claude/claude-security-guidance.md写入本项目特有的安全规则,提交到仓库。
效果:每回合结束自动收到安全 finding、每次 commit 自动获得跨文件复核。注意点:commit review 在 Windows 上跳过虚拟环境创建,仅当 claude-agent-sdk 已 importable 时才走 agentic 路径,否则回退 single-shot;非 git 仓库中 end-of-turn 与 commit review 会静默跳过。
六、与其他安全工具的协同
插件官方明确”不替代 Code Review”——它是 in-session 的”前置拦截器”。生产评估中,Code Review 负责 PR 阶段的多代理深度评审,security-guidance 负责”代码刚写完、PR 还没提”这个空档的兜底。在企业里,配合 /security-review 命令做按需扫描、CI 里加 SAST/SCA 工具做兜底,三层纵深才完整。
常见问题(FAQ)
Q1:独立评审是不是等于用不同模型?
不等价。独立评审指”独立上下文 + 独立 prompt”,模型可以相同;插件默认虽用不同模型,但隔离靠的是 SDK 与 prompt 拆分。
Q2:commit review 失败回退到 single-shot 损失什么?
失去跨文件阅读能力,误报率上升;仅基于 diff 做字符串级匹配,复杂漏洞容易漏判。
Q3:可以在评审里关闭模型调用吗?
可以禁用第二、第三层;第一层 per-edit 模式本就是无模型调用的纯字符串匹配,可独立启用。