跳转至

IK7LI3 Todo:步骤 5.5+6 拆出 Task 子 agent

关联 issue: IK7LI3 关联 spec: docs/project/current/IK7LI3-tech-spec.md 维护: 按 P0 → P5 顺序推进;每完成一个 P 级卡片,停下来与用户确认 diff,再进下一个。

P0:分支与 fixture 准备

  • P0.1 确认在 feat/IK7LI3-task-dispatch-poc 分支(已从 origin/develop ba49791 切出)
  • P0.2 在 skills/sql-dis-opt/sql-distributed/workspace/ 历史 case 库找真实跑过的 baseline.json / table_ctx.json 样本,作为 fixture 来源;不足则参考真实分布式 EXPLAIN 输出格式手工构造
  • P0.3 准备 B1 / B2 / B3 三套 fixture,落在 tests/IK7LI3/fixtures/<case_id>/:
  • baseline.json(含 baseline_mode / execution_time / fallback_reason)
  • table_ctx.json(含完整 distributed_context,B3 的 missing_info 含 shard_key)
  • distributed_context_facts.json(从 table_ctx.json 派生的紧凑 facts,作为 Task.prompt 输入)

出口:3 套 fixture 就位,每套文件结构完整、字段符合分布式特征。

P1:Task 工具契约探针(先验证机制,再改业务代码)

  • P1.1 写一个最小探针子 agent .opencode/agents/probe.md(临时,只回显 prompt 长度)
  • P1.2 用 opencode 跑一次 Task 调度探针,确认:
  • 主对话收到的字符串以 <task id="..." state="completed"> 开头
  • 主对话收到的内容只含子 agent 最后一条 assistant text
  • 子 session jsonl 日志路径可定位(为后续 token 计量做准备)
  • P1.3 验证 task: deny 让子 agent 无法再调 Task(让子 agent 尝试,应直接 fail)
  • P1.4 删除探针文件 .opencode/agents/probe.md

出口:本节确认 Task 工具契约与 spec §2 一致。若不一致,停下来更新 spec §2 与 §8,再进 P2。

P2:注册 sql-dis-router 子 agent

  • P2.1 写 .opencode/agents/sql-dis-router.md,frontmatter + system prompt 严格按 spec §3.2 / §3.3
  • P2.2 用 B1 fixture 手工触发一次 Task 调度,确认子 agent 能:
  • Read 两个 SKILL.md(rule-match + skill-analysis)
  • 返回符合契约的 JSON
  • 不附带 narrative
  • P2.3 若 P2.2 失败,定位是子 agent system prompt 问题还是权限问题,迭代修复

出口:子 agent 单独可用,输出 JSON 字段完整。

P3:主控 SKILL.md 改死走 Task 路径

  • P3.1 把 skills/sql-dis-opt/sql-distributed/SKILL.md 步骤 5.5 段替换为 Task 调度流程(按 spec §4.1)
  • P3.2 把步骤 6 段替换为"合并到 5.5-task,直接进步骤 7"说明(按 spec §4.2)
  • P3.3 检查全文不再出现 SQL_OPT_USE_TASK_DISPATCH 字样(开关已删)
  • P3.4 检查步骤 4 / 5 / 7-12 内容不动(本 POC 不碰)

出口:主控 SKILL.md 死走 Task 路径,inline 路径留在 develop。

P4:3 条用例 Task 路径实测

  • P4.1 跑 B1 Task 路径,收 jsonl 日志 + 路由结果
  • P4.2 跑 B2 Task 路径,收 jsonl 日志 + 路由结果
  • P4.3 跑 B3 Task 路径(重点看 missing_context 触发),收 jsonl 日志 + 路由结果
  • P4.4 用 jq 从 jsonl 抽 token 数据,生成 dispatch_poc_report.json(按 spec §6.3)

出口:3 份报告齐备,包含主/子 session token 数据与路由质量检查。

P5:对照退出标准做判定

  • P5.1 检查 G1:3 用例子 session 峰值 < 5k?
  • P5.2 检查 G2:3 用例主对话峰值 ≤ 16k?(对照基线 19.6k)
  • P5.3 检查路由合理:3 用例 selected_skills 符合 spec §6.1 期望?
  • P5.4 检查规则原文:matched_rule_entries 是 pending_rules 原文(非摘要)?
  • P5.5 检查 B3 降级:missing_context 非空触发主对话补充 + 重试?

判定:

  • 5 项全过 → POC 成功,进 P6
  • 任一不过 → 停下来写复盘到 tech-spec §8,决定是改 spec 重试还是终止 POC

P6:收尾

  • P6.1 整理 PR 描述(含实测数据表),发 PR 到 develop
  • P6.2 把 docs/project/current/IK7LI3-tech-spec.md §8 风险登记补完
  • P6.3 ~~开 follow-up issue:步骤 7 拆 Task 子 agent~~ → 已并入本 issue 第二档,见 P7-P10
  • P6.4 开 follow-up issue:评估是否合入 evidence-projection 分支
  • P6.5 开 follow-up issue:步骤 4/5 脚本实际执行验证(需分布式库环境)

出口:PR 合入或 POC 终止结论明确。


第二档:步骤 7 拆分(平级 specialist Task 并行 + 主 agent generation 汇总)

第一档 P0-P5 已完成(POC 验证通过)。 2026-08-12 修订:原 P7-P11(步骤 7 打包进单个 sql-dis-generator,后改为 7a inline + 7b 串行)均已废弃。新设计是 dml/index 两个平级 specialist Task 并行,主 agent generation 汇总;设计依据见 tech-spec §10.0-§10.9。

P7:契约去重(先去重再拆分,否则拆完仍是两个真理源)

  • P7.1 删 skills/sql-dis-opt/sql-distributed-optimization-generation/SKILL.md 输出契约中的 route_decision 字段
  • P7.2 skills/sql-dis-opt/sql-distributed-skill-analysis/SKILL.md 输出契约加 needs_dml_rewrite(决定是否发起 dml specialist)
  • P7.3 总控 SKILL.md 步骤 6 同步 dispatch 语义:needs_dml_rewrite / needs_index_evidence 分别决定两个 specialist
  • P7.4 删除 .opencode/agents/sql-dis-generator.md

出口:步骤 7 只剩一份输出契约(generation),瓶颈分类只在步骤 6 判一次。

P8:注册两个平级 specialist 子 agent

  • P8.1 保留并修订 .opencode/agents/sql-dis-index-advisor.md,frontmatter 严格按 tech-spec §10.5.1(必须 --- 开闭)
  • P8.2 新增 .opencode/agents/sql-dis-dml-advisor.md,frontmatter 严格按 tech-spec §10.4.1
  • P8.3 两个 agent 均跑 frontmatter 解析自检,确认 mode: subagent + task: deny 生效
  • P8.4 dml agent 嵌入 sql-distributed-dml-rewrite 规则;index agent 嵌入 sql-distributed-ddl-index 规则;两者不 Read .opencode/skills 子 skill
  • P8.5 两个 agent 分别实现 specialist JSON 契约;都不得输出最终 workflow JSON

出口:文件就位、frontmatter 可解析、契约不与 generation 冲突。

P9:主控 SKILL.md 步骤 7 改 specialist 并行 + generation 汇总

  • P9.1 规格层保持 generation + dml-rewrite + ddl-index 三个能力调用,不掺 Task 字样(按 §10.6.1)
  • P9.2 needs_dml_rewrite=true 时发起 sql-dis-dml-advisor;needs_index_evidence=true 时发起 sql-dis-index-advisor
  • P9.3 两个都为 true 时在同一轮并行发起;Task prompt 均使用原始 SQL + 同一份 distributed_context
  • P9.4 主 agent 收齐两个 specialist JSON 后调用 generation 汇总,决定最终 optimized_sql / create_index_ddl
  • P9.5 主对话校验最终 JSON、sqlglot、precheck.py、schema 和索引 DDL;步骤 8/9/10 仍由主控推进
  • P9.5 检查步骤 8 / 9 / 10 不动

出口:步骤 7 specialist 并行、generation 汇总;规格层框架无关、runtime 注解清晰。

P10:3 条用例实测

  • P10.1 跑 B1(dml=true, index=false):验证只发起 dml specialist,不发起 index Task
  • P10.2 跑 B2(dml=true, index=true):验证两个 specialist 同一轮发起,分别返回候选,generation 能汇总
  • P10.3 跑 B3(两者=false):验证前置门禁使两个 specialist 都不发起并降级
  • P10.4 用 tests/IK7LI3/extract_token_usage.py 抽主/子 session token 数据
  • P10.5 generation 汇总后的 optimized_sql 过 sqlglot + scripts/precheck.py(语法合法 + schema 不变)

出口:3 份报告齐备,含 token 数据与 G3-G7 检查项。

P11:对照退出标准做判定(用校准值 G1′/G2′,不用被证伪的 <5k)

  • P11.1 G1′:两个 specialist 子 session 峰值均 ≤ 20k?G1″:各自 API calls ≤ 3?
  • P11.2 G2′:主对话步骤 7 峰值 ≤ 20k?
  • P11.3 G3/G3′:B1/B2/B3 dispatch 行为与实际并行性符合 tech-spec §10.7?
  • P11.4 G4/G5:索引 DDL 前缀合规、无 DROP INDEX、作用域声明齐全?
  • P11.5 G6/G7:generation 最终 SQL 过校验?risk_assessment 含 specialist 风险 + generation 分布式判定?

判定:

  • 5 项全过 → 第二档成功,进 P12 收尾
  • 任一不过 → 停下来写复盘到 tech-spec §8,决定是改 spec 重试还是终止第二档

P12:第二档收尾

  • P12.1 在两个 specialist 文件顶部标注各自嵌入源 commit
  • P12.2 加 CI 检查项:dml/ddl SKILL.md 改动时提醒同步对应 agent
  • P12.3 整理第二档实测数据到 docs/project/current/IK7LI3-feasibility-evidence.md(追加章节)
  • P12.4 整理 PR 描述(含两档实测数据),发 PR 到 develop

出口:第二档 PR 合入或终止结论明确。

Backlog(本档不做,仅登记)

  • 步骤 10 sql-distributed-optimization-review 拆子 agent:大输入(explain 对比 + execute_result)、小输出(四类结论 + 修正 SQL),且该 skill 自述要求"站在独立 DBA / reviewer 视角,不延续上一轮乐观方向"——Task 的上下文隔离在此是质量要求而非单纯省 token(已由 E 方向 / P13 前置完成,见 ⑤')
  • 总控 sql-distributed/SKILL.md 瘦身:自身 11.9k tokens 常驻主对话,占 baseline 峰值 19.6k 的六成,是当前最大单项,未被任何拆分方案覆盖
  • Task 并行能力探针:同一轮发起两个 specialist 是否实际并发;不依赖 background 实验开关
  • docs/project/current/IK7LI3-feasibility-evidence.md 精简与"Task 本质"补章(已诊断,待执行)

第三档:SQL 输入契约路径化(2026-08-17,见 tech-spec §11)

P13:路径化输入改造

  • P13.1 SKILL.md 步骤 1 / 参数解析新增 SQL_FILE(优先)+ --sql-file PATH
  • P13.2 SKILL.md 新增步骤 3.6:统一写 $ROUND_DIR/user.sql(双模)
  • P13.3 步骤 4 / 5 / 离线采集脚本调用改 --sql-file "$ROUND_DIR/user.sql"
  • P13.4 步骤 6 / 7 / 8 Task prompt 改路径注入(USER_SQL_PATH + TABLE_CTX_PATH 等)
  • P13.5 步骤 8 generation 产出后落盘 $ROUND_DIR/optimized_sql.sql
  • P13.6 步骤 9 precheck 改 --original-sql-file / --optimized-sql-file;步骤 10 execute 改 --optimized-sql-file
  • P13.7 步骤 11 review Task prompt 改 ORIGINAL_SQL_PATH + OPTIMIZED_SQL_PATH + TABLE_CTX_PATH
  • P13.8 5 个 agent 文件输入契约与执行步骤同步为路径 Read

P14:路径化验证与文档纳管

  • P14.1 从 stash 精确恢复 docs/、mkdocs.yml 并纳入版本管理(本次提交)
  • P14.2 IK7LI3-tech-spec.md 追加 §11 路径化契约;IK7LI3-agent-io-flow.md 同步步骤 3.6-11
  • P14.3 tests/IK7LI3/fixtures/{B1,B2,B3}/ 冒烟验证路径化输入(B1 needs_dml_rewrite=true;B2 双 dispatch;B3 门禁降级)
  • P14.4 extract_token_usage.py 复测主对话峰值,验证 ~52k → ~40k 收敛
  • P14.5 服务器实测(--short-context)复核 token 与正确性

第四档:规则指纹预筛(2026-08-20,见 tech-spec §12)

P15:规则预筛降低步骤 6 上下文

  • P15.1 在 canonical/runtime pending_rules_1.md 增加规则指纹索引,规则正文不瘦身
  • P15.2 新增 rule_filter.py:16 维 SQL 指纹、索引表达式 AST 求值、候选正文裁剪;6 个单测通过
  • P15.3 sql-dis-rule-match 改为调用预筛脚本,只严格判定候选段落,禁止直接 Read 全量规则库
  • P15.4 同步 SKILL/README/agent-io-flow 并运行一致性检查
  • P15.5 服务器复测 sql-dis-rule-match peak effective < 32k

第五档:总控 SKILL 渐进加载(2026-08-20,见 tech-spec §13)

P16:总控渐进加载与 token 收敛

  • P16.1 Northwind 下界复现:main peak effective 32,242 / 34 calls,未完成步骤 2;rule-match peak 14,546
  • P16.2 提取 .opencode/skills/sql-distributed/references/generation.md,完整承接原步骤 8.1-8.5
  • P16.3 将 runtime SKILL.md 重写为精简的 13 步可执行状态机;文件字节数只作辅助观测,正常路径禁止预读 reference / 重读自身
  • P16.4 同步 .opencode/README.md 与 agent I/O flow;canonical skills/sql-dis-opt/ 不改 runtime 架构
  • P16.5 增加 runtime skill 结构契约单测并通过全部脚本测试;不得用字节数替代 token 验收
  • P16.6 全新 session 重跑 Northwind 下界:完成到合法停止状态、main peak effective ≤22,000、每次调用 context_total <32,000、无 SKILL 重读循环
  • P16.6a 记录流式阻塞样本:main ses_fe2110a84ffeglOliX3PenGE3M / rule-match ses_fe20e9972ffeC2XoxqVxxDIFL6;未完成调用 finish=None、0 tokens、无 error,判为 API/provider 阻塞,不计入 token 验收
  • P16.6b 保留原进程并发送同 session“继续”探针:主 session 被唤醒但重复 dispatch;新 rule-match ses_fe1fc5838ffem1pz3BlYxteXQI 同样 finish=None / 0 tokens / 无 error,确认不能恢复 provider 请求
  • P16.6c provider 恢复后用全新 session 重测;不得复用上述两个孤儿子 session
  • P16.6d runtime 防重复修复:步骤 6 父 agent 禁止预跑 rule_filter、只认 rule_match.json;Task 中断后报告阻塞并停止,禁止自动 redispatch;baseline 禁止外包 timeout
  • P16.6e 用 OpenCode TUI interactive 模式人工复测,保留人工中断/继续能力并记录 token
    • P16.6e-1 审计 ses_fe1e0d6ccffekMewGNvb50mJG6:16 calls / 5 compactions / peak effective 29,393 / sum 266,039;实际误用 ~/.claude/skills/sql-distributed 旧全局 skill,无子 session,样本判废
    • P16.6e-2 退出旧 TUI 后启动全新进程和全新 session;先确认项目 runtime SKILL_DIR 与 13 步编号,再跑 workflow
  • P16.6f 审计 ses_fe1d056d4ffehhWB6nz48ZuGPZ:旧全局 skill + 4 次 compaction;table_ctx.py 实际仅执行一次,旧 missing_info/摘要计划重采但尚未执行,样本判废
  • P16.6g 加固项目 runtime:缺分片键为本轮终态(不重采、不重派、不进下一轮),增加三层契约测试与 fresh-session 身份门禁
  • P16.6h OpenCode 预算调整:output/reserved=6144、tail_turns=3、preserve_recent_tokens=6000;配置已解析生效,待全新 TUI workflow 复测
  • P16.6i 修复 noshardkey_allset → missing 归一化错误;增加 no_shard_key / metadata_status,将任一 missing 全局终态改为候选级门禁,同步 runtime/canonical/测试
  • P16.7 下界通过后跑 stress SQL;所有调用 context_total <32,000,记录 generation reference 读取次数

P17:子 agent 显式注入 runtime SKILL_DIR(2026-08-25,见 tech-spec §13.10)

  • P17.1 审计 0824 DML advisor 触顶:确认已消费 rule_match,因 Task.prompt 缺少 SKILL_DIR 而搜索并 Read _lib.py,34,466 input 触顶前未落盘
  • P17.2 Tech Spec 与 agent I/O flow 记录五个 Task 的显式路径契约、禁止发现式回退与方案 B 决策门槛
  • P17.3 controller 五个 Task.prompt 均注入 SKILL_DIR=$SKILL_DIR
  • P17.4 五个 runtime agent 声明必填 SKILL_DIR;路径缺失/无效时 degraded,禁止搜索或 Read runtime 源码补路径
  • P17.5 增加逐 Task block 静态契约测试并通过 runtime scripts tests(22 tests)与 git diff --check
  • P17.6 全新 OpenCode session 复测 DML/rule-match:无 _lib.py/SKILL.md 搜索或 Read、产物与 ack 完整、每次 context_total <32,000
  • P17.7 根据 P17.6 记录方案 B 最终结论;当前静态评估为暂无必要,只有 A 生效后仍存在 helper 依赖导致的发现或触顶,才另行更新 Spec/Todo 实施 B

出口:五个子 session 都通过显式项目 runtime 路径完成脚本调用;方案 B 有可复核的“需要/暂无必要”结论。

P17 状态:🟡 进行中(runtime 与静态测试完成,待 P17.6 全新 session 验收及 B 最终结论)

P18:每轮独立 OpenCode session 与状态化衔接(2026-08-25,见 tech-spec §14;2026-08-31 否决)

否决决定:多轮不新开 session,继续在同一主 session 内推进并依赖强压缩(tech-spec §13.8)。理由:新开 session 每轮都要重跑环境校验与 baseline。P18B-D 永久关闭;多轮上下文问题改由压缩配置与主对话读取面收敛解决。

P18A:规格确认(代码前置门禁)

  • P18.1 审计现状:步骤 12 仅换 ROUND_DIR、不换主 session;确认五个 task: deny 子 agent 不能充当整轮 worker
  • P18.2 设计 controller / single-round worker 边界与 fresh opencode run 启动契约
  • P18.3 定义 workflow_state.json / round_handoff.json、固定 baseline、best bundle 晋升与 execution_unknown 处理
  • P18.4 同步 Tech Spec / Todo / agent I/O flow;停在文档门禁,取得用户二次确认后才能改 runtime

P18B:确定性状态机与 launcher

  • P18.5 先新增 controller 单测:schema、immutable hash、原子写、lock、seed、晋升/不晋升、max-round best、handoff 重放
  • P18.6 新增 workflow_controller.py 纯状态机;不得包含 SQL 生成或 specialist 逻辑
  • P18.7 fake opencode 验证 argv 无 -c/--continue/-s/--session,stdout 伪成功但缺 artifact 必须失败
  • P18.8 无数据库双 session probe:session ID 不同,项目 runtime identity 正确,每个 worker 可调用 Task

P18C:single-round worker 与执行安全

  • P18.9 baseline.py / execute.py 增加原子 execution journal;started 中断必须进入 manual_intervention,禁止自动重跑
  • P18.10 runtime SKILL 分 bootstrap / --round-worker;删除步骤 12 同 session 自增,controller 成为唯一 next-round owner
  • P18.11 五个 Task 保持 P17 SKILL_DIR 注入;worker 逐 ack 校验对应 artifact 存在、可解析且字段一致
  • P18.12 更新 runtime contract tests、.opencode/README.md 和 agent I/O flow

P18D:pipeline 与服务器验收

  • P18.13 pipeline 传显式 ${WS_DIR}/cases/${FOLDER_NAME};writer 从 workflow best bundle 发布,controller 不写 results
  • P18.14 单测后轮回退/功能风险保留旧 best、DDL bundle 不拆分、max rounds 返回 best 而非最后一轮
  • P18.15 lower-bound + stress SQL:每轮独立顶层 session、每次 context_total <32,000、每轮 main peak effective ≤22,000
  • P18.16 中断演练:execution journal=started 时杀进程,确认 manual_intervention 且无自动 retry

出口:SQL 优化轮次与顶层 session 一一对应;跨轮只依赖可验证 state/handoff;后轮失败不覆盖旧 best;所有调用低于 32k。

P18 状态:❌ 否决(2026-08-31;多轮保持同 session + 强压缩,P18B-D 关闭)

出口:下界流程完成,main peak effective ≤22,000 且所有调用 effective_input + output < 32,000;否则停止按字节删规则,另行评估 generation Task 隔离。


当前进度

卡片 状态 备注
P0 ✅ 完成 B1/B2/B3 fixture 就绪;B1 已二次迭代(加 dependent subquery 让 DML 信号明确)
P1 ✅ 完成 探针验证 Task 工具契约,发现"最后 tool 调用之后的所有 text 整体回写"(spec §2.2.1)
P2.1 ✅ 完成 .opencode/agents/sql-dis-router.md 已写;按 P2.2 B3 反馈迭代加强:加前置门禁段 + JSON 结构硬规则 + cherry-pick 禁止
P2.2 🟡 进行中 B1 跑过:机制通过但 fixture 期望偏差已修;B3 跑过:发现 cherry-pick 问题已修;B2 状态待用户确认;改完后 B1/B2/B3 都需重跑
P3 ✅ 完成 主控 SKILL.md 步骤 5.5/6 保持框架无关 skill 调用;Task 调度在 OpenCode runtime 层
P4-P6 ✅ 完成 第一档 POC 数据落 .tmp/IK7LI3_poc/dispatch_poc_report.json;feasibility-evidence 文档成稿
缺陷修复 ✅ 完成 2026-08-12:修 sql-dis-router.md / sql-dis-generator.md 断裂的 frontmatter(闭合 --- 被 ## task: deny 顶替,导致 agent 注册不成 subagent);已跑解析自检
旧 P7-P11 ❌ 废弃 原设计"步骤 7 打包进单个 sql-dis-generator"废弃,理由见 tech-spec §10.0。注:sql-dis-generator.md 已写出 21,906 chars(旧进度表误标"未开始"),按新 P7.4 删除
P7 ✅ .opencode 完成 步骤 6/7 拆开:sql-dis-rule-match + sql-dis-skill-analysis;含 needs_dml_rewrite;已删合并 router;skills/sql-dis-opt 未同步
P8 ✅ .opencode 完成 sql-dis-dml-advisor + sql-dis-index-advisor(步骤 8 平级 specialist)
P9 ✅ .opencode 完成 步骤重编号:6 rule-match → 7 analysis → 8 generation → 9 precheck → 10 execute → 11 review → 12 continue → 13 return
P10 🟡 进行中 提示词已拆;待 TUI 按新 agent 冒烟
P11 ⏳ 未开始 第二档:对照校准后退出标准判定
P12 ⏳ 未开始 第二档:收尾
P13 ✅ .opencode 完成 路径化输入改造(SKILL.md 步骤 1/3.6/4-11 + 5 agent 契约),2026-08-17
P14.1-2 ✅ 完成 文档从 stash 恢复纳管 + tech-spec §11 + 流程图同步
P14.3-5 ⏳ 未开始 冒烟 + token 复测 + 服务器实测
P15.1-4 ✅ 完成 规则指纹索引 + 确定性预筛脚本 + rule-match/runtime 文档同步;候选内容样例从 33,248B 降至 4,462B
P15.5 ⏳ 未开始 服务器复测 rule-match 是否低于 32k
P16.1 ✅ 完成 Northwind 下界复现:main 32,242 peak / 34 calls / 615,402 sum effective;步骤 2 前压缩循环
P16.2-7 🟡 进行中 generation 渐进加载 + 精简总控 + 缺分片键终态加固 + OpenCode 压缩预算调整 + 下界/stress 实测 token 验收
P17.1-5 ✅ runtime 完成 五个 Task 显式注入项目 SKILL_DIR;22 个静态/runtime 测试通过
P17.6-7 ⏳ 待服务器验收 fresh session 复核无源码发现/触顶,并给出方案 B 最终结论
P18A ✅ 设计完成 每轮独立顶层 session + workflow state/handoff;设计保留作历史记录
P18B-D ❌ 否决 2026-08-31 决定多轮不新开 session,用同 session 强压缩;B-D 关闭