vault backup: 2026-06-09 23:15:17
This commit is contained in:
@@ -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]]
|
||||
|
||||
Reference in New Issue
Block a user