# 27-EXAMPLE · 参考场景走查 — 一家开发型公司从建立到交付一个任务 > **所属**: [27 Graph Agent 架构](./27-graph-agent-architecture.md) 的**参考场景文档**。 > **版本**: v0.1 > **日期**: 2026-08-15 > **定位**: 这份文档不定义任何新机制,它把 [27-E2E 端到端任务执行流程](./27-e2e-task-execution-flow.md) 描述的架构**跑一遍具体的数**。它的用途有三个: > 1. **实现时的靶子**——每个阶段的输入输出都写成了具体的 JSON / 图形,可以直接拿来构造测试数据。 > 2. **验收场景**——P2/P3/P4 全部落地后,跑通这一个场景就等于端到端验证。 > 3. **沟通基准**——讨论"这里应该怎么设计"时,有一个共同的具体例子可指。 > > ⚠️ **本文档的「配图工厂」是为走查虚构的场景,不是用户提出的原始需求**。原始需求原话见 [27-REQ](./27-requirement.md)。 > > **注意**:文中所有数据是**设计意图的示例**,不是从运行中的系统里导出的真实记录。标 🔴 的地方是当前尚未实现、走查到此会断的环节。 --- ## 场景设定 用户想做一个「给公众号文章自动生成配图」的小工具,于是建一家公司来做这件事。 --- ## 阶段 1 · 建公司 **用户动作**:填两个字段提交。 ```jsonc // POST /api/company/create { "id": "auto-illust", "name": "配图工厂", "description": "做一个工具:输入公众号文章正文,自动理解段落语义并生成配图,输出图文混排的 HTML。需要能跑在本地,先做 CLI 版本。" } ``` **系统动作**([27-P2](../../done/system-design/27-p2-org-graph.md) §4.10): 1. `companyService.create()` 建目录 + `company.json`(`agents: []`) 2. 🔴 自动 `hire(id, 'orggraph-planning', {})` 3. 🔴 fire-and-forget 触发它的首轮对话,把 `description` 带进去 此刻 `company.json.agents = ["orggraph-planning"]`,其余为空。API 立刻返回,组织结构在后台异步生成。 --- ## 阶段 2 · orggraph-planning 生成 org graph **它读三样东西**: 1. 公司 description(上面那段) 2. `system/org-graph-templates/*.json`(候选骨架,[27-P2](../../done/system-design/27-p2-org-graph.md) §4.8) 3. `node bin/lemon.js company templates`(现实里能招到的角色,`listTemplates()` 返回 id/name/type/description) **它的判断**:description 里有"做一个工具""跑在本地""CLI 版本"→ 匹配 `dev.json`。 **它产出的 org graph**——注意这是一张**company 级 workflow**,不是组织架构图([27-E2E](./27-e2e-task-execution-flow.md) §五定案:Org Graph 是 company 级生成的 workflow,Work Graph 是 org node 级生成的 workflow,两者同构): ```jsonc // org_graph_nodes + org_graph_edges 的等价视图 { "nodes": ["org-planner", "org-coder", "org-validator"], "edges": [ { "from": "org-planner", "to": "org-coder", "condition": "success", "edge_kind": "forward" }, { "from": "org-coder", "to": "org-validator", "condition": "success", "edge_kind": "forward" }, { "from": "org-validator", "to": "org-coder", "condition": "fail", "edge_kind": "backward" } ] } ``` 边是 `success` / `fail` 执行流边,与 work graph 的边完全同构——**同一套 schema、同一个执行引擎、同一个控制台 UI 在两层复用**。 > 上面是 **P2 形态**(fail 只有一条兜底边)。P3 给边加了可空的 `fail_reason` > ([27-P3/P4](./27-p3-p4-work-graph-console.md) §四.D.2.2),`system/org-graph-templates/dev.json` 的骨架因此 > 多一条 `org-validator --fail[input_underspecified]--> org-planner`:归因判定是"规划给的约束不够"时退回重新规划, > 其余一切情况仍走这里画的这条无 `fail_reason` 的兜底边退回 `org-coder`。本文后续流程只用到兜底边,不受影响。 `ceo` / `hr` 这类不参与任务执行的角色仍然可以被招聘进公司(存在于 `company.json.agents[]`),但**不出现在 org graph 这张 workflow 里**——org graph 只画"任务怎么流过这家公司"。 **它提交图 + 执行招聘**(两步,[27-P2](../../done/system-design/27-p2-org-graph.md) §4.1 第 6-7 步): ```bash # 1. 整体提交图定义,过四项校验(无环 / 单一入口 / 可达性 / 回退边标注)后事务性落库 curl -X POST http://localhost:3010/api/company/auto-illust/org-graph -d @/tmp/orggraph.json # 2. 按拓扑序逐个招聘(注意:P2 v0.4 起 hire 不再需要 --reportsTo, # 图的结构已在第 1 步整体写入,招聘只负责建 agent 目录) node bin/lemon.js company hire --id auto-illust --role org-planner node bin/lemon.js company hire --id auto-illust --role org-coder node bin/lemon.js company hire --id auto-illust --role org-validator ``` 三个角色在 `system/templates/` 里都没有同名模板 → `hire()` 返回 `needs_training` → 触发既有的 agent-creator + innovator 培养流水线(`company.js:917-940`,已实现)。 招完后 orggraph-planning 关掉自己的心跳转入休眠(一次性任务)。后续增量招聘归 HR 管。 --- ## 阶段 3 · 用户下达一个具体任务 ```jsonc // 🔴 POST /api/company/auto-illust/tasks ← 这个端点目前不存在 { "task": "先做第一个版本:读一个 markdown 文件,按 H2 分段,每段调用图像生成 API 产出一张配图,最后输出内嵌 base64 图片的 HTML。图像 API 先用 mock,接口留出来。" } ``` 🔴 **缺口**:现有的 `POST /api/agent/task/dispatch`(`agent-chat.js:1470`)只支持 **agent → agent**(`from`/`to` 都必须是已存在的 agent 目录),没有"用户 → 公司"的入口。见 [27-E2E](./27-e2e-task-execution-flow.md) §三 阶段 3。 --- ## 阶段 4 · 任务进入 org graph 开始执行 任务不需要另建一张顶层图——**阶段 2 生成的 org graph 本身就是这家公司的 workflow**,任务直接在它上面跑: ``` [org-planner] --success--> [org-coder] --success--> [org-validator] ↑ │ └────fail(backward)──┘ ``` 从入度为 0 的节点(`org-planner`)开始执行。`execution_mode` 由用户选:`manual`(每步点"下一步")或 `auto`(一路跑到底)。假设选 `auto`。 --- ## 阶段 5 · org-planner 的 Work Graph(Level 1) `org-planner` 这个 org node 被激活,它先调 **workgraph-planning agent** 规划自己这一层的图。 **规划结果**——注意三个验收节点是**动态选进来的**([27-E2E](./27-e2e-task-execution-flow.md) §十一): ``` brd-planning → prd-planning → sdd-planning ─┬→ goal-test-data ───┐ └→ goal-test-script ─┴→ planner-validator → loop-validator ``` **planning agent 的选择理由**(这是它要在规划时说清楚的): | 验收节点 | 选/不选 | 理由 | |---|---|---| | `goal-test-script` | ✅ 选 | "按 H2 分段""输出 HTML"这些行为可以用代码断言真假 | | `goal-test-data` | ✅ 选 | markdown 输入空间复杂,需要正常/边界/异常样本(空文件、没有 H2、H2 嵌套) | | `goal-benchmark` | ❌ 不选 | 这一版图像 API 是 mock,没有"配图质量好不好"这种打分维度要评。**如果将来接真实图像 API,就要把这个节点加回来** | 这正是"动态选择加哪几个"的实际含义——不是三个固定都跑。 **产出的验收契约**(`acceptance.json`,[27-E2E](./27-e2e-task-execution-flow.md) §11.2): ```jsonc { "version": "1", "goal_id": "GOAL-xxx", // 这份验收标准属于哪个 goal(一次人类需求) "benchmark": null, // 本次没选这个节点 "test_data": { "cases": [ { "id": "normal", "input": {"md": "# T\n## A\n正文\n## B\n正文"}, "expect": {"sections": 2} }, { "id": "no-h2", "input": {"md": "# T\n只有正文"}, "expect": {"sections": 0} }, { "id": "empty", "input": {"md": ""}, "expect": {"error": "empty_input"} } ] }, "test_script": { "runner": "vitest", "path": "tests/acceptance.spec.js" } } ``` **两个并行验收节点是 fan-out 的第一个真实用例**——它们之间无依赖,可以同时跑,汇合到 `planner-validator`。🔴 这会撞上 `CONVENTIONS.md` §12「任意 (pid, agent) 同时只允许 1 个 running」和 SessionPool 的 key 复用(见 [27-E2E](./27-e2e-task-execution-flow.md) §7.4)。 `planner-validator` 的职责不只是审 SDD,还要审**验收标准本身**(§7.3):这套 test_data 覆盖了原始需求吗?有没有平凡通过的漏洞? --- ## 阶段 6 · org-coder 的 Work Graph(Level 1)+ 并行子图(Level 2) `org-coder` org node 激活,同样先调 planning agent。它读到上一阶段的 SDD,把工作拆成三个可并行的 unit: ``` ┌→ [md-parser] → [unittest] ─┐ [start] ┼→ [img-client] → [unittest] ─┼→ [integrate] → [integration-test] → [loop-validator] └→ [html-render]→ [unittest] ─┘ ``` - **fan-out**:三个 unit 无依赖,并行(DevLoop 的 `_groupUnitsByWave()` Kahn 分波已实现,🔴 但波内目前是串行的,`loop-controller.js:609` 注释 `// 串行跑`) - **fan-in**:`integrate` 节点等三条支线全绿才能进入 `ready`(多入边 = 汇合点,全部满足才推进,[27-P3/P4](./27-p3-p4-work-graph-console.md) §D.1) - 每个 `unittest` 失败 → 打回对应的 unit 重写 = **L1 循环**,`retry_budget=5` **假设 `integration-test` 失败了**:`html-render` 拿到的分段结构和 `md-parser` 产出的不一致。 这时 `loop-validator` 要判断"重新 planning 还是跳回某个节点"——这正是 DevLoop **BugTriager 四分类**已经解决的问题(`sdd-process.md` P-2): | 归因 | 本例是否命中 | 动作 | 烧不烧预算 | |---|---|---|---| | `contract_mismatch` | ✅ 命中 | 两个 unit 对"分段结构"的契约理解不一致 → 改 SDD 统一契约 → reset 两个 unit | ✅ 烧 `l2_budget` | | `impl_bug` | ❌ | — | 不烧 | | `spec_ambiguous` | ❌ | — | 升 L3 找人 | | `infra_flake` | ❌ | — | 不烧 | → 改 SDD → reset `md-parser` + `html-render` → 回到 L1 重跑这两条支线 → 再次 `integrate` → 再次 `integration-test`。 `l2_budget` 默认 3 轮,超出发 `project.l2_exhausted` 挂起等人。 --- ## 阶段 7 · org-validator org node + 三级恢复 `org-validator` 激活,消费阶段 5 产出的 `acceptance.json`: | 验收项 | 执行方式 | 状态 | |---|---|---| | `test_script` | 引擎起进程跑 vitest,读结果 | 🔴 执行器待建(可搬 DevLoop Integrator) | | `test_data` | 喂样本比对实际输出 | 🔴 同上 | | `benchmark` | 本次为 null,跳过 | — | **假设 `no-h2` 这个 case 一直过不了**,而且已经在 L1 打回 org-coder 重写 3 次、L2 重新 planning 1 次,仍然失败。 此时进入你描述的第三级 —— **L4 · 迭代 system agent**([27-E2E](./27-e2e-task-execution-flow.md) §八): 1. 判定这是**能力缺陷**而非粗心错误(`qa-judge` 的三分类:粗心错误 / 设计缺陷 / **能力缺陷** → `RETRAIN_REQUIRED` + `capability_gaps[]`。🔴 协议已定义在 `qa-judge/agent.md:223-333`,但没有程序化调用入口) 2. 触发 **L4-company**([27-E2E](./27-e2e-task-execution-flow.md) §八):**只迭代 `org-coder` 在 auto-illust 这家公司的记忆分区**(`companies/auto-illust/`),自动进行、无需人工确认——因为爆炸半径就限制在这一家公司内,改坏了也波及不到别人。 3. 回到 L1 重跑 → 再到 org-validator 验证 **注意这里不会碰 `coder` 的 general 本体**。如果这次失败暴露的是 `org-coder` 通用能力上的短板(不只是本公司场景特有的),那属于 **L4-general**:它不在任务循环里发生,而是等当日的 **agent dream 流程**——由 master agent 或人工触发,汇总当天所有公司的成功/失败经验,统一蒸馏一次 general 本体,走 git 版本化以便回滚。这个拆分保证了"为修一个任务而改坏十家公司共用 agent"这件事在架构上不可能发生。 **⚠️ 这里就是 §7.1 说的熔断失效风险**:L4 迭代完之后如果 L1/L2 的计数器重置,"迭代 agent → 重跑 → 再迭代"可以永远循环。所以必须有一个**跨层级共享、只增不减的任务级总预算**: ```jsonc { "total_agent_calls": 100, "total_tokens": 5000000, "wallclock_ms": 7200000, "l4_iterations": 2 } ``` 扣完即挂起等人工,不管哪一层还想重试。 --- ## 这个场景的成本量级 按 `plan-cost-concurrency.md` 的实测口径(DevLoop 中项目 8 unit / 2 PRD rev / 2 轮 L2 ≈ 39 次调用 / 410K token / $4.8 / 墙钟 20 分钟)外推本场景: | 阶段 | agent 调用次数(估) | |---|---| | orggraph-planning + 招 5 个角色(其中 2 个走培养流水线) | ~8 | | Level 0 任务图规划 | 1 | | org-planner:workgraph-planning 1 + brd/prd/sdd-planning 3 + 验收 2 + planner-validator 1 + loop-validator 1 | 8 | | org-coder:workgraph-planning 1 + 3 unit ×(code+test) 6 + 1.5 次重试 ~4 + integrate 1 + int-test 1 + judge 1 | ~14 | | L2 一轮修复(triage + 改 SDD + reset 后重跑 2 unit) | ~7 | | org-validator + L4 一次迭代 | ~6 | | **合计** | **~44 次** | 粗估 **$8-15、墙钟 40-90 分钟**(并行后)。这个量级下,"自动模式一键跑到底"必须在启动前把预估成本告诉用户。 --- ## 走查暴露的 🔴 断点清单 按阻塞程度排序,这也是实现顺序的依据: | # | 断点 | 出现阶段 | 对应设计 | |---|---|---|---| | 1 | `qa-judge` 没有程序化调用入口(判决无法驱动任何自动动作) | 5, 6, 7 | [27-E2E](./27-e2e-task-execution-flow.md) §11.3 | | 2 | org-validator 节点的验收执行能力(跑 test_script / 喂 test_data)未实现 | 5, 7 | §11.3 | | 3 | 「用户 → 公司」任务入口不存在 | 3 | §三 阶段 3 | | 4 | **P2 的 org graph 边模型需从 `reports_to` 改为 `success`/`fail` 执行流边** | 2, 4 | §五定案 + [27-P2](../../done/system-design/27-p2-org-graph.md) v0.4 修正 | | 5 | fan-out 并行撞 CONVENTIONS §12 不变量 + SessionPool key 复用 | 5, 6 | §7.4 | | 6 | 任务级总预算不存在 | 7 | §7.1 | | 7 | L4-general 的 agent dream 流程不存在(跨公司批量蒸馏层缺失,单点接口已齐) | 7 之后(离线) | §8.1 | | 8 | orggraph-planning / workgraph-planning agent 均未实现 | 2, 5, 6 | [27-P2](../../done/system-design/27-p2-org-graph.md) §4.9 | 第 4 项是**架构前提**,必须先改;改完之后做 1-3 项,这个场景就能在"串行、无 L4"的模式下端到端跑通一遍。