召回测试

createKbHitTest 召回回归测试集:问题列表(pin 置顶 / 期望 chunk chips(超 3 折 +N)/ 最近结果 ✓✗— / 删除)+ 新增问题 + 「运行全部」。passed 由 lastHits ∩ expectedChunkIds 派生(不信任外部传入);统计头走 hitTestStats(命中率 null = 未跑过而非 0),renderKbHitStats 可脱离列表单独渲染;徽标「参数仅本次会话生效」。

「运行全部」→ 300ms mock 检索逐题回填 lastHits(期望命中在前排 → ✓,否则 ✗)· Enter 新增问题 · pin 图标置顶固定

<div id="demo-kb-hittest"></div><p class="demo-label" id="kb-hittest-log" style="margin-top:8px">「运行全部」→ 300ms mock 检索逐题回填 lastHits(期望命中在前排 → ✓,否则 ✗)· Enter 新增问题 · pin 图标置顶固定</p>

安装

bun add @icen.ai/ui

一行引入该组件(CSS 与 behavior 自动带上,无需关心内部 CSS 文件名):

import '@icen.ai/ui/kit/kb-hittest';

也可以用脚手架直接打印引入行:

bunx --bun @icen.ai/ui add kb-hittest

Astro 项目注意:kit 入口里的 CSS import 在页面 <script> 里会被 Astro 的 client bundle 摇掉——请改在布局 frontmatter 里引 CSS(import '@icen.ai/ui/components/kb-search.css';),JS 行为仍可走 kit。Vite SPA / webpack 项目无此问题。

用法

import { createKbHitTest, renderKbHitStats } from '@icen.ai/ui/kit/kb-hittest';import { hitTestStats } from '@icen.ai/ui';   // kb-core 纯函数(主入口同源) const handle = createKbHitTest(el, {  cases: [    { id: 'q1', question: 'Q3 华东销售额为什么下滑?', expectedChunkIds: ['chunk-001'], pinned: true },    { id: 'q2', question: '供应商切换对交付周期的影响?', expectedChunkIds: ['chunk-052'] },    /* … */  ],  onRun: (cases) => {    // 检索由宿主执行(测试参数仅本次会话生效),跑完 setCases 回填 lastHits    const next = cases.map((c) => ({ ...c, lastHits: runRetrieval(c.question) }));    handle.setCases(next);           // passed 在内部按交集派生  },}); // 统计头单独复用:命中率大数字 + 均分 + 通过 x/y(未跑 hitRate 为 null →「—」)renderKbHitStats(el, hitTestStats(cases));