调用链追踪

RAG/LLM 调用链 span 树:query → 检索(展开体内嵌命中列表与分数条)→ 重排 → 生成的嵌套耗时条(宽度按同级最大耗时占比),error / running 分支默认展开,展开体自动渲染 detail、usage(↑↓ tok / $ 成本)与错误原因。initKbTrace 为 document 级委托(click 选中+折叠 / Enter / Space),动态插入免重跑;事件 icen:kb-trace-select / icen:kb-trace-toggle。数据经 kb-core normalizeSpans 归一(父先子后、孤儿容忍为顶层)。

点击行选中并折叠子 span · error 分支默认展开 · 展开「检索」span 看内嵌命中与分数条(无分命中显示「—」)

<div id="kb-trace-demo"></div><p class="demo-label" id="kb-trace-log" style="margin-top:8px">点击行选中并折叠子 span · error 分支默认展开 · 展开「检索」span 看内嵌命中与分数条(无分命中显示「—」)</p>

安装

bun add @icen.ai/ui

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

import { initKbTrace } from '@icen.ai/ui/kit/kb-trace';initKbTrace();

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

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

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

用法

import { renderKbTrace, initKbTrace } from '@icen.ai/ui/kit/kb-trace'; initKbTrace();   // document 级委托(click / Enter / Space),幂等 + 返回销毁函数 renderKbTrace(el, [  { id: 'q1', kind: 'query', name: '差旅报销上限是多少?', status: 'done', elapsedMs: 2380 },  { id: 'r1', parentId: 'q1', kind: 'retrieval', name: 'hybrid search', status: 'done', elapsedMs: 340,    hits: [{ chunkId: 'c-412', snippet: '单笔 5000 元以上需审批', score: 0.87, scoreKind: 'hybrid' }] },  { id: 'rr1', parentId: 'r1', kind: 'rerank', name: 'bge-reranker', status: 'done', elapsedMs: 180 },  { id: 'g1', parentId: 'q1', kind: 'generation', name: 'glm-4.6', status: 'done', elapsedMs: 1520,    usage: { inputTokens: 1240, outputTokens: 380, costUsd: 0.0021 } },  { id: 't1', parentId: 'q1', kind: 'tool', name: '联网检索兜底', status: 'error',    error: '上游 502(已跳过,不影响主链路)' },]);// 展开体按需渲染 detail / usage / hits / error;kind 枚举见 kb-core(检索/生成/重排/向量化/工具/护栏…)el.addEventListener('icen:kb-trace-toggle', (e) => console.log(e.detail.spanId, e.detail.open));