# 7. Agent 间通讯架构 > Agent 子进程之间完全隔离,不直接通讯。所有消息都经主进程路由,所有数据都通过 SQLite 共享。 --- ## 7.1 核心原则:框架是"神经系统" 每个 Agent 是一个独立的 ACP(Claude Code)子进程。它们之间 **不直接通讯**。 ``` ❌ 不是这样:Agent 之间直连 ┌──────┐ ┌──────┐ │Agent A│←──→│Agent B│ └──────┘ └──────┘ ✅ 而是这样:所有消息经主进程中转 ┌──────┐ ┌────────────┐ ┌──────┐ │Agent A│←──→│ 主进程路由 │←──→│Agent B│ └──────┘ │ (框架层) │ └──────┘ └────────────┘ ``` **类比**:部门之间不是互相打电话,而是通过公司的 OA 系统发任务、汇报、审批。 --- ## 7.2 消息类型 | 消息方法 | 方向 | 场景 | 版本 | |---------|------|------|------| | `task.assign` | 上级 → 下级 | 分派任务 | v1.0 | | `task.report` | 下级 → 上级 | 汇报结果/进度 | v1.0 | | `task.handover` | 同级 → 同级 | Pipeline 节点流转 | v1.1 | | `task.feedback` | 同级 → 同级 | 经验/数据反馈回流 | v1.1 | | `cxo.review` | CXO ↔ CXO | 方案审核请求 | v1.2 | | `cxo.approve` | CXO → CXO | 审核通过 | v1.2 | | `cxo.reject` | CXO → CXO | 审核驳回 | v1.2 | | `status.update` | 广播 | 状态变更通知 | v1.0 | | `status.heartbeat` | 下级 → 上级 | 心跳状态上报 | v1.2 | | `data.share` | 任意 | 共享数据/资源 | v1.2 | | `data.request` | 任意 | 请求数据/资源 | v1.2 | --- ## 7.3 消息流转的完整流程 ### 场景:Master 与用户聊完 → 下达指令给 CEO **Step 1: 用户跟 Master 聊天** ``` 用户: "我想做一个 AI 互动短剧平台,主打年轻女性市场" │ ▼ (WebSocket / HTTP) 框架服务器 │ ▼ (stdin pipe) Master ACP 进程 │ │ 根据 agent.md + soul.md 思考: │ → "用户意图: 做一个面向年轻女性的 AI 短剧平台" │ → "需要将意图结构化为 Goal,交给 CEO 去战略拆解" ``` **Step 2: Master 调用工具下达指令** ``` Master ACP 输出 (stdout): { "jsonrpc": "2.0", "method": "tool.call", "params": { "name": "task.assign", "args": { "to": "cxo-ceo-001", "task": { "description": "设计 AI 互动短剧平台的完整业务体系", "goal": { "target": "Q1 日活 10 万", "audience": "18-28 岁年轻女性", "product": "AI 互动短剧,支持用户二改" }, "priority": "high" } } } } ``` **Step 3: 框架拦截 → 路由 → 触发 CEO** ``` 框架主进程收到 Master 的工具调用: 1. 生成消息 ID,写入 SQLite messages 表 2. 查找 cxo-ceo-001 的 ACP 子进程 ├── 如果 CEO 正在运行 → 向 CEO 的 stdin 注入消息 └── 如果 CEO 处于 idle → 启动 CEO 的 ACP 子进程,注入消息 3. 给 Master 返回: "已发送,任务 ID: task-xxx" ``` **Step 4: CEO 收到指令,开始工作** ``` CEO ACP 进程的 stdin 收到: "[来自 Master 的任务] 设计 AI 互动短剧平台的完整业务体系 目标: Q1 日活 10 万 受众: 18-28 岁年轻女性 产品: AI 互动短剧,支持用户二改" CEO 根据 agent.md 和 soul.md 推理: → "需要 5 个 Role: 编剧、制作、运营、推广、数据" → "Pipeline: 选题→剧本→制作→上架→推广→反馈" CEO 调用工具 (stdout → 框架拦截): tool_call: role.create({ name: "编剧部", type: "role", ... }) tool_call: role.create({ name: "推广部", type: "role", ... }) tool_call: pipeline.set({ edges: [...] }) 框架拦截每个工具调用: → AgentScaffold 创建目录 → AgentRegistry 注册到数据库 → 启动 ACP 子进程 ``` **Step 5: CEO 不等编剧部完成,继续做其他事** ``` CEO 发完 role.create 后继续: → 给推广部分派任务 → 给数据部分派任务 → 开始自己的 5 分钟心跳循环 编剧部做完后: → 编剧部 ACP → (stdout) → 框架 → (stdin) → CEO ACP → CEO 收到汇报,评估结果,继续下一步 全程异步。 ``` --- ## 7.4 三种数据共享方式 | 方式 | 适用场景 | 机制 | |------|---------|------| | **消息传递** | 任务指令、结果汇报、状态更新 | 主进程路由,payload 携带 JSON | | **SQLite 查询** | 查看全局状态、组织架构、历史任务 | Agent 调用工具(如 `org.status`),主进程查 SQLite 返回 | | **文件路径引用** | 剧本、视频、数据报表等大文件 | 消息里传路径,目标 Agent 读取文件 | ### 消息传递(轻量数据) ```json { "method": "task.report", "params": { "from": "role-data-001", "to": "cxo-ceo-001", "payload": { "metrics": { "dau": 23000, "retention": 0.42, "conversion": 0.18 }, "insight": "古装题材在 18-25 岁女性中转化率最高 (23%)" } } } ``` ### SQLite 查询(全局状态) ``` CEO 调用: org.status() ↓ 框架主进程查询 SQLite ↓ 返回: { "total_agents": 12, "running": 8, "pipeline": "选题→剧本→制作→上架→推广→反馈", "goal_progress": 0.23, "recent_tasks": [...] } ``` ### 文件路径引用(大文件) ``` 编剧部完成剧本 → 流转到制作部: { "method": "task.handover", "params": { "from": "role-dramatist-001", "to": "role-producer-001", "payload": { "type": "script", "path": "data/agents/role-dramatist-001/workspace/assets/drama-ep01.md", "summary": "都市爱情第1集,含3个互动分支" } } } 制作部的 ACP 进程根据 path 读取文件 → 开始制作 (框架授予制作部对该路径的只读权限) ``` --- ## 7.5 通讯的设计约束 | 约束 | 原因 | |------|------| | 子进程之间不直连 | 隔离性——一个 Agent 崩溃不影响其他 Agent | | 所有通讯经主进程 | 可审计、可持久化、可限流、可切断 | | 大数据传路径不传内容 | 保持消息体轻量,避免主进程成为瓶颈 | | Agent 不感知并发 | 每个 Agent 以为自己是唯一的,框架在背后调度 | > **`task.assign` / `role.create` 这些工具不是 Agent 自己实现的,是框架暴露给 Agent 的。** > Agent 在 agent.md 里写了"可用工具: task.assign",框架在启动 ACP 时注册这些工具。 > 当 Agent 调用时,框架拦截并处理。