# 把知识库应用做成能定位错误的系统

原文: https://yishto.com/learn/ai-foundations/retrieval-orchestration-and-knowledge-apps/

作者: [Yishto](https://yishto.com/about/)

把知识应用拆成采集、检索、生成与审计，核对片段来源、权限、无答案和框架状态，定位错误发生的阶段。

首次发布: 2026-11-10
内容更新: 2026-11-10

知识助手回答错了，原因可能是文档没采集到、切分丢掉上下文、检索选错片段，或生成阶段没有遵守证据。把全部过程包成一个“RAG 调用”，很难知道该修哪一步。系统应保留足够的阶段信息，让错误可以定位，同时不把私有正文写入普通日志。

案例有两个虚构资料空间 T-1 与 T-2，各有一份文档。用户只被授权访问 T-1。即使检索候选包含 T-2 的文档，也不能把它交给用户或不应访问它的模型上下文。

## 采集与查询是两条不同流程

采集流程读取来源、解析、切分、保存元数据、计算表示并建立索引。查询流程处理问题、选择检索条件、取候选、排序、组装证据、生成与校验答案。某条查询成功不证明所有来源已经索引，某次索引成功也不证明答案正确。

RAG 原论文把参数化模型与外部非参数记忆结合，用于知识密集任务。现代应用会采用不同检索与生成安排，不能把一次向量搜索都视作与论文实现完全相同。共同需要处理的是外部材料怎样成为回答证据。

为每一步规定输入输出与版本。采集记录来源 ID、内容版本、解析状态和索引版本；查询记录问题版本、权限范围、候选 ID、排序信息与回答状态。元数据帮助调查，原文和敏感问题内容应按独立访问规则处理。

## 文档切分要保留可解释上下文

切片太小可能把条件与结论分开，太大可能混入无关内容并消耗窗口。标题、表格、代码和跨页段落有不同结构，应先用代表性文档检查解析质量，再调整切分。字符长度的统一阈值不能自动保证语义完整。

每个片段保存文档 ID、片段 ID、版本、位置与必要标题路径。引用应能回到实际来源。文档更新后要决定哪些片段失效、何时替换索引，以及查询期间如何防止混用不同版本。

embedding 将内容映射到数值表示，向量相似度只表达某种表示空间里的接近，不证明片段支持问题的结论。关键词检索、过滤与重排序可补充不同线索，应根据任务样本判断组合效果，而非给技术排统一名次。

## 权限必须在证据暴露前生效

租户、文档与共享范围要来自可信身份和资源规则。检索过滤可以减少跨空间候选，但仍要验证所有将要交给模型、用户与日志的结果。等模型生成答案后再删除私有文档引用，已经无法撤回进入上下文的信息。

下面只过滤候选 ID，忽略未知文档并保留 T-1 的结果。它假定 retrieved 中的 ID 都是字符串，tenant 已由可信认证流程确定。

```python
documents = {"D-1": {"tenant": "T-1", "text": "policy"},
             "D-2": {"tenant": "T-2", "text": "private"}}
def permitted(retrieved, tenant):
    return [doc_id for doc_id in retrieved
            if doc_id in documents and documents[doc_id]["tenant"] == tenant]
assert permitted(["D-2", "D-1"], "T-1") == ["D-1"]
assert permitted(["D-2"], "T-1") == []
assert permitted(["D-missing"], "T-1") == []
print(permitted(["D-2", "D-1"], "T-1"))
```

实际输出是 `['D-1']`。D-2 属于 T-2，被排除；只有 D-2 或只有未知 ID 的候选得到空结果。函数没有做向量搜索、身份认证或完整权限引擎，只检查租户字段。

真实共享策略可能涉及文档级权限、组成员、撤销与继承。权限变化需要及时反映到索引与缓存，并在最终读取时复核。按问题文本缓存答案时，还要包含权限与资料版本等必要差异，不能让一个用户的答案被无条件共享。

## 没有证据与矛盾证据都要有路径

检索无结果时，应返回无法依据当前资料回答，或者请求更具体问题。低分候选不一定无关，高分候选也不一定有答案，阈值要用标注样本验证。不要用默认知识补写一个看似来自资料库的答案。

多份材料冲突时，保留版本、日期与适用范围，按明确优先规则选择，或者提示冲突并复核。过时内容即使检索相似度很高，也可能不适用于当前问题。答案应引用支持具体主张的片段，而不是随意附一条相关链接。

生成阶段要区分直接证据、推断与未知。格式校验能检查引用 ID 是否存在，事实支持还需要核对文本。模型评审可以帮助扩大检查，但应和人工标签比较，不能把一个模型的认可视为绝对事实。

## 编排框架提供不同控制方式

LangGraph 用状态、节点与边组织流程，并提供持久化、流式和中断等能力，适合需要明确状态演进的任务。它不替应用规定提示或全部 Agent 架构。持久执行也不意味着外部副作用自动只执行一次。

LlamaIndex 提供采集与检索等抽象，选择时要核对当前版本与具体集成。Dify 的 Workflow 与 Chatflow 通过可视节点组织模型、检索与分支，两种应用形式有不同交互用途。框架可以减少连接工作，权限、评估、版本与运营仍需设计。

比较时先写要求：是否需要自定义重排、复杂恢复、人工中断、独立测试、团队维护与部署控制。再用一个小任务核对抽象能否暴露所需信息。不要因为演示流程能回答，就宣称它已经满足资料隐私和故障恢复要求。

## 按阶段评估与观测

采集检查可解析率、缺失段落与更新延迟；检索检查相关证据是否进入候选及排序；回答检查支持、遗漏与无答案处理；权限检查跨用户与撤销。分开记录能避免把所有错误都归给生成模型。

保留失败样本的文档与配置版本，修复后重放。记录候选 ID、必要分数、模型版本与耗时即可满足部分调查，不必默认保存整段私有正文。观测数据访问也要限制，删除资料时应考虑相关派生记录。

失败恢复包括重建部分索引、替换坏解析结果、停止某个来源与退回旧工作流。每个动作要说明影响哪些查询，并验证恢复后的证据版本。仅重启服务不能修复已经进入索引的错误内容。

## 练习：把错误送到对应阶段

准备有答案、无答案、过时、相互矛盾、解析缺失与跨租户六类合成资料。为每个问题保存期望证据与拒绝规则，分别检查采集、候选、答案和权限。

验收时，私有资料不会进入未授权上下文；无答案不会虚构来源；引用能回到正确版本；解析失败能区别于检索失败。模拟更新与撤销，确认缓存与索引按规则失效。本文过滤函数只证明候选的租户规则，检索质量与完整框架运行应另行测试。

## 资料来源与延伸阅读

- [Retrieval-Augmented Generation for Knowledge-Intensive NLP Tasks](https://arxiv.org/abs/2005.11401)
- [Stateful graph orchestration](https://docs.langchain.com/oss/python/langgraph/overview)
- [Retrieval and query engine concepts](https://docs.llamaindex.ai/en/stable/getting_started/concepts/)
- [Workflow and Chatflow](https://docs.dify.ai/en/cloud/use-dify/build/workflow-chatflow)

资料核验：2026-11-10。教学示例不代表线上实测。

## 相关文章

- [RAG 的最小闭环：检索、证据、回答](https://yishto.com/learn/rag/retrieval-pipeline/)
- [如何评估 RAG：把检索和回答分开检查](https://yishto.com/learn/rag/rag-evaluation/)
