diff --git a/cypher-executor/src/routes/portal-data.ts b/cypher-executor/src/routes/portal-data.ts index dabaf9d..035d0cc 100644 --- a/cypher-executor/src/routes/portal-data.ts +++ b/cypher-executor/src/routes/portal-data.ts @@ -225,7 +225,26 @@ portalDataRouter.get('/portal/data/search', (c) => if (!libraries.includes('*')) params.set('library', libraries.join(',')); // 透傳的只有「在權限範圍內再收窄」的 filter;owner_id/library 上面已由 server 定死, // caller 傳什麼都不看(URLSearchParams 是新建的,蓋不掉)。 - if (c.req.query('mode') === 'semantic') params.set('mode', 'semantic'); + if (c.req.query('mode') === 'semantic') { + params.set('mode', 'semantic'); + // 🔴 t183(leo 08-04 實撞:「語義搜尋搜到一大堆不相關的內容」 + // ——搜「火星座標」卻跑出 n8n 版本比較表、Leo 填答): + // Vectorize 會**硬湊滿 topK 筆**,湊不到就把低分的塞進來 ⇒ 尾巴全是無關內容。 + // kbdb 早就支援 min_score(`kbdb/src/embed.ts:225`,issue #67), + // 但 portal **從來沒傳** ⇒ 等同沒有閾值,低分尾全端到用戶面前。 + // + // 0.75 怎麼來的(**實測分數分布,不是猜的**;youlin 實例搜「火星座標 奧林帕斯山」): + // 0.908 / 0.881 / 0.881 / 0.880 / 0.870 / 0.815 / 0.798 / 0.787 ← 全是火星座標,真相關 + // ─────────────────────── 斷崖 ─────────────────────── + // 0.742 姨媽說故事 / 0.740 ax-academy / 0.739×8 n8n 版本比較表 ← 全是雜訊 + // 斷崖落在 0.787 與 0.742 之間 ⇒ 取 0.75:相關的全留、雜訊全砍。 + // + // 允許前端覆寫(想放寬看更多可傳 min_score),但**不接受 0/負數** + // ——那等於關掉閾值,正是這次要修的病本身。 + const msRaw = Number(c.req.query('min_score')); + const minScore = Number.isFinite(msRaw) && msRaw > 0 && msRaw < 1 ? msRaw : 0.75; + params.set('min_score', String(minScore)); + } const entryType = c.req.query('entry_type'); if (entryType) params.set('entry_type', entryType); const limit = c.req.query('limit');