fix(kbdb): search keyword 補 source filter(#66)+semantic 曝 top_k/min_score、entry 附 score(#67) #70

Closed
Leo wants to merge 0 commits from fix/search-source-filter-and-semantic-threshold into main
Owner

修 kbdb /entries/search 兩個已核實檢索缺口(雲端總管交辦,B 類平台維護)。關聯 #66 #67。

#66 keyword 路徑 source 參數解析後丟棄

根因routes/entries.ts 有解析 source,但 keyword 分支呼叫的 searchEntriesactions/entry-crud.ts)函式簽名根本沒有 source 參數——解析完即丟。#5.1 只接了 listEntries 那半;semantic 分支走 Vectorize metadata filter 本來就正常,唯獨 keyword 漏。

修法

  • searchEntries 尾端source?: string(positional 參數不動順序,全 repo grep 過 caller——kbdb route 兩處+測試兩處,既有呼叫點一個都不用改)。
  • conds 補與 listEntries #5.1 同款謂詞:json_extract(metadata_json, '$.source') = ?
  • route keyword 分支與 semantic 降級分支兩處傳入(降級不洩 filter)。

#67 semantic 固定 topK=20、零分數閾值

根因embed.ts topK: Math.min(opts.topK ?? 20, 100) 寫死預設、matches 全量 hydrate 回傳,低分尾硬湊 20 筆全是無關內容;route 也未曝任何參數。

修法

  • route 增 query 參數 top_k(預設 20、封頂 100)與 min_score(預設 0=不過濾)。壞值(非數字/非正)視同沒帶回預設、不 400——與其他 filter「壞值靜默忽略」慣例一致。
  • semanticSearchmin_score opt,依 score >= min_score 截低分尾(過濾放查詢端,Vectorize API 無此參數)。
  • semantic 回應的 entry 附 score 欄(加欄不改形:entries/count/mode 結構不變,console/portal/rag_chat 既有 caller 不解析多的欄位不受影響)。

向後相容

  • 不帶 sourcetop_kmin_score 時,SQL 與輸出行為與現況一字不變(semantic 僅多 score 資訊)。
  • 不動表(KBDB D6):source 走既有 metadata_json TEXT 欄的 json_extract,零 migration、零 schema 變更。
  • API-as-Wall:只改查詢邏輯,不碰 D1 結構。

測試(誠實回報)

  • 新增 kbdb/tests/search-source-and-score.test.ts 13 條:source 謂詞形狀/route 下傳/semantic 降級仍套 source/min_score 截斷/topK 透傳與封頂 100/壞值防呆/不帶參數行為不變/keyword 不受新參數影響。
  • 實跑結果npx vitest run 33/33 全綠(4 檔含既有 20 條無回歸);npx tsc --noEmit 0 錯
  • 未跑:miniflare/真 D1 的 json_extract 實際語意(測試手法同 library-filter.test.ts 先例——fake D1 只驗 SQL 形狀;json_extract source 謂詞與 #5.1 listEntries 已上線同款,風險低)。未跑 wrangler dev 端到端。

部署提醒

merge 後需 gated redeploy kbdb worker(leo 閘)——本 PR 不含任何部署動作。

修 kbdb `/entries/search` 兩個已核實檢索缺口(雲端總管交辦,B 類平台維護)。關聯 #66 #67。 ## #66 keyword 路徑 source 參數解析後丟棄 **根因**:`routes/entries.ts` 有解析 `source`,但 keyword 分支呼叫的 `searchEntries`(`actions/entry-crud.ts`)函式簽名根本沒有 source 參數——解析完即丟。#5.1 只接了 `listEntries` 那半;semantic 分支走 Vectorize metadata filter 本來就正常,唯獨 keyword 漏。 **修法**: - `searchEntries` **尾端**加 `source?: string`(positional 參數不動順序,全 repo grep 過 caller——kbdb route 兩處+測試兩處,既有呼叫點一個都不用改)。 - conds 補與 `listEntries` #5.1 同款謂詞:`json_extract(metadata_json, '$.source') = ?`。 - route keyword 分支與 semantic 降級分支兩處傳入(降級不洩 filter)。 ## #67 semantic 固定 topK=20、零分數閾值 **根因**:`embed.ts` `topK: Math.min(opts.topK ?? 20, 100)` 寫死預設、matches 全量 hydrate 回傳,低分尾硬湊 20 筆全是無關內容;route 也未曝任何參數。 **修法**: - route 增 query 參數 `top_k`(預設 20、封頂 100)與 `min_score`(預設 0=不過濾)。壞值(非數字/非正)視同沒帶回預設、不 400——與其他 filter「壞值靜默忽略」慣例一致。 - `semanticSearch` 增 `min_score` opt,依 `score >= min_score` 截低分尾(過濾放查詢端,Vectorize API 無此參數)。 - semantic 回應的 entry 附 `score` 欄(**加欄不改形**:entries/count/mode 結構不變,console/portal/rag_chat 既有 caller 不解析多的欄位不受影響)。 ## 向後相容 - 不帶 `source`/`top_k`/`min_score` 時,SQL 與輸出行為與現況一字不變(semantic 僅多 score 資訊)。 - **不動表(KBDB D6)**:source 走既有 `metadata_json` TEXT 欄的 json_extract,零 migration、零 schema 變更。 - **API-as-Wall**:只改查詢邏輯,不碰 D1 結構。 ## 測試(誠實回報) - 新增 `kbdb/tests/search-source-and-score.test.ts` 13 條:source 謂詞形狀/route 下傳/semantic 降級仍套 source/min_score 截斷/topK 透傳與封頂 100/壞值防呆/不帶參數行為不變/keyword 不受新參數影響。 - **實跑結果**:`npx vitest run` **33/33 全綠**(4 檔含既有 20 條無回歸);`npx tsc --noEmit` **0 錯**。 - 未跑:miniflare/真 D1 的 json_extract 實際語意(測試手法同 library-filter.test.ts 先例——fake D1 只驗 SQL 形狀;json_extract source 謂詞與 #5.1 listEntries 已上線同款,風險低)。未跑 wrangler dev 端到端。 ## 部署提醒 **merge 後需 gated redeploy kbdb worker(leo 閘)**——本 PR 不含任何部署動作。
Leo added 1 commit 2026-07-19 07:54:17 +00:00
#66:/entries/search keyword 路徑 source 解析後丟棄(#5.1 只接了 listEntries 那半)——
searchEntries 尾端加 source?(既有 positional caller 全不用改),conds 補與 listEntries
同款 json_extract(metadata_json,'$.source') 謂詞;route keyword 分支與 semantic 降級
分支兩處傳入。

#67:semantic 固定 topK=20、零分數閾值、低分尾硬湊數——route 曝 top_k(預設 20、封頂
100)與 min_score(預設 0=不過濾)query 參數;semanticSearch 依 min_score 截低分尾;
semantic 回應 entry 附 score 欄(加欄不改形)。壞值(非數字/非正)視同沒帶,不 400。

向後相容:不帶新參數時輸出與現況一致(semantic 僅多 score 資訊);不動表(D6)、
不動 D1 結構(API-as-Wall)。測試:新增 search-source-and-score.test.ts 13 條
(source 謂詞形狀/route 下傳/降級不洩 filter/min_score 截斷/topK 透傳封頂/壞值防呆/
不帶參數行為不變),kbdb vitest 33/33 綠、tsc 0。

關聯 #66 #67。merge 後需 gated redeploy kbdb worker(leo 閘)。

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01JUmjwkHLVBHM3ydhT1WSW3
Author
Owner

關閉說明(總管):本 PR 的 commit 65d85eb 因目錄共用事故已隨 docs push 先行上了 main(總管與 subagent 共用同一 clone、總管 push HEAD:main 時帶上了分支 commit——流程破口,教訓已記頂層 wiki)。總管已事後逐項審:兩呼叫點 source 傳遞正確、謂詞與 listEntries #5.1 同款、min_score/top_k 向後相容、33/33 測試綠 tsc 零錯——審核通過,main 上的版本留用

#66/#67 保持 open 直到 gated redeploy kbdb worker(leo 閘)+live 驗證後才關。

**關閉說明(總管)**:本 PR 的 commit `65d85eb` 因目錄共用事故已隨 docs push 先行上了 main(總管與 subagent 共用同一 clone、總管 `push HEAD:main` 時帶上了分支 commit——流程破口,教訓已記頂層 wiki)。**總管已事後逐項審**:兩呼叫點 source 傳遞正確、謂詞與 listEntries #5.1 同款、min_score/top_k 向後相容、33/33 測試綠 tsc 零錯——**審核通過,main 上的版本留用**。 #66/#67 保持 open 直到 **gated redeploy kbdb worker(leo 閘)**+live 驗證後才關。
Leo closed this pull request 2026-07-19 07:56:12 +00:00

Pull request closed

Sign in to join this conversation.