27-example-dev-company-walkthrough.md 14.1 KB

27-EXAMPLE · 参考场景走查 — 一家开发型公司从建立到交付一个任务

所属: 27 Graph Agent 架构 的参考场景文档。 版本: v0.1 日期: 2026-08-15 定位: 这份文档不定义任何新机制,它把 27-E2E 端到端任务执行流程 描述的架构跑一遍具体的数。它的用途有三个:

  1. 实现时的靶子——每个阶段的输入输出都写成了具体的 JSON / 图形,可以直接拿来构造测试数据。
  2. 验收场景——P2/P3/P4 全部落地后,跑通这一个场景就等于端到端验证。
  3. 沟通基准——讨论"这里应该怎么设计"时,有一个共同的具体例子可指。

⚠️ 本文档的「配图工厂」是为走查虚构的场景,不是用户提出的原始需求。原始需求原话见 27-REQ。

注意:文中所有数据是设计意图的示例,不是从运行中的系统里导出的真实记录。标 🔴 的地方是当前尚未实现、走查到此会断的环节。


场景设定

用户想做一个「给公众号文章自动生成配图」的小工具,于是建一家公司来做这件事。


阶段 1 · 建公司

用户动作:填两个字段提交。

// POST /api/company/create
{
  "id": "auto-illust",
  "name": "配图工厂",
  "description": "做一个工具:输入公众号文章正文,自动理解段落语义并生成配图,输出图文混排的 HTML。需要能跑在本地,先做 CLI 版本。"
}

系统动作(27-P2 §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 §4.8)
  3. node bin/lemon.js company templates(现实里能招到的角色,listTemplates() 返回 id/name/type/description)

它的判断:description 里有"做一个工具""跑在本地""CLI 版本"→ 匹配 dev.json。

它产出的 org graph——注意这是一张company 级 workflow,不是组织架构图(27-E2E §五定案:Org Graph 是 company 级生成的 workflow,Work Graph 是 org node 级生成的 workflow,两者同构):

// org_graph_nodes + org_graph_edges 的等价视图
{
  "nodes": ["code-planner", "code-coder", "code-validator"],
  "edges": [
    { "from": "code-planner", "to": "code-coder",     "condition": "success", "edge_kind": "forward" },
    { "from": "code-coder",   "to": "code-validator", "condition": "success", "edge_kind": "forward" },
    { "from": "code-validator", "to": "code-coder",     "condition": "fail",    "edge_kind": "backward" }
  ]
}

边是 success / fail 执行流边,与 work graph 的边完全同构——同一套 schema、同一个执行引擎、同一个控制台 UI 在两层复用。

ceo / hr 这类不参与任务执行的角色仍然可以被招聘进公司(存在于 company.json.agents[]),但不出现在 org graph 这张 workflow 里——org graph 只画"任务怎么流过这家公司"。

它提交图 + 执行招聘(两步,27-P2 §4.1 第 6-7 步):

# 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 code-planner
node bin/lemon.js company hire --id auto-illust --role code-coder
node bin/lemon.js company hire --id auto-illust --role code-validator

三个角色在 system/templates/ 里都没有同名模板 → hire() 返回 needs_training → 触发既有的 agent-creator + innovator 培养流水线(company.js:917-940,已实现)。

招完后 orggraph-planning 关掉自己的心跳转入休眠(一次性任务)。后续增量招聘归 HR 管。


阶段 3 · 用户下达一个具体任务

// 🔴 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 §三 阶段 3。


阶段 4 · 任务进入 org graph 开始执行

任务不需要另建一张顶层图——阶段 2 生成的 org graph 本身就是这家公司的 workflow,任务直接在它上面跑:

[code-planner] --success--> [code-coder] --success--> [code-validator]
                                ↑                    │
                                └────fail(backward)──┘

从入度为 0 的节点(code-planner)开始执行。execution_mode 由用户选:manual(每步点"下一步")或 auto(一路跑到底)。假设选 auto。


阶段 5 · code-planner 的 Work Graph(Level 1)

code-planner 这个 org node 被激活,它先调 workgraph-planning agent 规划自己这一层的图。

规划结果——注意三个验收节点是动态选进来的(27-E2E §十一):

brd-planning → prd-planning → sdd-planning ─┬→ task-test-data ───┐
                 └→ task-test-script ─┴→ code-planner-validator → loop-validator

planning agent 的选择理由(这是它要在规划时说清楚的):

验收节点 选/不选 理由
task-test-script ✅ 选 "按 H2 分段""输出 HTML"这些行为可以用代码断言真假
task-test-data ✅ 选 markdown 输入空间复杂,需要正常/边界/异常样本(空文件、没有 H2、H2 嵌套)
task-benchmark ❌ 不选 这一版图像 API 是 mock,没有"配图质量好不好"这种打分维度要评。如果将来接真实图像 API,就要把这个节点加回来

这正是"动态选择加哪几个"的实际含义——不是三个固定都跑。

产出的验收契约(acceptance.json,27-E2E §11.2):

{
  "version": "1",
  "okr_node_id": "O-001.1.1",
  "task_id": "T-xxx",
  "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 的第一个真实用例——它们之间无依赖,可以同时跑,汇合到 code-planner-validator。🔴 这会撞上 CONVENTIONS.md §12「任意 (pid, agent) 同时只允许 1 个 running」和 SessionPool 的 key 复用(见 27-E2E §7.4)。

code-planner-validator 的职责不只是审 SDD,还要审验收标准本身(§7.3):这套 test_data 覆盖了原始需求吗?有没有平凡通过的漏洞?


阶段 6 · code-coder 的 Work Graph(Level 1)+ 并行子图(Level 2)

code-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 §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 · code-validator org node + 三级恢复

code-validator 激活,消费阶段 5 产出的 acceptance.json:

验收项 执行方式 状态
test_script 引擎起进程跑 vitest,读结果 🔴 执行器待建(可搬 DevLoop Integrator)
test_data 喂样本比对实际输出 🔴 同上
benchmark 本次为 null,跳过 —

假设 no-h2 这个 case 一直过不了,而且已经在 L1 打回 code-coder 重写 3 次、L2 重新 planning 1 次,仍然失败。

此时进入你描述的第三级 —— L4 · 迭代 system agent(27-E2E §八):

  1. 判定这是能力缺陷而非粗心错误(qa-judge 的三分类:粗心错误 / 设计缺陷 / 能力缺陷 → RETRAIN_REQUIRED + capability_gaps[]。🔴 协议已定义在 qa-judge/agent.md:223-333,但没有程序化调用入口)
  2. 触发 L4-company(27-E2E §八):只迭代 code-coder 在 auto-illust 这家公司的记忆分区(companies/auto-illust/),自动进行、无需人工确认——因为爆炸半径就限制在这一家公司内,改坏了也波及不到别人。
  3. 回到 L1 重跑 → 再到 code-validator 验证

注意这里不会碰 coder 的 general 本体。如果这次失败暴露的是 code-coder 通用能力上的短板(不只是本公司场景特有的),那属于 L4-general:它不在任务循环里发生,而是等当日的 agent dream 流程——由 master agent 或人工触发,汇总当天所有公司的成功/失败经验,统一蒸馏一次 general 本体,走 git 版本化以便回滚。这个拆分保证了"为修一个任务而改坏十家公司共用 agent"这件事在架构上不可能发生。

⚠️ 这里就是 §7.1 说的熔断失效风险:L4 迭代完之后如果 L1/L2 的计数器重置,"迭代 agent → 重跑 → 再迭代"可以永远循环。所以必须有一个跨层级共享、只增不减的任务级总预算:

{ "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
code-planner:workgraph-planning 1 + brd/prd/sdd-planning 3 + 验收 2 + code-planner-validator 1 + loop-validator 1 8
code-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
code-validator + L4 一次迭代 ~6
合计 ~44 次

粗估 $8-15、墙钟 40-90 分钟(并行后)。这个量级下,"自动模式一键跑到底"必须在启动前把预估成本告诉用户。


走查暴露的 🔴 断点清单

按阻塞程度排序,这也是实现顺序的依据:

# 断点 出现阶段 对应设计
1 qa-judge 没有程序化调用入口(判决无法驱动任何自动动作) 5, 6, 7 27-E2E §11.3
2 code-validator 节点的验收执行能力(跑 test_script / 喂 test_data)未实现 5, 7 §11.3
3 「用户 → 公司」任务入口不存在 3 §三 阶段 3
4 P2 的 org graph 边模型需从 reports_to 改为 success/fail 执行流边 2, 4 §五定案 + 27-P2 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 §4.9

第 4 项是架构前提,必须先改;改完之后做 1-3 项,这个场景就能在"串行、无 L4"的模式下端到端跑通一遍。