最近有个想法:让芝麻园地的访客可以「问」网站的内容——比如“网站有哪些板块”、“Python 教程里怎么配环境”。光靠大模型瞎猜肯定不行,得先检索再回答,也就是 RAG(检索增强生成)。折腾了两天,总算跑通了,把选型和踩坑记录下来,给想自建知识库的朋友参考。
为什么选这三个组件
RAG 的核心是三件事:切块、存向量、生成。我的选型:
- 生成:DeepSeek。性价比高、中文效果好,之前就给服务器配好了 API key。
- 向量库:LanceDB。嵌入式数据库,不需要单独起服务,对这台只有 2G 内存的服务器特别友好。
- Embedding:fastembed + BGE 中文模型。这是最容易踩坑的点——DeepSeek 官方没有 embedding API,要么本地算,要么再花一份钱接第三方。我选了本地:fastembed 用 ONNX 推理,不用装沉重的 torch,BGE 小模型对中文支持也很好。
安装
服务器上是 Python 3.14 + uv 的环境。一开始担心 lancedb 没有 3.14 的包,查了一下松了口气:lancedb 用的是 cp310-abi3 稳定 ABI wheel,3.10 以上的 Python 都能直接用;fastembed 干脆是纯 Python。所以安装就是一条命令:
cd /opt/zhimalab-api
uv add lancedb fastembed openai
接入 FastAPI
我用一个独立的 app/rag.py 模块封装检索和生成,然后在 main.py 里暴露了两个接口:
@app.get("/rag/ask") # 问答:检索 + DeepSeek 生成
@app.get("/rag/search") # 检索:只返回相关片段,不调用模型
摄入文档走命令行脚本:rag.py add <目录>,把文档切块、向量化后写进 LanceDB;两个接口和 CLI 共用同一个数据库目录。
踩坑记录(这部分最值钱)
- HuggingFace 被墙。模型要从 HF 下载,服务器连不上,加环境变量
HF_ENDPOINT=https://hf-mirror.com走国内镜像。 - XetHub 401。新版 huggingface_hub 默认走 XetHub 的 CAS 通道下载,对镜像站直接报 401,必须加
HF_HUB_DISABLE_XET=1强制走普通 HTTP。这个报错很隐蔽,一开始还以为是镜像挂了。 - 权限问题。服务以
www-data用户运行,而向量库默认路径在/root下(权限 700),www-data 根本进不去。最后把数据目录和模型缓存都放到了/var/lib/zhimalab-rag并授权。 - systemd 不读
.bashrc。我之前把 key 配在 root 的.bashrc里,结果服务根本读不到——systemd 不会加载 shell 配置文件。正确做法是写进服务的 EnvironmentFile(/opt/zhimalab-api/.env)。 - 启动慢。服务重启后要等约 8 秒(onnxruntime 加载),别一重启就急着测,会 Connection refused。
实测效果
往库里放了一篇网站介绍,然后问它:
Q:芝麻园地有哪些板块?
A: 根据参考资料,芝麻园地(zhimalab.tech)的网站主要包含以下板块:博客、前端工具、互动教程、AI 实验室和儿童游戏。
检索得分 0.62,回答内容完全来自资料,没有编造。
下一步
- 把网站的文章、教程批量摄入知识库
- 给
/rag接口加权限和限流,再考虑对外暴露 - 试试点名
deepseek-reasoner做更复杂的推理问答
知识库的架子已经搭好了,剩下的就是往里面填内容。