修復中文路徑 preflight 與 BM25 核心詞落空,測資改照現實建

兩個 bug 同源於自檢測資「照能過建、不照現實建」:

- ingest preflight:git status --porcelain 預設會把含中文或空格的路徑加引號
  轉義,raw/ 白名單比對因此失效,中文檔名的 convert 產出被誤判為 raw/ 以外的
  未提交變更而中止攝入。舊測資用 ASCII 檔名,整條路徑從未被走過。

- search:BM25Okapi 的 idf 在 df >= N/2 時 <= 0(rank_bm25 對負 idf 的替代值
  epsilon x average_idf 在 average_idf 為負時同樣為負),與 search() 的 s > 0
  過濾相乘,會讓「每頁都提到的核心詞」查詢全數落空——知識庫愈小、詞愈核心
  愈嚴重,MCP 的 search_wiki 一併受害。改用 Lucene 式恆正 idf。
  舊測資每個查詢詞都只出現在一頁(df=1),恰好避開此配置。

變更:
- tools/ingest.py:preflight 比對前剝除 git 的轉義引號
- tools/search.py:_BM25 子類覆寫 _calc_idf 為 log(1 + (N-df+0.5)/(df+0.5))
- tools/selfcheck_ingest.py:新增 preflight 中文檔名放行 / 非 raw 擋下的檢查
- tools/selfcheck_search.py:新增與既有頁共用核心詞的測資,鎖住 idf 退化
- tools/convert/selfcheck.py、tools/selfcheck_lint.py:測資檔名改中文+空格
- AGENTS.md §13.4:新增「測資照現實建,不是照能過建」規則
- README.md §3.2:補 convert 產出應保持未提交、由 ingest 一併 commit 的流程

驗證:四個自檢全數通過;分別移除兩個修法後對應檢查會失敗。

Co-Authored-By: Claude Opus 4.8 <noreply@anthropic.com>
This commit is contained in:
LittleYellow
2026-07-22 07:21:45 +08:00
parent cfd1876359
commit 0b4c2bbb15
8 changed files with 108 additions and 43 deletions

View File

@@ -99,6 +99,13 @@ ollama list # 對照 tasks.ingest.model / tasks.lint.model / tasks.fallba
**前置條件**:須在 `main` 分支、且工作區除 `raw/` 外無未提交變更,否則會報錯中止。
> **`convert` 的產出請保持未提交,不要另開分支 commit。** 除 `raw/` 外無未提交變更的條件
> 刻意把 `raw/` 排除在外——正確流程是在 `main` 上 `convert`、確認 `raw/converted/*.md` 內容
> 無誤後直接 `ingest`,由 ingest 把來源與編譯出的 wiki 頁**一起** commit 進同一個分支。這樣
> PR 的 diff 同時含來源與產出,審核者才能對照 LLM 有無編譯錯誤。若先開分支 commit 了轉換檔,
> 切回 `main` 時那些檔案會隨分支離開工作區;此時請先 `git merge` 該分支回 `main` 再攝入
> `raw/` 不受 §1.5 HITL 閘門管轄,該條只規範 wiki 層變更)。
執行後:變更落在 `ingest/<時間戳>-<slug>` 分支。有 remote 時自動 push 並印出 PR 建立網址;
無 remote / 離線時分支保留本地,請手動 push 後開 PR。**經人工審核合併後才進 main。**