知行札记
专题技术实践AI 工程实践

知识库与引用实现

保存原文与权限,建立可更新的索引,并把检索结果转成可以核对的证据。

先给原文、段落与索引分别编号

一份文件可能多次更新,也可能以不同解析器生成文本。保存文件 ID、原始文件哈希、来源 URL、内容版本、解析器版本和访问控制;段落保存原文版本、页码或字符范围、标题路径。索引条目进一步保存 embedding 模型、维度、分块策略与索引版本。

这样能回答三个不同问题:用户引用的是哪份资料,模型看到的是哪段解析结果,检索用的是哪个版本的向量。只保存向量和一个文件名,无法重建失效引用、删除泄漏或解析错误。

{
  "documentId": "doc-17",
  "revision": "rev-3",
  "chunkId": "doc-17:rev-3:p4:2",
  "page": 4,
  "headingPath": ["部署", "备份"],
  "text": "每日增量备份保留七天。",
  "embeddingModel": "configured-embedding-model",
  "indexVersion": "index-6"
}

这是一条虚构的索引记录示例。资源权限可以存入索引以便过滤,也要保留在权威资源服务中核对;文档 ACL 变化时按更新策略同步或强制查询实时权限。

解析和分块以任务为依据

PDF 扫描页需要 OCR;复杂表格需要保留列标题与跨页关系;代码需要保持函数与路径;Markdown 可以沿标题层级分块。把每一类文件用相同字符长度机械切开,容易把结论与条件、表头与单元格分离。

先检查抽样解析结果,再建立小范围检索集。分块长度按目标 tokenizer 与检索任务选择,记录正文长度、元数据长度和 overlap;overlap 增加存储与重复召回。小块检索后扩展到父段落,通常需要保存稳定的父子关系。语义分块、late chunking、上下文补写各自引入新模型或额外计算,进入索引配置后应保留版本。

向量库已有 Postgres 时可以评估 pgvector;独立搜索服务或托管方案按团队条件选择。无论接口是 SQL、REST 还是框架 Retriever,必须支持权限、过滤、分页、删除和版本切换。pgvector 官方仓库 描述 exact/approximate 搜索与索引条件;真正容量需要以维度、过滤和读写负载测量。

客户端与数据库接线

TS 接线可以使用 AI SDK embedMany 加目标数据库官方客户端,或 Mastra/LangChain 的 parser、splitter 和 store 集成。Python 接线可以使用 sentence-transformers 或官方嵌入 API,加 qdrant-client、pgvector、LlamaIndex 或 Haystack。框架 Document 需明确映射上表字段,避免 metadata 在转换时丢失。

以下 SQL 演示 Postgres + pgvector 的单路稠密检索。384 是示例维度,需改为实际模型维度;参数绑定中的 $1 是向量,$2 是服务端已认证租户。索引与距离算子匹配。

CREATE EXTENSION IF NOT EXISTS vector;
CREATE TABLE knowledge_chunks (
  chunk_id text PRIMARY KEY,
  document_id text NOT NULL,
  document_version text NOT NULL,
  tenant_id text NOT NULL,
  body text NOT NULL,
  source jsonb NOT NULL,
  embedding vector(384) NOT NULL
);
CREATE INDEX knowledge_chunks_embedding_idx ON knowledge_chunks
  USING hnsw (embedding vector_cosine_ops);

SELECT chunk_id, body, source, document_version,
       embedding <=> $1::vector AS distance
FROM knowledge_chunks
WHERE tenant_id = $2
ORDER BY embedding <=> $1::vector
LIMIT 20;

应用通过驱动参数绑定执行,禁止把用户输入直接拼入 SQL。近似索引结合过滤可能返回不足的候选,应测量过滤后的召回并核对所用 pgvector 版本的迭代扫描和扫描预算。pgvector 文档。

查询链路逐步保留证据

用户问题先完成鉴权,再确定可检索集合。检索可以组合关键词与向量召回,随后去重、重排,并按 token 预算拼装证据。检索日志保存查询、过滤条件、候选 ID、排序分与最终使用片段。日志本身也要受资料权限和保留策略约束。

生成提示明确“只依据提供资料回答,资料不足时说明未知”,并给每段材料一个应用生成的短引用 ID。模型输出的引用 ID 经过 allowlist 验证后映射回原文位置。对引用的正确性还要检查:该段是否支持相邻断言,是否漏掉限制条件,是否误把旧版本当新规则。

例如两份文档分别规定“测试环境保留七天”与“生产环境保留三十天”,检索只返回第一份时,模型可能回答所有环境七天。检索命中率、回答忠实度与任务正确率必须分别测量;整段引用合法仍可能发生范围误读。

更新、删除与重建维持原子可见性

文档更新先生成新段落和向量,在可用后切换版本;旧版本何时删除按审计与引用需求处理。embedding 模型或维度改变通常需要重新嵌入,不能把不可比较的向量直接混在同一查询空间。索引重建可采用新索引准备好再切换活动指针,减少半成品可见窗口。

删除操作沿原文、段落、向量、关键词索引、缓存、摘要和图谱派生物传播。权限过滤尽量在召回阶段做,并在证据返回前再次核对;仅对最终答案做屏蔽可能已将秘密发送到模型服务。

评测保留问题、期望来源和可回答性标签。用正确证据直接喂模型的对照可以判断生成问题;固定生成器只更换检索器的对照可以判断召回问题。引入 GraphRAG、查询改写或 Text2SQL 后,将新增步骤的错误与费用单独记录。

导入与增强的工程配置

解析器可选 Docling、Unstructured 或 LlamaParse,核对正文是否上传云端。按标题、语法与版面结构切分,512–1024 token 与 10–20% overlap 仅作为归档中的搜索起点。嵌入批量受 token、请求和并发限额共同约束,对失败批次单独重试,使用稳定块身份写入。

Late chunking 需要长输入表示与分块池化的配合;contextual retrieval 需要保存生成的前缀、生成模型及版本。增强结果建成可对照的索引版本,测量收益和新增成本。原理与算法见信息检索。Text2SQL 另设只读入口,限制租户、表列、返回行数和运行时间;错误反馈隐去凭据。

最后更新于

本页目录