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, 角色定制, Claude-Code]
|
||||
create time: 2026-06-09 22:30
|
||||
---
|
||||
|
||||
{/* 本章目标:揭示 Agent 定义的完整数据模型、加载发现机制、工具过滤和与 AgentTool 的联动 */}
|
||||
# 自定义 Agent - 从 Markdown 到运行时的完整链路
|
||||
|
||||
## Agent 定义的三种来源
|
||||
## 概述
|
||||
|
||||
Claude Code 的 Agent 系统支持三种来源(Built-in、Plugin、User/Project/Policy),通过 Markdown 文件定义 Agent 的完整行为——包括工具控制、模型配置、权限模式、隔离策略和 Hooks。本文揭示从 Agent 定义的 Markdown 数据模型到运行时子 Agent 启动的完整链路。
|
||||
|
||||
## 正文
|
||||
|
||||
### 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,42 +82,34 @@ 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["加载 Markdown 文件"] --> B["解析 YAML frontmatter\n正文作为 system prompt"]
|
||||
B --> C["校验必需字段\nname, description"]
|
||||
C --> D["并行加载 Plugin Agents"]
|
||||
D --> E["初始化 Memory Snapshots"]
|
||||
E --> F["合并 Built-in + Plugin + Custom\n按 agentType 去重, 后者覆盖前者"]
|
||||
F --> G["分配颜色\nsetAgentColor()"]
|
||||
```
|
||||
|
||||
## 工具过滤的实现
|
||||
Markdown 文件的加载路径:
|
||||
|
||||
- `~/.claude/agents/*.md`(用户级,source = `'userSettings'`)
|
||||
- `.claude/agents/*.md`(项目级,source = `'projectSettings'`)
|
||||
- `managed/policy sources`(策略级,source = `'policySettings'`)
|
||||
|
||||
> [!tip] 容错处理
|
||||
> 静默跳过无 frontmatter 的 .md 文件(可能是参考文档),解析失败记录到 failedFiles 不阻塞其他 Agent。
|
||||
|
||||
### 工具过滤的实现
|
||||
|
||||
当 Agent 被派生时,`AgentTool` 根据定义中的 `tools` / `disallowedTools` 过滤可用工具列表:
|
||||
|
||||
```
|
||||
```text
|
||||
全部工具
|
||||
↓ disallowedTools 移除
|
||||
↓ tools 白名单过滤(如果指定)
|
||||
@@ -137,7 +134,7 @@ disallowedTools: [
|
||||
]
|
||||
```
|
||||
|
||||
## System Prompt 的注入方式
|
||||
### System Prompt 的注入方式
|
||||
|
||||
Agent 的 system prompt 通过 `getSystemPrompt()` 闭包延迟生成:
|
||||
|
||||
@@ -158,36 +155,24 @@ 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 查找"]
|
||||
B --> C["检查 requiredMcpServers"]
|
||||
C --> D["过滤工具列表\ntools / disallowedTools"]
|
||||
D --> E["解析模型\ninherit / 具体模型名 / 未指定"]
|
||||
E --> F["解析权限模式 permissionMode"]
|
||||
F --> G["构建隔离环境\n如果 isolation === worktree"]
|
||||
G --> H["注入 system prompt"]
|
||||
H --> I["注入 initialPrompt"]
|
||||
I --> J["启动子 Agent 循环\nforkSubagent / runAgent"]
|
||||
```
|
||||
|
||||
## 内置 Agent 参考
|
||||
### 内置 Agent 参考
|
||||
|
||||
| Agent | agentType | 角色 | 工具限制 | 模型 |
|
||||
|-------|-----------|------|---------|------|
|
||||
@@ -198,14 +183,23 @@ 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 用户提供空白画布。
|
||||
> [!info] SDK 限制
|
||||
> 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 获得跨会话的持久记忆:
|
||||
|
||||
- **`local`**:当前项目、当前用户有效
|
||||
- **`project`**:当前项目所有用户共享
|
||||
- **`user`**:所有项目共享
|
||||
| 范围 | 说明 |
|
||||
|------|------|
|
||||
| `local` | 当前项目、当前用户有效 |
|
||||
| `project` | 当前项目所有用户共享 |
|
||||
| `user` | 所有项目共享 |
|
||||
|
||||
Memory 通过 `loadAgentMemoryPrompt()` 注入到 system prompt 末尾,包含读写记忆的指令。Agent Memory Snapshot 机制在项目间同步 `user` 级记忆。
|
||||
|
||||
## 关联笔记
|
||||
|
||||
- [[skills|Skills 技能系统]]
|
||||
- [[hooks|Hooks 生命周期钩子]]
|
||||
- [[mcp-configuration|MCP 配置]]
|
||||
|
||||
Reference in New Issue
Block a user