基于 LangChain、Ollama 和 Qdrant 的个人知识库问答助手学习项目。
本项目用于从 0 到 1 学习 RAG 工作流,包括文档加载、文本切分、向量化、向量数据库检索、Prompt 组织和本地大模型问答。
- 读取
data/目录下的.txt、.md和.pdf文件 - 使用 LangChain
Document表示文档 - 使用
RecursiveCharacterTextSplitter切分文档 - 使用 Ollama 本地 Embedding 模型生成向量
- 使用 Qdrant 本地模式保存向量
- 根据问题检索相关文档片段
- 调用 Ollama 本地聊天模型生成答案
- 返回答案和参考来源
- 支持命令行连续问答
- 支持 Streamlit 网页问答界面
| 模块 | 技术 |
|---|---|
| 语言 | Python |
| LLM 框架 | LangChain |
| 本地模型 | Ollama |
| 聊天模型 | qwen3.5:9b |
| Embedding 模型 | nomic-embed-text:latest |
| 向量数据库 | Qdrant Local |
| 配置管理 | python-dotenv |
personal-kb-assistant/
├── app.py
├── cli.py
├── config.py
├── ingest.py
├── README.md
├── PROJECT_PLAN.md
├── .env
├── .env.example
├── data/
│ └── sample.txt
├── qdrant_store/
└── src/
├── __init__.py
├── loaders.py
├── splitter.py
├── embeddings.py
├── llms.py
├── prompts.py
├── retriever.py
└── chains.py
python -m venv .venv.\.venv\Scripts\Activate.ps1当前项目采用“用到哪个库,再安装哪个库”的方式。
已经用到的依赖包括:
pip install langchain-core
pip install langchain-text-splitters
pip install python-dotenv
pip install langchain-ollama
pip install qdrant-client langchain-qdrant
pip install pypdf查看本地模型:
ollama list当前项目使用:
qwen3.5:9b
nomic-embed-text:latest
如果还没有 Embedding 模型,运行:
ollama pull nomic-embed-text项目使用 .env 管理配置。
示例:
LLM_PROVIDER=ollama
OLLAMA_BASE_URL=http://localhost:11434
OLLAMA_CHAT_MODEL=qwen3.5:9b
OLLAMA_EMBEDDING_MODEL=nomic-embed-text:latest
VECTORSTORE_PROVIDER=qdrant
QDRANT_PATH=qdrant_store
QDRANT_COLLECTION=personal_kb
DATA_DIR=data
CHROMA_DIR=vectorstore
CHUNK_SIZE=800
CHUNK_OVERLAP=120
RETRIEVER_K=4说明:
.env是本地真实配置,不建议提交到代码仓库。.env.example是配置模板,可以保留给其他人参考。- 当前实际使用的是 Qdrant,
CHROMA_DIR暂时保留,方便以后切换。
把 .txt、.md 或 .pdf 文件放入 data/ 目录。
示例:
data/sample.txt
data/example.pdf
每次新增或修改文档后,运行:
python ingest.py成功后应该看到:
知识库构建完成
向量库目录: qdrant_store
Collection: personal_kb
python -m src.retriever "什么是 RAG?"成功后会返回相关文档片段和来源文件。
python -m src.chains然后输入问题,例如:
什么是 RAG?
程序会返回答案和参考来源。
python cli.py支持连续提问。
退出命令:
exit
quit
q
streamlit run app.py浏览器会自动打开页面。如果没有自动打开,可以访问终端中显示的地址,例如:
网页功能:
- 输入问题
- 点击“提问”
- 查看答案
- 查看参考来源
- 在侧边栏查看当前模型和知识库配置
如果新增或修改了 data/ 目录中的文档,需要先重新构建知识库:
python ingest.pydata 文档
↓
src/loaders.py
↓
src/splitter.py
↓
src/embeddings.py
↓
Qdrant 本地向量库
↓
src/retriever.py
↓
src/prompts.py
↓
src/llms.py
↓
src/chains.py
↓
cli.py
| 文件 | 作用 |
|---|---|
config.py |
统一读取 .env 配置 |
ingest.py |
构建知识库,把文档写入 Qdrant |
cli.py |
命令行连续问答入口 |
src/loaders.py |
加载 .txt / .md / .pdf 文档 |
src/splitter.py |
切分文档 |
src/embeddings.py |
创建 Ollama Embedding 模型 |
src/llms.py |
创建 Ollama 聊天模型 |
src/prompts.py |
保存问答 Prompt |
src/retriever.py |
从 Qdrant 检索相关文档 |
src/chains.py |
组合检索、Prompt 和 LLM,生成答案 |
src/graph.py |
使用 LangGraph 定义显式问答工作流 |
src/qa.py |
根据配置选择普通 Chain 或 Graph |
当前项目支持两种问答流程:
| 工作流 | 入口 | 说明 |
|---|---|---|
chain |
src/chains.py |
普通 LangChain 问答链 |
graph |
src/graph.py |
LangGraph 显式工作流 |
cli.py 和 app.py 统一调用:
from src.qa import asksrc/qa.py 会根据 .env 中的 QA_WORKFLOW 选择使用普通 Chain 或 LangGraph。
当前 LangGraph 工作流:
START
↓
retrieve
↓
should_generate
├── no_answer
└── generate
↓
END
配置方式:
QA_WORKFLOW=chain可选值:
chain
graph
使用普通 Chain:
QA_WORKFLOW=chain使用 LangGraph:
QA_WORKFLOW=graph依赖:
pip install langgraph后续可以新增 FastAPI 服务,让其他网页或前端应用通过 HTTP 接口调用当前知识库问答能力。
推荐新增入口文件:
api.py
核心思路:
其他页面 / 前端应用
↓ HTTP 请求
FastAPI api.py
↓
src.qa.ask()
↓
chain 或 graph
↓
返回 answer + sources
计划新增依赖:
pip install fastapi uvicorn计划提供接口:
| 接口 | 方法 | 作用 |
|---|---|---|
/ |
GET | API 根路径 |
/api/health |
GET | 健康检查 |
/api/config |
GET | 查看当前模型、向量库和工作流配置 |
/api/ask |
POST | 知识库问答接口 |
/api/ask 请求示例:
{
"question": "什么是 RAG?"
}/api/ask 响应示例:
{
"answer": "RAG 是 Retrieval-Augmented Generation 的缩写...",
"sources": [
{
"filename": "sample.txt",
"chunk_index": 1,
"source": "data/sample.txt",
"preview": "RAG 是 Retrieval-Augmented Generation..."
}
],
"workflow": "chain"
}推荐启动命令:
uvicorn api:app --reload启动后可以访问自动接口文档:
http://127.0.0.1:8000/docs
PowerShell 调用示例:
Invoke-RestMethod `
-Uri http://127.0.0.1:8000/api/ask `
-Method Post `
-ContentType "application/json" `
-Body '{"question":"什么是 RAG?"}'前端调用示例:
const response = await fetch("http://127.0.0.1:8000/api/ask", {
method: "POST",
headers: {
"Content-Type": "application/json",
},
body: JSON.stringify({
question: "什么是 RAG?",
}),
});
const data = await response.json();
console.log(data.answer);
console.log(data.sources);如果前端页面和 API 服务不在同一个端口,例如前端是 http://localhost:3000,后端是 http://localhost:8000,需要在 FastAPI 中配置 CORS。
原计划使用 Chroma 作为向量数据库,但当前 Windows 环境中 chromadb 写入阶段卡住,因此已切换为 Qdrant 本地模式。
Qdrant 当前运行方式为本地文件持久化,不需要 Docker。
当前 PDF 支持基于 pypdf。普通文字 PDF 支持较好;扫描版 PDF 或图片型 PDF 通常需要后续引入 OCR。
- 支持上传文件并重建知识库
- 支持扫描版 PDF OCR
- 支持 FastAPI 接口服务
- 支持 OpenAI / 兼容接口切换
- 增加测试用例
- 增加更好的引用来源展示