Claude Code 核心 Agent 路由调度决策
概述
Claude Code 的 Agent 路由调度系统是一个分层架构,负责决定何时、如何以及使用哪个 Agent 来执行任务。核心实现位于 src/tools/AgentTool/ 目录下。
核心组件
1. AgentTool.tsx - 主调度器
位置 : src/tools/AgentTool/AgentTool.tsx
这是 Agent 调度的入口点,负责:
- 解析用户输入和参数
- 选择合适的 Agent 类型
- 决定是否异步执行
- 处理工作树隔离和远程执行
2. 调度决策流程
typescript
// 核心调度逻辑在 AgentTool.tsx 的 call() 方法中
async call({ input, toolUseContext, onProgress, assistantMessage }) {
// 1. 选择 Agent 类型
const selectedAgent = selectAgent(subagent_type, availableAgents);
// 2. 权限和工具解析
const workerTools = assembleToolPool(workerPermissionContext, appState.mcp.tools);
// 3. 决定是否异步执行
const shouldRunAsync = (run_in_background || selectedAgent.background ||
isCoordinator || forceAsync || assistantForceAsync) &&
!isBackgroundTasksDisabled;
// 4. 执行路径分支
if (shouldRunAsync) {
// 异步 Agent 路径:注册后台任务
registerAsyncAgent({...}) && runAsyncAgentLifecycle({...})
} else {
// 同步 Agent 路径:直接执行
runAgent({...})
}
}
3. 异步 vs 同步决策
异步执行触发条件(满足任意一个):
run_in_background = true(用户明确指定)selectedAgent.background = true(Agent 定义为后台运行)isCoordinator = true(协调器模式)forceAsync = true(Fork Subagent 实验)assistantForceAsync = true(KAIROS 助手模式)
同步执行:默认模式,Agent 在父会话中同步运行
4. Agent 选择逻辑
选择优先级:
- Fork Subagent 路径 :当
isForkSubagentEnabled()为 true 时,强制使用 fork - 内置 Agent:从预定义的内置 Agent 中选择(如 verification, explore, plan)
- 自定义 Agent :从用户的
.claude/agents/目录加载 - 通用 Agent:回退到通用目的 Agent
5. 权限模式处理
Agent 可以覆盖父会话的权限模式:
typescript
// Agent 定义的权限模式
const agentPermissionMode = agentDefinition.permissionMode;
// 父会话的权限上下文
let toolPermissionContext = state.toolPermissionContext;
// 覆盖条件:Agent 定义了权限模式且父会话不是 bypass/acceptEdits/auto
if (
agentPermissionMode &&
state.toolPermissionContext.mode !== 'bypassPermissions' &&
state.toolPermissionContext.mode !== 'acceptEdits' &&
!(feature('TRANSCRIPT_CLASSIFIER') && state.toolPermissionContext.mode === 'auto')
) {
toolPermissionContext = {
...toolPermissionContext,
mode: agentPermissionMode,
};
}
安全与隔离机制
1. 工具过滤
typescript
// agentToolUtils.ts - filterToolsForAgent 函数
export function filterToolsForAgent({
tools,
isBuiltIn,
isAsync,
permissionMode,
}) {
return tools.filter(tool => {
// 禁止所有 Agent 使用的工具
if (ALL_AGENT_DISALLOWED_TOOLS.has(tool.name)) {
return false;
}
// 异步 Agent 只能使用白名单工具
if (isAsync && !ASYNC_AGENT_ALLOWED_TOOLS.has(tool.name)) {
return false;
}
return true;
});
}
禁止工具列表:
AGENT_TOOL_NAME- Agent 不能自我复制TASK_STOP_TOOL_NAME- 不能停止其他任务- 危险命令如
rm -rf /
异步 Agent 白名单(只读工具):
FILE_READ_TOOL_NAMEGREP_TOOL_NAMEGLOB_TOOL_NAME- 等
2. 工作树隔离(Worktree Isolation)
typescript
// 创建独立的 Git worktree
if (effectiveIsolation === 'worktree') {
const slug = `agent-${earlyAgentId.slice(0, 8)}`;
worktreeInfo = await createAgentWorktree(slug);
}
特点:
- 每个 Agent 获得代码库的独立副本
- 修改不会影响主分支
- 完成后自动清理(如果没有更改)
3. 远程隔离(Remote Isolation)
typescript
// 将 Agent 发送到远程 CCR 环境执行
if (effectiveIsolation === 'remote') {
const session = await teleportToRemote({
initialMessage: prompt,
description,
signal: toolUseContext.abortController.signal,
});
}
智能路由决策
1. Fork Subagent 机制
typescript
// 当启用 Fork Subagent 时,所有 Agent 都转为异步
const forceAsync = isForkSubagentEnabled();
// Fork 路径:子 Agent 继承父会话的完整上下文
if (isForkPath) {
// 使用父会话的系统提示词
forkParentSystemPrompt = toolUseContext.renderedSystemPrompt;
// 构建分叉消息(包含所有工具调用和结果)
promptMessages = buildForkedMessages(prompt, assistantMessage);
}
2. 自动分类器(Transcript Classifier)
typescript
// Agent 交接时的安全检查
const handoffWarning = await classifyHandoffIfNeeded({
agentMessages,
tools,
toolPermissionContext,
subagentType,
totalToolUseCount,
});
分类结果:
allowed- 允许交接blocked- 阻止交接并显示安全警告unavailable- 分类器不可用,显示警告
3. KAIROS 助手模式
在 KAIROS 模式下,所有 Agent 强制异步执行:
typescript
const assistantForceAsync = feature('KAIROS') ? appState.kairosEnabled : false;
原因:避免后台任务阻塞用户输入
4. 协调器模式
typescript
const isCoordinator = feature('COORDINATOR_MODE') ?
isEnvTruthy(process.env.CLAUDE_CODE_COORDINATOR_MODE) : false;
协调器模式下所有 Agent 后台运行,支持多 Agent 并行
执行生命周期
1. 异步 Agent 生命周期
typescript
// 注册后台任务
const agentBackgroundTask = registerAsyncAgent({
agentId: asyncAgentId,
description,
prompt,
selectedAgent,
setAppState: rootSetAppState,
});
// 在 Agent 上下文中运行
void runWithAgentContext(asyncAgentContext, () =>
runAsyncAgentLifecycle({
taskId: agentBackgroundTask.agentId,
abortController: agentBackgroundTask.abortController,
makeStream: (onCacheSafeParams) => runAgent({...}),
metadata,
description,
toolUseContext,
rootSetAppState,
agentIdForCleanup: asyncAgentId,
enableSummarization: isCoordinator || isForkSubagentEnabled(),
getWorktreeResult: cleanupWorktreeIfNeeded
})
);
异步 Agent 特点:
- 独立 AbortController
- 后台运行不阻塞父会话
- 完成后发送通知
- 支持进度汇总
2. 同步 Agent 生命周期
typescript
return runWithAgentContext(syncAgentContext, () =>
wrapWithCwd(async () => {
const agentMessages: MessageType[] = [];
for await (const message of runAgent({...})) {
agentMessages.push(message);
// 实时更新进度
updateAgentProgress(...);
}
// 完成并返回结果
return finalizeAgentTool(agentMessages, syncAgentId, metadata);
})
);
同步 Agent 特点:
- 共享父会话的 AbortController
- 实时流式输出
- 立即返回结果
- 无后台通知
进度跟踪与监控
1. 进度跟踪器
typescript
export type ProgressTracker = {
toolUseCount: number;
latestInputTokens: number;
cumulativeOutputTokens: number;
recentActivities: ToolActivity[];
};
2. 活动记录
typescript
export type ToolActivity = {
toolName: string;
input: Record<string, unknown>;
activityDescription?: string; // 预计算的活动描述
isSearch?: boolean; // 预计算的搜索操作标记
isRead?: boolean; // 预计算的读取操作标记
};
3. 实时进度更新
typescript
// 每收到一条消息就更新进度
updateProgressFromMessage(tracker, message, resolveActivity, tools);
// 向 SDK 发送进度事件
emitTaskProgress({
taskId,
toolUseId,
description: progress.lastActivity?.activityDescription,
startTime,
totalTokens: progress.tokenCount,
toolUses: progress.toolUseCount,
lastToolName
});
总结
Claude Code 的 Agent 路由调度系统具有以下特点:
- 分层决策:从 Agent 选择 → 权限检查 → 异步决策 → 执行路径
- 安全第一:严格的工具过滤、隔离机制和分类器验证
- 灵活配置:支持多种执行模式(同步/异步/远程/工作树)
- 智能路由:Fork Subagent、自动分类器等高级特性
- 全面监控:实时进度跟踪和生命周期管理
这个系统确保了 Agent 能够在安全、高效、可控的环境中执行复杂的任务编排。