一个面向学习和演示的 RAG 项目,支持:
- 上传 Markdown 文件并入库
- 使用 Chroma 做向量检索
- 基于检索结果生成回答
- 返回答案对应的 citations
- 通过 Streamlit 进行最小可用前端演示
如果你是第一次看这个仓库,建议先看这几份文档:
docs/plans/ 下保留了几份核心说明文档,用来记录项目结构、主要流程和关键设计取舍。
项目当前正式目录是:
D:\program\agent\projects\rag-assistant后续启动、测试、修改代码都以这个目录为准。
cd D:\program\agent\projects\rag-assistant
python -m pip install -r requirements.txt先复制:
Copy-Item .env.example .env当前项目最小只需要配置 chat 这条链路用到的 OpenAI 兼容接口:
OPENAI_API_KEY=你的真实key
OPENAI_BASE_URL=https://你的中转站/v1如果 .env 没写其它项,项目会自动使用 config.py 中的默认值。
当前默认行为是:
chat走 OpenAI 兼容接口embedding默认走本地模型
对应默认值:
EMBEDDING_PROVIDER=local
LOCAL_EMBEDDING_MODEL=sentence-transformers/paraphrase-multilingual-MiniLM-L12-v2
EMBEDDINGS_MODEL=text-embedding-3-small
CHAT_MODEL=gpt-5.4如果你不想使用本地 embedding,而想改成 API embedding,可以在 .env 中显式加入:
EMBEDDING_PROVIDER=openai
EMBEDDINGS_MODEL=text-embedding-3-small此时 embedding 会走:
OPENAI_API_KEYOPENAI_BASE_URL
注意:
- 切换 embedding provider 后,最好清空旧的向量库再重新 ingest
- 因为本地 embedding 和 OpenAI embedding 生成的向量不在同一个向量空间里
cd D:\program\agent\projects\rag-assistant
python -m uvicorn app.main:app --reload启动后访问:
- Swagger UI:
http://127.0.0.1:8000/docs - Health check:
http://127.0.0.1:8000/health
cd D:\program\agent\projects\rag-assistant
streamlit run streamlit_app.py --server.headless true然后手动打开:
http://localhost:8501
如果你不介意每次启动自动打开浏览器,也可以直接运行:
streamlit run streamlit_app.py- 启动 FastAPI 后端
- 启动 Streamlit 页面
- 在页面里上传一个
.md文件并点击Ingest - 输入问题并点击
Ask - 查看:
answercitations
如果你保持默认配置 EMBEDDING_PROVIDER=local,要注意下面几点:
- 第一次使用本地 embedding 时,模型可能会从 HuggingFace 下载到本地缓存
- 如果你当前网络不能访问 HuggingFace,第一次
ingest可能会超时 - 即使模型已经下载过,初始化时也可能做远端校验或补文件
- 如果没有代理,或者 Python 进程没有正确走代理,也可能导致超时
一句话:
- 本地 embedding 的推理是在本机做的
- 但模型文件第一次通常还是要从 HuggingFace 获取
如果你当前网络环境对 HuggingFace 不稳定,演示时更建议切换到 API embedding
当前返回的 citations 是按检索到的 chunk 返回,不是按文件数返回。
所以如果:
- 一个文件被切成多个 chunk
- 或者问题检索到了多个相关 chunk
那么你会看到多条 citation,这属于当前实现的正常行为。
最常见原因是:
- 当前走的是本地 embedding
- 后端在初始化本地模型时访问 HuggingFace 超时
- 前端
requests.post(..., timeout=60)等不到结果
因为不同 embedding provider 产生的向量不兼容,旧向量库不能直接混用。
这是 Streamlit 默认行为。
如果不想自动弹浏览器,使用:
streamlit run streamlit_app.py --server.headless true推荐先跑这几组核心测试:
python -m pytest tests/test_config.py -v
python -m pytest tests/test_ingest_service.py -v
python -m pytest tests/test_query_service.py -v
python -m pytest tests/test_health_api.py -vInvoke-RestMethod -Method Post -Uri 'http://127.0.0.1:8000/rag/ask' -ContentType 'application/json' -Body '{"question":"What is RAG?","top_k":3}'当前项目已经具备:
- Markdown ingest
- chunk 切分
- 本地/ OpenAI embedding provider 切换
- Chroma 检索
- grounded answer
- citations 返回
- FastAPI + Streamlit 演示链路
当前更偏“教学项目 / 课程项目完成版”,后续还可以继续打磨前端体验和运行稳定性。