vault backup: 2026-06-09 23:15:17

This commit is contained in:
2026-06-09 23:15:17 +08:00
parent 31fd89aafe
commit e92c0327d9
111 changed files with 7276 additions and 8846 deletions
@@ -1,12 +1,17 @@
---
title: "自定义 Agent - 从 Markdown 到运行时的完整链路"
description: "揭秘 Claude Code 自定义 Agent 完整链路:Agent 定义的 Markdown 数据模型、三种加载来源、工具过滤策略和与 AgentTool 的联动机制。"
keywords: ["自定义 Agent", "Agent 定义", "Markdown Agent", "Agent 配置", "角色定制"]
tags: [自定义Agent, Agent定义, Markdown, Agent配置, 角色定制]
create time: 2026-06-09 22:30
---
{/* 本章目标:揭示 Agent 定义的完整数据模型、加载发现机制、工具过滤和与 AgentTool 的联动 */}
# 自定义 Agent - 从 Markdown 到运行时的完整链路
## Agent 定义的三种来源
## 概述
揭秘 Claude Code 自定义 Agent 完整链路:Agent 定义的 Markdown 数据模型、三种加载来源、工具过滤策略和与 AgentTool 的联动机制。
## 正文
### Agent 定义的三种来源
Claude Code 的 Agent 不仅仅来自用户自定义——系统有三类来源,按优先级合并:
@@ -18,7 +23,7 @@ Claude Code 的 Agent 不仅仅来自用户自定义——系统有三类来源
合并逻辑在 `getActiveAgentsFromList()` 中:按 `agentType` 去重,后者覆盖前者。这意味着你可以在 `.claude/agents/` 中放一个 `Explore.md` 来完全替换内置的 Explore Agent。
## Markdown Agent 文件的完整格式
### Markdown Agent 文件的完整格式
```markdown
---
@@ -69,7 +74,7 @@ color: "blue" # 终端中的 Agent 颜色标识
(正文内容 = system prompt)
```
### 字段解析细节
#### 字段解析细节
- **`tools`**:通过 `parseAgentToolsFromFrontmatter()` 解析,支持逗号分隔字符串或数组
- **`model: "inherit"`**:使用主线程的模型(区分大小写,只有小写 "inherit" 有效)
@@ -77,46 +82,44 @@ color: "blue" # 终端中的 Agent 颜色标识
- **`isolation: "remote"`**:仅在 Anthropic 内部可用(`USER_TYPE === 'ant'`),外部构建只支持 `worktree`
- **`background`**:`true` 使 Agent 始终在后台运行,主线程不等待结果
## 加载与发现机制
### 加载与发现机制
`getAgentDefinitionsWithOverrides()`(被 `memoize` 缓存)执行完整的发现流程:
```
1. 加载 Markdown 文件
├── loadMarkdownFilesForSubdir('agents', cwd)
│ ├── ~/.claude/agents/*.md (用户级,source = 'userSettings')
│ ├── .claude/agents/*.md (项目级,source = 'projectSettings')
│ └── managed/policy sources (策略级,source = 'policySettings')
│
└── 每个 .md 文件:
├── 解析 YAML frontmatter
├── 正文作为 system prompt
├── 校验必需字段(name, description)
├── 静默跳过无 frontmatter 的 .md 文件(可能是参考文档)
└── 解析失败 → 记录到 failedFiles,不阻塞其他 Agent
2. 并行加载 Plugin Agents
└── loadPluginAgents() → memoized
3. 初始化 Memory Snapshots(如果 AGENT_MEMORY_SNAPSHOT 启用)
└── initializeAgentMemorySnapshots()
4. 合并 Built-in + Plugin + Custom
└── getActiveAgentsFromList() → 按 agentType 去重,后者覆盖前者
5. 分配颜色
└── setAgentColor(agentType, color) → 终端 UI 中区分不同 Agent
```mermaid
flowchart TD
A["1. 加载 Markdown 文件"] --> B["loadMarkdownFilesForSubdir('agents', cwd)"]
B --> C["~/.claude/agents/*.md 用户级 source='userSettings'"]
B --> D[".claude/agents/*.md 项目级 source='projectSettings'"]
B --> E["managed/policy sources 策略级 source='policySettings'"]
A --> F["每个 .md 文件"]
F --> G["解析 YAML frontmatter"]
F --> H["正文作为 system prompt"]
F --> I["校验必需字段 name/description"]
F --> J["静默跳过无 frontmatter 的 .md 文件"]
F --> K["解析失败 -> 记录到 failedFiles,不阻塞其他 Agent"]
A --> L["2. 并行加载 Plugin Agents"]
L --> M["loadPluginAgents() memoized"]
A --> N["3. 初始化 Memory Snapshots"]
N --> O["initializeAgentMemorySnapshots()"]
A --> P["4. 合并 Built-in + Plugin + Custom"]
P --> Q["getActiveAgentsFromList() 按 agentType 去重,后者覆盖前者"]
Q --> R["5. 分配颜色"]
R --> S["setAgentColor(agentType, color)"]
```
## 工具过滤的实现
### 工具过滤的实现
当 Agent 被派生时,`AgentTool` 根据定义中的 `tools` / `disallowedTools` 过滤可用工具列表:
```
全部工具
↓ disallowedTools 移除
↓ tools 白名单过滤(如果指定)
可用工具
```mermaid
flowchart TD
A["全部工具"] --> B["disallowedTools 移除"]
B --> C{"tools 指定?"}
C -->|"是"| D["tools 白名单过滤"]
C -->|"否"| E["全部保留"]
D --> F["可用工具"]
E --> F
```
- **`tools` 未指定**:Agent 可以使用所有工具(默认全能)
@@ -137,7 +140,7 @@ disallowedTools: [
]
```
## System Prompt 的注入方式
### System Prompt 的注入方式
Agent 的 system prompt 通过 `getSystemPrompt()` 闭包延迟生成:
@@ -158,36 +161,27 @@ getSystemPrompt: () => {
对于 Built-in Agent,`getSystemPrompt` 接受 `toolUseContext` 参数,可以根据运行时状态(如是否使用嵌入式搜索工具)动态调整 prompt 内容。
## 与 AgentTool 的联动
### 与 AgentTool 的联动
当主 Agent 需要派生子 Agent 时:
```
AgentTool.call({ subagent_type: "reviewer", ... })
↓
1. 从 agentDefinitions.activeAgents 查找 agentType === "reviewer"
↓
2. 检查 requiredMcpServers(如果 Agent 要求特定 MCP 服务器)
↓
3. 过滤工具列表(tools / disallowedTools)
↓
4. 解析模型:
- "inherit" → 使用主线程模型
- 具体模型名 → 直接使用
- 未指定 → 主线程模型
↓
5. 解析权限模式(permissionMode)
↓
6. 构建隔离环境(如果 isolation === "worktree")
↓
7. 注入 system prompt(getSystemPrompt())
↓
8. 注入 initialPrompt(如果定义了)
↓
9. 启动子 Agent 循环(forkSubagent / runAgent)
```mermaid
flowchart TD
A["AgentTool.call({ subagent_type: 'reviewer', ... })"] --> B["从 agentDefinitions.activeAgents 查找 agentType === 'reviewer'"]
B --> C["检查 requiredMcpServers"]
C --> D["过滤工具列表 tools/disallowedTools"]
D --> E{"解析模型"}
E -->|"'inherit'"| F["使用主线程模型"]
E -->|"具体模型名"| G["直接使用"]
E -->|"未指定"| F
E --> H["解析权限模式 permissionMode"]
H --> I["构建隔离环境 isolation === 'worktree'"]
I --> J["注入 system prompt getSystemPrompt()"]
J --> K["注入 initialPrompt 如果定义了"]
K --> L["启动子 Agent 循环 forkSubagent/runAgent"]
```
## 内置 Agent 参考
### 内置 Agent 参考
| Agent | agentType | 角色 | 工具限制 | 模型 |
|-------|-----------|------|---------|------|
@@ -198,9 +192,10 @@ AgentTool.call({ subagent_type: "reviewer", ... })
| **Code Guide** | `claude-code-guide` | Claude Code 使用指南 | 只读 | — |
| **Statusline Setup** | `statusline-setup` | 终端状态栏配置 | 有限 | — |
SDK 入口(`sdk-ts`/`sdk-py`/`sdk-cli`)不加载 Code Guide Agent。环境变量 `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS` 可以完全禁用内置 Agent,给 SDK 用户提供空白画布。
> [!tip]
> SDK 入口(`sdk-ts`/`sdk-py`/`sdk-cli`)不加载 Code Guide Agent。环境变量 `CLAUDE_AGENT_SDK_DISABLE_BUILTIN_AGENTS` 可以完全禁用内置 Agent,给 SDK 用户提供空白画布。
## Agent Memory:持久化的 Agent 状态
### Agent Memory:持久化的 Agent 状态
当 `memory` 字段启用时,Agent 获得跨会话的持久记忆:
@@ -209,3 +204,9 @@ SDK 入口(`sdk-ts`/`sdk-py`/`sdk-cli`)不加载 Code Guide Agent。环境
- **`user`**:所有项目共享
Memory 通过 `loadAgentMemoryPrompt()` 注入到 system prompt 末尾,包含读写记忆的指令。Agent Memory Snapshot 机制在项目间同步 `user` 级记忆。
## 关联笔记
- [[claude-code-best/docs/features/extensibility/hooks]]
- [[claude-code-best/docs/features/extensibility/skills]]
- [[claude-code-best/docs/features/fork-subagent]]