2026-04-21_rebuild_handoff.md 9.8 KB

KnowHub 重建与去重工作交接文档

日期:2026-04-21 上下文:修复同事 agent 失控污染的 tao_dev_1 数据,统一为 howard_dedup 版本;同时系统化去重,建立正确的需求-能力关系。


一、DB 当前状态

计数 版本分布
capability 315 全部 howard_dedup
strategy 94 全部 howard_dedup
resource 2508 全部 howard_dedup
requirement 99 全部 v0未动,不要动)
knowledge 1046 未动
junction 表 计数
requirement_capability 659 ⚠️ 不完整(见待办 2)
capability_tool 1275
capability_knowledge 0(源数据无)
capability_resource 0(源数据无)
strategy_capability 660
strategy_resource 2585
requirement_strategy 94
requirement_resource 2585

关键 schema 提醒

是否有 relation_type 列
strategy_capability ✅ 有(值:'compose'
capability_knowledge ✅ 有
strategy_knowledge ✅ 有
requirement_capability 没有,不要加(按 A 方案,语义 = 研究发现的所有 cap)
其他 junction 都没有(只有 FK 两列)

二、已完成的工作

2.1 历次 capability 去重(ROUND 1 → 2 → C → 4)

对原 tao_dev_1 + v0 数据做了 4 轮合并:

  • Round 1:手动聚类 35 簇,合并 112 条 member + 删 22 条 VCAP(CAP-tao_dev_1-NN-NN 占位)→ 465 → 331
  • Round 2:26 簇跨领域合并 → 331 → 289
  • Round C:6 条跨版本(v0 foundation 吸收 tao_dev_1 同义条)→ 289 → 283
  • Round 4:修复 rebuild 时 alias 漏判产生的 32 条新 dup → 354 → 315

2.2 数据重建(从 /Users/sunlit/Downloads/output 2/ 99 folder)

由于同事的 agent 失控污染:

  • purge 所有 capability/strategy/resource(v0 + tao_dev_1)+ 所有 junction
  • seed 历次合并 canonical + 21 条 v0 foundation(+重建 CAP-006)
  • 从 99 folder 重 ingest,全部标 version=howard_dedup
  • 别名表 536 条确保跨所有历史名字都能命中已有 canonical,避免二次重复

2.3 手动修复 6 个 malformed folder

源数据 schema 不标准但有内容可抢救:

  • 004: strategy.strategy.phases + capability_mapping (cap name only)
  • 031: strategy.strategy.phases + capability_mapping (capability_id/name)
  • 044: capabilities_extracted 用老 schema(capability_id/capability_name
  • 053: phases[] 顶层 list + core_workflow 文本
  • 066: execution_phases + key_capabilities
  • 070: capabilities_mapping only

全部已经手动解析 + DB 写入。

2.4 Rename & 扩写

32 条 canonical 的 name/description 被改写以覆盖合并后的语义范围(应用 rename_merged_capabilities.py)。

2.5 capability_tool 回填

capabilities_extracted.jsonimplements 字段反向回填了 1275 条 cap-tool 关系。


三、已创建的脚本(knowhub/scripts/

脚本 作用 幂等
merge_capabilities.py 4 轮 canonical 合并映射 + junction 冲突处理
rename_merged_capabilities.py 32 条 canonical 改名
rebuild_howard_dedup.py 全量重建:purge → seed → ingest output 2/ → 改名 ✅(resume mode)
dedup_howard_round4.py Round 4 修复 rebuild 产生的 dup
salvage_malformed_folders.py 早期尝试处理 malformed folder 的脚本(未使用,我后来手动处理了) -

所有脚本使用 autocommit=True,每次操作独立提交——连接断了可以直接重跑。


四、备份位置

/tmp/knowhub_backup_2026-04-21/(执行 rebuild 前完整快照)

  • capability.json (365 rows, 原 v0+tao_dev_1 混合状态)
  • strategy.jsonresource.jsonrequirement.jsonknowledge.json
  • 所有 junction 表的 JSON 快照

/tmp/capabilities_all.md(465 条 tao_dev_1 pre-round-1 原始快照,重建时作为别名源)


五、待完成工作(按优先级)

待办 1:补齐历史 requirement_capability 到"研究全集"(方案 A)

问题:当前 req_cap=659 基本等于 strat_cap=660 的镜像,只含 strategy 的 workflow_outline 子集。按 A 方案设计应该是所有 capabilities_extracted.json 里出现的 caps 全集(research-discovered)。

操作

  1. 遍历 /Users/sunlit/Downloads/output 2/ 的 99 个 folder
  2. capabilities_extracted.json,对每个 cap 用 alias map 解析成 howard_dedup canonical ID(逻辑与 rebuild_howard_dedup.py 的 cap resolution 部分一致)
  3. INSERT INTO requirement_capability (requirement_id, capability_id) VALUES (REQ_NN, CAP-X) ON CONFLICT DO NOTHING
  4. 对 malformed 格式的 folder(044 用 capability_id/capability_name、053 用 phases 里的 caps 等)也要按特殊结构处理——参考 salvage_malformed_folders.py 的逐 folder 处理逻辑

预期增量:1016 cap_entries(含重复) - dedup → 约 900 个 (req, cap) pairs;现有 659 → 预期 ~900+。

不要

  • 不要加 relation_type
  • 不要动 strategy_capability(保持 compose 语义)

待办 2:处理 5 份重跑数据(等用户发来)

User 将提供 032/046/069/085/097 的重跑数据(可能是新的 folder 替换)。 处理时必须:

  1. 检查现有孤儿数据

    • REQ_032:DB 已有 24 条 resource(folder=032 tag),没 junction
    • REQ_069:25 条
    • REQ_085:36 条
    • REQ_097:24 条
    • REQ_046:0 条(从未入库)
    • 如果新数据含这些 URL:INSERT ... ON CONFLICT 会更新同样的 resource(URL hash ID 确定)
    • 如果新数据不含某些 URL:旧 resource 就是孤儿(考虑删除或保留)
  2. 按 rebuild_howard_dedup.py 的 ingest_folder 逻辑处理

    • match requirement by exact description
    • create resources(howard_dedup version)
    • resolve capabilities via alias map
    • create strategy(howard_dedup,按 is_selected=true 选 1 条)
    • wire ALL junctions including 新的 req_cap 全集逻辑(待办 1 的延伸)
  3. 关键:req_cap 要写 ALL caps in capabilities_extracted,不只是 strategy 用到的(A 方案)

待办 3(可选,之前说"先不忙"):Embedding 重算

所有 315 条 capability + 94 条 strategy 的 embedding 都是空。 当用户想启用语义搜索时,批量调用 knowhub/embeddings.pyget_embeddings_batch 重算:

for each cap: embedding = get_embedding(f"{name} {description}")

待办 4(可选):effects/criterion 从备份回灌

Round 1-3 合并时丢失了 member caps 的 effects + criterion 数据。 用户有备份,可从 /tmp/knowhub_backup_2026-04-21/capability.json 的旧数据里,对当前 howard_dedup caps 做:

  • 如果当前 canonical 的 effects 是 []、criterion 是 '':从备份找同名或同 ID 的老记录合并进来

六、已知数据问题(转告同事)

6.1 Pipeline 输出 schema 不统一

  • 5 folder 的 strategy.json 各造一格(phases/execution_phases/capabilities_mapping 等字段名)
  • 1 folder(044)的 capabilities_extracted.json 用了老 schema
  • 建议:Pipeline 加 schema validator

6.2 LLM 空输出

  • 069/085:strategies: [](没产出策略)
  • 008/034/053:extracted_capabilities: [](没产出能力)
  • 建议:重试或 fallback

6.3 JSON 文件损坏

  • 032:只含 {"ping"}
  • 046:strategies 是 str
  • 077:JSONDecodeError
  • 097:JSONDecodeError
  • 建议:atomic write(tmp+rename)

6.4 LLM is_new 判定不可靠

新批次 is_new=true 的 cap 大量是已有能力的重新命名。 建议:pipeline 在产出 is_new=true 前先做 DB 语义查重(name 精确匹配 + embedding cos)。

6.5 VCAP 机制已退役但 code 还在

  • decisions.md §18 决议 VCAP 退役,但 ingest_research_output.py 还在造 CAP-tao_dev_1-NN-NN
  • 建议:下线 VCAP 分支,is_new=true 必须 pre-resolve 或降级为错误

七、下次 session 快速重建上下文的步骤

  1. 读本文档knowhub/docs/2026-04-21_rebuild_handoff.md
  2. 读历史脚本knowhub/scripts/rebuild_howard_dedup.py 是主逻辑,内含 alias 构建、canonical 选择、junction 写入的全套实现)
  3. 查询 DB 现状确认未被外部干扰:

    python -c "
    from knowhub.knowhub_db.pg_capability_store import PostgreSQLCapabilityStore
    s=PostgreSQLCapabilityStore(); cur=s._get_cursor()
    for t in ['capability','strategy','resource']:
       cur.execute(f'SELECT version, COUNT(*) AS c FROM {t} GROUP BY version')
       for r in cur.fetchall(): print(f'{t}/{r[\"version\"]}: {r[\"c\"]}')
    "
    
    1. 开工:优先做 待办 1(补齐 req_cap) 再等 待办 2(5 份重跑数据)

    八、写入 DB 时的通用约束(务必遵守)

    1. ID 规范(都用短 hash,ID 里不带 version):
    2. capability: CAP-<hash8(normalized_name)>CAP-NNN(v0 foundation)
    3. strategy: strategy-<hash8(req_text + "|" + strategy_name)>
    4. resource: resource/research/<platform.lower()>/<hash12(url)>

    5. Alias 构建传递闭包(避免 CAP-A → CAP-B → CAP-C 这种链式问题未解析到最终 canonical):

      member_to_canonical = {m: final_canonical for ...}
      # 遇到循环或多层嵌套时一定要解析到 final
      
  4. AnalyticDB 约束

    • 新加列 + ON CONFLICT DO UPDATE 对 beam 表不兼容 → 都改 DELETE + INSERT
    • autocommit=True 强制(否则 idle-in-tx 会长期持锁)
    • 连接不稳定 → 脚本必须幂等、支持断点续跑
  5. junction 写入全部用 ON CONFLICT DO NOTHING,避免重复 PK 错误

  6. 不要修改 requirementknowledge 表及其相关 junction