Skip to content

Five Layer Defense

wangliang edited this page Jul 25, 2026 · 3 revisions

五层防御体系

ai-coding-ok v3.1+ 如何保证 PDCA 循环永不跳过——即使在长会话、短指令和边缘场景下。


问题:纯文本指令不够

早期版本的 ai-coding-ok 完全依赖 Markdown 中的"⚠️ 必须在编码前读取记忆文件"这样的文字指令。实践中,AI 模型会在以下情况下跳过:

  • 会话过长(30+ 轮,早期指令被挤出上下文)
  • 用户给出简短指令("加个搜索功能")
  • AI 在多轮编码后进入"惯性模式"
  • 子 agent 未继承 PDCA 指令

解决方案: 纵深防御体系,每一层独立捕获 PDCA 违规。


五层架构

graph TB
    subgraph "第一层:最硬"
        L1[CLAUDE.md<br/>⛔ STOP — 任何代码工作前必须先调用 Skill<br/>会话启动时自动加载]
    end
    subgraph "第二层:全平台"
        L2[AGENTS.md<br/>7 步 Plan 强制要求 + 4 步 Act 强制要求<br/>AI 每次任务首先读取]
    end
    subgraph "第三层:全平台"
        L3[copilot-instructions.md<br/>强制记忆更新输出章节<br/>响应中不可省略]
    end
    subgraph "第四层:Claude Code"
        L4[Claude Code Hooks<br/>SessionStart + UserPromptSubmit + PreToolUse + Stop<br/>Exit 2 阻断未完成 Act 的会话]
    end
    subgraph "第五层:Claude Code"
        L5[安装时自动配置<br/>SOURCE_DIR_PATTERN 正则<br/>Hooks 只在源码文件变更时触发]
    end
    L1 --> L2 --> L3 --> L4 --> L5
Loading

第一层:CLAUDE.md STOP 指令

平台: Claude Code
机制: CLAUDE.md 在 Claude Code 会话启动时自动加载。内容:

⛔ STOP — CALL Skill("ai-coding-ok") BEFORE ANY CODE WORK.
THEN CALL Skill("ai-coding-ok") AFTER ALL WORK.
THIS IS NON-NEGOTIABLE.

@AGENTS.md

为什么有效: Claude Code 无法跳过加载 CLAUDE.md。第一行是 STOP 指令——AI 在处理任何用户请求前先看到它。@AGENTS.md 导入拉取完整的 PDCA 强制要求。

捕获的失效场景: 新会话 + 简短指令("加个登录页")——Claude Code 先加载 CLAUDE.md,命中 STOP,调用 skill。


第二层:AGENTS.md Plan + Act 强制要求

平台: 全平台(Claude Code、Copilot、Cursor、OpenCode)
机制: AGENTS.md 顶部包含明确指令:

## ⚠️ AI Agent 必读规范(每次任务必须执行)

### Plan 阶段(强制,任务开始前)
1. 读取 AGENTS.md
2. 读取 system-prompt.md
3. 读取 workflows.md
4. 读取 coding-standards.md
5. 读取 project-memory.md
6. 读取 decisions-log.md
7. 读取 task-history.md

### Act 阶段(强制,任务结束后)
1. 更新 task-history.md(始终)
2. 更新 decisions-log.md(架构变更时)
3. 更新 project-memory.md(事实变更时)
4. 同步更新过时的 agent 文档

> ⛔ 以上步骤不可跳过。

为什么有效: 这是 AI 进入任务时读取的第一个文件。"强制"和"不可跳过"配合 7 步检查清单,难以忽略。

捕获的失效场景: 第一层失效(CLAUDE.md 某原因未加载)。AGENTS.md 作为架构速查始终被读取。


第三层:copilot-instructions.md 强制输出章节

平台: 全平台(Copilot 自动加载,其他工具读取)
机制: .github/copilot-instructions.md 要求 AI 响应必须包含 ## 记忆更新 章节:

## 输出格式(必须包含所有章节)

每次响应必须包含:
- ## 摘要
- ## 变更内容
- ## 记忆更新(⚠️ 必填)
  - task-history.md:[已更新 / 无需变更]
  - decisions-log.md:[已更新 / 无需变更]
  - project-memory.md:[已更新 / 无需变更]

为什么有效: AI 无法"完成"而不包含此章节。如果试图省略,格式约束会标记响应为不完整。

捕获的失效场景: AI 编码完成,试图在未更新记忆的情况下结束响应。输出格式要求记忆更新章节——至少必须确认每个文件。


第四层:Claude Code Hooks

平台: 仅 Claude Code
机制: .claude/settings.local.json 中的四个 hooks:

Hook 触发时机 作用
SessionStart 会话启动 验证环境就绪,提醒 PDCA
UserPromptSubmit 用户提交提示 检测是否为编码任务,提醒 Plan
PreToolUse AI 即将使用工具 阻断危险操作(git push、SSH 等)
Stop 会话即将结束 检查 task-history.md 是否已更新

Stop hook(最关键)

如果 task-history.md 在会话期间未被修改,Stop hook 以退出码 2 结束。这阻断会话结束,并通过 asyncRewake: true 唤醒 AI,提示执行 Act 阶段。

为什么有效: 这是机械约束,不是文字指令。AI 无法绕过——如果记忆未更新,会话字面上无法结束。

捕获的失效场景: AI 编码完成,未更新记忆,试图结束会话。Stop hook 触发,exit 2,唤醒 AI 完成 Act。


第五层:安装时自动配置

平台: 仅 Claude Code
机制: 在 Mode A(安装)期间,hooks 中的 {{SOURCE_DIR_PATTERN}} 占位符被替换为用户的实际源码目录:

用户说:"src/ tests/"
→ 正则:^src/\\|^tests/

这确保 hooks 只在源码文件变更时触发——而非项目中的每个文件。

为什么有效: 没有这层,hooks 会因 README.md、package.json 等文件变更而触发,产生噪音和误报。模式范围限定使 hooks 真正实用。


防御覆盖矩阵

场景 第一层 第二层 第三层 第四层 第五层
新会话、简短指令
长会话(30+ 轮) ⚠️
子 agent ⚠️ ⚠️
"改个 typo"
用户明确说跳过
Copilot(无 hooks)
Cursor(无 hooks)

✅ = 捕获 | ⚠️ = 部分覆盖 | ❌ = 不适用


平台覆盖

平台 可用层级 PDCA 强制力
Claude Code 全部 5 层 🛡️🛡️🛡️🛡️🛡️ 最高
GitHub Copilot 第 2-3 层 🛡️🛡️🛡️ 强
Cursor 第 2-3 层 🛡️🛡️🛡️ 强
OpenCode 第 2-3 层 🛡️🛡️🛡️ 强

设计原则

每一层独立工作——如果一层失效,下一层接住。没有单点故障。

"不要把鸡蛋放一个篮子里。放五个篮子,每个篮子形状不同。"——ai-coding-ok 防御哲学


下一步

Clone this wiki locally