问题与数据契约
检索命中相似文本并不代表回答可核验。发布正文、索引正文和用户打开的文章必须属于同一版本。本文讨论单站知识库,公开文章进入检索,私有账户数据不进入公共索引。
记录至少包含 slug、collection、title、content、contentHash、sectionHeading、startLine 和 endLine。正文存储为完整 LONGTEXT,标签存储为 JSON 数组。内容哈希基于原始正文计算;不要对检索文本做归一化后拿它替代发布版本的哈希。
分块与排序边界
先解析 Markdown 语法树,再以 H2/H3 建立父子层次。段落、列表和代码块是原子节点,不能用截取前 1500 字的方法控制长度。特别长的代码块应单独保存,并在上下文装配时明确决定是否纳入,而不是静默截断。
词法检索适合型号、标识符和精确术语;向量检索适合改写问题。两套排名可通过 RRF 合并:每个文档的分数等于各排名中的 1/(k+rank) 之和。它不要求不同检索器的原始分数具有相同尺度,但 k 和候选数量仍需用实际查询集验证。
可运行的排名融合示例
以下代码只演示候选融合,不执行 Embedding,也不代表完整 RAG 系统。
import assert from "node:assert/strict";
function rrf(rankings, k = 60) {
const scores = new Map();
for (const ranking of rankings) {
[...new Set(ranking)].forEach((id, i) =>
scores.set(id, (scores.get(id) || 0) + 1 / (k + i + 1)));
}
return [...scores].sort((a, b) => b[1] - a[1]);
}
assert.equal(rrf([["a", "b"], ["b", "c"]])[0][0], "b");
assert.deepEqual(rrf([]), []);引用与失效处理
引用必须携带版本和段落锚点。页面改版后,旧回答中的引用可能指向新版内容,因此应展示引用时的版本摘要;需要长期证据时,应另存不可变修订。不存在的 slug 返回 404,撤稿内容必须同时从列表、索引和 sitemap 移除。
上线验收应覆盖:中文改写、精确代码术语、无相关资料问题、撤稿、超长代码块和重复标题。记录 Recall@k、引用有效率及拒答样本,不能只展示几个命中截图。本项目当前提供词法基线与结构化分块,Embedding 和重排服务需要独立评测后接入。
原始资料
- Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks:检索与生成结合的研究背景。本文的数据版本和发布检查是工程设计,不是该论文的性能结论。
感谢阅读本文
如果你觉得内容有帮助,欢迎点赞支持或分享给同行开发者。