四块互相交织的 benchmark 覆盖增量,统一提交: 1) 通信遥测(#23):orchestrator 路由 peer 消息时按 correlation_id 计请求/应答到 SwarmRun.collaboration(内部状态,不进 Manager 事件流);collector 算 s_communication。 治理计数由 run.approvals 派生(合规/总数)→ s_governance。 2) Q_quality 掩码归一(v2.1 裁定):metrics.quality_score 改为对 present 输入加权归一, 非编码任务自动忽略 TestPassRate,全缺 → NaN(不伪造)。 3) 质量插桩 / Group B:新增 Pod 内代码测试沙箱(orchestrator/sandbox.py,环境清洗 + 超时强杀 + 资源限额 + 路径越界校验,门控 ENABLE_QUALITY_EVAL)与 held-out fixture (benchmark/fixtures/);run 完成时用留出测试评分得 TestPassRate → Q_quality → collector 合成 reward。安全边界见 docs/integration/security-boundary.md §8.1。 4) 决策引擎 / Group A(#10,Option A score-at-pull):新增 orchestrator/decision_engine.py —— 信息素 τ(Redis 持久、(role,agent) 键控、冷启动 0.5、ρ 蒸发、夹紧、学习常开)+ η 启发式评分 + ε-greedy 概率采样;每次 dispatch 产一条 DecisionTrace → SwarmRun.decisions;collector 算 tau/eta/p_decision。概率选择门控 ENABLE_ACO_DISPATCH (默认关,CI 用 ACO_SEED 固定)。 覆盖:单次 run 真实可算字段由 4 提升至最多 10/15(新增 communication/reward/tau/eta/ p_decision,外加 governance 有条件)。 测试:新增 test-sandbox / test-quality / test-decision-engine;扩充 collector/metrics 用例; CI 纳入全部 benchmark 套件 + flag-on 的 ACO e2e。本地 11 项 gate 全绿。 诚实边界(未越界声称): - Group A 为单边匹配(Option B 待 Group C);概率派发优于贪心未证;默认关闭。 - reward 的 CodeReview/UserAcceptance 未采集(掩码忽略);P_risk 为审批派生低估。 - s_gain/s_swarm/g_e/g_e_cost/benchmark 仍 NaN —— 需基线(#21/#13),本 PR 不动验收。 影响范围:Swarm(orchestrator + benchmark + docs + CI)。不改 Manager↔Swarm 事件契约 (遥测均为运行时内部状态);不影响 Client/计费/密钥/发布链路。新增 ENABLE_QUALITY_EVAL / ENABLE_ACO_DISPATCH 两个开关,默认关闭。 Closes #10 Closes #23 Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
4.7 KiB
4.7 KiB
质量插桩(Benchmark Group B):TestPassRate → Q_quality → reward
把「生成代码」变成可计算的质量分,进而让 reward 由 NaN 转为真实可算。本文档是该链路的唯一入口。
1. 链路总览
specialist agent 生成文件 ──┐
├─(完成时, 门控)─► 沙箱执行 fixture 留出测试 ─► TestPassRate
fixture 留出测试 (held-out) ─┘ │
▼
quality_score(掩码归一) ─► Q_quality ─► collector ─► reward
- 谁生成代码:swarm 自身的执行单元(
agent/task_executor.py,OpenAI 兼容模型),其输出含files:[{path,action,content}]写入工作区。 - 谁评分:fixture 的留出测试(held-out),swarm 看不到 → 避免「自己出卷自己改」。swarm 自带的
test_*.py仅作协作/鲁棒性信号(agent_test_pass_rate),不计入 Q_quality(Owner 裁定)。
2. 组件与文件
| 组件 | 文件 | 职责 |
|---|---|---|
| 代码沙箱 | orchestrator/sandbox.py + sandbox_runner.py |
在临时工作目录的子进程内运行测试;超时强杀、资源限额、环境清洗、路径越界校验;从 JSON 读取计数 |
| Fixture | benchmark/fixtures/__init__.py + <id>/fixture.json + <id>/tests/test_*.py |
任务目标 + 留出测试 + target_time_seconds + required_capabilities |
| 质量评测 | orchestrator/quality.py |
收集生成文件(区分 impl/测试)、沙箱评分、合成 Q_quality |
| 运行时存储 | SwarmRun.quality(swarm_runtime.py) |
存评测结果,供 collector 读取 |
| 触发点 | main.py: refresh_swarm_run_status(run 完成时) |
门控 + 绑定 fixture 时调用评测并落库 |
| 采集 | benchmark/collectors/run_collector.py |
由 quality + run 数据合成 reward |
| 公式 | benchmark/metrics.py: quality_score / reward |
纯函数(掩码归一 / 加权和) |
3. Q_quality:掩码归一(v2.1 裁定)
Q_quality = Σ_{i∈present} wᵢ·xᵢ / Σ_{i∈present} wᵢ,i∈{TestPassRate, CodeReview, UserAcceptance},默认 w=0.4/0.3/0.3。
- 不适用项传
None,同时退出分子与分母 → 分值恒在[0,100]且跨任务类型可比。 - 非编码任务(
required_capabilities不含{python,code_generation,testing,pytest,...})→TestPassRate=None自动忽略。 - 当前只采集到
TestPassRate;CodeReview/UserAcceptance未接入 →Q_quality退化为TestPassRate。 - 三项全无 →
NaN(规则 #9,不伪造 0)。
4. reward 何时为真
collector 在以下全部满足时计算 reward,否则 NaN + coverage=False:
- 绑定 fixture 且
Q_quality为真实数(沙箱产出了 TestPassRate); V_speed可算(fixture 给target_time_seconds,run 时长 > 0);E_cost可算(预算 + 用量)。
派生口径:s_task=完成率、r_robust=鲁棒分、g_gov=审批合规(无受治理操作→100)、p_rework=retry>0 的任务占比、p_risk=审批高危占比(无受治理操作→0)。
⚠️ 已知低估:
p_risk仅由审批派生、p_rework仅由 retry 派生(未含评审重开)。两者与治理覆盖缺口绑定,已在 collector 与 coverage 文档显式标注,不作隐藏假设。
5. 安全(执行不可信代码)
详见 ../integration/security-boundary.md §8.1。要点:
- OS 级隔离边界 = K8s Pod(非 root/只读根/NetworkPolicy/限额/seccomp,部署侧强制,非本仓)。
- 沙箱在 Pod 内做纵深防御:临时目录即用即删、超时强杀、资源限额、环境清洗(密钥/Token/代理变量不入子进程)、路径越界校验、输出截断。
- 默认关闭:仅
ENABLE_QUALITY_EVAL=1且在隔离 Pod 内启用。不构成独立安全边界,不替代 Pod 层强化沙箱。
6. 诚实边界(本链路未关闭的)
- 仅 1 个示例 fixture(
add_function);统一任务集未建。 CodeReview/UserAcceptance未接入(需评审/验收信号源,部分属 Product/Manager)。Q_quality真 ≠G_E/Benchmark_Agent真:gain仍需基线(Group C),故s_swarm/g_e/g_e_cost/benchmark仍 NaN。- 本链路不构成 benchmark 主链路验收。
7. 测试
scripts/test-sandbox.py:沙箱真实执行、计数、超时、环境清洗、路径越界(无需模型 key)。scripts/test-quality.py:fixture 评分 →Q_quality=100→reward转真;并断言gain/benchmark仍 NaN(不越界声称)。