Files
Arcrun/system-dev/docs/3-specs/library-map/design.md
T
uncle6me-web 962d863ef7 fix(kbdb): 藏書地圖 M3 收尾——讀端自動核對重算,不再依賴 ingest 接鏈
真因(總管實測,system-dev/wiki/mistakes.md 08-08 段):design 原訂「ingest 尾端呼
POST /map/recompute」,但 repo 內查無任何呼叫點,三週沒接上,沒手動 backfill 過的租戶
(絕大多數)GET /map 恆回空;MCP 說明文字還宣稱「地圖由 ingest 尾端自動重算(M3)」——假話。

leo 否決「降級成即時聚合、不維護快取」的提案(會丟失 narrative 這類摘要本體,只算得出
count)。改法:GET /map/GET /map/:library 讀端自己核對即時三元組數,落差就地呼叫既有的
recomputeLibraryMap 補算(kbdb/src/actions/library-map.ts ensureFreshLibraryMaps)。聚合
SQL 沒有第二套、narrative/relation_profile/bridges 摘要欄位原封不動,只是觸發時機從「等
外部呼叫」改成「讀的當下順手核對」。同時解掉:全租戶自動 backfill/跟得上新資料/不依賴
跨 repo 的 ingest 接鏈。

附帶修 recomputeLibraryMap 的 narrative 欄位:沒帶值時原本會清空,改成沿用上一版(避免
自動重算把 ingest 端/人工填過的 narrative 靜默洗掉)。

修正三處說謊的說明文字(mcp/src/tools/kbdb_map.ts、console-ui console/index.html):
「地圖由 ingest 尾端自動重算(M3)」不存在,改為誠實描述讀端即時核對機制;404 語意從
「從未 recompute」改為「查無此庫」(已知但空的庫現在會自動補成 triplet_count:0 的 200,
不會落到 404)。

測試:kbdb 新增 6 案(18/18 全綠,覆蓋自動 backfill/跟得上資料/narrative 保留/
404 vs 空庫誠實分辨/owner 隔離/無 triplet template 不報錯);mcp 新增 1 案釘住舊謊言
不再出現。kbdb 125/125、mcp 69/77(同基線 8 個 oauth 既有失敗,非本次引入)全綠;
tsc 兩包乾淨(kbdb 1 個既有 auth.test.ts 錯誤與 stash 前一致,非本次引入)。

SDD:system-dev/docs/3-specs/library-map/tasks.md M3 從「07-19 誤標 」更正為實況;
design.md §3 加 2026-08-08 更正說明。未動 frontmatter status(仍 draft,D35 生命週期
鐵律留給總管/leo 裁)。

殘項:本次修改只在本機驗證(真 SQLite + 假 binding 單元測試),未部署 prod;未在真實
KBDB(如 yuga3bse 租戶)重新實測 kbdb_get_map 非空——需部署後才能貼實測輸出。

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
2026-08-08 00:44:55 +08:00

53 lines
5.3 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
---
status: draft
note: leo 2026-07-19「藏書地圖可以走」=design confirmed 可動工(M1/M2 起跑);active 標記待對照 Arcrun 現行 active SDD 收斂。
---
# library-map(藏書地圖)— Design
## 1. 資料結構:`library_map` Template(照 leo spec §3
每庫一個 map block。slots`library`(text)`narrative`(text,抽自該庫頂層 wiki 首段)/`top_entities`(arraydegree 排序 top-N)`relation_profile`(arraypredicate 分布=庫的性格)`bridges`(array,同 entity 跨庫 join)`triplet_count`(number)`commit_hash`(text)`status`(active|superseded)。
三元組按庫過濾:先核實現況——rag-ingest-cards v2 的 triplet 已帶 `source_uri`、entries 已有 `metadata.library`portal-auth P1);若 triplet 定位庫仍不足,在 Triplet **Template schema** 加 optional `library` slot(改 template 不動表)。
> **核實結果(2026-07-19M1 對 prod 實查)**triplet templateprod 名 `triplet`,非 MCP 註解寫的 `graph_triplet`slotssubject/predicate/object/…/source_uri/…,**無 `library` slot**entries 的 `metadata.library` 機制在但既有資料未標記(`?library=kb` → 0 筆)→ **定位庫不足,走預案**:M1 於 recompute 時冪等地在 triplet template 加 optional `library` slot`ensureTripletLibrarySlot`,改 template 不動表);slot 值由 ingest 端補寫(M3)。過渡期 `/map/recompute` 收 optional `source_prefix` 參數,對「無 library 值的舊 triplet」以 `source_uri` 前綴歸庫(如 `gitea:Leo/kb@`)——前綴由 caller 提供,base 不寫死 URI 語意;bridges 的「對面庫」只認 library slot 標記值,M3 backfill 前會偏稀疏(誠實限制)。
## 2. 重算的家:SQL 只能住基本盤(D6 推論,本 SDD 關鍵歸屬裁定)
degree 排序/predicate 統計/跨庫 join 是聚合 SQL——**D6 鐵律:插件與 workflow 全程禁 SQL**。故重算實作=**kbdb base 新增內建端點 `POST /map/recompute?library=`**(基本盤內 SQL 合法,一段交易:算→建新 block→舊標 superseded)。ingest workflowA 類)尾端用 `http_request` 呼此端點——A 類接 B 類 API,牆不破。
讀取端點 `GET /map`(全館,每庫一行)/`GET /map/:library`(詳圖),MCP/GUI 共用。
## 3. 更新機制(leo spec §4
ingest 完成 → 取本次 commit diff 涉及的庫集合 → 逐庫呼 `/map/recompute`。無 cron 全量。首次 backfill=對每個既有庫手動各呼一次(installer/腳本一行)。
> **2026-08-08 更正(matrix/arcrun CC**:上面這條「ingest 尾端接鏈」的路徑本身沒錯(`arcrun-rag`
> 那條管線也確實接了,`670f38a`),但它**只覆蓋接了鏈的那一條 ingest**——這個 repo 內(kbdb/
> cypher-executor/mcp)從沒有任何呼叫點會打 `/map/recompute`,導致沒手動 backfill 過的租戶
> (絕大多數)恆空,且拖了三週沒人發現/接上(見 `system-dev/wiki/mistakes.md` 08-08 段)。
> **改法**(leo 否決「降級成即時聚合、不維護快取」的提案,因為那會丟失 narrative 這類摘要
> 本體):`GET /map``GET /map/:library` 讀端自己核對即時三元組數,落差就地呼叫既有的
> `recomputeLibraryMap` 補算(`kbdb/src/actions/library-map.ts` `ensureFreshLibraryMaps`)。
> 聚合 SQL 仍只住 kbdb base(沒有違反 §2 的歸屬裁定),只是觸發時機從「等外部呼叫」改成
> 「讀的當下順手核對」——這條讀端機制本身就是「無 cron 全量」的自動 backfill,取代了
> 「首次 backfill=對每個既有庫手動各呼一次」這句手動步驟。細節見
> `system-dev/docs/3-specs/library-map/tasks.md` M3 段。
## 4. 注入(leo spec §5,本功能重點)
- **MCP instructions**arcrun-mcp 啟動組 instructions 時拉 `GET /map` 嵌入(快取+TTL,或每次連線現拉——量數百 token,現拉可接受)。
- **`get_map` 工具**:薄殼呼 `/map``/map/:library`。與 #68 的 kbdb_graph_neighbors 同族(D17 KBDB MCP 面),可同 PR 或緊接。
- **GUI**console/portal 首頁 render `GET /map`——庫卡片(narrativetop entities+規模)+跨庫 bridges 一覽;點庫進該庫搜尋。
## 5. 與 D30 檢索治本的連動(本 SDD 新增,超出原 spec)
leo 終景「補充的只 vectorize entities+一句話」與本件是同一素材的兩用:map block 的 narrativetop_entities=卡級/庫級摘要嵌入單位。落法:map block 的 content 欄寫成可嵌人話(`{library}{narrative}。核心:{top_entities}`),標 embed → **semantic 第一跳打 map 層做庫路由**,第二跳才進庫內(D30「向量做路由、定稿給 LLM 讀」)。#58/#59 的殘影/模型問題在 map 層天然緩解(block 少、可整層重刷)。
## 6. Retrieval 流程(改造後,leo spec §6 原文)
session 啟動 → instructions 已含全館地圖(push 零查詢)→ 需細節 get_map(library) → graph query 找 entity/關係 → 依 index 取 repo wiki 定稿(真相源不變)。
## 7. 歸屬
kbdb base 端點=B 類(PR);ingest 尾端接鏈=A 類(workflow 改版,arcrun-rag/個人庫同款);MCPB 類;GUI=B 類(console 路由)。全框架件:寫一次,arcrun-rag/Mira/未來客戶全實例受益(bundle 更新分發)。