All Pages Edit on GitHub

从 0 到 1 构建个人知识库问答助手

English | 中文

这个教程带你从 0 到 1 做一个“个人知识库问答助手”。目标不是堆满框架,而是让你真正理解一个 RAG 应用从用户提问到最终回答的完整链路。

完成后你应该能讲清楚:

最终效果

用户上传或放入一批 Markdown、PDF、网页笔记后,可以提问:

我的 30 天 AI 学习计划里,第 2 周应该做什么?

系统返回:

第 2 周建议重点完成 RAG 入门,包括阅读 RAG 文档、准备测试文档、实现文档切分、检索、RAG 最小版本、引用来源和 20 条测试问题。

来源:
- 30-day-plan.md / Week 2

推荐技术栈

新手建议先用最小组合:

模块 推荐
语言 Python
API 服务 FastAPI
本地存储 SQLite
向量检索 先用内存或 SQLite,后续换 pgvector/Qdrant
文档格式 先支持 Markdown,再支持 PDF
评测 CSV/JSON + 简单评分脚本

不要第一天就引入太多框架。先跑通数据流,再替换组件。

总体架构

用户问题
  -> 后端 API
  -> 查询改写
  -> 检索相关 chunk
  -> 组装 Prompt
  -> 调用模型
  -> 解析答案和引用
  -> 记录日志和反馈

离线索引流程:

文档导入
  -> 文档解析
  -> 文本清洗
  -> Chunk 切分
  -> 生成 Embedding
  -> 保存 chunk + metadata + vector

Step 1:完成最小聊天调用

先不要做知识库。第一步只验证模型 API 能正常调用。

你要做到:

检查点:

Step 2:读取本地文档

先支持 Markdown 文件。读取文件后,把内容和用户问题一起放进 Prompt。

示例 Prompt:

你是个人知识库助手。请只基于下面资料回答问题。

资料:
{document_text}

用户问题:
{question}

如果资料中没有答案,请说“资料中没有找到答案”。

这一步会很快遇到上下文太长的问题,所以不能长期把整篇文档塞给模型。

Step 3:实现 Chunk 切分

Chunk 是文档切分后的片段。新手可以先用简单策略:

示例数据结构:

{
  "chunk_id": "30-day-plan#week-2#001",
  "title": "30-Day Plan",
  "source": "checklists/30-day-plan.md",
  "section": "Week 2:RAG 入门",
  "text": "Day 8 阅读 RAG 文档..."
}

判断 chunk 好不好,不看数量,而看用户提问时能不能检索到完整依据。

Step 4:先做关键词检索

在引入向量检索前,先做一个关键词检索版本。它不高级,但很适合帮助你理解检索流程。

最低要求:

这一步能让你先跑通 RAG 的主链路。

Step 5:加入 Embedding 和向量检索

Embedding 会把文本转换成向量,用来做语义相似度检索。

索引时:

chunk text -> embedding model -> vector -> 保存

查询时:

question -> embedding model -> query vector -> 相似度搜索 -> top-k chunks

注意事项:

Step 6:组装 RAG Prompt

把检索到的 chunk 作为“可用资料”,而不是让模型自由发挥。

推荐模板:

你是个人知识库问答助手。

规则:
- 只能基于“可用资料”回答
- 不要编造资料中没有的信息
- 每个关键结论都要给出来源
- 如果资料不足,明确说明缺少什么

可用资料:
{retrieved_chunks}

用户问题:
{question}

输出格式:
答案:
{answer}

来源:
- {source title} / {section}

Step 7:加入引用来源

引用不是装饰,而是 RAG 的信任基础。每个回答至少要能追溯到:

建议 API 返回:

{
  "answer": "string",
  "sources": [
    {
      "title": "30-Day Plan",
      "source": "checklists/30-day-plan.md",
      "section": "Week 2",
      "chunk_id": "30-day-plan#week-2#001",
      "score": 0.82
    }
  ]
}

Step 8:处理无法回答

资料不足时,系统应该拒答。

常见拒答条件:

拒答示例:

资料中没有找到这个问题的明确答案。当前检索到的内容主要和 RAG 学习计划有关,没有包含部署费用信息。

Step 9:建立最小评测集

准备 30 条问题:

每条记录:

{
  "id": "kb_001",
  "question": "第 2 周学习什么?",
  "expected_behavior": "回答 RAG 入门任务并引用 30-day-plan",
  "required_sources": ["checklists/30-day-plan.md"],
  "tags": ["rag", "easy"]
}

Step 10:上线前检查

上线前至少确认:

更完整的检查见:RAG Production Checklist

常见迭代方向

问题 优化方向
检索不到答案 优化 chunk、metadata、query rewrite
检索到了但答错 改 Prompt、加引用校验、加强拒答
引用不准 保存更细 metadata,限制模型引用来源
成本高 减少 top-k、压缩上下文、缓存 embedding
延迟高 异步索引、缓存、选择更快模型

最终你应该交付什么

这比只写“我会 RAG”有说服力得多。