最小化的 RAG(Retrieval-augmented generation) 知识问答系统(基于阿里云通义千问)
- 🤖 智能问答:基于您的知识库文档进行精准回答
- 📚 文档管理:支持多种格式文档导入(TXT、MD、JSON)
- 🔍 语义检索:使用向量相似度进行智能文档检索
- 💬 流式对话:实时流式输出,体验流畅
- 🎯 来源追溯:每个答案都可以查看引用来源
- 🌐 Web 界面:基于 Streamlit 的友好用户界面
- LLM: 阿里云通义千问(Qwen)
- 向量数据库: ChromaDB
- Web 框架: Streamlit
- 向量化: 阿里云 text-embedding-v4
- Python 3.8+
- 阿里云 API Key(获取地址)
# 创建虚拟环境 python -m venv venv # 激活虚拟环境source venv/bin/activate # macOS/Linux# 或 venv\\Scripts\\activate # Windows# 安装依赖包 pip install -r requirements.txt# 复制配置示例文件 cp .env.example .env # 编辑 .env 文件,填入您的阿里云 API Key# 必填项:ALIYUN_MODEL_API_KEY# 导入单个文件 python data_loader.py --input ./data/sample.txt # 导入整个目录 python data_loader.py --input ./data/ --pattern *.txt *.md # 导入 JSON 食谱文件 python data_loader.py --input ./data/recipes/ --pattern *.json # 清空数据库后重新导入 python data_loader.py --input ./data/ --clearstreamlit run app.py然后在浏览器中访问 http://localhost:8501
# 查看数据库统计 python data_loader.py --stats # 清空数据库 python data_loader.py --clear这个工具用于直接查询向量数据库中的文档块,支持精确查询和模糊搜索。
关于 Chunk(文档块)
Chunk 是 RAG 系统中的基本概念,指的是将长篇文档分割成的较小的文本片段。每个 chunk 包含:
- 文本内容:文档的实际内容片段
- 元数据:如文件名、类型、来源等
- 向量表示:文本转换成的高维向量,用于语义相似度匹配
RAG 系统通过将用户问题转化为向量,然后在数据库中搜索相似度最高的 chunk,从而找到最相关的知识来源。
source venv/bin/activate python query_chunk.py "煤球冰淇淋"📋 查看输出示例
================================================================================ 🔍 正在按名称精确查询:'煤球冰淇淋' ================================================================================ ✅ 找到文档块 #1: ================================================================================ 📦 文档块数据: --------------------------------------------------------------------------------{"document": "名称:煤球冰淇淋\n描述:一款融合现代分子烹饪与传统冰淇淋工艺的创意甜品。外层采用食用活性炭与黑芝麻调制的漆黑外壳,形如真实煤球;内层则是清爽的香草奶油冰淇淋与黑可可馅料的对比。咬下时,苦甜的可可与香草的温暖逐层绽放,黑色外壳增添神秘的视觉冲击与独特的风味层次。适合秋冬季食用,特别是在艺术展览、高端甜品秀与创意餐厅的创新甜品环节中亮相。也适合作为主题派对与新年庆典的特色甜品,其独特的视觉效果与风味组合让人印象深刻。\n类型:甜品\n关键词:甜品, 冰淇淋, 创意, 现代, 分子美食, 秋冬\n配料:\n- 200 ml 香草奶油冰淇淋基底\n- 50 g 食用活性炭粉\n- 30 g 黑芝麻粉\n- 100 g 黑可可馅料\n- 50 g 食用黑糖衣\n步骤:\n1. 先制香草冰淇淋基底并冷冻至半凝固状,混入黑可可馅料旋纹状冷冻至硬。\n2. 取出冰淇淋球,用模具整形成球形。\n3. 将食用活性炭与黑芝麻粉混合均匀,加入少量液体制成浓稠糊状。\n4. 快速将冰淇淋球浸入活性炭黑芝麻糊中,使表面均匀覆盖。\n5. 再次冷冻至外壳完全硬化。\n6. 可在表面点缀金色食用粉增添光泽,呈现煤球的质感。", "metadata":{"file_name": "煤球冰淇淋.json", "file_path": "./data/recipes/煤球冰淇淋.json", "image_path": "data/images/煤球冰淇淋.jpg", "instructions": "1. 先制香草冰淇淋基底并冷冻至半凝固状,混入黑可可馅料旋纹状冷冻至硬。\n2. 取出冰淇淋球,用模具整形成球形。\n3. 将食用活性炭与黑芝麻粉混合均匀,加入少量液体制成浓稠糊状。\n4. 快速将冰淇淋球浸入活性炭黑芝麻糊中,使表面均匀覆盖。\n5. 再次冷冻至外壳完全硬化。\n6. 可在表面点缀金色食用粉增添光泽,呈现煤球的质感。", "name": "煤球冰淇淋", "recipe_source": "https://example.com/recipes/coal-ball", "source": "file", "tags": "甜品, 冰淇淋, 创意, 现代, 分子美食, 秋冬", "type": "甜品" }, "embedding": [ [0.062532894, -0.041486017, -0.028275743, -0.087578036, -0.045100451, -0.041805878, -0.105362326, 0.064196169, -0.015265383, 0.105938077, 0.004897877, 0.015937092, 0.07184086, -0.012378634, -0.012818444, 0.025668873, -0.039023083, -0.017976208, -0.070305526, -0.025700858, 0.034481052, -0.005793489, -0.009443906, 0.01501749, 0.020087292, -0.002648852, 0.05095391, 0.055527929, -0.014073899, 0.006429213], ... // (1024 total values, generated by text-embedding-v4) ] } -------------------------------------------------------------------------------- ✅ 共找到文档块数量:1 # 使用 --like 或 -l 标志启用模糊匹配 python query_chunk.py --like "煤球" python query_chunk.py -l "豆腐"# 指定最多返回的结果数量 python query_chunk.py --like "冰淇淋" --max 10| 参数 | 说明 | 示例 |
|---|---|---|
name | 甜品名称或关键字(位置参数) | python query_chunk.py "煤球冰淇淋" |
-l, --like | 启用模糊匹配(包含关系,忽略大小写) | python query_chunk.py --like "煤球" |
--max | 最多返回的结果数量(默认 50) | python query_chunk.py -l "煤球" --max 20 |
侧边栏设置
- 重新加载引擎:添加新文档后刷新
- 数据库统计:查看文档数量
- 搜索设置:调整检索参数
- 清除历史:重置对话
主聊天界面
- 输入问题获取答案
- 展开查看来源文档
- 查看相关度分数
| 变量名 | 说明 | 默认值 |
|---|---|---|
ALIYUN_MODEL_API_KEY | 阿里云 API 密钥 | 必填 |
ALIYUN_BASE_URL | API 端点 | https://dashscope.aliyuncs.com/compatible-mode/v1 |
ALIYUN_CHAT_MODEL | 对话模型 | qwen-plus |
ALIYUN_EMBED_MODEL | 嵌入模型 | text-embedding-v4 |
ALIYUN_EMBED_DIM | 向量维度 | 1024 |
CHROMA_DB_PATH | 数据库路径 | ./vector_db |
- qwen-turbo: 快速响应,适合简单对话
- qwen-plus: 平衡性能和成本(推荐)
- qwen-max: 最强性能,适合复杂任务
- qwen-flash: 极速响应,适合高并发场景
Minimal-RAG/ ├── app.py # Streamlit Web 应用 ├── data_loader.py # 数据加载工具 ├── rag_engine.py # RAG 核心引擎 ├── requirements.txt # Python 依赖 ├── .env.example # 配置示例 ├── clear.sh # 清空数据库脚本(macOS/Linux) ├── load-json.sh # 加载 JSON 脚本(macOS/Linux) ├── stats.sh # 查看统计脚本(macOS/Linux) └── vector_db/ # 向量数据库目录(执行 clear 脚本时自动创建) 本项目自带一个用于演示与研究的 data 目录(例如 data/recipes/),其中包含若干甜品的 JSON 数据。为便于展示基于私有资料库进行问答的示例,项目还同时加入了一些用于演示的“伪造甜品”条目,例如:
- 煤球冰淇淋
- 抹茶白豆腐
这些示例数据仅用于功能演示与技术研究,不代表真实菜谱,请勿用于生产或商业用途。你可以将该目录替换为你自己的私有文档(支持 TXT/MD/JSON),然后通过 data_loader.py 导入至向量数据库,以构建你的专属知识库。
# 清空数据库 ./clear.sh # 加载 JSON 资料库(存入向量数据库 ChromaDB) ./load-json.sh # 查看统计信息 ./stats.sh# 清空数据库 clear.bat # 加载 JSON 资料库(存入向量数据库 ChromaDB) load-json.bat # 查看统计信息 stats.bat文档准备
- 使用 UTF-8 编码保存文档
- 将相关文档放在同一目录
- JSON 文件支持中文字段
提问技巧
- 问题越具体,答案越精确
- 可以要求引用具体来源
- 调整相关度阈值过滤无关结果
性能优化
- 定期清理无用文档
- 合理设置检索数量(n_results)
- 根据需求选择合适的模型
A: 检查 .env 文件中的 ALIYUN_MODEL_API_KEY 是否正确配置
A: 降低相关度阈值(min_relevance)或检查文档是否正确导入
A: 确保文件使用 UTF-8 编码,检查文件路径是否正确
本项目采用 MIT 许可证。 详情请参阅 LICENSE 文件。
