本地 RAG 可以把文档切片并存入本机 Chroma,再检索相关片段交给 DeepSeek 生成答案。Chroma 和 embedding 可以留在本机,但使用 DeepSeek API 时,提交给模型的上下文会离开本机,不能把它描述成完全离线方案。

架构与边界

典型流程是:加载文档、切片、生成 embedding、写入 Chroma、检索 Top-K 片段、拼接上下文、调用模型生成答案。文档原文和向量可以本地保存;如果使用云端模型,问题和检索片段会发送到 API 服务,应先做脱敏和访问控制。

环境准备

python3 -m venv .venv
source .venv/bin/activate
pip install chromadb openai langchain langchain-community
pip install sentence-transformers pypdf python-docx python-dotenv

如果需要固定依赖,请把经过测试的完整版本写入 requirements.txt。带有比较符号的 pip 版本约束要加引号,例如 pip install 'openai>=1.0.0'。

使用 Chroma 建立本地集合

import chromadb
from openai import OpenAI

chroma = chromadb.PersistentClient(path="./chroma_db")
collection = chroma.get_or_create_collection("docs")
client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

collection.add(
    ids=["doc-1"],
    documents=["这里是已经切片的文档内容"],
    embeddings=[embedding_vector],
)

result = collection.query(query_embeddings=[query_vector], n_results=3)
context = "\n\n".join(result["documents"][0])

实际项目应给每个片段保存来源、页码、更新时间和权限标签,避免检索结果无法追溯。

调用 DeepSeek API

response = client.chat.completions.create(
    model="deepseek-flash",
    messages=[
        {"role": "system", "content": "只根据提供的资料回答,资料不足时明确说明。"},
        {"role": "user", "content": f"资料:\n{context}\n\n问题:{question}"},
    ],
    temperature=0.2,
)
print(response.choices[0].message.content)

DeepSeek 官方当前文档列出 deepseek-flash 和 deepseek-v4-pro。旧的 deepseek-v4-flash 名称属于兼容旧请求的名称,正式代码应以官方模型列表和价格页面为准。

检索质量与安全

  • 中文文档先按标题、段落和列表结构切片,再调整 chunk size 和 overlap。
  • 用召回率、答案引用正确率和拒答准确率评估,不只看响应速度。
  • 检索结果必须过滤租户、部门和文档权限。
  • 对用户问题、文档内容和系统提示分层,防止提示注入。
  • 对模型调用设置超时、重试、缓存和成本上限。

参考资料

如果数据不能离开内网,应把生成模型也部署在本地,或使用经过合规评估的私有化推理服务。

EOF · 全文完 RAG 与向量数据库 · · 共 615 字

感谢耐心读到这里。若这篇文字曾带来片刻启发或共鸣,不妨点亮喜欢或分享给同路人。

喜欢 0
DISCUSSION / 读者评论 0 条评论

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注