1. 核心通信机制
claude code采用了基于文件系统的邮箱系统作为Agent之间的主要通信机制,具有以下特点:
1.1 邮箱系统架构
- 存储结构:每个Agent都有独立的邮箱文件,位于
.claude/teams/{team_name}/inboxes/{agent_name}.json - 消息格式:使用JSON格式存储消息,包含发送者、内容、时间戳等信息
- 并发控制:通过文件锁机制防止多Agent同时写入造成的冲突
- 消息类型:支持多种结构化消息类型,如权限请求、任务分配、关闭请求等
1.2 消息传递流程
- 发送消息:Agent通过
writeToMailbox()方法向目标Agent的邮箱写入消息 - 读取消息:Agent通过
readMailbox()或readUnreadMessages()读取自己邮箱中的消息 - 消息处理:Agent通过轮询机制(如
waitForNextPromptOrShutdown())监听新消息 - 消息标记:读取后的消息会被标记为已读,避免重复处理
2. 设计模式应用
本项目在Agent通信和管理中应用了多种设计模式:
2.1 发布-订阅模式 (Publish-Subscribe)
- 实现方式:通过邮箱系统,Agent可以向特定Agent或团队发送消息
- 核心组件:
teammateMailbox.ts中的writeToMailbox()和readMailbox()方法 - 优势:解耦发送者和接收者,支持异步通信,无需直接引用
2.2 代理模式 (Proxy)
- 实现方式:通过
runWithTeammateContext()和runWithAgentContext()为Agent提供上下文隔离 - 核心组件:
agentContext.ts和teammateContext.ts中的上下文管理 - 优势:确保Agent之间的状态隔离,同时共享必要的系统资源
2.3 观察者模式 (Observer)
- 实现方式:Agent通过轮询机制监听邮箱中的新消息
- 核心组件:
inProcessRunner.ts中的waitForNextPromptOrShutdown()方法 - 优势:实时响应新消息,支持Agent的持续运行和交互
2.4 命令模式 (Command)
- 实现方式:通过结构化消息(如关闭请求、权限请求等)执行特定操作
- 核心组件:
teammateMailbox.ts中的各种消息类型定义和处理函数 - 优势:标准化消息格式,便于扩展和维护
2.5 责任链模式 (Chain of Responsibility)
- 实现方式:消息处理通过不同的处理器进行分发
- 核心组件:
inProcessRunner.ts中的消息处理逻辑 - 优势:分离消息类型和处理逻辑,提高代码可维护性
2.6 工厂模式 (Factory)
- 实现方式:通过
getAgentDefinitionsWithOverrides()加载和创建Agent实例 - 核心组件:
loadAgentsDir.ts中的Agent加载和解析逻辑 - 优势:统一Agent的创建和配置,支持多种来源的Agent定义
3. 关键实现细节
3.1 邮箱系统实现
// 读取邮箱消息
export async function readMailbox(
agentName: string,
teamName?: string,
): Promise<TeammateMessage[]> {
const inboxPath = getInboxPath(agentName, teamName);
try {
const content = await readFile(inboxPath, 'utf-8');
const messages = jsonParse(content) as TeammateMessage[];
return messages;
} catch (error) {
const code = getErrnoCode(error);
if (code === 'ENOENT') {
return [];
}
logError(error);
return [];
}
}
// 写入邮箱消息
export async function writeToMailbox(
recipientName: string,
message: Omit<TeammateMessage, 'read'>,
teamName?: string,
): Promise<void> {
await ensureInboxDir(teamName);
const inboxPath = getInboxPath(recipientName, teamName);
const lockFilePath = `${inboxPath}.lock`;
// 确保邮箱文件存在
try {
await writeFile(inboxPath, '[]', { encoding: 'utf-8', flag: 'wx' });
} catch (error) {
const code = getErrnoCode(error);
if (code !== 'EEXIST') {
logError(error);
return;
}
}
// 使用文件锁防止并发写入
let release: (() => Promise<void>) | undefined;
try {
release = await lockfile.lock(inboxPath, {
lockfilePath: lockFilePath,
...LOCK_OPTIONS,
});
// 读取现有消息
const messages = await readMailbox(recipientName, teamName);
// 添加新消息
const newMessage: TeammateMessage = {
...message,
read: false,
};
messages.push(newMessage);
// 写回邮箱文件
await writeFile(inboxPath, jsonStringify(messages, null, 2), 'utf-8');
} catch (error) {
logError(error);
} finally {
if (release) {
await release();
}
}
}
3.2 Agent运行和通信
// 运行进程内Agent
export async function runInProcessTeammate(
config: InProcessRunnerConfig,
): Promise<InProcessRunnerResult> {
const {
identity,
taskId,
prompt,
agentDefinition,
teammateContext,
toolUseContext,
abortController,
} = config;
// 创建Agent上下文
const agentContext: AgentContext = {
agentId: identity.agentId,
parentSessionId: identity.parentSessionId,
agentName: identity.agentName,
teamName: identity.teamName,
agentColor: identity.color,
planModeRequired: identity.planModeRequired,
isTeamLead: false,
agentType: 'teammate',
invocationKind: 'spawn',
invocationEmitted: false,
};
// 构建系统提示
let teammateSystemPrompt: string;
// ... 系统提示构建逻辑 ...
// 解析Agent定义
const resolvedAgentDefinition: CustomAgentDefinition = {
agentType: identity.agentName,
whenToUse: `In-process teammate: ${identity.agentName}`,
getSystemPrompt: () => teammateSystemPrompt,
tools: agentDefinition?.tools
? [
...new Set([
...agentDefinition.tools,
SEND_MESSAGE_TOOL_NAME,
TEAM_CREATE_TOOL_NAME,
TEAM_DELETE_TOOL_NAME,
TASK_CREATE_TOOL_NAME,
TASK_GET_TOOL_NAME,
TASK_LIST_TOOL_NAME,
TASK_UPDATE_TOOL_NAME,
]),
]
: ['*'],
source: 'projectSettings',
permissionMode: 'default',
...(agentDefinition?.model ? { model: agentDefinition.model } : {}),
};
// 主Agent循环
while (!abortController.signal.aborted && !shouldExit) {
// 处理当前提示
// ... 提示处理逻辑 ...
// 运行Agent
await runWithTeammateContext(teammateContext, async () => {
return runWithAgentContext(agentContext, async () => {
// 标记任务为运行中
updateTaskState(
taskId,
task => ({ ...task, status: 'running', isIdle: false }),
setAppState,
);
// 运行Agent循环
for await (const message of runAgent({
agentDefinition: iterationAgentDefinition,
promptMessages,
toolUseContext,
canUseTool: createInProcessCanUseTool(
identity,
currentWorkAbortController,
(waitMs: number) => {
updateTaskState(
taskId,
task => ({ ...task, permissionWaitMs: (task.permissionWaitMs || 0) + waitMs }),
setAppState,
);
},
),
abortController: currentWorkAbortController,
options: {
...toolUseContext.options,
model,
forkContextMessages,
contentReplacementState: teammateReplacementState,
isTeammate: true,
teammateIdentity: identity,
},
})) {
// 处理Agent消息
// ... 消息处理逻辑 ...
}
});
});
// 发送 idle 通知
await sendIdleNotification(
identity.agentName,
identity.color,
identity.teamName,
{
idleReason: workWasAborted ? 'interrupted' : 'available',
summary: getLastPeerDmSummary(allMessages),
},
);
// 等待下一个提示或关闭请求
const waitResult = await waitForNextPromptOrShutdown(
identity,
abortController,
taskId,
toolUseContext.getAppState,
setAppState,
identity.parentSessionId,
);
// 处理等待结果
// ... 等待结果处理逻辑 ...
}
// 返回结果
return {
success: true,
messages: allMessages,
};
}
4. 优势与特点
- 去中心化通信:基于文件系统的邮箱系统实现了去中心化的通信机制,Agent之间无需直接引用即可通信
- 可靠性:通过文件锁机制确保消息传递的可靠性,避免并发写入冲突
- 可扩展性:支持多种消息类型和处理逻辑,易于扩展新的通信功能
- 上下文隔离:通过AsyncLocalStorage为每个Agent提供独立的上下文,确保状态隔离
- 灵活性:支持进程内和进程间的Agent通信,适应不同的部署场景
5. 应用场景
- 团队协作:多个Agent可以组成团队,共同完成复杂任务
- 任务分配:通过任务分配消息实现Agent之间的工作分配
- 权限管理:通过权限请求/响应机制实现Agent的权限控制
- 状态同步:通过 idle 通知等机制同步Agent的状态
- 资源共享:Agent之间可以共享工具、模型等资源
6. 总结
本项目采用了基于文件系统的邮箱系统作为Agent通信的核心机制,结合多种设计模式实现了灵活、可靠的Agent协作系统。这种设计不仅支持简单的消息传递,还能处理复杂的权限管理、任务分配等场景,为多Agent系统提供了强大的通信基础设施。
通过发布-订阅、代理、观察者等设计模式的应用,本项目实现了Agent之间的解耦和高效协作,同时保持了系统的可扩展性和可维护性。这种设计思路对于构建复杂的多Agent系统具有重要的参考价值。