RAG 知识库智能问答系统设计方案
一、背景与目标
1.1 业务背景
随着企业知识库规模持续扩大,传统单次静态检索(Naive RAG)在召回质量、推理深度、多文档综合能力上已无法满足生产需求。用户提问的多样性远超单一检索策略的覆盖范围,从精确事实查询到跨文档综合分析,需要一套能够感知问题类型、自适应调度检索策略的智能问答系统。
1.2 设计目标
- 准确性:所有回答必须来源于知识库,强制引用溯源,抑制幻觉
- 性能:按问题类型选择最轻量的检索路径,避免无意义的多轮探索
- 完备性:覆盖从精确查找到复杂多跳推理的全部问题类型
- 可靠性:检索失败时有明确的降级策略,不因知识库覆盖不足而崩溃
1.3 设计原则
工具不暴露实现细节 暴露给 Agent 的每个工具必须对应一个 Agent 层面的意图,内部实现(如 rerank、chunk 分割)不作为独立工具暴露。
固定路径优先,动态规划兜底 简单问题走固定流水线保证性能,只有检索路径无法静态确定时才进入 Research 动态规划,避免将所有问题推入高成本的多轮探索。
分类越简单,系统越稳定 问题类别的划分依据是「驱动检索行为的根本差异」,而不是问题的表面形式,类别之间边界清晰,无模糊地带。
二、系统架构总览
2.1 整体架构图
┌─────────────────────────────────────────────────────┐
│ 用户问题 │
└─────────────────────┬───────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 路由层 │
│ Classifier → Query Analyzer │
└──────┬──────────────┬──────────────┬────────────────┘
↓ ↓ ↓
┌──────────┐ ┌──────────────┐ ┌──────────────┐
│ 语义检索 │ │ 关系查询 │ │ Research │
│ 固定路径 │ │ 固定路径 │ │ 动态规划 │
└──────┬───┘ └──────┬───────┘ └──────┬───────┘
↓ ↓ ↓
┌─────────────────────────────────────────────────────┐
│ 执行层 │
│ hybrid_search / keyword_search / graph_search │
│ search_files / query_file / get_file_outline │
│ read_section │
└─────────────────────┬───────────────────────────────┘
↓
┌─────────────────────────────────────────────────────┐
│ 生成层 │
│ Answer Generator → Quality Checker │
└─────────────────────┬───────────────────────────────┘
↓
最终回答
2.2 分层说明
| 层级 | 职责 | 核心组件 |
|---|---|---|
| 路由层 | 意图分类、实体提取、路径决策 | Classifier、Query Analyzer |
| 执行层 | 工具调用、检索执行、结果整合 | 7个工具、Context Builder |
| 生成层 | 回答生成、质量验证、降级决策 | Answer Generator、Quality Checker |
2.3 核心数据流
用户问题
→ Classifier(类别 + 置信度)
→ Query Analyzer(实体 + filters + 路由决策)
→ Query Rewriter / Chain Planner(子查询 / 执行计划)
→ 工具调用(检索结果 + 文件内容)
→ Context Builder(整合 + Token 管控)
→ Answer Generator(回答 + 引用)
→ Quality Checker(验证 → 输出 or 升级)
三、知识库建设
3.1 文件类型支持
| 类型 | 格式 | 章节解析 |
|---|---|---|
| 文档类 | PDF、Word、Markdown | ✅ 支持章节结构提取 |
| 表格类 | Excel、CSV | ❌ 无章节,按行/块处理 |
| 演示类 | PPT | ✅ 按幻灯片分块 |
| 纯文本 | TXT、日志 | ❌ 无章节,按段落/行处理 |
3.2 文档解析与预处理
原始文件
↓ 文档解析(Unstructured.io / LlamaParse)
结构化内容(文本 + 表格 + 图片描述)
↓ 清洗(去除页眉页脚、无效字符、格式噪声)
干净文本
↓ 章节识别(标题层级检测)
章节树(section_id + title + content + page_range)
3.3 分块策略
知识库采用章节级分块为主,语义级分块为辅的双层策略:
章节级分块(有结构化文件)
- 以标题边界为分块依据,保留完整语义单元
- 每个 section 生成唯一 section_id,支持
read_section精准定位 - 同时生成章节摘要,用于
get_file_outline返回
语义级分块(无结构化文件)
- 按段落 / 固定 token 窗口(512 tokens)分块,相邻块保留 64 token 重叠
- 每个 chunk 生成唯一 chunk_id,用于向量和关键字索引
3.4 索引构建
| 索引类型 | 内容 | 用途 |
|---|---|---|
| 向量索引 | chunk / section 内容的 embedding | hybrid_search 语义召回 |
| 关键字索引 | chunk / section 内容的 BM25 倒排 | hybrid_search 关键字召回 / keyword_search |
| 知识图谱 | 实体抽取 + 关系三元组 | graph_search |
| 文件级索引 | 文件名 + 标签 + 摘要的 embedding | search_files |
3.5 元数据设计
每个文件和分块附带以下元数据,用于 filters 过滤:
{
"file_id": "uuid",
"filename": "A公司采购框架合同_2024.pdf",
"date": "2024-03-15",
"department": "法务部",
"tags": ["合同", "采购"],
"path": "/contracts/2024/",
"is_signed": true
}
filters 支持字段:
| 字段 | 类型 | 说明 |
|---|---|---|
| date_range | array | 时间范围,如 ["2024-01-01", "2024-12-31"] |
| department | string | 部门过滤 |
| tags | array | 标签过滤,AND 关系 |
| path_prefix | string | 路径前缀过滤 |
| is_signed | bool | 是否为盖章正式文件 |
四、工具集设计
4.1 设计原则
工具设计遵循一条核心原则:每个工具对应一个且仅一个 Agent 意图,不暴露内部实现细节。
Agent 的意图 对应工具
─────────────────────────────────────────────
"我要检索相关内容" → hybrid_search(内含 rerank)
"我要精确匹配名称" → keyword_search
"我要查实体关系" → graph_search
"我要找相关文件" → search_files
"我要问这个文件" → query_file
"我要看文件结构" → get_file_outline
"我要读某个章节" → read_section
4.2 检索类工具(3个)
| 工具 | 用途 | 适用场景 | 输入来源 |
|---|---|---|---|
hybrid_search | 向量 + 关键字 RRF 融合检索,内置 rerank 精排 | 所有主路径的默认检索工具,覆盖 90% 场景 | Query Rewriter 改写后的查询 |
keyword_search | BM25 关键字精确检索 | Fallback 降级 / Research 链式路径 fan-out 实体过滤 | Fallback 触发 / Chain Planner 生成的实体名 |
graph_search | 知识图谱实体关系多跳检索 | 关系查询主路径 / Research 链式路径第一跳实体枚举 | Query Analyzer 提取的实体名 |
hybrid_search 关键参数:
{
"query": "采购合同付款条款",
"top_k": 8,
"rerank": true,
"rerank_top_k": 3,
"vector_weight": 0.6,
"keyword_weight": 0.4,
"filters": {
"date_range": ["2024-01-01", "2024-12-31"],
"tags": ["合同"]
}
}
4.3 文件操作类工具(4个)
| 工具 | 层级 | 用途 | 输入来源 |
|---|---|---|---|
search_files | 意图层 | 文件级语义检索,返回相关文件列表、摘要及相关性得分 | 用户问题中的文件相关描述 |
query_file | 意图层 | 对指定文件直接问答,内部自动完成章节定位与精读 | 已知 file_id + 自然语言问题 |
get_file_outline | 精读层 | 获取文件全部章节大纲与各章节摘要 | file_id |
read_section | 精读层 | 读取指定章节完整内容,支持同时读取多章 | get_file_outline 返回的 section_id |
search_files 返回示例:
{
"files": [
{
"file_id": "xxx",
"filename": "A公司采购框架合同_2024.pdf",
"relevance_score": 0.92,
"summary": "与A公司签订的年度采购框架协议,含付款、交货、违约条款",
"metadata": { "date": "2024-03-15", "tags": ["合同", "采购"] }
}
]
}
query_file 内部执行逻辑:
query_file(file_id, question)
→ get_file_outline(获取章节大纲)
→ 定位相关 section_id
→ read_section(精读目标章节)
→ 生成针对该文件的回答
4.4 工具调用链规范
主路径(已知目标文件):
hybrid_search(获得 file_id)→ query_file(直接问答)
跨文件对比(需要 Agent 直接操控精读层):
search_files → get_file_outline(多文件)→ read_section(多章节)→ Agent 综合
探索场景:
search_files → 返回文件列表 + 摘要(无需进一步生成)
五、意图分类体系
5.1 分类维度与设计依据
问题分类的目的是决定检索策略,因此分类维度必须是「驱动检索行为的根本差异」,而非问题的表面形式。
三个核心维度:
| 维度 | 说明 |
|---|---|
| 答案构造方式 | 直接提取 / 语义提取 / 图谱提取 / 动态推理 |
| 答案来源分布 | 单一位置 / 单文档 / 图谱 / 多文档未知集合 |
| 检索步骤依赖 | 无依赖 / 并行无依赖 / 串行依赖 |
5.2 类别定义
| # | 类别 | 核心判断标准 | 答案构造 | 来源分布 | 检索依赖 | 典型示例 |
|---|---|---|---|---|---|---|
| 1 | 语义检索 | 答案存在于知识库,单步检索可定位,无论精确还是模糊 | 直接/语义提取 | 单文档内 | 无 | "A合同的付款周期是多少?" / "违约责任怎么规定的?" |
| 2 | 关系查询 | 答案是实体间关系,起始实体已知,需图谱遍历 | 图谱提取 | 图谱结构 | 无 | "B集团旗下有哪些子公司,各做什么业务?" |
| 3 | Research | 检索路径无法静态确定,需 Agent 动态规划,覆盖对比分析、链式推理、跨文档综合、探索导航 | 动态推理/综合 | 多文档(未知集合) | 串行或并行 | "负责制造的子公司违约条款有何差异?" / "有哪些采购相关文件?" |
| — | 超出范围 | 知识库中不存在可回答该问题的内容 | 无需构造 | 无 | 无 | "帮我写首诗" / "明天天气怎么样?" |
5.3 类别边界判断规则
答案是实体间关系,且起始实体已知?
→ Yes:关系查询
→ No:继续
知识库根本不存在相关信息?
→ Yes:超出范围
→ No:继续
检索路径需要动态规划(多步 / 路径不确定)?
→ Yes:Research
→ No:语义检索
混淆对判断:
| 混淆对 | 判断问题 | 结论 |
|---|---|---|
| 关系查询 vs Research | 起始实体已知,且关系本身就是答案吗? | 是 → 关系查询;还需动态规划 → Research |
| 语义检索 vs Research | 一步 hybrid_search 能定位答案吗? | 能 → 语义检索;路径不确定 → Research |
5.4 Classifier 节点设计
模型选型: 使用轻量模型(Haiku / GPT-4o-mini),目标耗时 < 0.5s
输出格式:
{
"type": "semantic | graph | research | out_of_scope",
"confidence": 0.0 ~ 1.0,
"reason": "一句话说明"
}
置信度策略:
- confidence < 0.7 → 保守降级为语义检索
- 用户显式指定意图(如"帮我深度研究...")→ 直接采用,跳过自动分类
六、问答工作流
6.1 总体流程
用户问题
↓
[Classifier]
意图分类:semantic / graph / research / out_of_scope
confidence < 0.7 → 降级为 semantic
↓
[Query Analyzer]
提取实体、时间、部门等信息
生成 filters
确认路由路径
↓
按类别进入对应执行路径
↓
[Context Builder]
整合检索结果
Token 预算管控
↓
[Answer Generator]
生成回答 + 引用标注
↓
[Quality Checker]
验证回答质量
↓
answered?
├─ Yes → 输出
└─ No → Fallback → 仍不足 → 升级 Research → 最多2轮 → 输出
6.2 各类别执行路径
语义检索(~3s)
Query Rewriter(改写为语义化子查询)
↓
hybrid_search(filters 过滤范围)
↓
query_file(针对命中文件问答)
↓
Answer Generator
关系查询(~5s)
graph_search(枚举实体关系)
+
hybrid_search(并行,补充文本细节)
↓
图谱结果建关系框架 + 文本结果填细节
↓
query_file(针对各文件问答)
↓
Answer Generator(分层引用:图谱 + 文本)
Research(8 ~12s)
Chain Planner(生成动态执行计划)
↓
按计划执行:
串行链式(实体范围未知,路径依赖):
graph_search(第一跳,枚举实体列表)
→ keyword_search fan-out(第二跳,过滤目标实体,并行)
→ hybrid_search fan-out(第三跳,各实体召回,并行)
→ query_file × N(各实体分组问答)
并行展开(子问题相互独立):
hybrid_search × N(并行)
→ query_file × N(并行)
探索导航:
search_files → 返回文件列表 + 摘要
↓
综合生成(按子问题 / 实体 / 维度组织输出)
超出范围(<0.5s)
零检索 → 直接告知用户知识库无相关内容
→ 说明可能的原因(问题超出范围 / 建议补充文件)
6.3 升级机制
语义检索和关系查询在以下任一条件触发后升级为 Research:
| 触发条件 | 说明 |
|---|---|
| Fallback Chain 全部走完仍无结果 | 单步策略已穷尽所有可能 |
| 所有召回结果 rerank_score < 0.3 | 召回质量不足以支撑回答 |
| Quality Checker 判定 answered=false | 已有结果无法构成有效回答 |
语义检索 / 关系查询
↓ 触发升级条件
Fallback Chain(见 6.4)
↓ 仍不足
升级为 Research
↓
Agent 动态规划(最多2轮补充检索)
↓
仍无法回答 → 告知用户,建议补充文件或调整问题
6.4 Fallback 降级链
当检索结果为空或质量不足时,按顺序执行,严禁跳步、逆序、重复调用相同参数:
Step 1: 放宽 filters
去掉日期限制,或扩大日期范围
去掉 department / tags 等非必要过滤条件
Step 2: 换工具
hybrid_search 无结果 → keyword_search(精确匹配)
keyword_search 无结果 → 放宽 filters 后重试 hybrid_search
Step 3: 改写查询
使用同义词或上位词重新表达
拆解问题,只搜核心实体
Step 4: search_files
重新理解知识库内容范围
判断是否根本不存在相关文件
Step 5: 升级 Research 或告知用户
说明已尝试的检索路径
建议用户补充文件或换一种问法
6.5 Token 预算管控
| 累计消耗 | 触发动作 |
|---|---|
| < 8,000 tokens | 正常执行,全量加载检索结果 |
| 8,000 ~ 10,000 tokens | 停止新增精读,改用 query_file 摘要模式 |
| > 10,000 tokens | 停止所有检索,基于已有内容生成,回答末尾标注"受上下文限制" |
| 超过 8 轮工具调用 | 强制停止,汇报当前已获取信息和缺口 |
各工具 Token 消耗估算:
| 工具 | 估算消耗 |
|---|---|
| hybrid_search(top_k=5) | ~600 tokens |
| keyword_search(top_k=5) | ~400 tokens |
| graph_search | ~500 tokens |
| search_files(top_k=5) | ~500 tokens |
| query_file | ~800 tokens |
| get_file_outline | ~400 tokens |
| read_section(单章) | ~600 tokens |
6.6 Quality Checker 设计
检查项:
| 字段 | 类型 | 说明 |
|---|---|---|
| answered | bool | 是否实质性回答了用户问题 |
| has_citation | bool | 关键信息是否全部有来源标注 |
| has_hallucination_risk | bool | 是否包含超出 context 的内容 |
| need_more_retrieval | bool | 信息是否明显不足,需补充检索 |
| missing_aspects | array | 未被回答的子问题列表 |
路由规则:
need_more_retrieval=true AND 当前循环次数 < 2
→ 回到检索阶段,以 missing_aspects 为新查询补充检索
其他情况
→ 直接输出当前回答
七、生成规范
7.1 回答格式规范
语义检索(简单事实):
直接回答 + 来源标注
控制在 3 句话以内,不分段
关系查询:
## 关系概述
(图谱结构描述)
## 各实体详情
### 实体A
内容 + 来源
### 实体B
内容 + 来源
Research(综合分析):
## 结论摘要
(2~3句话总结核心答案)
## 详细说明
### [维度/子问题1]
内容 + 来源
### [维度/子问题2]
内容 + 来源
## 信息局限说明
(若存在信息缺口 / 冲突 / 检索受限,在此说明)
7.2 引用标注规范
文本来源:【来源:文件名,章节名】
图谱来源:【来源:知识图谱,relation: XX】
每一条关键信息后必须附带来源标注,不允许出现无来源的结论性陈述。
7.3 冲突处理与裁决规则
当不同文件对同一问题给出矛盾信息时,按以下优先级裁决:
优先级(从高到低):
1. 盖章 PDF > 未签字草稿
2. 日期更新 > 日期更旧
3. 上级部门文件 > 下级部门文件
4. 正式发布版 > 修订草案
冲突输出格式:
[信息冲突说明]
来源A:[内容摘要]【文件名,日期,类型】
来源B:[内容摘要]【文件名,日期,类型】
根据优先级规则,采用来源A(理由:日期更新 / 为盖章正式版)。
建议自行核实最终版本。
无法依据规则裁决时(同日期、同级别),列出两种说法,交由用户判断,不做倾向性结论。
7.4 信息不足时的回复规范
情况一:Fallback 全部走完,仍无结果
→ 告知用户已尝试的检索路径
→ 说明知识库中未找到相关信息
→ 建议补充上传相关文件,或调整问题描述
情况二:部分信息缺失,已有部分答案
→ 先输出已有信息(附来源)
→ 在"信息局限说明"中明确指出缺口
→ 不得用推测内容填补缺口
情况三:超出范围
→ 直接说明该问题超出知识库范围
→ 不触发任何检索流程
八、质量保障
8.1 性能目标
| 类别 | P50 | P95 | LLM 调用次数 |
|---|---|---|---|
| 语义检索 | 2.5s | 4s | 2次(改写 + 生成) |
| 关系查询 | 4s | 6s | 2次(改写 + 生成) |
| Research | 8s | 14s | 3~5次 |
| 超出范围 | 0.3s | 0.5s | 1次(分类) |
8.2 质量指标
| 指标 | 目标值 | 保障手段 |
|---|---|---|
| 召回率 Recall@5 | > 85% | hybrid_search 双路召回 + 内置 rerank |
| 幻觉率 | < 3% | 强制引用规范 + Quality Checker |
| 分类准确率 | > 90% | confidence < 0.7 时保守降级 |
| Fallback 成功率 | > 70% | 五步有序降级链 |
| 答案有引用率 | 100% | Answer Generator 强制要求 |
8.3 可观测性设计
节点级追踪: 每个节点记录耗时、输入 token、输出 token、工具调用参数与结果,支持完整链路追溯。
路由分布监控: 统计各类别占比,识别 Classifier 是否过于保守(大量降级为语义检索)或过于激进(大量进入 Research)。
召回质量追踪: 记录每次检索的 rerank_score 分布,监控 top-1 score 趋势,score 持续偏低说明索引质量或分块策略需要优化。
Fallback 触发率: 监控各 Step 触发频率。Step 4(search_files)频繁触发说明知识库覆盖存在系统性盲区。
Token 预算命中率: 监控 truncated=true 的比例,超过 10% 需检查分块策略或 top_k 设置。
8.4 评估数据集建设
覆盖四个类别,各类别构造不少于 50 条标注问答对:
| 类别 | 构造重点 |
|---|---|
| 语义检索 | 覆盖精确表达和口语化同义表达两种形式 |
| 关系查询 | 覆盖单跳和双跳关系,含跨部门实体 |
| Research | 覆盖对比分析、链式推理、探索导航三种子场景 |
| 超出范围 | 覆盖知识库空白、问题类型不符、指代不明三种情况 |
评估指标:准确率、引用覆盖率、幻觉率、平均耗时。