能力映射总表
| 能力 | 新组件 | 对应现有模块 | 改动 |
|---|---|---|---|
| Agent 启动与会话复用 | — | packages/acp-core/protocol/ClaudeCliProtocol.js + server/src/core/session-pool.js | REUSE |
| 多 Agent 调用 facade | — | server/src/core/agent-manager.js · master-session.js | REUSE |
| 任务 → 步骤拆分 | — | server/src/tools/orchestrate-tool.js | REUSE |
| DAG 依赖解析 | — | server/src/core/scheduler.js (getExecutionGroups) | REUSE |
| Pipeline 描述结构 | — | server/services/pipeline-service.js | REUSE · units.json 复用 step 结构 |
| 重试 + 反思 | retryWithReflection() 写在 loop-controller.js 内 | 参考 server/services/evolution-loop.js (PRAE) 思路,但不抽公共 | NEW · P5 再考虑合并 |
| ACP / Claude CLI 协议层 | — | packages/acp-core/ | REUSE |
| Agent 模板注册 | 6 个新模板 | system/templates/_registry.json | NEW |
| 三层 Loop 编排 | LoopController | server/src/core/loop-controller.js | NEW |
| PRD/SDD 文档存储 | DocStore | server/services/doc-store.js | NEW |
| Unit 状态机 | UnitRegistry | server/services/unit-registry.js | NEW |
| HTTP / SSE 入口 | /api/devloop/* | server/routes/devloop.js → 挂在 server/index.js | NEW |
| Web 看板 | DevLoopDashboard.vue | 放在 web/src/views/,复用 PipelineEditor DAG 渲染 | NEW |
| 结果持久化根 | — | data/companies/{cid}/projects/{pid}/ | REUSE · 沿用 company-scoped 文件根 |
| 进程沙箱 / 端口管理 | — | server/src/engine/process-guard.js | REUSE |
| WS 流式 | — | server/routes/claude-chat-ws.js | REUSE · DevLoop SSE 走 HTTP 复用同套帧 |
分层视图
三色块代表三种改动类型;越靠下越基础,越靠上越业务。
红 新增 · 灰 复用 · 黄 补丁 · 黑 底层依赖
为什么 P1~P4 不抽公共 retry 函数
EvolutionLoop 当前实现 PRAE (Perceive → Reason & Plan → Execute → Evaluate → Reflect),里面有「失败 → 反思 → 重试」逻辑。直觉上 L1 可以共用,但初版决定不抽:
- 避免回归风险:EvolutionLoop 跑的是 Skill 进化,目前在生产里运行。动它意味着要把 Skill 进化的回归一起做。
- 反思 prompt 差异大:Skill 进化的反思是「Skill 评分低,怎么改 prompt」;L1 的反思是「单测失败,代码哪里错」。共用会让 prompt 模板变成「上帝模板」,反而难维护。
- 80 行不算多:P2 在 loop-controller.js 内重写一份 retryWithReflection 也就 80 行,DRY 不必这么早追。
// P2 直接在 server/src/core/loop-controller.js 写一份新的 async function retryWithReflection(unit, budget) { let failures = []; for (let i = 0; i < budget; i++) { await agentManager.callAgent('coder', { spec: unit.spec, history: failures }); const r = await agentManager.callAgent('tester', { unit }); if (r.ok) return { ok: true, retries: i }; failures.push(r.failures); } return { ok: false, reason: "budget_exceeded" }; } // P5 视实测情况再决定是否与 evolution-loop 合并到 packages/ 公共目录
这条改动同步影响 plan-migration.html 的 P2 阶段:retry 函数从「抽公共」改为「直接新写」。
不动的边界
本次改造绝不触碰:
- ACP 协议本身(
packages/acp-core/) - Master / Orchestrator 已有行为(仅注册新的 6 个 Agent 模板)
- WebSocket 路由(
/ws/claude) - SkillsMarket / Arena 路径下任何文件
- 认证 / 用户系统(
routes/auth.js,routes/users.js)