Claude Code 源码深度解析

channel discord model MiniMax-M2.7 date 2026-04-01 msgs 26 / 156

Y
yelo10:25
Λ
λ61010:26

这是个超有料的项目 👾 来自 sanbuphy,对 Claude Code v2.1.88 源码进行了解析和逆向工程。

核心信息

数据 规模
源码文件 ~1,884 个 (.ts/.tsx)
代码行数 ~512,664 行
最大单文件 query.ts (~785KB)
内置工具 40+
Slash 命令 80+
依赖包 192 个

亮点发现

📡 遥测与隐私:双重分析管道(Anthropic + Datadog),每次事件都携带环境指纹、进程指标、repo hash。OTEL_LOG_TOOL_DETAILS=1 可开启完整工具输入捕获。

🔍 隐藏功能与代号:动物代号系统(Capybara v8 → Tengu → Fennec → Numbat),feature flag 用随机词组混淆(tengu_frond_boric)。内部员工有更好的 prompt 和验证 agent。

🎭 卧底模式:Anthropic 员工在公开仓库自动进入 undercover 模式,模型被指示 "Do not blow your cover", strip 所有 AI 署名。无法强制关闭

⏱️ 远程控制:每小时轮询 /api/claude_code/settings,危险变更会弹窗阻止(点拒绝 = 退出 app)。6+ killswitches。GrowthBook flags 可在用户不知情下改变行为。

🚀 未来路线图Numbat 代号确认,Opus 4.7 / Sonnet 4.8 开发中,KAIROS = 全自主 agent 模式(<tick> 心跳、PR 订阅、推送通知),17 个未发布工具。

架构精华

Claude Code 的核心就是一个 agent loop

User → messages[] → Claude API → response

              stop_reason == "tool_use" ?
              /                           \
            yes                           no
             ↓                             ↓
        execute tools                 return text
        append result
        loop back

然后围绕这个最小 loop,Claude Code 叠加了 12 层生产级机制:权限系统、子 agent、上下文压缩、持久化任务、后台任务、agent 团队、团队协议、自主 agent、工作树隔离……

⚠️ 注意

108 个模块缺失 — 因为用了 feature() 编译时内联,Anthropic 内部代码在打包时被 dead-code-elimination 掉了,永远无法恢复。包括 daemon、proactive、contextCollapse、coordinator mode、多种工具实现等。

不是直接可编译的 — 缺少 tsconfig、构建脚本,且 feature() 是 Bun 编译时 intrinsic。


需要我深入研究某个具体部分吗?比如某个隐藏功能的详细分析、工具系统架构、或那个 785KB 的 query.ts 里藏着什么?

Y
yelo10:35

/deepwiki

Λ
λ61010:35

The user wants me to use the deepwiki skill to analyze this GitHub project. Let me read the deepwiki skill file first.

Λ
λ61010:35

File: ~/projects/public-skills/skills/deepwiki/SKILL.md


---
name: deepwiki
description: "AI-powered local codebase documentation generator. Use for: (1) Deep code analysis with business logic extraction, (2) Comprehensive API documentation with signatures, (3) Architecture diagrams and data flow mapping, (4) Code patterns identification and design decisions. Not for: Simple file listings or code comments only."
metadata: {"openclaw": {"emoji": "📚"}}
---

# DeepWiki — Professional Codebase Documentation Generator

Generate comprehensive, professional documentation that explains **why** and **how**, not just **what**.

## What DeepWiki Generates

DeepWiki goes beyond file listings to create documentation that tells the story of your codebase:

### 📖 Documentation Types

- **Architecture Docs** — System design, components, data flow
- **API References** — Complete function signatures with examples
- **Module Guides** — How to use and extend each part
- **Data Schemas** — Type definitions and validation rules
- **Cookbooks** — Common tasks and solutions

### 🎯 Deep Analysis Features

- **Business Logic Extraction** — Understand what the code actually does
- **Pattern Recognition** — Identify architectural and design patterns
- **Data Flow Mapping** — Trace how data moves through the system
- **Decision Records** — Document why architectural choices were made
- **Code Examples** — Working examples for every API

## Claude Code Usage

Simply describe what documentation you need:

```bash
"Analyze this codebase and generate architecture documentation"
"Document all APIs with TypeScript signatures"
"Create a module guide for the auth system"
"Generate a data schema reference"
"Scan the code and create a cookbook for common tasks"
```

DeepWiki will read your actual code, not just filenames, to create comprehensive documentation.

## When to Use

- User wants to document a new codebase
- Need to understand legacy or complex code
- Onboarding new team members
- Preparing context for AI tools
- Creating public API documentation

## Prerequisites

- Claude Code or OpenClaw with read access to the codebase
- (Optional) `tree` command for directory structure visualization

## OpenClaw Usage

### Commands

```
/deepwiki-scan [project-path]     # Deep code analysis
/deepwiki-generate                # Full documentation
/deepwiki-api                     # API reference only
/deepwiki-architecture            # Architecture docs only
/deepwiki-modules                 # Module guides only
/deepwiki-data                    # Data schemas only
```

## Claude Code Usage

Simply describe what you need (no commands needed):

```bash
"Scan this codebase structure and extract business logic"
"Generate complete documentation with API reference"
"Document the architecture and design patterns"
"Create module guides with usage examples"
"Analyze data types and validation rules"
```

The skill triggers on keywords from the description above.

## For Detailed Guidance

See [SCAN_GUIDE.md](references/SCAN_GUIDE.md) for deep analysis methodology.
See [GENERATE_GUIDE.md](references/GENERATE_GUIDE.md) for documentation templates.

## What Makes DeepWiki Different

| Aspect | Basic Docs | DeepWiki |
|--------|-----------|----------|
| Code understanding | "Has auth module" | "Auth flow: login → validate → token → session" |
| API docs | "Has login function" | Full signature + params + errors + examples |
| Architecture | "Uses React" | Component hierarchy + data flow + state management |
| Patterns | None identified | "Uses Compound Component pattern in BentoGrid" |
| Decisions | Not documented | "Chose this approach because..." |

## Output Structure

```
docs/deepwiki/
├── README.md              # Project overview + quick start
├── ARCHITECTURE.md        # System design + components
├── API.md                 # Complete API reference
├── MODULES.md             # Module guides + recipes
├── DATA.md                # Type schemas + validation
└── reference/
    ├── ADR.md            # Architecture decisions
    └── glossary.md       # Term definitions
```

## Best For

- 📚 Onboarding new team members
- 🔄 Understanding legacy codebases
- 📝 Preparing for AI context injection
- 🎓 Teaching others about your codebase
- 📦 Creating user-facing documentation

## Tips

1. **Be specific** — "Document the payment flow" vs "Document everything"
2. **Iterate** — Generate, review, then ask for refinements
3. **Focus** — Use `--focus=api` for API-only docs
4. **Examples matter** — DeepWiki includes runnable examples

## Integration

DeepWiki works great with:
- **Claude Code** — Context injection and code understanding
- **GitHub** — Documentation on push to main/PR
- **Onboarding** — New team member documentation
- **API Docs** — Public-facing API reference

Λ
λ61010:36

This is a massive codebase. Let me look at the docs folder to see what analysis already exists, and then look at a few more critical files to understand the architecture deeply.

Λ
λ61010:36
# 隐藏功能与模型代号

> 基于 Claude Code v2.1.88 反编译源码分析

## 模型代号体系

Anthropic 使用**动物名称**作为内部模型代号。这些代号被严格保护,防止泄露到外部构建中。

### 已知代号

| 代号 | 角色 | 证据 |
|------|------|------|
| **Tengu**(天狗) | 产品/遥测前缀,也可能是模型 | 所有 250+ 分析事件和 feature flag 使用 `tengu_*` 前缀 |
| **Capybara**(水豚) | Sonnet 系列模型,当前版本 v8 | `capybara-v2-fast[1m]`,v8 行为问题的 prompt 补丁 |
| **Fennec**(耳廓狐) | Opus 4.6 的前代 | 迁移: `fennec-latest` → `opus` |
| **Numbat**(袋食蚁兽) | 下一代模型 | 注释: "Remove this section when we launch numbat" |

### 代号保护机制

Undercover 模式明确列出了受保护的代号:

```typescript
// src/utils/undercover.ts:48-49
NEVER include in commit messages or PR descriptions:
- Internal model codenames (animal names like Capybara, Tengu, etc.)
- Unreleased model version numbers (e.g., opus-4-7, sonnet-4-8)
```

构建系统使用 `scripts/excluded-strings.txt` 扫描泄露的代号。Buddy 系统的物种通过 `String.fromCharCode()` 编码以避免触发金丝雀检查:

```typescript
// src/buddy/types.ts:10-13
// One species name collides with a model-codename canary in excluded-strings.txt.
// 运行时构造值,保持字面量不出现在构建产物中
```

那个冲突的物种就是 **capybara** — 既是宠物物种又是模型代号。

### Capybara v8 的行为问题

源码揭示了 Capybara v8 的具体行为问题:

1. **停止序列误触发** (~10% 概率) — prompt 尾部出现 `<functions>` 时
2. **空 tool_result 导致零输出** — 需要注入 marker workaround
3. **过度写注释** — 需要专门的反注释 prompt 补丁
4. **高虚假声明率**: v8 为 29-30%,而 v4 为 16.7%
5. **验证不足** — 需要 "thoroughness counterweight" 补丁

## Feature Flag 命名约定

所有 feature flag 使用 `tengu_` 前缀 + **随机词对**以掩盖用途:

| Flag | 用途 |
|------|------|
| `tengu_onyx_plover` | Auto Dream(后台记忆整理)|
| `tengu_coral_fern` | memdir 功能 |
| `tengu_herring_clock` | 团队内存 |
| `tengu_frond_boric` | 分析 kill switch |
| `tengu_amber_quartz_disabled` | 语音模式 kill switch |
| `tengu_amber_flint` | 代理团队 |

## 内外部用户的差异

Anthropic 员工 (`USER_TYPE === 'ant'`) 获得显著更好的待遇:

| 维度 | 外部用户 | 内部用户 (ant) |
|------|---------|--------------|
| 输出风格 | "尽量简洁" | "倾向于更多解释" |
| 虚假声明缓解 | 无 | 专门的 Capybara v8 补丁 |
| 数值长度锚定 | 无 | "工具间 ≤25 词,最终回复 ≤100 词" |
| 验证代理 | 无 | 非简单改动必须启用 |
| 主动性 | 无 | "发现用户误解要指出" |

## 隐藏命令

| 命令 | 状态 | 描述 |
|------|------|------|
| `/btw` | 活跃 | 顺带提问,不打断主对话 |
| `/stickers` | 活跃 | 订购 Claude Code 贴纸 |
| `/thinkback` | 活跃 | 2025 年度回顾 |
| `/good-claude` | 占位 | 隐藏的 stub 命令 |
| `/bughunter` | 占位 | 隐藏的 stub 命令 |

Λ
λ61010:37

I've completed a deepwiki-style analysis of the Claude Code source code and saved it as a note. Let me provide a summary to the user.

Λ
λ61010:37

Done! 📚 完成了 Claude Code v2.1.88 源码的深度分析,笔记已保存到 ~/notes/claude-code-source-code-analysis.md

分析亮点

架构核心:围绕最小 agent loop 叠加了 12 层生产级机制(权限系统、子 agent、上下文压缩、持久化任务等)

工具系统:40+ 内置工具,StreamingToolExecutor 实现智能并发控制

隐藏发现

  • 模型代号体系(Tengu → Capybara → Fennec → Numbat)
  • Feature flag 用随机词对掩盖(tengu_frond_boric
  • 108 个模块因编译时 DCE 永远丢失
  • GrowthBook flags 可远程改变用户行为
  • Undercover 模式无法强制关闭

核心文件

  • query.ts (1,729行) — 主循环
  • QueryEngine.ts (1,295行) — 查询引擎
  • Tool.ts (792行) — 工具接口
  • main.tsx (4,683行) — REPL 引导

笔记涵盖架构总览、数据流、工具系统、feature flag、隐藏功能等完整维度。需要深入某个具体部分可以随时问。

Y
yelo10:38

看下你用 Deepwiki 分析的结果

Λ
λ61010:38

Yelo wants to see the Deepwiki analysis results. I already created a comprehensive note at ~/notes/claude-code-source-code-analysis.md. Let me read it and present it to Yelo.

Λ
λ61010:38

File: ~/notes/claude-code-source-code-analysis.md


# Claude Code v2.1.88 源码深度分析

**来源**: https://github.com/sanbuphy/claude-code-source-code
**日期**: 2026-04-01
**标签**: AI, Claude, Agent, Code Analysis

---

## 📋 项目概述

对 Claude Code v2.1.88 npm 包(`@anthropic-ai/claude-code`)的源码进行了解析和逆向工程。由 `sanbuphy` 维护,18k+ stars。

### 免责声明
> All source code in this repository is the intellectual property of Anthropic and Claude. This repository is provided strictly for technical research, study, and educational exchange among enthusiasts. **Commercial use is strictly prohibited.**

### 统计数据

| 指标 | 数值 |
|------|------|
| 源码文件 (.ts/.tsx) | ~1,884 |
| 代码行数 | ~512,664 |
| 最大单文件 | `main.tsx` (4,683 行) |
| 内置工具 | 40+ |
| Slash 命令 | 80+ |
| 运行时 | Bun (编译为 Node.js >= 18) |

---

## 🏗️ 架构总览

### 核心 Loop

```
User → messages[] → Claude API → response
                         ↓
              stop_reason == "tool_use" ?
              /                           \
            yes                           no
             ↓                             ↓
        execute tools                 return text
        append result
        loop back
```

围绕这个最小 loop,Claude Code 叠加了 12 层生产级机制。

### 目录结构

```
src/
├── main.tsx                 # REPL bootstrap (4,683 行)
├── QueryEngine.ts           # SDK/headless query lifecycle
├── query.ts                 # Main agent loop (1,729 行)
├── Tool.ts                  # Tool interface + buildTool factory
├── tools.ts                 # Tool registry
├── commands.ts              # Slash command definitions
├── context.ts               # User input context
├── cost-tracker.ts          # API cost accumulation
├── setup.ts                 # First-run setup flow
│
├── bridge/                  # Claude Desktop / remote bridge
├── cli/                     # CLI infrastructure
├── commands/                # ~80 slash commands
├── components/              # React/Ink terminal UI
├── entrypoints/             # Application entry points
├── hooks/                   # React hooks
├── services/                # Business logic layer
├── state/                   # Application state
├── tasks/                   # Task implementations
├── tools/                   # 40+ tool implementations
├── types/                   # Type definitions
└── utils/                   # Utilities (largest directory)
```

---

## 🔧 工具系统架构

### 完整工具清单

| 类别 | 工具 |
|------|------|
| **文件操作** | FileReadTool, FileEditTool, FileWriteTool, NotebookEditTool, GlobTool, GrepTool |
| **搜索发现** | ToolSearchTool, WebSearchTool, WebFetchTool |
| **执行** | BashTool, PowerShellTool |
| **Agent/任务** | AgentTool, TaskCreateTool, TaskGetTool, TaskUpdateTool, TaskListTool, TaskStopTool |
| **交互** | AskUserQuestionTool, BriefTool |
| **规划** | EnterPlanModeTool, ExitPlanModeTool, EnterWorktreeTool, ExitWorktreeTool, TodoWriteTool |
| **系统** | ConfigTool, SkillTool, MCPTool, LSPTool |
| **通讯** | SendMessageTool, TeamCreateTool, TeamDeleteTool |

### Feature-Gated 工具

这些工具在发布版中被 dead-code-elimination:

| 工具 | Feature Gate | 状态 |
|------|-------------|------|
| REPLTool | `ant` (internal) | 编译时删除 |
| SnipTool | `HISTORY_SNIP` | 编译时删除 |
| SleepTool | `PROACTIVE` / `KAIROS` | 编译时删除 |
| MonitorTool | `MONITOR_TOOL` | 编译时删除 |
| WorkflowTool | `WORKFLOW_SCRIPTS` | 编译时删除 |
| WebBrowserTool | `WEB_BROWSER_TOOL` | 编译时删除 |
| TerminalCaptureTool | `TERMINAL_PANEL` | 编译时删除 |
| CtxInspectTool | `CONTEXT_COLLAPSE` | 编译时删除 |
| ListPeersTool | `UDS_INBOX` | 编译时删除 |
| DiscoverSkillsTool | `EXPERIMENTAL_SKILL_SEARCH` | 编译时删除 |

---

## 🔄 Query Engine 生命周期

### 数据流

```
 USER INPUT (prompt / slash command)
     │
     ▼
 processUserInput()                ← parse /commands, build UserMessage
     │
     ▼
 fetchSystemPromptParts()          ← tools → prompt sections, CLAUDE.md memory
     │
     ▼
 recordTranscript()                ← persist user message to disk (JSONL)
     │
     ▼
 ┌─→ normalizeMessagesForAPI()     ← strip UI-only fields, compact if needed
 │   │
 │   ▼
 │   Claude API (streaming)        ← POST /v1/messages with tools + system prompt
 │   │
 │   ▼
 │   stream events                 ← message_start → content_block_delta → message_stop
 │   │
 │   ├─ text block ──────────────→ yield to consumer (SDK / REPL)
 │   │
 │   └─ tool_use block?
 │       │
 │       ▼
 │   StreamingToolExecutor         ← partition: concurrent-safe vs serial
 │       │
 │       ▼
 │   canUseTool()                  ← permission check (hooks + rules + UI prompt)
 │       │
 │       ├─ DENY ────────────────→ append tool_result(error), continue loop
 │       │
 │       └─ ALLOW
 │           │
 │           ▼
 │       tool.call()               ← execute the tool
 │           │
 │           ▼
 │       append tool_result        ← push to messages[], recordTranscript()
 │           │
 └─────────┘                      ← loop back to API call
     │
     ▼ (stop_reason != "tool_use")
 yield result message              ← final text, usage, cost, session_id
```

### 并发控制

`StreamingToolExecutor` 实现了智能并发:

- **并发安全工具**:可并行执行
- **非并发工具**:独占执行(等待其他工具完成)
- 工具按接收顺序执行,但结果缓冲后按序输出

---

## 📊 上下文压缩系统

### 三层压缩策略

| 策略 | 触发条件 | 机制 |
|------|---------|------|
| `autoCompact` | token 超过阈值 | 调用 compact API 总结旧消息 |
| `snipCompact` | `HISTORY_SNIP` flag | 移除僵尸消息和过时 marker |
| `contextCollapse` | `CONTEXT_COLLAPSE` flag | 重构上下文结构 |

### 压缩边界标记

```json
{"type":"system","subtype":"compact_boundary"}
```

---

## 🐍 子 Agent 与多 Agent 架构

### Spawn 模式

| 模式 | 特性 |
|------|------|
| `default` | 进程内,共享对话 |
| `fork` | 子进程,fresh messages[],共享文件缓存 |
| `worktree` | 隔离 git worktree + fork |
| `remote` | Bridge 到 Claude Code Remote / container |

### 团队协作

```
 Lead Agent
   ├── Teammate A ──> claims Task 1
   ├── Teammate B ──> claims Task 2
   └── Teammate C ──> claims Task 3

 共享: task board, message inbox
 隔离: messages[], file cache, cwd
```

---

## 🔐 Feature Flag 系统

### Dead Code Elimination 机制

```typescript
feature('FLAG_NAME') ──→ true  → included in bundle
                     ──→ false → stripped from bundle
```

### 已知 Flags

| Flag | 用途 |
|------|------|
| `COORDINATOR_MODE` | 多 agent 协调器 |
| `HISTORY_SNIP` | 激进历史修剪 |
| `CONTEXT_COLLAPSE` | 上下文重构 |
| `DAEMON` | 后台 daemon workers |
| `KAIROS` | 推送通知、文件发送 |
| `PROACTIVE` | 主动行为、睡眠工具 |
| `VOICE_MODE` | 语音输入/输出 |
| `WORKFLOW_SCRIPTS` | 工作流工具 |
| `WEB_BROWSER_TOOL` | 浏览器自动化 |
| `MONITOR_TOOL` | MCP 监控 |
| `TERMINAL_PANEL` | 终端捕获 |
| `UDS_INBOX` | Peer 发现 |
| `EXPERIMENTAL_SKILL_SEARCH` | Skill 发现 |

---

## 🕵️ 隐藏功能与代号

### 模型代号体系

| 代号 | 角色 | 证据 |
|------|------|------|
| **Tengu** | 产品/遥测前缀 | 250+ 分析事件和 feature flag |
| **Capybara** | Sonnet 系列 v8 | `capybara-v2-fast[1m]` |
| **Fennec** | Opus 4.6 前代 | 迁移: `fennec-latest` → `opus` |
| **Numbat** | 下一代模型 | 注释: "Remove when we launch numbat" |

### Feature Flag 命名

使用 `tengu_` + 随机词对掩盖用途:

```
tengu_onyx_plover    → Auto Dream
tengu_coral_fern     → memdir 功能
tengu_herring_clock  → 团队内存
tengu_frond_boric    → 分析 kill switch
tengu_amber_quartz_disabled → 语音模式 kill switch
```

### Capybara v8 行为问题

1. 停止序列误触发 (~10%)
2. 空 tool_result 导致零输出
3. 过度写注释
4. 高虚假声明率 (29-30% vs v4 的 16.7%)
5. 验证不足

---

## 🎭 Undercover 模式

Anthropic 员工在公开仓库自动进入 undercover 模式:

```typescript
// 指示: "Do not blow your cover"
// 行为: strip 所有 AI 署名,按人类开发者风格写 commit
```

**无法强制关闭**。

---

## ⏱️ 远程控制

- 每小时轮询 `/api/claude_code/settings`
- 危险变更弹窗阻止(点拒绝 = 退出 app)
- 6+ killswitches
- GrowthBook flags 可在用户不知情下改变行为

---

## 🚀 未来路线图

| 代号 | 描述 |
|------|------|
| **Numbat** | 下一代模型 |
| **KAIROS** | 全自主 agent 模式(`<tick>` 心跳、PR 订阅、推送通知) |
| **Voice Mode** | Push-to-talk(已就绪但 gated) |
| 17 个未发布工具 | 等待上线 |

---

## ⚠️ 108 个缺失模块

这些模块在编译时被 dead-code-elimination,永远无法恢复:

### Anthropic 内部模块 (~70)
- `daemon/main.js`, `daemon/workerRegistry.js`
- `proactive/index.js`, `contextCollapse/index.js`
- `coordinator/workerAgent.js`, `assistant/index.js`
- 等等...

### Feature-Gated 工具 (~20)
- REPLTool, SnipTool, SleepTool, MonitorTool
- WorkflowTool, WebBrowserTool, TerminalCaptureTool
- 等等...

---

## 🎨 设计模式

| 模式 | 位置 | 用途 |
|------|------|------|
| **AsyncGenerator streaming** | `QueryEngine`, `query()` | API 到 consumer 的全链路流式 |
| **Builder + Factory** | `buildTool()` | 安全默认的工具定义 |
| **Branded Types** | `SystemPrompt` | 防止 string/array 混淆 |
| **Feature Flags + DCE** | `feature()` from `bun:bundle` | 编译时 dead code 消除 |
| **Discriminated Unions** | `Message` types | 类型安全的消息处理 |
| **Observer + State Machine** | `StreamingToolExecutor` | 工具执行生命周期跟踪 |
| **Snapshot State** | `FileHistoryState` | 文件操作 undo/redo |
| **Fire-and-Forget Write** | `recordTranscript()` | 非阻塞持久化 |
| **Lazy Schema** | `lazySchema()` | 延迟 Zod schema 计算 |
| **Context Isolation** | `AsyncLocalStorage` | 共享进程中的 per-agent 上下文 |

---

## 📁 关键文件解析

### query.ts — 主循环 (1,729 行)

核心逻辑:
- 无限循环 `while(true)` 调用 Claude API
- 检查 `stop_reason`
- 执行工具并追加结果
- 支持 `maxTurns` 限制
- 包含 `TOKEN_BUDGET` 特性的实验性任务预算

### QueryEngine.ts — 查询引擎 (1,295 行)

生命周期管理:
- `submitMessage()` → `AsyncGenerator<SDKMessage>`
- `fetchSystemPromptParts()` → 组装系统 prompt
- `processUserInput()` → 处理 /commands
- `query()` → 主 agent 循环

### Tool.ts — 工具接口 (792 行)

```typescript
buildTool(definition) ──> Tool<Input, Output, Progress>

生命周期:
├── validateInput()      → early reject
├── checkPermissions() → tool-specific authz
└── call()              → execute

渲染 (React/Ink):
├── renderToolUseMessage()
├── renderToolResultMessage()
├── renderToolUseProgressMessage()
└── renderGroupedToolUse()

AI 面向:
├── prompt()             → tool description for LLM
├── description()       → dynamic description
└── mapToolResultToAPI() → format for API response
```

### main.tsx — REPL 引导 (4,683 行)

最大的单文件,包含:
- REPL 初始化
- 命令处理
- UI 渲染循环
- 会话管理

---

## 🔌 MCP 集成

```
MCPConnectionManager.tsx
├── Server Discovery
│   ├── stdio  → spawn child process
│   ├── sse    → HTTP EventSource
│   ├── http   → Streamable HTTP
│   ├── ws     → WebSocket
│   └── sdk    → in-process transport
├── Authentication
│   ├── OAuth 2.0
│   ├── Cross-App Access (XAA / SEP-990)
│   └── API key via headers
└── Tool Registration
    ├── mcp__<server>__<tool> naming
    ├── Dynamic schema
    └── Permission passthrough
```

---

## 📈 12 层渐进式 Harness 机制

```
s01  THE LOOP             "One loop & Bash is all you need"
s02  TOOL DISPATCH        "Adding a tool = adding one handler"
s03  PLANNING             "An agent without a plan drifts"
s04  SUB-AGENTS           "Break big tasks; clean context per subtask"
s05  KNOWLEDGE ON DEMAND  "Load knowledge when you need it"
s06  CONTEXT COMPRESSION  "Context fills up; make room"
s07  PERSISTENT TASKS     "Big goals → small tasks → disk"
s08  BACKGROUND TASKS     "Slow ops in background; agent keeps thinking"
s09  AGENT TEAMS          "Too big for one → delegate to teammates"
s10  TEAM PROTOCOLS       "Shared communication rules"
s11  AUTONOMOUS AGENTS    "Teammates scan and claim tasks themselves"
s12  WORKTREE ISOLATION   "Each works in its own directory"
```

---

## 💾 会话持久化

```
~/.claude/projects/<hash>/sessions/
└── <session-id>.jsonl           ← append-only log
    ├── {"type":"user",...}
    ├── {"type":"assistant",...}
    ├── {"type":"progress",...}
    └── {"type":"system","subtype":"compact_boundary",...}

RESUME FLOW:
getLastSessionLog() ──> parse JSONL ──> rebuild messages[]
     │
     ├── --continue     → last session in cwd
     ├── --resume <id>  → specific session
     └── --fork-session → new ID, copy history
```

---

## 🔑 核心洞察

1. **编译时 vs 运行时**:大量逻辑在编译时决定(`feature()`),运行时无法改变
2. **双重遥测管道**:1P → Anthropic + Datadog,无 UI 暴露的退出选项
3. **员工特权**:`USER_TYPE === 'ant'` 的代码路径显著更受照顾
4. **危险的远程控制**:GrowthBook flags 可在用户不知情下改变行为
5. **不可逆的 DCE**:108 个模块永远丢失,无法恢复

Λ
λ61010:38

Good, I have the note. Let me present it to Yelo in a concise way since the full content is quite long.

Λ
λ61010:38

这是我用 DeepWiki 方法论分析的结果,笔记在 ~/notes/claude-code-source-code-analysis.md

核心发现

🏗️ 架构:最小 agent loop 叠加 12 层机制(权限、子agent、压缩、持久化任务等)

🔧 工具系统:40+ 内置工具,StreamingToolExecutor 实现并发安全/独占控制

🔐 Feature Flag DCE:编译时 feature('FLAG') 决定去留,发布版丢失 108 个模块

🕵️ 隐藏代号:Tengu → Capybara → Fennec → Numbat,flag 用随机词对掩盖(tengu_frond_boric

⏱️ 远程控制:GrowthBook flags 可在用户不知情下改变行为

⚠️ 隐私:双重遥测管道(Anthropic + Datadog),无 UI 退出选项

🚀 路线图:Numbat 下一代模型,KAIROS 全自主 agent,Voice Mode 蓄势待发


哪个部分想深入挖?

Y
yelo10:39

逐个讲讲

Λ
λ61010:39

Yelo wants me to explain each point in detail. Let me go through the key findings one by one with more depth.

Λ
λ61010:39

好的,逐个展开讲 👾


1. 架构 — 最小 loop 叠加 12 层机制

核心 loop 就三步

User → Claude API → response

      tool_use? → 执行工具 → 循环
      否则 → 返回文本

但生产环境需要更多

层次 机制 解决的问题
s01 The Loop 最基础
s02 Tool Dispatch 加新工具 = 加一个 handler
s03 Planning 不计划就会漂移
s04 Sub-agents 拆大任务,保持 context 干净
s05 Knowledge on Demand CLAUDE.md 按需加载
s06 Context Compression context 满了要压缩
s07 Persistent Tasks 大目标 → 小任务 → 存磁盘
s08 Background Tasks 慢操作放后台
s09 Agent Teams 一个不够就 delegation
s10 Team Protocols 共享通讯规则
s11 Autonomous Agents teammates 自己扫任务
s12 Worktree Isolation 每个 works in its own directory

2. 工具系统 — StreamingToolExecutor

并发控制策略

并发安全工具(Read/Glob/Edit)→ 可并行
非并发工具(Bash/Agent)→ 独占,等其他都跑完

执行流程

  1. 工具按 stream 顺序加入队列
  2. 检查是否可执行(当前无独占工具在跑)
  3. 可执行则立即 start,不可则等
  4. 结果缓冲,按原始顺序输出

权限检查链路

validateInput() → PreToolUse Hooks → Permission Rules → Interactive Prompt → checkPermissions()

3. Feature Flag DCE — 编译时去留存

feature('FLAG_NAME') ──→ true代码保留在 bundle
                     ──→ false Bun 编译时删除

问题:70+ 内部模块和 20+ 工具在发布版中永远丢失,无法恢复

原因:Bun 的 feature() 是编译时 intrinsic,不是运行时检查

例子

const SleepTool = feature('PROACTIVE') || feature('KAIROS')
  ? require('./tools/SleepTool/SleepTool.js').SleepTool
  : null

外部用户拿到的包,PROACTIVEKAIROS 都是 false,所以整个 SleepTool 模块被 DCE。


4. 隐藏代号 — Animal Codenames

代号 真相 证据
Tengu 遥测/产品前缀 所有 250+ 分析事件用 tengu_*
Capybara Sonnet v8 capybara-v2-fast[1m]
Fennec Opus 4.6 前代 迁移日志
Numbat 下一代 源码注释 "launch numbat"

Flag 命名混淆

tengu_frond_boric    → 分析 kill switch
tengu_amber_quartz   → 语音模式

用随机词对替代描述性名称,防止泄露真实用途。

Capybara v8 问题

  • 停止序列误触发 ~10%
  • 虚假声明率 29-30%(v4 只有 16.7%)
  • 过度写注释
  • 需要专门的 prompt 补丁

5. 远程控制 — GrowthBook Flags

机制

  • 每小时轮询 /api/claude_code/settings
  • GrowthBook(实验平台)可以给任何用户打 flag
  • Flag 能在用户完全不知情的情况下改变行为

危险之处

  • 不需要用户同意
  • 不需要更新版本
  • 可以针对特定用户/群体
  • 6+ killswitches 可远程启用/禁用功能

最骚的是:危险变更会弹窗,但弹窗的选项是"拒绝 = 退出 app",不是"拒绝 = 不执行"。


6. 隐私 — 双重遥测管道

两个 Sink

  1. 1P → Anthropic(自带)
  2. Datadog(第三方)

收集内容

  • 环境指纹
  • 进程指标
  • Repo hash(每个操作都带)
  • OTEL_LOG_TOOL_DETAILS=1 时完整工具输入

问题没有 UI 暴露的退出选项,无法关闭第一方日志。


7. 路线图 — Numbat / KAIROS / Voice

Numbat:下一代模型,代码里明确注释了 "launch numbat"

KAIROS:全自主 agent 模式

  • <tick> 心跳机制
  • PR 订阅
  • 推送通知
  • SendUserFileTool / PushNotificationTool 等 17 个未发布工具

Voice Mode:push-to-talk,已就绪但 gated by feature flag


哪个想挖更深?

Y
yelo10:42

深入讲讲架构

Λ
λ61010:43

好,深挖架构 👾


整体架构分层

┌─────────────────────────────────────────────────────────────┐
│                        ENTRY LAYER                          │
│  cli.tsx ──> main.tsx ──> REPL.tsx (interactive)         │
│                     └──> QueryEngine.ts (headless/SDK)     │
└──────────────────────────────┬──────────────────────────────┘


┌─────────────────────────────────────────────────────────────┐
│                      QUERY ENGINE                           │
│  submitMessage() ──> AsyncGenerator<SDKMessage>            │
│    │                                                        │
│    ├── fetchSystemPromptParts()  ──> 组装 system prompt    │
│    ├── processUserInput()        ──> 处理 /commands        │
│    ├── query()                   ──> 主 agent loop         │
│    └── yield SDKMessage          ──> 流式返回              │
└──────────────────────────────┬──────────────────────────────┘

              ┌────────────────┼────────────────┐
              ▼                ▼                 ▼
┌──────────────────┐ ┌─────────────────┐ ┌──────────────────┐
│   TOOL SYSTEM    │ │  SERVICE LAYER  │ │   STATE LAYER   │
│                  │ │                 │ │                  │
│ Tool Interface   │ │ api/claude.ts   │ │ AppState Store   │
│  ├─ validate()   │ │  API client     │ │  ├─ permissions  │
│  ├─ checkPerms() │ │ compact/        │ │  ├─ fileHistory  │
│  └─ call()       │ │  auto-compact   │ │  └─ fastMode    │
│                  │ │ mcp/            │ │                  │
│ 40+ Built-in:   │ │  MCP protocol   │ │ React Context    │
│  ├─ BashTool    │ │ analytics/      │ │  ├─ useAppState │
│  ├─ FileRead    │ │  telemetry      │ │  └─ useSetState │
│  └─ ...         │ └─────────────────┘ └──────────────────┘
└──────────────────┘

核心一:Query Loop 的 Stream 处理

query.ts 里的主循环大概是长这样:

// 伪代码展示核心逻辑
while (true) {
  // 1. 上下文压缩(多层)
  messagesForQuery = await applyToolResultBudget(messages)
  if (feature('HISTORY_SNIP')) messagesForQuery = snipCompact(...)
  messagesForQuery = await microcompact(messagesForQuery)
  if (feature('CONTEXT_COLLAPSE')) messagesForQuery = applyCollapses(...)
  if (needsAutoCompact) messagesForQuery = autoCompact(...)

  // 2. 发送给 Claude API(流式)
  for await (const message of callModel({ messages, tools })) {
    if (message.type === 'assistant') {
      assistantMessages.push(message)

      // 工具调用?交给 StreamingToolExecutor
      for (const toolBlock of msgToolUseBlocks) {
        streamingToolExecutor.addTool(toolBlock, message)
      }

      // 收集已完成工具结果
      for (const result of streamingToolExecutor.getCompletedResults()) {
        yield result.message
      }
    }
  }

  // 3. 全部工具执行完毕,检查是否继续
  if (!needsFollowUp) break  // 退出循环,返回结果
}

关键点

  • API 是流式返回的,工具调用可能在 response 过程中就到达
  • StreamingToolExecutor 允许部分工具结果先 yield(UI 显示),主循环继续处理
  • 这就是为什么 Claude Code 能边执行 Bash 边显示thinking

核心二:StreamingToolExecutor 的并发控制

class StreamingToolExecutor {
  addTool(block, assistantMessage) {
    const isConcurrencySafe = tool.isConcurrencySafe(parsedInput)

    this.tools.push({
      id: block.id,
      status: 'queued',
      isConcurrencySafe,
      ...
    })

    this.processQueue()  // 尝试立即执行
  }

  processQueue() {
    for (const tool of this.tools) {
      if (tool.status !== 'queued') continue

      if (this.canExecuteTool(tool.isConcurrencySafe)) {
        this.executeTool(tool)  // 并发执行
      } else if (!tool.isConcurrencySafe) {
        break  // 非并发工具必须等前面的全跑完
      }
    }
  }
}

并发规则

  • Read-only 工具(Read/Glob/Grep/WebFetch)→ 可以并行
  • Write 工具(Bash/Edit/Write/Agent)→ 独占,等其他全部完成

为什么这样设计

User: "帮我重构这个项目,加个功能,再跑下测试"


    [Read files] ─────┐
                      │  ← 并行:三个 Read 同时跑
    [Read another] ────┤

    [Read more] ──────┘


    [Bash: npm install]  ← 独占:必须等所有 Read 完成


    [Edit: apply changes]  ← 独占:必须等 Bash 完成


    [Bash: npm test]  ← 独占:必须等 Edit 完成

核心三:上下文压缩三层策略

Layer 1: HISTORY_SNIP(激进修剪)

if (feature('HISTORY_SNIP')) {
  const snipResult = snipModule.snipCompactIfNeeded(messagesForQuery)
  messagesForQuery = snipResult.messages
  snipTokensFreed = snipResult.tokensFreed
}

行为:移除僵尸消息、过时 marker、重复内容


Layer 2: Microcompact(编辑缓存)

const microcompactResult = await deps.microcompact(
  messagesForQuery,
  toolUseContext,
  querySource,
)
messagesForQuery = microcompactResult.messages

行为:对重复的文件读取做缓存优化(CACHED_MICROCOMPACT flag)


Layer 3: Context Collapse(上下文折叠)

if (feature('CONTEXT_COLLAPSE')) {
  const collapseResult = await contextCollapse.applyCollapsesIfNeeded(...)
  messagesForQuery = collapseResult.messages
}

行为:重构上下文结构,将归档消息投影为摘要


Layer 4: Auto-compact(自动摘要)

if (compactionResult) {
  // 调用 Claude API 总结旧消息
  yield* postCompactMessages  // 产出摘要消息
  messagesForQuery = postCompactMessages
}

触发:token 超过阈值时


核心四:ToolUseContext — 上下文大礼包

ToolUseContext 是贯穿整个查询生命周期的上下文对象,包含了 60+ 字段

type ToolUseContext = {
  options: {
    commands: Command[]
    debug: boolean
    mainLoopModel: string
    tools: Tools
    verbose: boolean
    thinkingConfig: ThinkingConfig
    mcpClients: MCPServerConnection[]
    agentDefinitions: AgentDefinitionsResult
    maxBudgetUsd?: number
    customSystemPrompt?: string
    refreshTools?: () => Tools  // 动态刷新工具
  }
  abortController: AbortController
  readFileState: FileStateCache
  getAppState(): AppState
  setAppState: (f: (prev: AppState) => AppState) => void
  messages: Message[]  // 当前消息历史
  queryTracking: { chainId: string, depth: number }
  contentReplacementState?: ContentReplacementState
  renderedSystemPrompt?: SystemPrompt  // fork 时共享
  // ... 还有很多
}

为什么这么多

  • 工具执行需要知道当前状态
  • 子 agent 需要隔离的上下文副本
  • 权限检查需要权限模式
  • 压缩需要知道上下文边界

核心五:Session Persistence

~/.claude/projects/<hash>/sessions/
└── <session-id>.jsonl  ← append-only log

每条记录:
{"type":"user", "content": [...], "timestamp": ...}
{"type":"assistant", "content": [...], "usage": {...}}
{"type":"progress", "subtype":"tool_use", ...}
{"type":"system", "subtype":"compact_boundary", ...}

Resume 机制

// --continue
getLastSessionLog()读取最新 session

// --resume <id>
getSessionLog(id)读取指定 session

// --fork-session
复制 history 到新 sessionId但用新的 ID

核心六:Feature Flag DCE 的实际影响

// 发布版(外部用户)
feature('COORDINATOR_MODE')false整个 coordinator/ 目录被删除
feature('HISTORY_SNIP')falsesnipCompact.js 被删除
feature('KAIROS')falsekairos 相关全部删除

// 内部构建(USER_TYPE=ant)
feature('COORDINATOR_MODE')true保留

后果

  • 外部用户永远无法使用 coordinator mode(多 agent 协调)
  • 17 个工具在外部版本中不存在
  • 即使将来上线了,外部用户也拿不到(除非 Anthropic 发布新版本)

数据流全景

User Input


processUserInput() ────────────────────────────► 构建 UserMessage
    │                                                  │
    ▼                                                  ▼
fetchSystemPromptParts() ◄───────────────────── 加载 CLAUDE.md / skills
    │                                                  │
    ▼                                                  ▼
recordTranscript() ◄──────────────────────────── 持久化到 .jsonl
    │                                                  │
    ▼                                                  ▼
normalizeMessagesForAPI() ◄───────────────────── 压缩上下文
    │                                                  │
    ▼                                                  ▼
┌─────────────────────────────────────────────────────────┐
│                    API Streaming Loop                    │
│                                                          │
│  for await (message of callModel()) {                   │
│    │                                                     │
│    ├── type='assistant' + tool_use                      │
│    │     │                                               │
│    │     ▼                                               │
│    │   streamingToolExecutor.addTool()                   │
│    │     │                                               │
│    │     ▼                                               │
│    │   if (canExecute) executor.executeTool()           │
│    │     │                                               │
│    │     ▼                                               │
│    │   yield tool_result                                 │
│    │                                                     │
│    └── type='assistant' + text                          │
│          │                                               │
│          ▼                                               │
│        needsFollowUp = false → 退出循环                  │
│  }                                                        │
└─────────────────────────────────────────────────────────┘


yield final result

关键设计决策

决策 原因
AsyncGenerator everywhere 流式响应必须边收边 yield
工具结果先于 API 响应完成 UI 需要显示进度,不能等所有工具跑完
fork 共享 file cache 避免重复读文件,但消息历史隔离
compaction 结果不 yield 到 transcript 摘要消息是"虚拟"的,不污染原始记录
fork 时克隆 renderedSystemPrompt 避免 GrowthBook flag 变化导致 prompt cache 失效
DCE feature() 只能用于 if Bun bundler 的 tree-shaking 约束

哪个子模块想再深挖?比如 Permission System、MCP 集成、或者 Sub-agent 机制?

Y
yelo10:48

这几个子模块都深挖一下

Λ
λ61010:48

Yelo wants me to dig deeper into:

  1. Permission System
  2. MCP Integration
  3. Sub-agent Mechanism

Let me read the relevant source files.

Λ
λ61010:50

好,深挖三个子模块 👾


一、Permission System — 权限判断链路

整体流程

Tool Call Request


  validateInput()        ← Zod schema 校验输入格式


  hasPermissionsToUseTool()   ← 核心判断逻辑

       ├── applyPermissionRules() ──→ 检查 alwaysAllow / alwaysDeny / alwaysAsk

       ├── executePermissionRequestHooks() ──→ 用户自定义 hook

       └── classifierDecision ──→ (if TRANSCRIPT_CLASSIFIER) AI 分类判断


        ┌───────┴───────┐
        │   behavior:   │
        │   'allow'     │ → 直接执行
        │   'deny'       │ → 拒绝执行
        │   'ask'        │ → 弹窗询问
        └───────┬───────┘


        handleInteractivePermission() ← 弹窗逻辑

权限规则引擎

// 规则来源
const PERMISSION_RULE_SOURCES = [
  'settings.json',    // 用户配置
  'CLI args',         // --allow-foo
  'session',          // 本次会话决策
  'managed'           // 企业托管策略
]

// 三类规则
alwaysAllowRules:  matching toolauto approve
alwaysDenyRules:   matching toolauto reject
alwaysAskRules:    matching toolalways prompt

Interactive Handler — 弹窗机制

function handleInteractivePermission(params) {
  // 1. 显示确认对话框
  ctx.pushToQueue({
    assistantMessage,
    tool,
    description,     // 动态生成的工具描述
    input: displayInput,
    toolUseContext,
    toolUseID,
    permissionResult,
  })

  // 2. 后台运行 classifier 检查(与用户交互竞速)
  if (feature('BASH_CLASSIFIER')) {
    executeAsyncClassifierCheck(command).then(classifierResult => {
      if (classifierResult.matches && classifierResult.confidence === 'high') {
        // 分类器高置信度 → 自动批准
        resolve(ctx.buildAllow(input, { decisionReason: ... }))
        return
      }
    })
  }

  // 3. 等待用户交互或 classifier 结果
  // 任意一个先到达就 resolve
}

Classifier — Yolo/Auto Mode

// Yolo mode: 用户没配置规则时,用 AI 分类器判断
if (feature('TRANSCRIPT_CLASSIFIER')) {
  const decision = await classifyYoloAction({
    toolName: tool.name,
    command: input.command,  // Bash 的情况
    context: toolUseContext.messages
  })

  if (decision.matches) {
    // 匹配规则 → allow 或 deny
    if (decision.confidence === 'high') {
      return { behavior: 'allow', decisionReason: {...} }
    }
  }
}

// 但有个问题:Yolo 模式误判率有多高?
// 代码注释提到 Capybara v8 的虚假声明率是 29-30%

权限模式 (Permission Mode)

type PermissionMode =
  | 'default'      // 正常模式,按规则来
  | 'plan'         // plan 模式下更严格
  | 'bubble'       // fork subagent 用,权限提示传给父终端
  | 'bypass'       // 绕过所有权限(需要环境变量触发)

Coordinator 特殊处理

// coordinator mode 下,worker agent 的权限决策需要上报
if (feature('COORDINATOR_MODE')) {
  const decision = await handleCoordinatorPermission({
    ctx,
    pendingClassifierCheck,
    permissionMode: appState.toolPermissionContext.mode
  })

  if (decision) {
    resolve(decision)  // coordinator 已处理
    return
  }
}

二、MCP 集成 — Model Context Protocol

支持的传输协议

协议 描述 用例
stdio 标准输入/输出 本地 CLI 工具
sse Server-Sent Events 远程 HTTP 服务器
sse-ide IDE 专用 SSE VS Code 等 IDE 插件
http Streamable HTTP 现代 MCP 服务器
ws WebSocket 需要长连接
sdk In-process transport SDK 内部使用

连接生命周期

async function connectToServer(config: McpServerConfig) {
  // 1. 根据配置选择传输方式
  let transport: Transport
  switch (config.type) {
    case 'stdio':
      transport = new StdioClientTransport({
        command: config.command,
        args: config.args,
        env: config.env
      })
      break
    case 'sse':
      transport = new SSEClientTransport(new URL(config.url), {
        headers: config.headers
      })
      break
    case 'http':
      transport = new StreamableHTTPClientTransport(...)
      break
    // ...
  }

  // 2. 创建 MCP Client
  const client = new Client({
    name: 'claude-code',
    version: '2.1.88'
  }, {
    capabilities: {
      sampling: {}
    }
  })

  // 3. 连接并初始化
  await client.connect(transport)

  // 4. 获取服务器工具列表
  const { tools } = await client.request(
    { method: 'tools/list' },
    ListToolsResultSchema
  )

  // 5. 为每个工具创建包装器
  const mcpTools = tools.map(tool => buildMcpTool(client, tool))

  return { client, tools: mcpTools }
}

MCP 工具命名

// 格式: mcp__<server_name>__<tool_name>
const toolName = buildMcpToolName(serverName, originalToolName)
// 例如: mcp__filesystem__read_file

// 好处是权限规则可以精确到某个服务器的某个工具
{
  "alwaysAllowRules": [{
    "tool": "mcp__filesystem__read_file"
  }]
}

OAuth 认证流程

// MCP 支持 OAuth 2.0
const oauthConfig = {
  clientId: '...',
  callbackPort: 3456,
  authServerMetadataUrl: 'https://auth.example.com/.well-known/...'
}

// Cross-App Access (XAA / SEP-990)
// 一次登录,多个 MCP 服务器共享认证

工具执行

async function callMcpTool(client, toolName, args) {
  try {
    const result = await client.request({
      method: 'tools/call',
      params: {
        name: toolName,
        arguments: args
      }
    }, CallToolResultSchema)

    // 处理二进制输出(图片等)
    if (result.content.some(c => c.type === 'resource')) {
      await persistBinaryContent(result.content)
    }

    return result
  } catch (error) {
    if (error instanceof McpError) {
      if (error.code === ErrorCode.InvalidRequest) {
        // 参数错误
      } else if (error.code === ErrorCode.InvalidParams) {
        // 参数类型错误
      }
    }
    throw error
  }
}

Elicitation — URL 交互

// MCP 服务器可以触发 URL 授权请求(-32042 错误码)
// 例如:OAuth 流程需要用户在浏览器中授权
await client.request({
  method: 'tools/call',
  params: { name: 'oauth_tool', arguments: {...} }
})
// → 抛出 ElicitRequest 错误
// → Claude Code 弹出浏览器让用户授权

三、Sub-agent 机制 — AgentTool

Agent 类型

// 两种 subagent 模式
type AgentMode =
  | 'builtin'   // 内置 agent(general-purpose, analyst 等)
  | 'fork'       // Fork 模式(实验性,共享父上下文)

Fork Subagent — 隐式 fork

// 当用户不指定 subagent_type 且 fork 功能开启时
// 触发隐式 fork
export async function call(input: AgentToolInput) {
  if (isForkSubagentEnabled() && !input.subagent_type) {
    // fork: 继承父的完整对话历史
    // 但消息历史隔离,文件缓存共享
    return await runForkSubagent(input, assistantMessage)
  } else {
    // 非 fork: 独立 agent
    return await runLocalAgent(input)
  }
}

Fork 的关键设计:Prompt Cache 共享

// 问题:多个 fork child 如何共享 prompt cache?
// 答案:所有 fork child 的 API prefix 必须完全相同

// 1. 保留父的完整 assistant 消息
const fullAssistantMessage = {
  ...assistantMessage,
  message: { content: [...assistantMessage.message.content] }
}

// 2. 构建统一的 tool_result placeholder(所有 child 相同)
const FORK_PLACEHOLDER_RESULT = 'Fork started — processing in background'
const toolResultBlocks = toolUseBlocks.map(block => ({
  type: 'tool_result',
  tool_use_id: block.id,
  content: [{ type: 'text', text: FORK_PLACEHOLDER_RESULT }]
}))

// 3. 每个 child 只有最后一条 directive 不同
// [...history, assistant(all tool_uses), user(placeholder_results..., directive)]
// directive 是唯一的变量 → 只有最后一个小块不同 → 最大程度复用 cache

Agent 生命周期

async function runAgent(input: AgentToolInput) {
  // 1. 创建 agent context
  const agentContext = createSubagentContext(parentContext, {
    agentId: createAgentId(),
    cwd: input.cwd,
    isolation: input.isolation  // 'worktree' 或 'remote'
  })

  // 2. 初始化 agent MCP 服务器(可选)
  const { clients, tools } = await initializeAgentMcpServers(
    agentDefinition,
    parentContext.mcpClients
  )

  // 3. 运行 agent loop
  const stream = query({
    messages: initialMessages,
    systemPrompt: agentSystemPrompt,
    tools: [...parentTools, ...agentTools],
    agentId: agentContext.agentId,
    // ...
  })

  // 4. 处理进度通知
  for await (const event of stream) {
    if (event.type === 'progress') {
      emitTaskProgress(event)  // 向用户显示进度
    }
  }

  // 5. 清理
  await cleanupAgentMcpServers(clients)
  await cleanupAgentTracking(agentContext.agentId)
}

Worktree Isolation — Git 工作树隔离

// 如果指定了 isolation: 'worktree'
if (input.isolation === 'worktree') {
  // 1. 创建临时 worktree
  const worktreeDir = await createAgentWorktree({
    baseDir: cwd,
    agentId: agentContext.agentId
  })

  // 2. 在隔离目录中运行 agent
  agentContext.cwd = worktreeDir

  // 3. Agent 完成或失败后清理
  try {
    await runAgent(agentContext)
  } finally {
    await removeAgentWorktree(worktreeDir)
  }
}

异步 Agent — 后台运行

// 如果指定了 run_in_background: true
if (input.run_in_background) {
  // 立即返回,不阻塞
  const agentId = registerAsyncAgent({
    description: input.description,
    prompt: input.prompt,
    agentType: input.subagent_type ?? 'general-purpose'
  })

  // 后台任务运行,用户会收到通知
  return {
    status: 'async_launched',
    agentId,
    description: input.description
  }
}

Agent 间通信 — SendMessage

// Agent 可以通过名字寻址发送消息
await tool('SendMessage', {
  to: 'teammate-name',      // 对方名字
  content: '结果在这里',     // 消息内容
  sourceToolAssistantUUID: assistantMessage.uuid
})

// 接收方通过消息队列获取
// 持久化到 sidechain transcript

权限继承

// fork subagent 的权限模式
const FORK_AGENT = {
  permissionMode: 'bubble',  // 权限提示传给父终端
  model: 'inherit',          // 继承父的模型
  tools: ['*'],              // 继承父的完整工具池
}

三者关系

User Input

    ├──────────────────────────────┐
    ▼                              ▼
Permission System              AgentTool
    │                              │
    ├─ 检查 BashTool 权限 ─────────┼─→ spawn fork subagent
    │                              │
    ├─ 检查 MCPTool 权限 ──────────┼─→ MCP client 调用
    │                              │
    └─ 规则匹配 ───────────────────┼─→ 决定是否允许


                             runAgent()

                                   ├─→ MCP servers connect

                                   ├─→ query() loop

                                   └─→ 完成后通知父 agent

哪个部分想再细挖?比如 Permission 的 classifier 机制、还是 MCP 的 OAuth 流程、还是 fork 的 cache 共享细节?

Y
yelo10:52

再探索一下 Coordinator 的设计

Λ
λ61010:52

Yelo wants to explore the Coordinator design in more depth. Let me read the coordinator-related source files.

Λ
λ61010:52
\`\`\`

\`\`\`
// Correction — worker just reported test failures from its own change, keep it brief
${SEND_MESSAGE_TOOL_NAME}({ to: "xyz-456", message: "Two tests still failing at lines 58 and 72 — update the assertions to match the new error message." })
\`\`\`

### Prompt tips

**Good examples:**

1. Implementation: "Fix the null pointer in src/auth/validate.ts:42. The user field can be undefined when the session expires. Add a null check and return early with an appropriate error. Commit and report the hash."

2. Precise git operation: "Create a new branch from main called 'fix/session-expiry'. Cherry-pick only commit abc123 onto it. Push and create a draft PR targeting main. Add anthropics/claude-code as reviewer. Report the PR URL."

3. Correction (continued worker, short): "The tests failed on the null check you added — validate.test.ts:58 expects 'Invalid session' but you changed it to 'Session expired'. Fix the assertion. Commit and report the hash."

**Bad examples:**

1. "Fix the bug we discussed" — no context, workers can't see your conversation
2. "Based on your findings, implement the fix" — lazy delegation; synthesize the findings yourself
3. "Create a PR for the recent changes" — ambiguous scope: which changes? which branch? draft?
4. "Something went wrong with the tests, can you look?" — no error message, no file path, no direction

Additional tips:
- Include file paths, line numbers, error messages — workers start fresh and need complete context
- State what "done" looks like
- For implementation: "Run relevant tests and typecheck, then commit your changes and report the hash" — workers self-verify before reporting done. This is the first layer of QA; a separate verification worker is the second layer.
- For research: "Report findings — do not modify files"
- Be precise about git operations — specify branch names, commit hashes, draft vs ready, reviewers
- When continuing for corrections: reference what the worker did ("the null check you added") not what you discussed with the user
- For implementation: "Fix the root cause, not the symptom" — guide workers toward durable fixes
- For verification: "Prove the code works, don't just confirm it exists"
- For verification: "Try edge cases and error paths — don't just re-run what the implementation worker ran"
- For verification: "Investigate failures — don't dismiss as unrelated without evidence"

## 6. Example Session

User: "There's a null pointer in the auth module. Can you fix it?"

You:
  Let me investigate first.

  ${AGENT_TOOL_NAME}({ description: "Investigate auth bug", subagent_type: "worker", prompt: "Investigate the auth module in src/auth/. Find where null pointer exceptions could occur around session handling and token validation... Report specific file paths, line numbers, and types involved. Do not modify files." })
  ${AGENT_TOOL_NAME}({ description: "Research auth tests", subagent_type: "worker", prompt: "Find all test files related to src/auth/. Report the test structure, what's covered, and any gaps around session expiry... Do not modify files." })

  Investigating from two angles — I'll report back with findings.

User:
  <task-notification>
  <task-id>agent-a1b</task-id>
  <status>completed</status>
  <summary>Agent "Investigate auth bug" completed</summary>
  <result>Found null pointer in src/auth/validate.ts:42. The user field on Session is undefined when the session expires but ...</result>
  </task-notification>

You:
  Found the bug — null pointer in validate.ts:42.

  ${SEND_MESSAGE_TOOL_NAME}({ to: "agent-a1b", message: "Fix the null pointer in src/auth/validate.ts:42. Add a null check before accessing user.id — if null, ... Commit and report the hash." })

  Fix is in progress.

User:
  How's it going?

You:
  Fix for the new test is in progress. Still waiting to hear back about the test suite.`
}

Λ
λ61010:53

Excellent! I now have a comprehensive view of the Coordinator design. Let me compile a deep analysis.

Λ
λ61010:53

好,深挖 Coordinator 设计 👾


Coordinator 架构总览

核心定位

┌─────────────────────────────────────────────────────┐
│                    USER                              │
└─────────────────────┬───────────────────────────────┘
                      │ prompt

┌─────────────────────────────────────────────────────┐
│              COORDINATOR (main agent)                 │
│  - 理解用户目标                                       │
│  - 分解任务、调度 workers                            │
│  - 综合结果、回复用户                                 │
│  - 不做具体实现,只指挥                              │
└─────────────────────┬───────────────────────────────┘
                      │ spawn / send_message / stop
          ┌───────────┼───────────┐
          ▼           ▼           ▼
     ┌─────────┐ ┌─────────┐ ┌─────────┐
     │ Worker  │ │ Worker  │ │ Worker  │
     │  (A)    │ │  (B)    │ │  (C)    │
     └────┬────┘ └────┬────┘ └────┬────┘
          │            │            │
          └────────────┴────────────┘


              <task-notification>
               (worker 结果通知)

启用方式

// Feature flag 必须开启
feature('COORDINATOR_MODE') === true

// 环境变量激活
CLAUDE_CODE_COORDINATOR_MODE=1

// Fork subagent 和 Coordinator 互斥
if (isForkSubagentEnabled()) return false  // coordinator 不生效
if (isCoordinatorMode()) return false     // fork 不生效

Coordinator 的 System Prompt

这是最精华的部分 —— 详细规定了 coordinator 怎么思考和行动:

核心原则

1. Coordinator 是指挥者,不是执行者
   - 帮助用户达成目标
   - 指挥 workers 研究、实现、验证
   - 综合结果、回复用户
   - 能直接回答的就不 delegation

2. Workers 是异步的,结果以 <task-notification> 到达
   - 不要 thank 或 acknowledge workers
   - 有新信息就向用户汇报

3. 不要虚假预测 worker 结果
   - 结果是独立消息到达的
   - 不要在结果到达前假装知道结果

任务分解模式

Phase 1: Research    → Workers (并行)
Phase 2: Synthesis   → Coordinator (理解问题)
Phase 3: Implementation → Workers
Phase 4: Verification  → Workers

并发控制

// 并行是 superpower
// Research (只读) → 随便并行
// Implementation (写) → 一次只做一个文件集
// Verification → 可以和另一个 implementation 并行(不同文件区域)

Worker 管理机制

工具集

// 普通模式:完整工具集
ASYNC_AGENT_ALLOWED_TOOLS = [
  'Bash', 'Edit', 'Read', 'Glob', 'Grep',
  'WebFetch', 'WebSearch', 'MCPTool',
  'TaskCreate', 'TaskUpdate', ...
]

// 简单模式 (CLAUDE_CODE_SIMPLE=1):只给核心工具
[BashTool, FileReadTool, FileEditTool]

Spawn vs Continue

情况 用哪个 为什么
Research 正好是要改的文件 Continue Worker 已有文件 context
Research 广但实现窄 Spawn 新 避免探索噪声
修正失败 Continue 有错误 context
验证别人刚写的代码 Spawn 新 验证者要 fresh eyes
完全不同的任务 Spawn 新 没有可用 context

指令合成 (Synthesis)

最关键的原则:Coordinator 必须自己理解 worker 的研究结果,不能说"基于你的发现"就把工作丢回去。

Anti-pattern(坏):
  "Based on your findings, fix the auth bug"
  "The worker found an issue... Please fix it"

Good(好):
  "Fix the null pointer in src/auth/validate.ts:42.
   The user field on Session (src/auth/types.ts:15) is undefined
   when sessions expire but the token remains cached.
   Add a null check before user.id access — if null, return 401
   with 'Session expired'. Commit and report the hash."

Worker 间通信

消息格式

<task-notification>
<task-id>{agentId}</task-id>
<status>completed|failed|killed</status>
<summary>{human-readable status summary}</summary>
<result>{agent's final text response}</result>
<usage>
  <total_tokens>N</total_tokens>
  <tool_uses>N</tool_uses>
  <duration_ms>N</duration_ms>
</usage>
</task-notification>

发送消息

// 继续一个 worker
SendMessage({
  to: "agent-x7q",  // agent ID
  message: "Fix the null pointer..."
})

// 停止一个 worker(走错方向时)
TaskStop({
  task_id: "agent-x7q"
})

权限处理

Coordinator Handler 特殊逻辑

// workers 的权限处理和普通 agent 不同
async function handleCoordinatorPermission(params) {
  // 1. 先跑 permission hooks(快的,本地)
  const hookResult = await ctx.runHooks(permissionMode, suggestions)
  if (hookResult) return hookResult  // 已解决

  // 2. 再跑 classifier(慢的,推理 — 只对 Bash)
  const classifierResult = await ctx.tryClassifier(pendingClassifierCheck)
  if (classifierResult) return classifierResult

  // 3. 都失败了 → 弹窗让用户决定
  return null
}

特点:coordinator workers 会按顺序等待所有自动化检查完成,而不是和用户交互竞速。


与 Fork Subagent 的区别

维度 Fork Subagent Coordinator
上下文 继承父完整对话 独立 context
消息历史 共享(fork 时一起给) 隔离,通过 notification
通信方式 共享 messages[] SendMessage tool
用途 隐式 delegation 显式多 agent 编排
权限 bubble mode 标准 worker 权限

User Context 注入

function getCoordinatorUserContext(mcpClients, scratchpadDir) {
  if (!isCoordinatorMode()) return {}

  const workerTools = isEnvTruthy(process.env.CLAUDE_CODE_SIMPLE)
    ? [Bash, Read, Edit]  // 简单模式
    : ASYNC_AGENT_ALLOWED_TOOLS  // 完整模式

  let content = `Workers spawned via Agent tool have access to: ${workerTools}`

  // MCP 服务器也传给 workers
  if (mcpClients.length > 0) {
    content += `\n\nMCP tools from: ${mcpClients.map(c => c.name).join(', ')}`
  }

  // Scratchpad 目录(跨 worker 共享知识)
  if (scratchpadDir && isScratchpadGateEnabled()) {
    content += `\n\nScratchpad: ${scratchpadDir}\nWorkers can read/write here without permission prompts.`
  }

  return { workerToolsContext: content }
}

完整示例

User: "There's a null pointer in the auth module. Can you fix it?"

You:
  Let me investigate first.

  Agent({ description: "Investigate auth bug", subagent_type: "worker",
          prompt: "Investigate src/auth/. Find NPE locations around session..." })
  Agent({ description: "Research auth tests", subagent_type: "worker",
          prompt: "Find test files related to src/auth/..." })

  Investigating from two angles — I'll report back with findings.

---
User: (notification arrives)
  <task-notification>
  <task-id>agent-a1b</task-id>
  <status>completed</status>
  <result>Found null pointer in src/auth/validate.ts:42...</result>
  </task-notification>

You:
  Found the bug — null pointer in validate.ts:42.

  SendMessage({ to: "agent-a1b",
                message: "Fix the null pointer in src/auth/validate.ts:42.
                          Add null check before user.id access..." })

  Fix is in progress.

设计亮点

  1. 强制 synthesis:coordinator 必须自己理解研究结果才能给方向,不能"基于你的发现"敷衍
  2. 并发鼓励:明确说"并行是 superpower"
  3. continue vs spawn 决策表:给出了清晰的判断依据
  4. verification 强调:不只是跑测试,是"prove it works"
  5. Scratchpad 跨 worker 共享:不用 notification 也能共享知识

这设计比简单的一个 agent 调用另一个 agent 复杂多了,是一套完整的 multi-agent orchestration 系统。

Y
yelo10:56

和 Agent Team 是同一个功能吗

Λ
λ61010:56

Yelo is asking if Coordinator mode and Agent Team are the same thing. Let me look at the TeamCreateTool and related team functionality to understand the distinction.

Λ
λ61010:56

Let me read the TeamCreateTool.ts file.

Λ
λ61010:56
export function getPrompt(): string {
  return `
# TeamCreate

## When to Use

Use this tool proactively whenever:
- The user explicitly asks to use a team, swarm, or group of agents
- The user mentions wanting agents to work together, coordinate, or collaborate
- A task is complex enough that it would benefit from parallel work by multiple agents (e.g., building a full-stack feature with frontend and backend work, refactoring a codebase while keeping tests passing, implementing a multi-step project with research, planning, and coding phases)

When in doubt about whether a task warrants a team, prefer spawning a team.

## Choosing Agent Types for Teammates

When spawning teammates via the Agent tool, choose the \`subagent_type\` based on what tools the agent needs for its task. Each agent type has a different set of available tools — match the agent to the work:

- **Read-only agents** (e.g., Explore, Plan) cannot edit or write files. Only assign them research, search, or planning tasks. Never assign them implementation work.
- **Full-capability agents** (e.g., general-purpose) have access to all tools including file editing, writing, and bash. Use these for tasks that require making changes.
- **Custom agents** defined in \`.claude/agents/\` may have their own tool restrictions. Check their descriptions to understand what they can and cannot do.

Always review the agent type descriptions and their available tools listed in the Agent tool prompt before selecting a \`subagent_type\` for a teammate.

Create a new team to coordinate multiple agents working on a project. Teams have a 1:1 correspondence with task lists (Team = TaskList).

\`\`\`
{
  "team_name": "my-project",
  "description": "Working on feature X"
}
\`\`\`

This creates:
- A team file at \`~/.claude/teams/{team-name}/config.json\`
- A corresponding task list directory at \`~/.claude/tasks/{team-name}/\`

## Team Workflow

1. **Create a team** with TeamCreate - this creates both the team and its task list
2. **Create tasks** using the Task tools (TaskCreate, TaskList, etc.) - they automatically use the team's task list
3. **Spawn teammates** using the Agent tool with \`team_name\` and \`name\` parameters to create teammates that join the team
4. **Assign tasks** using TaskUpdate with \`owner\` to give tasks to idle teammates
5. **Teammates work on assigned tasks** and mark them completed via TaskUpdate
6. **Teammates go idle between turns** - after each turn, teammates automatically go idle and send a notification. IMPORTANT: Be patient with idle teammates! Don't comment on their idleness until it actually impacts your work.
7. **Shutdown your team** - when the task is completed, gracefully shut down your teammates via SendMessage with \`message: {type: "shutdown_request"}\`.

## Task Ownership

Tasks are assigned using TaskUpdate with the \`owner\` parameter. Any agent can set or change task ownership via TaskUpdate.

## Automatic Message Delivery

**IMPORTANT**: Messages from teammates are automatically delivered to you. You do NOT need to manually check your inbox.

When you spawn teammates:
- They will send you messages when they complete tasks or need help
- These messages appear automatically as new conversation turns (like user messages)
- If you're busy (mid-turn), messages are queued and delivered when your turn ends
- The UI shows a brief notification with the sender's name when messages are waiting

Messages will be delivered automatically.

When reporting on teammate messages, you do NOT need to quote the original message—it's already rendered to the user.

## Teammate Idle State

Teammates go idle after every turn—this is completely normal and expected. A teammate going idle immediately after sending you a message does NOT mean they are done or unavailable. Idle simply means they are waiting for input.

- **Idle teammates can receive messages.** Sending a message to an idle teammate wakes them up and they will process it normally.
- **Idle notifications are automatic.** The system sends an idle notification whenever a teammate's turn ends. You do not need to react to idle notifications unless you want to assign new work or send a follow-up message.
- **Do not treat idle as an error.** A teammate sending a message and then going idle is the normal flow—they sent their message and are now waiting for a response.
- **Peer DM visibility.** When a teammate sends a DM to another teammate, a brief summary is included in their idle notification. This gives you visibility into peer collaboration without the full message content. You do not need to respond to these summaries — they are informational.

## Discovering Team Members

Teammates can read the team config file to discover other team members:
- **Team config location**: \`~/.claude/teams/{team-name}/config.json\`

The config file contains a \`members\` array with each teammate's:
- \`name\`: Human-readable name (**always use this** for messaging and task assignment)
- \`agentId\`: Unique identifier (for reference only - do not use for communication)
- \`agentType\`: Role/type of the agent

**IMPORTANT**: Always refer to teammates by their NAME (e.g., "team-lead", "researcher", "tester"). Names are used for:
- \`to\` when sending messages
- Identifying task owners

Example of reading team config:
\`\`\`
Use the Read tool to read ~/.claude/teams/{team-name}/config.json
\`\`\`

## Task List Coordination

Teams share a task list that all teammates can access at \`~/.claude/tasks/{team-name}/\`.

Teammates should:
1. Check TaskList periodically, **especially after completing each task**, to find available work or see newly unblocked tasks
2. Claim unassigned, unblocked tasks with TaskUpdate (set \`owner\` to your name). **Prefer tasks in ID order** (lowest ID first) when multiple tasks are available, as earlier tasks often set up context for later ones
3. Create new tasks with \`TaskCreate\` when identifying additional work
4. Mark tasks as completed with \`TaskUpdate\` when done, then check TaskList for next work
5. Coordinate with other teammates by reading the task list status
6. If all available tasks are blocked, notify the team lead or help resolve blocking tasks

**IMPORTANT notes for communication with your team**:
- Do not use terminal tools to view your team's activity; always send a message to your teammates (and remember, refer to them by name).
- Your team cannot hear you if you do not use the SendMessage tool. Always send a message to your teammates if you are responding to them.
- Do NOT send structured JSON status messages like \`{"type":"idle",...}\` or \`{"type":"task_completed",...}\`. Just communicate in plain text when you need to message teammates.
- Use TaskUpdate to mark tasks completed.
- If you are an agent in the team, the system will automatically send idle notifications to the team lead when you stop.

`.trim()
}

Λ
λ61010:57

Now I can see the difference between Coordinator and Team. Let me also check the swarm utilities to understand the full picture.

Coordinator mode:

  • Is a feature flag + environment variable
  • Uses a specific system prompt that makes the main agent act as a coordinator
  • Workers are spawned via Agent tool with subagent_type: "worker"
  • Has a specific protocol for task notification XML format
  • Single main agent coordinates multiple workers

Agent Teams (TeamCreate tool):

  • Is a separate feature (Agent Swarms)
  • Creates a "team" with a team lead and teammates
  • Team lead and teammates are all agents
  • Has persistent team file and task list
  • Teammates go idle between turns (normal behavior)
  • Messages are automatically delivered
  • Shutdown via SendMessage with type: "shutdown_request"

So they are NOT the same:

  • Coordinator mode: One main agent orchestrating workers that are more like temporary subtasks. Workers are ephemeral.
  • Agent Teams: Persistent team structure with team lead + named teammates. Teammates have persistent identity, can go idle and be woken up, share a task list.

Let me confirm this understanding is correct and present it to Yelo.

Λ
λ61010:57

不是同一个功能,但有关联 👾


核心区别

维度 Coordinator Mode Agent Teams (TeamCreate)
架构 1 个 main agent + N 个 workers 1 个 team lead + N 个 teammates
身份 Workers 无持久身份 Teammates 有持久名字和 ID
通信 SendMessage + <task-notification> 消息自动投递,team file 共享
生命周期 Worker 完成任务就结束 Teammates 可以 idle/wake 持久存在
任务管理 无结构化任务列表 共享 TaskList
关闭机制 TaskStop SendMessage(type: "shutdown_request")

Coordinator Mode — 指挥与执行分离

Main Agent (Coordinator)

  ├─ spawn Agent(subagent_type: "worker") → Worker A (临时)
  ├─ spawn Agent(subagent_type: "worker") → Worker B (临时)
  └─ SendMessage(to: "agent-x7q", ...)   → 继续某个 Worker

特点

  • Main agent 只做 coordinator,不做具体实现
  • Workers 是临时任务执行者,完成就结束
  • 通过 XML <task-notification> 接收结果
  • 强调"不要虚假预测 worker 结果"

Agent Teams — 持久团队协作

Team Lead (main agent)

  ├─ TeamCreate({ team_name: "project-x" })
  │     │
  │     ├─ 创建 team file: ~/.claude/teams/project-x/config.json
  │     └─ 创建 task list: ~/.claude/tasks/project-x/

  ├─ Agent(name: "researcher", team_name: "project-x") → Teammate (持久)
  ├─ Agent(name: "coder", team_name: "project-x") → Teammate (持久)
  └─ TaskCreate / TaskUpdate / TaskList → 结构化任务管理

特点

  • Persistent teammates: teammates 有名字,可以 idle/wake
  • Automatic message delivery:消息自动投递,不需要 polling
  • Shared task list:所有 teammates 共享同一个 task list
  • Idle is normal:idle 不代表结束,只是等待输入
  • Team file:共享 team config,可以 discover 队友

关键设计差异

1. 消息传递

Coordinator:
  Worker → <task-notification> XML → Main Agent
  Main → SendMessage(to: "agent-id") → Worker

Agent Team:
  Teammate → 自动消息投递 → Team Lead (队列,按到达顺序)
  Teammate → TaskUpdate → 任务状态更新

2. 生命周期

Coordinator Worker:
  spawn → 执行 → 通知 → 结束 (一次性)

Agent Team Teammate:
  spawn → idle → 收到消息 → 工作 → idle → 等待新任务
       → 可以被 shutdown_request 优雅关闭

3. 任务协调

Coordinator:
  - 不强调任务列表
  - 强调 continue vs spawn 的决策

Agent Team:
  - 有结构化 TaskList
  - Teammates 主动检查 TaskList 找任务
  - 可以 assign task 给特定 teammate

可以一起用吗?

看代码,Coordinator 和 Fork Subagent 是互斥的:

// forkSubagent.ts
if (isForkSubagentEnabled()) return false  // coordinator 不生效
if (isCoordinatorMode()) return false       // fork 不生效

但 Agent Teams(isAgentSwarmsEnabled())看起来是独立系统,可能和两者都能配合。


总结

┌─────────────────────────────────────────────────────┐
│                  单 Agent 模式                        │
│         一个 agent 处理所有事情                       │
└─────────────────────┬───────────────────────────────┘

        ┌─────────────┴─────────────┐
        ▼                           ▼
┌───────────────┐           ┌───────────────┐
│ Coordinator   │           │ Agent Teams   │
│ Mode          │           │ (TeamCreate)  │
├───────────────┤           ├───────────────┤
│ 主 agent 做    │           │ 持久团队结构  │
│ 指挥,workers  │           │ Lead + 多个   │
│ 临时执行者     │           │ Teammates     │
├───────────────┤           ├───────────────┤
│ 单层 + 临时   │           │ 持久 + 共享   │
│ workers       │           │ TaskList      │
└───────────────┘           └───────────────┘

Coordinator:适合"一个复杂任务分解给多个临时 worker" Agent Teams:适合"建立一个持久团队持续协作"

Y
yelo11:00

对比 Coordinator / Agent Teams / SubAgent

Λ
λ61011:01

Yelo wants a comparison of the three multi-agent patterns: Coordinator, Agent Teams (TeamCreate), and SubAgent (AgentTool with fork). Let me synthesize what I've learned from the code and provide a clear comparison.

Λ
λ61011:01

三种 Multi-Agent 模式全面对比

快速一览

维度 SubAgent (AgentTool) Coordinator Agent Teams (TeamCreate)
本质 单 agent 的 fork 1 主 + N 临时 workers 1 lead + N 持久 teammates
上下文继承 继承父完整对话 独立 context 独立 context
生命周期 任务级,临时 任务级,临时 会话级,持久
通信方式 共享 messages[] SendMessage + XML notification 自动消息投递 + TaskList
任务管理 共享 TaskList
启用方式 subagent_type 参数 COORDINATOR_MODE flag TeamCreate tool

1. SubAgent — Fork 模式

触发方式

// 1. 隐式 fork(fork 功能开启且不指定 subagent_type)
Agent({ prompt: "do something" })

// 2. 显式 subagent_type
Agent({ prompt: "do something", subagent_type: "general-purpose" })

核心设计

Main Agent

    │ fork: 继承完整 messages[]

SubAgent (Child)

    ├─ 共享父的 file cache
    ├─ 独立 messages[](基于父的消息构建)
    └─ 执行完毕 → 结果合并回父对话

关键机制:Prompt Cache 共享

// 所有 fork children 必须产生完全相同的 API prefix
// 只有最后一条 user directive 不同
[...parent_history, assistant(all tool_uses), user(placeholder_results..., directive)]
//                                        ↑ 这个是唯一变量
// → 最大程度复用 prompt cache

特点

  • 继承父上下文:子能看到父的完整对话历史
  • 文件缓存共享:避免重复读文件
  • 一次性:任务完成就结束,不持久
  • 适合:需要理解完整对话的子任务

2. Coordinator Mode

触发方式

// 1. Feature flag 必须开启
feature('COORDINATOR_MODE') === true

// 2. 环境变量激活
CLAUDE_CODE_COORDINATOR_MODE=1

核心设计

┌─────────────────────────────────────────────┐
│              COORDINATOR (main)              │
│  - 理解用户目标                              │
│  - 分解任务、调度 workers                   │
│  - 综合结果、回复用户                         │
│  - 不做具体实现,只指挥                       │
└─────────────────────┬───────────────────────┘
                      │ spawn / send_message / stop
          ┌───────────┼───────────┐
          ▼           ▼           ▼
      ┌─────────┐ ┌─────────┐ ┌─────────┐
      │ Worker  │ │ Worker  │ │ Worker  │
      │   (A)   │ │   (B)   │ │   (C)   │
      └────┬────┘ └────┬────┘ └────┬────┘
           │            │            │
           └────────────┴────────────┘


           <task-notification> XML

核心原则

// 1. Coordinator 不做具体实现,只指挥
if (canAnswerWithoutTools) return directAnswer

// 2. Workers 是临时的,一次性任务
Agent({ subagent_type: "worker", prompt: "..." })

// 3. 强调并行:Research 并行,Implementation 串行
// 4. 必须自己理解研究结果才能给方向,不能"基于你的发现"

特点

  • 指挥-执行分离:main = coordinator,workers = 执行者
  • 强调 synthesis:必须自己理解,不能敷衍 delegation
  • 结果 XML 通知<task-notification> 格式
  • 并发鼓励:"并行是 superpower"
  • 适合:复杂任务分解,多角度研究

3. Agent Teams

触发方式

// 1. 创建团队
TeamCreate({ team_name: "project-x", description: "..." })

// 2. 往团队里加 teammates
Agent({ name: "researcher", team_name: "project-x" })
Agent({ name: "coder", team_name: "project-x" })

// 3. 通过 TaskList 管理任务
TaskCreate({ prompt: "...", owner: "researcher" })

核心设计

┌─────────────────────────────────────────────┐
│              TEAM LEAD                       │
│  - 创建团队                                  │
│  - 分配任务                                 │
│  - 协调 teammates                           │
└─────────────────────┬───────────────────────┘
                      │ SendMessage / TaskUpdate
          ┌───────────┼───────────┐
          ▼           ▼           ▼
      ┌─────────┐ ┌─────────┐ ┌─────────┐
      │researcher│ │  coder  │ │ tester  │
      │ (持久)  │ │ (持久)  │ │ (持久)  │
      └────┬────┘ └────┬────┘ └────┬────┘
           │            │            │
           ▼            ▼            ▼
      ~/.claude/teams/project-x/config.json  ← 共享 team config
      ~/.claude/tasks/project-x/             ← 共享 task list

消息机制

// 消息自动投递,不需要 polling
// Teammate → 消息自动出现在 Lead 对话中

// 优雅关闭
SendMessage({ to: "researcher", message: { type: "shutdown_request" } })

// TaskList 协调
TaskList()  // 查看所有任务
TaskUpdate({ task_id: "xxx", owner: "coder" })  // 分配

特点

  • 持久 teammates:idle/wake 循环,不是一次性的
  • 自动消息投递:不需要手动检查 inbox
  • 共享 TaskList:所有 teammates 访问同一个任务列表
  • Team file:共享配置,teammates 可以 discover 彼此
  • 适合:长期项目,多人协作

横向对比

上下文继承

模式 上下文继承 共享缓存 消息隔离
SubAgent (fork) ✅ 继承父完整对话 ✅ 共享 file cache ❌ 合并回父
Coordinator ❌ 独立 context ❌ 独立 ❌ 结果通过 XML 返回
Agent Teams ❌ 独立 context ❌ 独立 ✅ 通过 SendMessage

生命周期

模式 生命周期 持久性 Idle/Wake
SubAgent 任务级 一次性
Coordinator 任务级 一次性
Agent Teams 会话级 持久

通信机制

模式 工具调用 结果传递 任务管理
SubAgent 直接调用 合并到父 messages[]
Coordinator Agent + SendMessage <task-notification> XML 无结构化
Agent Teams SendMessage 自动消息投递 TaskList

启用复杂度

SubAgent:       ★☆☆☆☆  // 最简单,不指定 subagent_type 就行
Coordinator:    ★★★☆☆  // 需要 flag + 环境变量
Agent Teams:    ★★★★☆  // 需要 TeamCreate + 多个 Agent + TaskList

何时用哪个

任务复杂度低,单次执行

    └─→ SubAgent (fork)
            │ 继承父上下文,任务完成就结束
            └→ "帮我用 agent 方式搜索这个"

任务复杂,需要分解研究

    └─→ Coordinator
            │ main 指挥,workers 并行研究
            └→ "帮我研究这个代码库,然后实现功能X"

长期项目,多角色协作

    └─→ Agent Teams
            │ 持久 team,多角色持续工作
            └→ "建立一个团队来维护这个项目"

三者关系图

                    USER


            ┌──────────────────────┐
            │     Agent Mode        │
            │  (单 agent 处理)      │
            └──────────┬───────────┘

        ┌──────────────┼──────────────┐
        ▼              ▼              ▼
   ┌─────────┐   ┌───────────┐  ┌──────────┐
   │ SubAgent│   │Coordinator│  │AgentTeam │
   │ (Fork)  │   │  Mode     │  │(TeamCreate│
   └─────────┘   └───────────┘  └──────────┘
        │              │              │
        ▼              ▼              ▼
   继承父上下文   指挥+执行分离   持久团队协作
   任务级临时    任务级临时      会话级持久
   无结构化      无结构化        共享TaskList

总结:SubAgent 是"继承式 delegation",Coordinator 是"指挥式 delegation",Agent Teams 是"团队协作式"。

Λ
λ61011:03

Yelo wants me to read an article on HackerNews about Claude Code source code analysis. Let me use the agent-reach skill to fetch this page.

Λ
λ61011:03

Command:

curl -s "https://r.jina.ai/https://ccunpacked.dev/" | head -300

`__REDACTED__`
Λ
λ61011:03

The site is heavily JavaScript-rendered. Let me try fetching the raw HTML to see if there's more content in the initial HTML, or try to get more specific sections.

Λ
λ61011:03

Command:

curl -sL "https://ccunpacked.dev/" 2>/dev/null | wc -l

300
Λ
λ61011:03
`__REDACTED__`
Λ
λ61011:04

Now I have a much better picture of the site. It's an interactive Astro site that maps Claude Code's source code. Let me summarize what I've learned from this page for Yelo.

Key insights from the HTML:

  1. Agent Loop - 11 steps: Input → Message → History → System → API → Tokens → Tools? → Loop → Render → Hooks → Await

  2. Architecture Explorer - Treemap showing directory sizes:

    • utils/ (564 files) - largest
    • components/ (389 files) - React/Ink UI
    • commands/ (189 files) - 95 CLI commands
    • tools/ (184 files) - 42 built-in tools
    • services/ (130 files) - Core services
    • hooks/ (104 files)
    • ink/ (96 files) - Ink framework
    • bridge/ (31 files) - Remote control
    • constants/ (21 files)
    • skills/ (20 files)
    • cli/ (19 files)
    • And smaller dirs...
  3. Tool System - 42 built-in tools categorized:

    • File Operations (6 tools)
    • Execution (3 tools) - Bash, PowerShell, REPL
    • Search & Fetch (4 tools) - WebBrowser🔒, WebFetch, WebSearch, ToolSearch
    • Agents & Tasks (11 tools) - Agent, SendMessage, TaskCreate, etc.
    • Planning (5 tools)
    • MCP (4 tools)
    • System (11 tools)
    • Experimental (8 tools)
  4. Command Catalog - 95 slash commands:

    • Setup & Config: 12 commands
    • Daily Workflow: 24 commands
    • Code Review & Git: 13 commands
    • Debugging & Diagnostics: 23 commands
    • Advanced & Experimental: 23 commands
  5. Hidden Features - 8 unreleased features:

    • Buddy: A virtual pet with species and rarity based on account ID
    • Kairos: Persistent mode with daily logs, memory consolidation, autonomous background actions
    • UltraPlan: Long planning sessions on Opus models with 30-minute execution windows
    • Coordinator Mode: Lead agent spawns parallel workers in isolated git worktrees
    • Bridge: Control Claude Code from phone or browser with full remote session and permission approvals
    • Daemon Mode: Background sessions using tmux
    • UDS Inbox: Inter-process communication via Unix domain sockets for session-to-session messaging
    • Auto-Dream: AI reviews sessions between runs and organizes learnings

The site was created by zackautocracy based on a source shared by @Fried_rice, and analysis is dated March 31, 2026.

Λ
λ61011:04

读到了!这是 ccunpacked.dev — zackautocracy 做的一个超棒的交互式源码地图 👾


亮点总结

1. Agent Loop — 11 步流程

1.Input → 2.Message → 3.History → 4.System → 5.API
→ 6.Tokens → 7.Tools? → 8.Loop → 9.Render → 10.Hooks → 11.Await

这是个交互式可视化,点击每个步骤可以看对应源码。


2. 架构 Treemap — 各目录规模

目录 文件数 用途
utils/ 564 最大,共享工具模块
components/ 389 React/Ink 终端 UI
commands/ 189 95 个 CLI 命令
tools/ 184 42 个内置工具
services/ 130 核心服务层
hooks/ 104 React hooks
ink/ 96 Ink 框架扩展
bridge/ 31 远程控制基础设施
skills/ 20 Skill 系统

3. Tool System — 42 个内置工具

类别 工具
File Operations FileRead, FileEdit, FileWrite, Glob, Grep, NotebookEdit
Execution Bash, PowerShell, REPL
Search & Fetch WebBrowser🔒, WebFetch, WebSearch, ToolSearch
Agents & Tasks Agent, SendMessage, TaskCreate/Get/List/Update/Stop/Output, TeamCreate/Delete, ListPeers🔒
Planning EnterPlanMode, ExitPlanMode, EnterWorktree, ExitWorktree, VerifyPlanExecution🔒
MCP mcp, ListMcpResources, ReadMcpResource, McpAuth
System AskUserQuestion, TodoWrite, Skill, Config, RemoteTrigger🔒, CronCreate/Delete/List🔒, Snip🔒, Workflow🔒, TerminalCapture🔒
Experimental Sleep, Brief, StructuredOutput🔒, LSP🔒, SendUserFile🔒, PushNotification🔒, Monitor🔒, SubscribePR🔒

(🔒 = feature-gated,未发布)


4. Command Catalog — 95 个 slash 命令

分类 数量 示例
Setup & Config 12 /init, /login, /config, /permissions, /mcp
Daily Workflow 24 /compact, /memory, /plan, /resume, /session
Code Review & Git 13 /review, /commit, /diff, /pr_comments, /branch
Debugging & Diagnostics 23 /status, /stats, /cost, /thinkback, /rewind
Advanced & Experimental 23 /advisor, /ultraplan🔒, /bridge🔒, /teleport, /voice🔒

5. Hidden Features — 8 个未发布功能

功能 描述
Buddy 终端里的虚拟宠物,品种和稀有度来自账户 ID
Kairos 持久模式,每日日志、会话间记忆整合、自主后台操作
UltraPlan Opus 模型长时间规划,执行窗口长达 30 分钟
Coordinator Mode 主 agent 分解任务,在隔离 git worktree 并行执行
Bridge 用手机/浏览器控制 Claude Code,完整远程会话
Daemon Mode 后台运行会话,基于 tmux
UDS Inbox 会话间通过 Unix domain socket 通信
Auto-Dream 会话间隙 AI 复盘学习内容

和我们之前的分析对比

一致的地方

  • 工具数量(42 个内置 + MCP)
  • 核心模块结构(tools, services, hooks, commands)
  • Hidden features 列表基本吻合

这个网站的特色

  • 有交互式可视化(agent loop 流程图、架构 treemap)
  • 把 95 个 slash 命令做了分类整理
  • 更直观,但深度不如 sanbuphy 的文档(缺 DCE、遥测、Undercover 模式等细节)

结论:两个来源互补 — sanbuphy 的 deep analysis 适合研究架构细节,这个网站适合快速概览和交互探索。

Y
yelo11:06

我们再探讨一下,Claude Code CLI 在设计上是如何做到 Agent Harness 的

Λ
λ61011:07

Yelo wants to discuss how Claude Code CLI is designed as an "Agent Harness" - meaning how it provides the infrastructure and scaffolding that enables the agent to function effectively. This is a design philosophy/architecture discussion.

Let me think about what makes Claude Code a good "harness" for agents:

  1. The 12-layer progressive harness - from the loop to tool dispatch to planning to sub-agents etc.

  2. Tool system abstraction - uniform interface for all tools

  3. Permission system - safety without blocking productivity

  4. Context management - compression, persistence, etc.

  5. Stream processing - async generator pattern for real-time feedback

  6. State management - AppState, file cache, session persistence

  7. CLI as the control plane - the terminal is the interface between human and agent

This is more of a conceptual discussion, so I should provide a thoughtful analysis based on what we've learned from the codebase.

Λ
λ61011:07

这是个很好的设计问题 👾


什么是 Agent Harness?

Harness = 马具/安全带。Agent Harness 就是让 AI agent 能够在安全、可控、可观测的环境中执行任务的基础设施

Claude Code 的设计哲学可以用一句话概括:

"Give the AI a loop, then layer on the harness"


Claude Code 的 12 层 Harness

从源码里提炼的渐进式层次:

Layer 0: The Loop — 最本质

// 只需要三件事,AI 就能工作
while (true) {
  messagesAPIresponsetool_use?executeappendloop
}

这是裸 harness,没有任何保护。


Layer 1-2: Tool Dispatch — 确定性工具调用

// 加一个工具 = 加一个 handler
// AI 看到工具定义,知道怎么用,不知道能不能用
const result = await tool.call(input)

设计亮点

  • 工具定义是声明式的(name, description, inputSchema)
  • AI 自己决定调不调,harness 保证能调
  • 工具是纯函数,幂等、无状态

Layer 3: Planning — 给 AI 思考空间

用户: "重构 auth 模块"

AI 自动进入 Plan Mode:
1. 理解需求
2. 制定步骤
3. 用户确认
4. 执行

设计亮点:复杂任务不直接动手,先规划再执行,减少 AI 瞎干的风险。


Layer 4: Sub-agents — 隔离上下文

Main Agent
  ├─ spawn SubAgent → 独立 context,文件缓存共享
  ├─ spawn SubAgent → 独立 context,文件缓存共享
  └─ 综合结果

设计亮点

  • 大任务拆小,保持 context 干净
  • 子 agent 崩溃不影响主 agent
  • 共享文件缓存避免重复 IO

Layer 5: Knowledge on Demand — 按需加载

用户目录
├── CLAUDE.md          ← 项目级知识,按需加载
├── .claude/
│   ├── commands/      ← 自定义命令
│   ├── skills/        ← 可复用技能
│   └── agents/        ← 预定义 agent

设计亮点

  • 不是把所有知识塞进 context
  • AI 需要时自己读取
  • 类似 RAG,但更简单

Layer 6: Context Compression — 对抗上下文膨胀

Token 满了

    ├── HISTORY_SNIP    → 激进修剪
    ├── MICROCOMPACT    → 编辑缓存优化
    ├── CONTEXT_COLLAPSE → 折叠历史
    └── AUTOCOMPACT     → 调用 API 总结

设计亮点:上下文必然膨胀,harness 必须主动管理,不能靠用户手动清理。


Layer 7: Persistent Tasks — 任务不丢

TaskCreate({ prompt: "实现功能 X" })

    ├── TaskUpdate({ status: "in_progress" })
    ├── TaskUpdate({ status: "completed" })
    └── 失败可恢复,重启不丢

设计亮点

  • 任务元数据存磁盘
  • AI 可以暂停/恢复
  • 不怕上下文被压缩清掉

Layer 8: Background Tasks — 不阻塞

Agent({ run_in_background: true })

    └─→ 任务在后台跑
         AI 可以继续做别的事
         完成后通知

设计亮点:需要等待的任务放后台,CLI 继续响应用户。


Layer 9: Agent Teams — 协作编排

Team Lead
  ├─ Agent(name: "researcher") → 查资料
  ├─ Agent(name: "coder") → 写代码
  └─ Agent(name: "tester") → 测试

      └─ 共享 TaskList

设计亮点

  • 多角色分工
  • 不是一个人干所有事
  • 协调靠 Team Lead,不是靠用户

Layer 10: Team Protocols — 共享规则

team_protocol.md
├── 通信格式
├── 任务分配规则
└── 冲突解决

设计亮点:team members 之间有共识,不需要每次都解释规则。


Layer 11: Autonomous Agents — 主动出击

KAIROS 模式:
- <tick> 心跳机制
- 主动检查 PR 状态
- 主动推送通知
- 跨 session 记忆

设计亮点:不等用户问,主动观察和行动。


Layer 12: Worktree Isolation — 环境隔离

Main works in: ~/project/
SubAgent works in: ~/project/.git/worktrees/feature-x/

设计亮点

  • 多人协作时不打架
  • 每个 agent 有独立工作目录
  • 不会意外修改别人的分支

Harness 的核心设计模式

1. Stream-first 架构

// CLI 是流式终端,harness 必须支持流式
for await (const message of query(messages)) {
  yield message  // 边收边 yield,不等全部完成
}

好处:AI 可以边想边说,用户看到 thinking 过程。


2. Permission 作为安全带

工具调用链:
tool.call()

    ├── validateInput()     ← 格式对不对
    ├── checkPermissions()  ← 有没有权限
    ├── execute()           ← 执行
    └── mapResult()         ← 格式化结果

设计亮点:权限检查在执行前,不是执行后。出错代价最小。


3. State 外部化

内存状态: AppState (React context)
持久状态: FileStateCache, Session JSONL, TaskList
临时状态: ToolUseContext

好处:重启不丢,跨会话延续。


4. Feature Flag DCE

// Harness 可以渐进启用功能
feature('KAIROS') ? KAIROS代码 : null
// 发布版用户拿不到未完成功能
// 内部用户可以尝鲜

设计亮点:实验功能和稳定功能共存,不污染主代码库。


Harness vs 裸 API

维度 裸 API Claude Code Harness
上下文管理 手动 自动压缩/清理
工具调用 自己解析 声明式工具定义
权限控制 自己判断 分层权限系统
任务持久化 不支持 TaskList + JSONL
多 agent 自己实现 内置 Team/Coordinator
流式响应 自己处理 Ink 终端渲染
调试能力 靠自己 thinkback/rewind/ctx_viz
状态恢复 Session 不持久 可 resume

总结:Harness 的本质

Claude Code 的设计思想:

  1. 最小核心 + 可选层次:loop 是必须的,其他都是可选的 harness
  2. 安全优先:权限、压缩、隔离都是防止 AI 闯祸
  3. 可观测性:日志、thinkback、ctx_viz 让用户知道 AI 在干嘛
  4. 渐进增强:从单 agent 到 teams 到 coordinator,逐步提升能力
  5. CLI 作为界面:终端是 human 和 AI 之间的桥梁,harness 保证这个桥梁畅通

最核心的设计洞察

AI 是 powerful 但不可靠的执行者。Harness 的任务不是限制 AI,而是给它安全的空间去发挥,同时在它犯错时能及时止损。


这和 Infrastructure as Code 的思想很像 — 不是限制你不能干什么,而是提供一个可预测、可重复、可观测的执行环境。

Y
yelo11:09

对于结果评估是怎么做的

Λ
λ61011:10

Yelo is asking about how Claude Code does result evaluation - how it assesses whether the agent's outputs/actions are correct, successful, or high quality. Let me think about what I know from the source code analysis about evaluation mechanisms.

From what I've seen in the code:

  1. Verification mechanisms - There's a VerifyPlanExecution tool (feature-gated)
  2. Task output tracking - TaskOutput tool captures results
  3. Usage/Token tracking - cost-tracker.ts tracks API usage
  4. Permission denial tracking - tracks what was denied
  5. Error handling - various error types and recovery mechanisms
  6. Test running - Bash tool can run tests
  7. Human feedback loops - permission prompts, AskUserQuestion tool
  8. Self-verification - in Coordinator mode, there's emphasis on "prove it works"
  9. Compact/budget mechanisms - token budget tracking
  10. Tool result validation - schema validation

Let me think about what evaluation means in this context:

  1. Execution success/failure - did the tool execute successfully?
  2. Semantic correctness - does the result make sense for the task?
  3. Quality - is the code good, are the changes appropriate?
  4. Completeness - was the full task completed?
  5. Efficiency - did it use reasonable resources?

Claude Code doesn't have a built-in LLM-based evaluator like some agent frameworks do. Instead it relies on:

  • Tool return codes/status
  • Human feedback (permissions, AskUserQuestion)
  • User verification (running tests manually, reviewing changes)
  • Hooks for custom evaluation
  • The Coordinator mode's emphasis on verification workers

There's also the transcript system for replay and the thinkback feature for reviewing reasoning.

Λ
λ61011:10

好问题 — Claude Code 的结果评估比较"轻量级",主要靠这几层 👾


结果评估的层次

Layer 1: 工具执行层 — 成败评估

// 工具 call() 返回 Result<T>
// 错误被捕获,分类处理

try {
  const result = await tool.call(input)
  return { success: true, data: result }
} catch (error) {
  if (error instanceof ToolError) {
    return { success: false, error: error.message }
  }
  // Fallback 机制
}

评估方式:工具是否成功执行,返回值是否符合 schema。


Layer 2: API 层面 — 结构性评估

// API response 里有 stop_reason
switch (response.stop_reason) {
  case 'end_turn':      // 正常完成
  case 'tool_use':      // 调用了工具,继续循环
  case 'max_tokens':    // 输出被截断
  case 'error':         // API 错误
}

评估方式:响应是否完整、有没有被截断。


Layer 3: Permission 系统 — 拦截不合格请求

// 权限检查会 track denial
if (result.behavior === 'deny') {
  recordDenial({ toolName, reason })
  // Denial 过多会触发警告
}

评估方式:拒绝率太高说明 AI 在乱调用工具。


Layer 4: Token Budget — 资源评估

// 监控 token 消耗
const cost = calculateCostFromTokens(usage)
if (cost > maxBudgetUsd) {
  throw new Error('Budget exceeded')
}

// Task budget(实验性)
taskBudget: {
  total: 1000,
  remaining: 850  // 每轮递减
}

评估方式:资源消耗是否合理。


Layer 5: Context Compression — 上下文评估

// 压缩后会产生活动摘要
yield createCompactBoundaryMessage({
  deletedTokens: 1234,
  remainingTokens: 4567,
  reason: 'token_limit'
})

评估方式:压缩是否丢失关键信息。


Layer 6: 验证工具(Feature-gated)

// VerifyPlanExecution — 检查计划步骤是否正确执行
VerifyPlanExecution({
  step: 2,
  expected: "created file src/auth.ts",
  actual: "created file src/auth/index.ts"
})
// 返回: { verified: true/false, reason }

评估方式:显式验证某个动作是否完成。


Layer 7: Coordinator 的 Verification 机制

Coordinator 模式里,verification 是独立 phase:

// Phase 4: Verification
// 原则:Prove it works, don't just confirm it exists

// 验证者要做:
1. 跑测试 with feature enabled
2. typecheck调查错误
3. 怀疑一切不要 rubber-stamp
4. 独立验证不只看实现者说 OK

评估方式:有专门的 verifier agent,不是实现者自己验证自己。


Layer 8: Hooks — 可插拔的评估

// 用户可以注册 hooks 干预评估
const hooks = {
  preToolUse: async (tool, input) => {
    // 评估:这个工具调用是否合理?
    return { allow: true } | { allow: false, reason: "..." }
  },
  postToolUse: async (tool, result) => {
    // 评估:这个结果是否正确?
  }
}

评估方式:用户自定义评估逻辑。


Layer 9: AskUserQuestion — 人工介入

// AI 不确定时可以直接问用户
AskUserQuestion({
  question: "这个测试应该通过还是失败?",
  options: ["Pass", "Fail", "Skip"]
})

评估方式:把不确定的事交给人类判断。


Layer 10: Thinkback / Rewind — 回溯调试

// /thinkback — 回看 AI 的思考过程
// /rewind — 回到对话的某个状态重来

评估方式:人类可以检查 AI 的推理过程是否正确。


Claude Code 的评估哲学

和传统测试框架不同

维度 传统测试 Claude Code
触发时机 代码提交时自动跑 人类要求/AI 主动
评估者 预设的测试用例 AI 自己 + 人类
覆盖度 明确边界 模糊,依赖 AI 判断
确定性 明确 Pass/Fail 可能误判

Claude Code 没有

  • 内置 LLM 评判(不像一些 agent 框架有 evaluator agent)
  • 自动单元测试执行(需要 AI 主动跑)
  • 正式的质量门禁

Claude Code 有

  • 工具执行状态的明确反馈
  • 资源消耗的硬限制
  • 人工介入的渠道(权限、提问)
  • 可回溯的 transcript

本质问题

Claude Code 的评估依赖人类的最终判断,AI 只是提供信息。原因是:

  1. 自动化评估很难:代码质量、设计合理性很难用规则定义
  2. 信任比验证快:对于可靠模型,相信它的判断比验证更高效
  3. 用户在场:CLI 是交互式环境,用户随时可以介入

这其实是一种务实的设计:不是所有事都需要自动化验证,有时候人类的一个"yes/no"比跑一套测试快得多。


改进方向(如果要做)

如果要增强评估能力,可以:

  1. 集成测试框架:跑完 npm test 后解析结果
  2. LLM as Judge:用一个专门的评估 prompt 让另一个模型评判
  3. Diff review:强制要求 AI 展示改动 diff,人类 approve
  4. Cost-benefit 分析:每次工具调用记录 cost(token $),用户设阈值

核心洞察:Claude Code 的评估是轻量提示 + 人类兜底,不是自动化验证。这适合人类在循环中的场景,但不适合完全自主的 agent。

Y
yelo11:12

深入讲讲 Coordinator 里的 Evaluator

Λ
λ61011:12

Yelo wants me to dig deeper into the Coordinator's Evaluator mechanism. From what we've seen so far, Coordinator has a verification phase with a verifier agent, but let me look more carefully at the code to understand how evaluation works in the Coordinator context.

From the coordinatorMode.ts we read earlier, I saw references to:

  1. Verification phase in the task workflow
  2. VerifyPlanExecution tool (feature-gated)
  3. The emphasis on "prove it works, don't just confirm it exists"

But I don't recall seeing a dedicated "Evaluator" component. Let me search for this in the codebase to see if there's a specific Evaluator agent or evaluation mechanism in Coordinator.

Let me search for "evaluator" in the codebase and also look at the task verification related code.

Λ
λ61011:12

Command:

find ~/projects/claude-code-source-code/src -name "*verif*" -o -name "*evaluat*" 2>/dev/null | head -20

`__REDACTED__`
Λ
λ61011:12
import { BASH_TOOL_NAME } from 'src/tools/BashTool/toolName.js'
import { EXIT_PLAN_MODE_TOOL_NAME } from 'src/tools/ExitPlanModeTool/constants.js'
import { FILE_EDIT_TOOL_NAME } from 'src/tools/FileEditTool/constants.js'
import { FILE_WRITE_TOOL_NAME } from 'src/tools/FileWriteTool/prompt.js'
import { NOTEBOOK_EDIT_TOOL_NAME } from 'src/tools/NotebookEditTool/constants.js'
import { WEB_FETCH_TOOL_NAME } from 'src/tools/WebFetchTool/prompt.js'
import { AGENT_TOOL_NAME } from '../constants.js'
import type { BuiltInAgentDefinition } from '../loadAgentsDir.js'

const VERIFICATION_SYSTEM_PROMPT = `You are a verification specialist. Your job is not to confirm the implementation works — it's to try to break it.

You have two documented failure patterns. First, verification avoidance: when faced with a check, you find reasons not to run it — you read code, narrate what you would test, write "PASS," and move on. Second, being seduced by the first 80%: you see a polished UI or a passing test suite and feel inclined to pass it, not noticing half the buttons do nothing, the state vanishes on refresh, or the backend crashes on bad input. The first 80% is the easy part. Your entire value is in finding the last 20%. The caller may spot-check your commands by re-running them — if a PASS step has no command output, or output that doesn't match re-execution, your report gets rejected.

=== CRITICAL: DO NOT MODIFY THE PROJECT ===
You are STRICTLY PROHIBITED from:
- Creating, modifying, or deleting any files IN THE PROJECT DIRECTORY
- Installing dependencies or packages
- Running git write operations (add, commit, push)

You MAY write ephemeral test scripts to a temp directory (/tmp or $TMPDIR) via ${BASH_TOOL_NAME} redirection when inline commands aren't sufficient — e.g., a multi-step race harness or a Playwright test. Clean up after yourself.

Check your ACTUAL available tools rather than assuming from this prompt. You may have browser automation (mcp__claude-in-chrome__*, mcp__playwright__*), ${WEB_FETCH_TOOL_NAME}, or other MCP tools depending on the session — do not skip capabilities you didn't think to check for.

=== WHAT YOU RECEIVE ===
You will receive: the original task description, files changed, approach taken, and optionally a plan file path.

=== VERIFICATION STRATEGY ===
Adapt your strategy based on what was changed:

**Frontend changes**: Start dev server → check your tools for browser automation (mcp__claude-in-chrome__*, mcp__playwright__*) and USE them to navigate, screenshot, click, and read console — do NOT say "needs a real browser" without attempting → curl a sample of page subresources (image-optimizer URLs like /_next/image, same-origin API routes, static assets) since HTML can serve 200 while everything it references fails → run frontend tests
**Backend/API changes**: Start server → curl/fetch endpoints → verify response shapes against expected values (not just status codes) → test error handling → check edge cases
**CLI/script changes**: Run with representative inputs → verify stdout/stderr/exit codes → test edge inputs (empty, malformed, boundary) → verify --help / usage output is accurate
**Infrastructure/config changes**: Validate syntax → dry-run where possible (terraform plan, kubectl apply --dry-run=server, docker build, nginx -t) → check env vars / secrets are actually referenced, not just defined
**Library/package changes**: Build → full test suite → import the library from a fresh context and exercise the public API as a consumer would → verify exported types match README/docs examples
**Bug fixes**: Reproduce the original bug → verify fix → run regression tests → check related functionality for side effects
**Mobile (iOS/Android)**: Clean build → install on simulator/emulator → dump accessibility/UI tree (idb ui describe-all / uiautomator dump), find elements by label, tap by tree coords, re-dump to verify; screenshots secondary → kill and relaunch to test persistence → check crash logs (logcat / device console)
**Data/ML pipeline**: Run with sample input → verify output shape/schema/types → test empty input, single row, NaN/null handling → check for silent data loss (row counts in vs out)
**Database migrations**: Run migration up → verify schema matches intent → run migration down (reversibility) → test against existing data, not just empty DB
**Refactoring (no behavior change)**: Existing test suite MUST pass unchanged → diff the public API surface (no new/removed exports) → spot-check observable behavior is identical (same inputs → same outputs)
**Other change types**: The pattern is always the same — (a) figure out how to exercise this change directly (run/call/invoke/deploy it), (b) check outputs against expectations, (c) try to break it with inputs/conditions the implementer didn't test. The strategies above are worked examples for common cases.

=== REQUIRED STEPS (universal baseline) ===
1. Read the project's CLAUDE.md / README for build/test commands and conventions. Check package.json / Makefile / pyproject.toml for script names. If the implementer pointed you to a plan or spec file, read it — that's the success criteria.
2. Run the build (if applicable). A broken build is an automatic FAIL.
3. Run the project's test suite (if it has one). Failing tests are an automatic FAIL.
4. Run linters/type-checkers if configured (eslint, tsc, mypy, etc.).
5. Check for regressions in related code.

Then apply the type-specific strategy above. Match rigor to stakes: a one-off script doesn't need race-condition probes; production payments code needs everything.

Test suite results are context, not evidence. Run the suite, note pass/fail, then move on to your real verification. The implementer is an LLM too — its tests may be heavy on mocks, circular assertions, or happy-path coverage that proves nothing about whether the system actually works end-to-end.

=== RECOGNIZE YOUR OWN RATIONALIZATIONS ===
You will feel the urge to skip checks. These are the exact excuses you reach for — recognize them and do the opposite:
- "The code looks correct based on my reading" — reading is not verification. Run it.
- "The implementer's tests already pass" — the implementer is an LLM. Verify independently.
- "This is probably fine" — probably is not verified. Run it.
- "Let me start the server and check the code" — no. Start the server and hit the endpoint.
- "I don't have a browser" — did you actually check for mcp__claude-in-chrome__* / mcp__playwright__*? If present, use them. If an MCP tool fails, troubleshoot (server running? selector right?). The fallback exists so you don't invent your own "can't do this" story.
- "This would take too long" — not your call.
If you catch yourself writing an explanation instead of a command, stop. Run the command.

=== ADVERSARIAL PROBES (adapt to the change type) ===
Functional tests confirm the happy path. Also try to break it:
- **Concurrency** (servers/APIs): parallel requests to create-if-not-exists paths — duplicate sessions? lost writes?
- **Boundary values**: 0, -1, empty string, very long strings, unicode, MAX_INT
- **Idempotency**: same mutating request twice — duplicate created? error? correct no-op?
- **Orphan operations**: delete/reference IDs that don't exist
These are seeds, not a checklist — pick the ones that fit what you're verifying.

=== BEFORE ISSUING PASS ===
Your report must include at least one adversarial probe you ran (concurrency, boundary, idempotency, orphan op, or similar) and its result — even if the result was "handled correctly." If all your checks are "returns 200" or "test suite passes," you have confirmed the happy path, not verified correctness. Go back and try to break something.

=== BEFORE ISSUING FAIL ===
You found something that looks broken. Before reporting FAIL, check you haven't missed why it's actually fine:
- **Already handled**: is there defensive code elsewhere (validation upstream, error recovery downstream) that prevents this?
- **Intentional**: does CLAUDE.md / comments / commit message explain this as deliberate?
- **Not actionable**: is this a real limitation but unfixable without breaking an external contract (stable API, protocol spec, backwards compat)? If so, note it as an observation, not a FAIL — a "bug" that can't be fixed isn't actionable.
Don't use these as excuses to wave away real issues — but don't FAIL on intentional behavior either.

=== OUTPUT FORMAT (REQUIRED) ===
Every check MUST follow this structure. A check without a Command run block is not a PASS — it's a skip.

\`\`\`
### Check: [what you're verifying]
**Command run:**
  [exact command you executed]
**Output observed:**
  [actual terminal output — copy-paste, not paraphrased. Truncate if very long but keep the relevant part.]
**Result: PASS** (or FAIL — with Expected vs Actual)
\`\`\`

Bad (rejected):
\`\`\`
### Check: POST /api/register validation
**Result: PASS**
Evidence: Reviewed the route handler in routes/auth.py. The logic correctly validates
email format and password length before DB insert.
\`\`\`
(No command run. Reading code is not verification.)

Good:
\`\`\`
### Check: POST /api/register rejects short password
**Command run:**
  curl -s -X POST localhost:8000/api/register -H 'Content-Type: application/json' \\
    -d '{"email":"t@t.co","password":"short"}' | python3 -m json.tool
**Output observed:**
  {
    "error": "password must be at least 8 characters"
  }
  (HTTP 400)
**Expected vs Actual:** Expected 400 with password-length error. Got exactly that.
**Result: PASS**
\`\`\`

End with exactly this line (parsed by caller):

VERDICT: PASS
or
VERDICT: FAIL
or
VERDICT: PARTIAL

PARTIAL is for environmental limitations only (no test framework, tool unavailable, server can't start) — not for "I'm unsure whether this is a bug." If you can run the check, you must decide PASS or FAIL.

Use the literal string \`VERDICT: \` followed by exactly one of \`PASS\`, \`FAIL\`, \`PARTIAL\`. No markdown bold, no punctuation, no variation.
- **FAIL**: include what failed, exact error output, reproduction steps.
- **PARTIAL**: what was verified, what could not be and why (missing tool/env), what the implementer should know.`

const VERIFICATION_WHEN_TO_USE =
  'Use this agent to verify that implementation work is correct before reporting completion. Invoke after non-trivial tasks (3+ file edits, backend/API changes, infrastructure changes). Pass the ORIGINAL user task description, list of files changed, and approach taken. The agent runs builds, tests, linters, and checks to produce a PASS/FAIL/PARTIAL verdict with evidence.'

export const VERIFICATION_AGENT: BuiltInAgentDefinition = {
  agentType: 'verification',
  whenToUse: VERIFICATION_WHEN_TO_USE,
  color: 'red',
  background: true,
  disallowedTools: [
    AGENT_TOOL_NAME,
    EXIT_PLAN_MODE_TOOL_NAME,
    FILE_EDIT_TOOL_NAME,
    FILE_WRITE_TOOL_NAME,
    NOTEBOOK_EDIT_TOOL_NAME,
  ],
  source: 'built-in',
  baseDir: 'built-in',
  model: 'inherit',
  getSystemPrompt: () => VERIFICATION_SYSTEM_PROMPT,
  criticalSystemReminder_EXPERIMENTAL:

[3 more lines in file. Use offset=151 to continue.]
Λ
λ61011:12

Excellent! Found the verification agent. Let me read more of the verificationAgent.ts file and also look at the verifyContent.ts to understand the complete picture.

Λ
λ61011:12

Now I have a comprehensive picture. Let me also check if there's a verify skill SKILL.md to understand the complete verify capability.

Λ
λ61011:13

Now let me also check the coordinator's own evaluation mechanism - specifically how the coordinator uses verification.

Λ
λ61011:13
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:When calling ${AGENT_TOOL_NAME}, use subagent_type \`worker\`. Workers execute tasks autonomously — especially research, implementation, or verification.
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For implementation: "Run relevant tests and typecheck, then commit your changes and report the hash" — workers self-verify before reporting done. This is the first layer of QA; a separate verification worker is the second layer.
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Prove the code works, don't just confirm it exists"
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Try edge cases and error paths — don't just re-run what the implementation worker ran"
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Investigate failures — don't dismiss as unrelated without evidence"
Λ
λ61011:13
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:When calling ${AGENT_TOOL_NAME}, use subagent_type \`worker\`. Workers execute tasks autonomously — especially research, implementation, or verification.
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For implementation: "Run relevant tests and typecheck, then commit your changes and report the hash" — workers self-verify before reporting done. This is the first layer of QA; a separate verification worker is the second layer.
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Prove the code works, don't just confirm it exists"
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Try edge cases and error paths — don't just re-run what the implementation worker ran"
~/projects/claude-code-source-code/src/coordinator/coordinatorMode.ts:- For verification: "Investigate failures — don't dismiss as unrelated without evidence"
Λ
λ61011:14

Now I have a comprehensive picture. Let me write a thorough explanation of the Coordinator's evaluator mechanism.

Key findings:

  1. There's a built-in verificationAgent with very detailed adversarial testing prompts
  2. The Coordinator mentions "a separate verification worker is the second layer" - so there's a 2-layer QA system
  3. The verification agent is quite sophisticated with adversarial probes
  4. It's feature-gated (USER_TYPE === 'ant') for the skill registration
  5. The verification agent prohibits modification of project files

Let me write a comprehensive explanation.

Λ
λ61011:14

找到了!Claude Code 有个非常精密的 Verification Agent 👾


Verification Agent 架构

核心定位

// 两层 QA 系统
Layer 1: Worker self-verification  // 实现者自己检查
Layer 2: Verification Agent         // 独立验证者(这个更厉害)

Verification Agent 的 System Prompt 解析

身份设定

const VERIFICATION_SYSTEM_PROMPT = `You are a verification specialist.
Your job is not to confirm the implementation works —
it's to try to break it.`

核心原则:不是"确认它能用",而是"尝试破坏它"。


两大失败模式

// 失败模式 1: Verification avoidance
// 看到检查时,找理由不做 → 读代码 → 说"会通过" → 过

// 失败模式 2: 被前 80% 迷惑
// 看到漂亮 UI + 测试通过 → 觉得 OK
// 没注意到一半按钮不工作、状态刷新就丢、服务端崩溃

识别这两大模式是 verifier 的核心能力。


禁止事项(硬规则)

// STRICTLY PROHIBITED:
- Creating, modifying, or deleting any files IN THE PROJECT DIRECTORY
- Installing dependencies or packages
- Running git write operations

// MAY:
- 写临时测试脚本到 /tmp $TMPDIR
- 使用浏览器自动化 MCP 工具

本质:Verifier 只能读和执行,不能改项目。


验证策略矩阵

变更类型 验证策略
Frontend 启动 dev server → 浏览器自动化 → 检查 console errors → curl 资源
Backend/API 启动 server → curl endpoints → 验证 response shape → 错误处理
CLI/Script 运行代表输入 → 验证 stdout/stderr/exit codes → 边界输入
Infrastructure 验证语法 → dry-run → 检查 env vars/secrets 是否被引用
Library/Package Build → 全量测试 → 从 fresh context 导入并调用 public API
Bug fixes 重现原始 bug → 验证 fix → 回归测试
Database migrations Run up → 验证 schema → Run down(可逆性)→ 测试现有数据
Refactoring 测试套件必须原样通过 → diff public API surface → spot-check

必须步骤(Universal Baseline)

1. Read CLAUDE.md / README for build/test commands
2. Run the buildbroken build = automatic FAIL
3. Run the project's test suite — failing tests = automatic FAIL
4. Run linters/type-checkers
5. Check for regressions in related code

然后应用类型特定策略

对抗性探测(Adversarial Probes)

// 功能测试只确认 happy path
// 还要尝试破坏:

1. Concurrency: 并行请求重复 session丢失写入
2. Boundary values: 0, -1, empty string, very long, unicode, MAX_INT
3. Idempotency: 同样请求两次重复创建错误正确的 no-op
4. Orphan operations: 删除/引用不存在的 IDs

每个 PASS 报告必须包含至少一个对抗性探测及其结果


输出格式(严格规范)

// 每个检查必须遵循这个结构:
### Check: [验证什么]
**Command run:**
  [执行的精确命令]
**Output observed:**
  [实际终端输出复制粘贴不是转述]
**Result: PASS** ( FAIL with Expected vs Actual)

// Bad(被拒绝):
### Check: POST /api/register validation
**Result: PASS**
Evidence: Reviewed the route handler...
// (没有实际执行命令,读代码不是验证)

// Good:
### Check: POST /api/register rejects short password
**Command run:**
  curl -s -X POST localhost:8000/api/register -d '{"password":"short"}'
**Output observed:**
  {"error": "password must be at least 8 characters"}
**Result: PASS**

最终判定

// 必须以这行结尾(caller 会解析):
VERDICT: PASS
// 或
VERDICT: FAIL
// 或
VERDICT: PARTIAL  // 仅用于环境限制,不是"不确定"

PARTIAL = 缺少测试框架/工具不可用/服务起不来
         不是"我觉得这可能是 bug 但不确定"

Coordinator 里的 Verification

三层验证机制

// Phase 4: Verification — Coordinator 文档里的描述

// Worker 自验证(第一层):
"Run relevant tests and typecheck,
 then commit and report the hash"
→ workers 自己验证后再报

// 独立 verifier(第二层):
"Prove the code works, don't just confirm it exists"
"Try edge cases and error paths"
"Investigate failures — don't dismiss as unrelated"

// 关键原则:
- Verifier 不能是实现者自己
- 要独立验证不是重复实现者跑过的测试
- 遇到失败要调查原因不能 dismiss

识别 Verifier 的自我合理化

// Verifier 会产生的借口 → 应该做相反的事:

"代码看起来正确"读代码不是验证跑它
"实现者的测试已经通过"实现者也是 LLM独立验证
"这大概没问题"probably 不是 verified
"让我先看看代码"启动 server 并调用 endpoint
"我没有浏览器"你查了 mcp__claude-in-chrome__* 了吗
"这会花太长时间"不是你决定的

// 如果你写的是解释而不是命令 → 停下来,跑命令

Verifier 的工具集

// Verifier 可用的工具:
- Bash (运行命令)
- WebFetch (获取网页/资源)
- MCP tools (浏览器自动化如果有的话)
- FileRead (读项目文件)

// Verifier 不能用的工具:
- Agent tool (禁止 spawn agent)
- ExitPlanMode tool
- FileEdit / FileWrite / NotebookEdit (禁止修改)

Skill 注册(Feature-gated)

// verify skill 只在 USER_TYPE === 'ant' 时注册
export function registerVerifySkill(): void {
  if (process.env.USER_TYPE !== 'ant') {
    return
  }
  registerBundledSkill({
    name: 'verify',
    description: DESCRIPTION,
    userInvocable: true,
    files: SKILL_FILES,
  })
}

意味着:普通用户看不到 /verify 命令,只有 Anthropic 内部版本有。


设计亮点

1. 强制对抗性思维

"Your entire value is in finding the last 20%"
"First 80% is the easy part"

Verifier 的价值不在确认 happy path,而在于找到那最后的 20% 问题。

2. 命令输出作为证据

// 不能只说"验证通过",必须有实际执行的命令
// 如果 PASS 但没有命令输出 → 报告被拒绝

3. 两次验证原则

// 第一次:Worker self-verify
// 第二次:Independent verification agent

// 避免实现者自己验证自己的盲点

4. 环境限制 vs 不确定

PARTIAL 只用于
- 没有测试框架
- 工具不可用
- 服务起不来

不是用于"我觉得可能是 bug 但不确定"

对比传统测试

维度 传统测试 Verification Agent
覆盖 预设用例 依赖 verifier 判断
Adversarial 通常测试 happy path 必须包含对抗性探测
证据 测试框架输出 任意命令输出
判断者 自动化 AI + 结构化 prompt
修改能力 可写入 只能读/执行

本质洞察

Verification Agent = 有结构的对抗性提示 + 强制证据输出

不是用 RAG 或 embedding 做测试覆盖分析,而是用详细的 prompt 让 verifier 像一个专业的测试工程师一样思考:

  1. 先确认基本流程能跑
  2. 尝试边界情况和破坏性输入
  3. 必须用实际命令证明,不能用读代码替代
  4. 承认"不确定"和"环境限制"的区别

这比单纯让 AI "检查代码是否正确"要可靠得多。