WeKnora 回答溯源

回答里的出处不直接把真实块 UUID 交给模型,也不信任模型手写的 <kb chunk_id="...">。WeKnora 在单次请求内把来源登记为短别名(如 c1、w1),要求模型只输出 <ref id="cN"/>;流式生成后再由系统展开成真实块引用。用户侧「点到原文」的主路径是 chunk_id → 块上存的文本;不同类型文件(MD、PDF、Office 等)在入库时已被抽成同一套文本块,呈现时再按类型决定是弹块内容、拼全文,还是另开原件预览。

方案怎么做

别名怎么来、cN 怎样变成 chunk_id

检索结果(或 Agent 工具结果)进入模型前,注册表 RegisterChunk:

  1. 按本请求内首次登记顺序编号 :第 1 个新块 → c1,第 2 个 → c2......即 c%d = 当前已登记别名数 + 1。
  2. 不是 按文档里的 chunk_index、也不是按库表插入顺序。
  3. 同一 chunk_id 再出现只复用原别名,避免 Agent 多轮里同一块多个号。
go 复制代码
// internal/llmreference/registry.go
if existing := r.chunkByID[ref.ChunkID]; existing != nil {
    return existing.Alias // 复用
}
ref.Alias = fmt.Sprintf("c%d", len(r.chunkByAlias)+1) // 顺序递增

网页同理为 wN。展开时查 chunkByAlias,写成 <kb doc="..." chunk_id="真实UUID" ... />;未知别名与模型伪造的 <kb> 丢弃。别名仅存活于本次助手回答。

从 chunk 回到「原文」:各类型怎么呈现

先分清两层对象:

层 是什么
检索/引用层 库里的 Chunk:chunk_id + content + start_at/end_at(在解析后文本流上的字符区间)
原件层 用户上传的 MD / PDF / DOCX 等文件本身

入库时 DocReader 等会把 PDF、Office 等先抽成 Markdown/纯文本,再分块;开源路径里 角标溯源默认先落到块文本 ,并不依赖拿 start_at 去 PDF 页上画红框。页级/框级高亮是另一类能力(见下文 PDF),技术上可做,部分基于 WeKnora 的产品已经做得更细。

用户点引用后的共同路径(关键)

找到 chunk_id 之后,并不是 再打开「全文 MD」、用 start_at 滚到某一行高亮。产品把该块自己存下的 content 当作可展示的原文片段:

text 复制代码
<ref id="cN"/> → 展开 chunk_id
  → 悬停:GET 该块 → 浮层直接渲染 chunk.content(这一段就是给用户看的「原文」)
  → 点击:引用面板按 chunk_id 高亮列表项,展开的仍是检索时带上的块文本 / snippet
  → 另开文档抽屉:可看「分块列表 / 拼出来的全文 / 原件预览」------与角标「精确定位到全文第 N 字」不是同一条链路

所以 MD 也一样:定位主键是 chunk 记录,不是全文里的光标位置。 start_at/end_at 不参与「点引用 → 滚到全文某处」。

那 start_at 干什么用?「全文」又是什么?

入库切分时,start_at/end_at 记在当时那份文本流 上的字符区间,主要用于块列表排序、合并时估重叠窗口------不用于点引用时跳转到全文某处。

文档抽屉里的「全文」视图,本质是 多块相邻拼接、去掉重叠,凑出一篇可读长文:

text 复制代码
块1.content  +  块2.content  +  块3.content  + ...
     │              │
     └─ 按 start_at 排序
     └─ 相邻若有公共后缀/前缀 → 文本重叠匹配去掉重复再接上
     └─ 中间有明显间隙 → 空行硬接
            ↓
      拼出来的「全文」(给用户通读)

要点:

  • 凑的是各块里已存的 content ,不是再打开磁盘上的 MD/PDF,用 [start_at:end_at] 去切现行文件。
  • 分块本身常带 overlap,所以必须去重拼接,否则全文会重复段落。
  • 点引用角标不走这条路 :角标只展示那一个块 的 content;「拼全文」是抽屉里另开的通读能力,不会先拼完全文再在里面二次定位该块。

文章改了,start_at 会不会不准?

会。偏移绑定的是分块当时 的文本;源文件变更后若未重新解析/分块,旧区间相对新文件就会漂。但角标展示走的是块里快照式的 content,不依赖拿现行文件按旧偏移去切,所以「点引用看到的那段话」仍是入库(或上次索引)时的块内容。要与最新原文一致,需要重新处理文档生成新 chunk;这也是不做「全文内字符级跳转」的原因之一------偏移体系本身怕文档漂移。

按类型:定位与呈现

类型 chunk 里有什么 点引用时用户看到什么 start/end 与「全文」
Markdown / 纯文本 对源 MD/TXT 分块;content≈当时原文片段 直接展示该块 content;不在全文里二次定位 排序 + 相邻块去重拼接成「全文」视图
PDF(电子页) 内置路径从文字层抽出 MD 再分块;content 接近可选中文本 开源默认 :浮层/引用面板展示抽取块文本;抽屉可用 iframe 预览整份 PDF,不按 chunk 跳页画框。若解析写入页码,前端用文字层匹配/坐标,即可做到「第几页 + 高亮那段字」(腾讯 ima 等基于 WeKnora 的产品已有类似回溯高亮) 开源里 start_at 主要在抽取 MD 上;页级能力要另存 page/bbox 或页内文本映射
PDF(扫描页) 页先渲染成图写入 MD(scanned_pdf),可检索正文多来自后续 VLM OCR / 配文子块 开源默认 :角标常落到 OCR 子块(识别稿)。若 OCR/版面引擎同时产出页码 + 文字框,预览可在页图上画框回标;纯「整页图 → 一段无框 OCR 文本」则很难精到框 比电子页多一跳「图 → 认字 → 子块」;框级回溯取决于 OCR 是否带几何信息,不是 chunk 文本本身自带的
DOCX / PPT / 表格等 同样先抽取再分块 引用侧看块文本;抽屉可预览原件 拼全文 / 原件预览两条线,引用不映射版心坐标
FAQ / 无文件知识 块即问答条目 浮层直接展示条目文本 无文件原件;一般不谈拼全文
网页引用 wN 无 chunk,展开为 <web url> 打开/展示 URL 不走 chunk 区间

同一份 PDF 里电子页与扫描页可以混排(见《WeKnora 文档解析》):电子页走文字块,扫描页走图片 + OCR 子块。开源默认溯源都是 chunk_id → 块 content,但块里装的「原文」来源不同------一个是抽字,一个是认字。

text 复制代码
MD/TXT:        文件 ≈ 文本流 ≈ chunk.content → 单块即片段;多块去重拼接 ≈ 通读全文
PDF 电子页:    文字层 → MD → text chunk → 开源默认看抽取稿;
               增强:页码 + 文字层匹配/bbox → 预览内跳页高亮(如 ima)
PDF 扫描页:    渲染图 → OCR/配文子块 → 开源默认看识别稿;
               增强:OCR 带页码+框 → 页图上画框;无框则难精到「哪个框」

开源默认 vs 产品增强(PDF)

  • 开源 WeKnora:引用主路径是块文本;PDF 预览多为整文件打开,公开前端路径里未见「按 chunk 跳页 + 页内红框」的完整闭环。解析里出现的 bbox 更多用于抽图裁剪,不是引用回标协议。
  • 可实现,且部分产品已做 :电子版用文字层定位相对直接;扫描版要 OCR/版面输出几何信息。腾讯 ima 等基于 WeKnora 的产品已能在回溯时高亮原文,属于在统一 chunk 之上叠加的阅读器能力。

提升了什么

别名协议把「能否引用」收成系统查表;开源呈现侧用统一的 chunk 文本 覆盖多文件类型,先保证「这段话从哪块来」。MD 接近「块即原文」;PDF/Office 默认「读内容看块、看版式看预览」。页级高亮作为可选增强层,不挡主链路落地。

好处与代价

好处

  • 降低模型编造出处;展开失败则标签消失。
  • Agent 多轮同块别名稳定;角标与引用面板可分开控制。
  • 多格式共用一套 chunk 溯源;页内高亮可按产品需要叠加,不必绑死开源默认路径。

代价

  • 流式标签需缓冲;自定义提示可能干扰 <ref> 协议。
  • cN 是当次登记序,跨请求不能说「还是 c3」。
  • 开源默认:PDF 电子页精到抽取段落,扫描页精到 OCR 子块------还不是「第几页哪个框」。要页/框级需改元数据与 PDF 阅读器;扫描页还受识别质量影响,角标文案可能与肉眼看页有出入。
  • 全文合并依赖文本重叠,极端脏数据拼缝可能不完美。

基于 WeKnora v0.7.0

上一篇:WeKnora 上下文管理 | 下一篇:WeKnora 模型接入

相关推荐
智驭未来掌门人1 小时前
在 CLion 里创建 Qt 项目,真正需要想清楚的是什么
后端
数据库小学妹1 小时前
MySQL MDL锁等待排查:DDL卡住与长事务定位
数据库·后端·mysql
全栈弄潮儿1 小时前
Python实战第13期:模块与包
后端·python·编程语言
Thneonl1 小时前
ClickHouse UPDATE:一秒返回,三小时才生效
数据库·后端
LuHang2 小时前
Vue3 大屏项目 MQTT 实战:机场与无人机 OSD 实时数据总线
前端
2401_885885042 小时前
芬兰语音通知接口怎样对接?语音提醒接入流程
android·前端·python·php·语音识别
铁皮饭盒2 小时前
这6个小模型各有绝活, 且都可cpu/浏览器端运行
前端·后端
徐小夕2 小时前
JitKnow AI知识库 4.7 发布|多文档推理+拖拽 Agent + 技能库,打造更懂业务的 AI 知识中台
前端·vue.js·github
掘黄金的打工人2 小时前
AI-Agent python
agent·ai编程