27-naming-conventions.md 13 KB

27-NAMING · Graph Agent 体系命名规范

所属: 27 Graph Agent 架构 的跨文档命名约定。 版本: v0.2(§六 OKR 正名已落地到代码层,见该节执行结果表) 日期: 2026-08-15 适用范围: 27 系列全部文档 + 后续实现中新建的 system agent id、表名、字段名、API 路径。 为什么需要这份文档: 本体系引入的概念(planner / validator / planning / benchmark)在仓库里全部已经有同名但不同义的既有占用。不先统一,日后 grep 和排查会持续付出代价。


一、总规则

{作用域}-{职能}

任何 agent id、验收产物类型、评测体系名,都必须带作用域前缀,不允许裸用 planner / validator / planning / benchmark。

作用域从大到小:

作用域 含义
orggraph 公司级 workflow
workgraph org node 级 workflow
{domain} 业务领域(code / content / ops …),即 org node 所属领域
company-goal 公司的目标(建公司时写入,OKR 树的输入)
task-goal 一次用户请求的目标(唯一,验收边界;R-12 说的就是这一层)
subagent-goal 子任务的目标(一个 task-goal 分解出多个)
task 图中的执行单元(一个 task-goal 分解出多个,可并行)
agent 单个 system agent
skill 单个 skill

二、规划类 agent —— {产出物}-planning

id 职责 所在层级
orggraph-planning 根据公司目标/描述,生成公司级 workflow(org graph) company,建公司时跑一次
workgraph-planning 根据任务,为某个 org node 生成该节点的 workflow(work graph) org node,每次接到任务时
brd-planning 产出 BRD work graph 内的节点
prd-planning 产出 PRD work graph 内的节点
sdd-planning 产出 SDD work graph 内的节点

⚠️ 重命名:27-P2 v0.2/v0.3 里叫 org-graph-creator 的 agent,统一改名为 orggraph-planning。v0.4 起全文使用新名。


三、Org node agent —— {domain}-{职能}

org graph 上的节点 agent,一律带领域前缀:

id 职责
code-planner 开发领域:规划阶段的 org node
code-coder 开发领域:实现阶段的 org node
code-validator 开发领域:验收阶段的 org node
content-planner / content-writer / content-validator 内容领域的同构三段

不允许裸用 planner / coder / validator —— 它们必须能被一眼看出属于哪个领域,否则跨领域公司(既做开发又做内容)会立刻撞名。


四、验收产物 —— goal-{类型}

work graph 内动态选入的验收产出节点(见 27-E2E §十一):

id 产出
goal-benchmark 打分式验收标准(维度 + 权重 + 及格线)
goal-test-data 输入样本集(正常 / 边界 / 异常)
goal-test-script 可执行断言脚本

为什么是 goal- 而不是 task-

关键区分是基数:

概念 基数 定义
goal 一个人类需求描述 = 1 个 验收的边界。回答"这次交付到底算不算满足了人提的要求"
task 一个 goal 分解出 N 个 图中的执行单元。可并行、可下钻 sub agent,一个 goal 在图里会有很多个
okr 跨多个 goal 的长周期度量树 Objective / Key Result,见 §六

验收标准回答的是"人类想要的东西做到了没有"——这是 goal 级的判定。task 只是达成它的执行分支,一个 goal 下有很多个;把验收挂在 task 上会导致"到底以哪个 task 的验收为准"根本无法回答。

goal 是三层递归的(R-13)

「goal」本身在三个层级上各有一个,与 27-E2E §11.3「验收逐层递归」严格对应——每一层的 goal 就是那一层的验收边界:

goal 归属 谁验收它 落在哪
company-goal 公司 OKR 树(长周期度量) company.json.goal,建公司时写入
task-goal 一次用户请求 org graph 末端的 {domain}-validator 任务入口带入
subagent-goal 子任务 / 并行分支 该 work graph 内的 validator 节点 由 workgraph-planning 拆分时产生

company-goal 与 OKR 的关系:company-goal 是建公司时的一句话定性目标,是 OKR 树的输入——OKR 把它拆成可度量的 Objective → Key Result。两者不是替代关系,不要用 OKR 节点去存 company-goal。

三个验收 agent(goal-benchmark / goal-test-data / goal-test-script)是通用的,不按层级拆分:它们在哪一层被调用,就为那一层的 goal 产出验收标准。这与 §八bis 的元 agent 继承(全局通用本体 + 记忆分区)一致——不需要 task-goal-benchmark / subagent-goal-benchmark 这种按层级复制的 agent。

一处命名轴不一致(待定,不阻塞):company-goal / task-goal 是按作用域命名,subagent-goal 是按执行者命名。按作用域应为 subtask-goal。当前按提出时的原词 subagent-goal 记录,若要统一改为 subtask-goal,全局换一个词即可。

决策沿革(完整过程见 27-REQ R-10 / R-12):最初选 task-,理由是"goal 被 OKR 占用";§六 把 OKR 正名后该理由失效,改用"验收跟着一次 task 执行走"继续保留 task-;最终因上面的基数论证推翻,定为 goal-。


五、三种 benchmark 必须分开(当前全部叫 benchmark)

仓库里 benchmark 一词同时指三件完全不同的事。统一加前缀区分:

新名 指什么 现状
skill-benchmark 给 Skill 打分 + Arena ELO 排行榜 ✅ 已实现:server/services/benchmark-runner.js、benchmark-db.js、benchmark_runs 表(主键 skill_name)、comparisons ELO 表、路由 /benchmarks /benchmark-all /benchmark/status
agent-benchmark 给单个 system agent 打能力分,用于 hire / depositTemplate() 的 ≥95 门槛 ⚠️ 部分存在:system_agents.benchmark_score 字段(P0 已落地)、_registry.json 的 benchmarkScore(实测仅 3 条非空:ceo=97 / qa-judge=95 / base=90)
goal-benchmark 给单个 goal(一次人类需求描述)定验收标准,由 goal-benchmark agent 产出、validator 节点执行 🔴 本次设计新增,尚未实现

代码层重命名的影响面(未执行,需单独排期)

文档层的消歧已在 27 系列全部完成。代码层的重命名是一次真实的数据迁移,不是 find-replace,因此本轮只给出影响面清单,不动代码:

对象 位置 风险
benchmark_runs / comparisons / security_scans 表 data/benchmark.sqlite 改表名需迁移脚本 + 停机;这三张表服务于线上 Arena 排行榜
benchmarkScore 字段 system/templates/_registry.json(磁盘数据) 改字段名需同步改所有读写方 + 迁移已有数据
/benchmarks /benchmark-all /benchmark/status server/routes/ 公开 API,改路径破坏外部调用方
benchmark-runner.js / benchmark-db.js server/services/ 文件重命名成本低,但所有 require 点要同步

建议:代码层保持现状(既有的就默认是 skill-benchmark 语义),只对新增代码强制用新前缀。即 goal-benchmark 相关的表、字段、路由从第一天就带前缀,不与既有的混在一起。等哪天真要清理历史命名时,再按上表单独排期。


六、OKR 体系:从 goal 改名为 okr

⚠️ 注意与 §四 的区别:本节说的是把 OKR 体系/树/节点从 goal 这个词里解放出来。解放之后 goal 被重新赋予 §四 的新含义 ——「一个人类需求描述」。两者不冲突,但读的时候要分清:okr 是跨多个 goal 的长周期度量树,goal 是一次具体的人类需求。

这棵树的正式名称是 OKR(Objective - Key Result),不应该叫 "goal"。当前代码里 goal 既是树的名字、又是树里第 1 层节点的名字,是一处自我遮蔽的命名。

层级改动(已实施)

迁移前:

G-001          → Goal        (第1层)
G-001.1        → Objective   (第2层)
G-001.1.1      → Key Result  (第3层)
G-001.1.1.1    → Sub-Task    (第4层+)

迁移后:

O-001          → Objective  (第1层)
O-001.1        → Key Result (第2层)
O-001.1.1      → Sub-Task   (第3层+)

改法

体系整体叫 OKR,第 1 层的 "Goal" 也一并正名 —— OKR 的标准词汇里没有 "Goal" 这一层,现在的第 1 层实际承担的是"一个大目标下挂多组 OKR"的容器角色:

层 旧名 新名 ID 前缀
1 Goal Objective(顶层目标) O-001
2 Objective Key Result O-001.1
3 Key Result Sub-Task O-001.1.1
4+ Sub-Task (合并进 Sub-Task 层级) O-001.1.1.1

这样是标准的 Objective → Key Result → Sub-Task 三层。如果确实需要保留四层,则第 1 层建议叫 Mission(M-001),下挂 Objective / Key Result / Sub-Task —— 但不要再叫 Goal。

影响面与执行结果(✅ 已实施)

v0.2 更正:本节初版把磁盘数据迁移标为「高风险」,那是高估。实地核实后,存量数据几乎为空: data/goals/_index.json 与 data/companies/idearun/goals/_index.json 都是 [], data/goals/G-001/ 只剩一个孤儿 history.log(goal.json 早已丢失), system/tasklog/ 完全为空。真实风险是低的。

对象 处理 状态
server/services/goals.js → okr-service.js;GoalsService → OkrService git mv + 标识符改名 ✅
server/routes/goals.js → okr.js git mv ✅
/api/goals/* → /api/okr/* index.js / agent-server.js 同时注册新旧两条路径,旧路径作为向后兼容别名 ✅
/api/company/:cid/goals/* → /okr/*(7 条) 用数组路径 [/:companyId/okr...,/:companyId/goals...] 一次挂两个 URL ✅
data/{,companies/*/}goals/ → okr/ scripts/migrate-goals-to-okr.js(npm run okr:migrate) ✅
ID 前缀 G- → O-;goal.json → objective.json 同上脚本,含 nodes 的 key、children 数组、_index.json、progress.json、history.log ✅
层级名 ['Goal','Objective','KeyResult','SubTask'] → ['Objective','KeyResult','SubTask','SubTask'] parseNodeId() ✅
goalId 请求体字段 agent-chat.js 的 dispatch/report 同时接受 objectiveId(新)与 goalId(旧),写入时两个字段都留 ✅
OkrDashboard.vue / CompanyDashboard.vue 切到 /api/okr ✅ 前后端命名终于一致
bin/lemon.js 新增 okr create/add-node/list/status,保留 goal * 作为别名 ✅

迁移脚本要点(scripts/migrate-goals-to-okr.js):

  • --dry-run 预演;幂等可重复执行;迁移前自动备份为 *.bak-goals
  • 处理一个反直觉的边界:OkrService 构造函数会自动 mkdir 目标目录,所以「okr/ 已存在」不等于「已迁移过」——只要服务被 require 过一次就会留下空壳。脚本用 isEmptyOkrDir() 区分空壳与真实数据,空壳直接移除后继续迁移。
  • 容忍孤儿条目(有 history.log 无 goal.json)

验证:server/tests/unit/okr-service.test.js(7 例)+ 全量 npm run test:unit(652 例全绿)。

对 27 系列的直接影响

27-E2E §三 阶段 3 指出:27 号文档 work_graphs.goal_task_id 这个单字段不足以定位一个 OKR 节点(需要 companyId + 树 ID + 节点 ID 三元组)。改名后该字段应为:

okr_node_id  TEXT,   -- 形如 'O-001.1.1',配合 company_id 定位
task_id      TEXT,   -- 形如 'T-xxx',system/tasklog/{taskId}.json

七、速查表

不要用 要用
planner code-planner / content-planner / …
validator code-validator / content-validator / …
planning orggraph-planning / workgraph-planning / brd-planning / prd-planning / sdd-planning
org-graph-creator orggraph-planning
benchmark(裸用) skill-benchmark / agent-benchmark / goal-benchmark
test-data / test-script(裸用) goal-test-data / goal-test-script
goal / goals(指 OKR 体系时) okr
Goal(指 OKR 第 1 层节点) Objective(或 Mission,若保留四层)
goalId(OKR 树根 ID) objectiveId
nodeId(树内节点) nodeId(不变,已由 objectiveId 限定作用域)
G-001.1.1 O-001.1.1