# 20. Agent 创建流程:Scaffold-First 架构 > **核心原则:先建骨架,再填内容。** > Agent 目录必须先通过 AgentScaffold 父类创建,后续的 Hunt/Digest 才能往里面写文件。 --- ## 20.1 Create 流程(五阶段严格串行) 当 Innovator 需要创建一个全新的 Agent 时,严格按照以下五个阶段串行执行: ``` Scaffold → Hunt → Digest → Evolve → Execute │ │ │ │ │ ▼ ▼ ▼ ▼ ▼ 创建骨架 调研写入 消化提炼 验证测试 执行任务 ``` ### 阶段 1: Scaffold(脚手架创建骨架) **由引擎硬编码执行,不依赖 LLM。** 当 Innovator 输出 `[CALL: meta_creator]` 时,`agent-chat.js` 中的 `executeMetaCreator()` 函数直接调用 `AgentScaffold.create()`,在 `data/agents/{agent_name}/` 下生成完整的标准目录结构: ``` data/agents/{agent_name}/ ├── agent.md ← 身份定义 ├── soul.md ← 灵魂人格 ├── identity.md ← 标识信息 ├── user.md ← 用户关系 ├── tools.md ← 工具权限 ├── heartbeat.md ← 心跳任务 ├── config.json ← 配置(含 cli.toolPolicy) ├── .claude/skills/ │ └── main_skill/ │ └── SKILL.md ← 核心技能(初始为空壳) ├── memory/ │ ├── short-term/ │ ├── long-term/ │ ├── sessions/ │ └── daily/ ├── knowledge/ ← Digest 阶段写入 knowhow/benchmark ├── workspace/ ← Hunt 阶段写入调研数据 │ ├── code/ │ ├── data/ │ └── assets/ └── logs/ ``` ### 阶段 2: Hunt(知识狩猎) **执行型子 Agent,有完整工具权限。** meta_hunt 在新建 Agent 的目录下运行,将调研结果写入该 Agent 的 `workspace/` 目录: ``` data/agents/{agent_name}/workspace/ ├── knowhow.md ← 方法论调研 ├── toplist.md ← 标杆案例 ├── agent_profile.md ← Agent 人格画像(思维、风格、工具、心跳、用户关系) └── crawl/ ← 爬取数据 ├── source_01.md └── source_02.md ``` ### 阶段 3: Digest(知识消化) **执行型子 Agent,读取 workspace/ 的调研数据,提炼输出到 knowledge/ 和 SKILL.md,并基于 agent_profile 生成定制化 Bootstrap 文件。** ``` 输入: workspace/knowhow.md + workspace/toplist.md + workspace/agent_profile.md + workspace/crawl/ 输出: ├── knowledge/knowhow.md ← 精炼后的方法论 ├── knowledge/benchmark.md ← 评分标准(≥5个维度) ├── .claude/skills/main_skill/SKILL.md ← 基于方法论生成的核心技能 ├── agent.md ← 身份定义、职责、规则(基于 agent_profile) ├── soul.md ← 思维方式、沟通风格、价值观 ├── tools.md ← 工具权限和文件操作范围 ├── heartbeat.md ← 自检频率和质量监控规则 └── user.md ← 与用户/上级的关系定义 ``` ### 阶段 4: Evolve(验证进化) 用测试用例验证新 Agent 的输出质量,对照 `knowledge/benchmark.md` 评分。 ### 阶段 5: Execute(执行用户任务) Agent 已创建并验证通过,直接调用执行用户最初的需求。 --- ## 20.2 meta_creator 引擎级拦截 ### 为什么不让 Claude 子进程执行 meta_creator? | 方案 | 可靠性 | 问题 | |------|--------|------| | Claude 拼 curl 命令调 scaffold API | ⚠️ 低 | LLM 可能拼错 JSON、遗漏字段、URL 写错 | | Claude 用 Write 工具手动建目录 | ❌ 极低 | 会漏掉标准子目录、忘记写 config.json | | **引擎硬编码执行 AgentScaffold** | ✅ 100% | 代码确定性执行,不依赖 LLM | ### 实现位置 `server/routes/agent-chat.js` 中的子 Agent 调度循环: ```javascript // ═══ 硬编码拦截: meta_creator → 直接调用 AgentScaffold 父类 ═══ if (call.agent === 'meta_creator') { res = await executeMetaCreator(call.task, agentId, convId, sendSSE, callId); } else { res = await agentManager.callAgent(call.agent, call.task, { ... }); } ``` ### executeMetaCreator 执行逻辑 1. **解析参数** — 从 Innovator 的任务文本提取 agent_name、display_name、domain 2. **调用 AgentScaffold.create()** — 生成完整目录结构 + bootstrap 文件 3. **写入初始 SKILL.md** — 基于任务描述生成空壳 SKILL.md(后续由 Digest 填充) 4. **返回结构化结果** — 包含创建的目录列表,供 Innovator Reflect 验证 --- ## 20.3 子 Agent 工作目录 ### 问题 所有子 Agent 的 Claude CLI 进程之前都运行在项目根目录 `lemonboss/`,导致: - Claude CLI 读不到 `.claude/skills/` 下的 l1/l2 知识文件 - Hunt 的输出写到错误的位置 ### 解决方案 `agent-manager.js` 的动态 Agent 发现逻辑现在会计算正确的工作目录: ```javascript // 独立 Agent → 运行在 Agent 自己的目录下 agentConfig.workDir = agentDir; // data/agents/{agentName}/ // Scoped Skill → 运行在所属 Agent 的目录下 const ownerAgentDir = path.dirname(path.dirname(path.dirname(foundPath))); agentConfig.workDir = ownerAgentDir; // data/agents/innovator-001/ ``` `_runViaProtocol()` 优先使用 agent-specific workDir: ```javascript const effectiveWorkDir = agent.workDir || this.workDir; ``` ### 效果 - meta_hunt 运行在 `data/agents/innovator-001/`,自动读取全部 18 个 SKILL.md 作为知识上下文 - 新创建的 Agent 运行时能读取自己目录下的 `.claude/skills/` ### 路径约定(⚠️ 关键) 由于 meta_hunt/meta_digest 等子 Agent 运行在 `data/agents/innovator-001/` 目录下, 所有指向其它 Agent 的路径都必须使用 **`../{agent_name}/`** 格式(上一级的兄弟目录): ``` 正确: ../{agent_name}/workspace/knowhow.md 错误: data/agents/{agent_name}/workspace/knowhow.md ← 会变成嵌套路径! 错误: workspace/knowhow.md ← 会写到 innovator-001 自己的目录 ``` 目录结构关系: ``` data/agents/ ├── innovator-001/ ← 子 Agent CLI 的 CWD │ ├── .claude/skills/ ← l1/l2 知识文件 │ └── workspace/ ← innovator 自己的工作区 ├── poetry_writer/ ← ../ poetry_writer/ 可以访问到 │ ├── workspace/ ← Hunt 写入这里 │ ├── knowledge/ ← Digest 写入这里 │ └── .claude/skills/ ← Digest 生成 SKILL.md 到这里 └── other_agent/ ``` --- ## 20.4 l1/l2 Skill 角色定位 ### 当前架构(执行型,v1) l1/l2 SKILL.md 文件作为**知识手册**,被 Claude CLI 进程自动读取。 meta_hunt 等执行型 Agent 参考这些知识,**直接使用原生工具**(Bash、Read、Write)执行任务。 ``` meta_hunt (执行型, 有工具权限) ├── 参考 l2-web-research/SKILL.md → 了解搜索方法 ├── 参考 l1-web-fetch/SKILL.md → 了解爬取方法 └── 直接用 Bash curl 执行搜索和爬取 ``` ### 未来架构(递归编排型,v2) 每个 l1/l2 作为独立子 Agent 通过 `[CALL:]` 调度: ``` meta_hunt (编排型, 无工具) ├── [CALL: l2-web-research] → 独立 CLI 进程 │ ├── [CALL: l1-search-engine] → 独立 CLI 进程 │ └── [CALL: l1-web-fetch] → 独立 CLI 进程 └── [CALL: l1-text-transform] → 独立 CLI 进程 ``` v2 需要 `agentManager.callAgent()` 支持递归 `[CALL:]` 解析,并加入 `maxDepth` 防止死循环。 --- ## 20.5 数据流向图 ``` 用户: "帮我创建一个写诗的 Agent" │ ▼ Innovator (--tools "", 纯文本编排) │ ├── [CALL: meta_creator] ──▶ 引擎硬编码 ──▶ AgentScaffold.create() │ 创建 data/agents/poetry_writer/ (模板 Bootstrap) │ ├── [CALL: meta_hunt] ──▶ Claude CLI (cwd: innovator-001/) │ 读取 .claude/skills/l1-*/l2-* 知识 │ 用 Bash/curl 搜索调研 │ 写入 data/agents/poetry_writer/workspace/ │ └── knowhow.md + toplist.md + agent_profile.md │ ├── [CALL: meta_digest] ──▶ Claude CLI (cwd: innovator-001/) │ 读取 workspace/ (knowhow + toplist + agent_profile) │ 提炼写入 knowledge/knowhow.md + benchmark.md │ 生成 .claude/skills/main_skill/SKILL.md │ 生成 Bootstrap: agent.md, soul.md, tools.md, │ heartbeat.md, user.md │ ├── [CALL: meta_evolving] ──▶ Claude CLI (cwd: poetry_writer/) │ 运行测试用例 │ 对照 benchmark 评分 │ └── [CALL: poetry_writer] ──▶ Claude CLI (cwd: poetry_writer/) 执行用户的原始需求 ```