# LangChain + Qdrant 向量数据库实战:从 Docker 安装到 RAG 问答全链路
LangChain + Qdrant 向量数据库实战:从 Docker 安装到 RAG 问答全链路
适合人群:LangChain 开发者、RAG 应用工程师、AI 工程落地、知识库开发人员
摘要
本文完整记录了在 Windows 环境下使用 LangChain + Qdrant 搭建企业知识库问答系统的全流程。从 Docker 安装 Qdrant、Python 依赖配置、环境变量管理,到 QdrantDB 封装、文档建库、向量检索、LCEL 链式 RAG 问答,覆盖全链路实战。对比 Milvus 与 Qdrant 的选型差异,附带完整可运行代码和高频踩坑排查方案。
一、为什么选 Qdrant?Milvus vs Qdrant 选型对比
在本地开发和中小规模知识库场景中,向量数据库的选型直接影响开发体验。以下是 Milvus 与 Qdrant 的核心对比:
| 对比项 | Milvus (v2.6) | Qdrant (v1.12) |
|---|---|---|
| 内存占用 | 启动需 4-8 GB | 仅需 512 MB - 1 GB |
| 依赖复杂度 | 需 etcd、MinIO、Pulsar 等 5+ 组件 | 单容器,零依赖 |
| 部署难度 | 多容器编排,启动慢 | docker run 一行启动 |
| Windows 兼容性 | 偶发连接问题 | 原生 HTTP/gRPC,稳定 |
| 适用场景 | 大规模生产集群 | 本地开发、中小项目、原型验证 |
| 性能 | 亿级向量,分布式扩展 | 百万级向量,毫秒响应 |
选型结论:本地开发、学习项目、中小规模知识库,Qdrant 是更轻、更快、更稳的选择。
二、项目目录结构总览
F:\LangChain\
├── env\.env # 环境变量配置文件
├── data\
│ ├── raw\XX销售有限公司员工守则.pdf # 原始知识库素材
│ └── readable\ # 预处理后的可读文本
├── DB\
│ ├── __init__.py # 使 DB 成为 Python 包
│ ├── MilvusDB.py # Milvus 适配器(保留原实现)
│ └── QdrantDB.py # Qdrant 适配器(新增)
├── providers\
│ └── models.py # 模型封装(Embedding + LLM)
└── Practice\07\0727_qdrant\ # Qdrant 版本练习脚本
├── 01_基础完整版.py # 单 PDF 全内联(保留 Milvus)
├── 02_基础封装版.py # 调用封装(保留 Milvus)
├── 03_升级封装版.py # 多目录递归加载(保留 Milvus)
├── 04_Retriever 基础检索.py # 检索程序(已适配 Qdrant)
├── 05_手动 RAG.py # 手动组装 RAG(已适配 Qdrant)
├── 06_LCEL RAG.py # LCEL 链式 RAG(已适配 Qdrant)
├── 07_建库程序.py # 文档入库(已适配 Qdrant)
├── 08_rag_service.py # RAG 服务类(已适配 Qdrant)
└── 09_问答入口.py # 交互式终端(已适配 Qdrant)
三、Docker 安装 Qdrant
3.1 前置条件
- Windows 10/11 专业版(已启用 WSL2)
- Docker Desktop 已安装并运行
- 至少 2GB 可用内存
3.2 创建数据持久化目录
mkdir "F:\LangChain\qdrant_data"
3.3 拉取镜像并启动容器
docker run -d --name qdrant \
-p 6333:6333 -p 6334:6334 \
-v "F:/LangChain/qdrant_data:/qdrant/storage" \
qdrant/qdrant:v1.12.0
参数详解:
| 参数 | 说明 |
|---|---|
-d | 后台运行 |
--name qdrant | 容器名称 |
-p 6333:6333 | HTTP REST API 端口 |
-p 6334:6334 | gRPC 端口(LangChain 使用此端口) |
-v ... | 数据持久化到本地目录,容器重启不丢数据 |
3.4 验证容器运行状态
docker ps --filter name=qdrant
应显示 STATUS: Up,PORTS: 0.0.0.0:6333-6334。
3.5 Web UI 可视化管理(可选)
浏览器访问 http://localhost:6333/dashboard,可图形化管理集合、查看向量数据。
四、Python 依赖安装
在虚拟环境中安装 Qdrant 相关依赖:
"F:\LangChain\.venv\Scripts\pip.exe" install qdrant-client langchain-qdrant
国内网络可加清华镜像加速:
pip install qdrant-client langchain-qdrant -i https://pypi.tuna.tsinghua.edu.cn/simple
依赖说明:
| 包名 | 作用 |
|---|---|
qdrant-client | Qdrant 原生客户端,用于创建集合、统计信息 |
langchain-qdrant | LangChain 适配器,提供 QdrantVectorStore 类 |
五、.env 环境变量配置
编辑 F:\LangChain\env\.env,添加 Qdrant 及模型配置:
# DashScope 向量模型 API Key
DASHSCOPE_API_KEY=sk-your-key-here
# 本机 Docker Qdrant 服务地址
QDRANT_URL=http://localhost:6333
# 中文文本向量模型
EMBEDDING_MODEL=text-embedding-v4
# 大模型 API(OpenAI 兼容格式)
DEEPSEEK_BASE_URL=https://api.siliconflow.cn/v1
DEEPSEEK_API_KEY=sk-your-key-here
配置注意事项:
QDRANT_URL不要带端口号后面的路径,纯http://localhost:6333即可- 如使用 LongCat-2.0 等第三方模型,复用
DEEPSEEK_BASE_URL和DEEPSEEK_API_KEY,只需改model参数
六、QdrantDB 适配器封装详解
文件位置:F:\LangChain\DB\QdrantDB.py
这一层封装是整个项目的核心,它屏蔽了 Qdrant 底层 API 的复杂性,上层代码只需调用 get_qdrant_client() 即可获得 LangChain 适配的向量库实例。
6.1 完整代码
import os
from dotenv import load_dotenv
from qdrant_client import QdrantClient
from qdrant_client.models import Distance, VectorParams
from langchain_qdrant import QdrantVectorStore
from providers.models import get_embedding_model
def get_qdrant_client(collection_name, is_delete=False, url="http://localhost:6333"):
"""
获取 Qdrant 向量库实例,可选择是否删除旧集合
参数:
- collection_name: 集合名称(必传)
- is_delete: 是否删除旧集合
- url: Qdrant 服务地址
内部逻辑:
1. 读取 Qdrant 服务地址
2. 创建 Qdrant 原生客户端(跳过版本兼容性检查)
3. 根据 is_delete 决定是否删除旧 collection
4. 如 collection 不存在,自动创建(指定 vector_size=1024, Distance.COSINE)
5. 构造并返回 QdrantVectorStore 实例
"""
load_dotenv()
url = os.getenv("QDRANT_URL", url)
# 创建原生客户端,跳过兼容性检查(避免版本警告)
client = QdrantClient(url=url, grpc_port=6334, check_compatibility=False)
# 检测集合是否存在
collection_exists = False
try:
client.get_collection(collection_name)
collection_exists = True
except Exception:
pass
# 删除旧集合
if is_delete and collection_exists:
client.delete_collection(collection_name)
print(f"已删除旧 collection: {collection_name}")
collection_exists = False
# 自动创建新集合
if not collection_exists:
vector_size = 1024 # DashScope text-embedding-v4 维度
client.create_collection(
collection_name=collection_name,
vectors_config=VectorParams(
size=vector_size,
distance=Distance.COSINE,
),
timeout=30, # 创建耗时较长,需显式设置超时
)
print(f"已创建新 collection: {collection_name} (dim={vector_size})")
# 创建 LangChain 适配的向量库实例
vector_store = QdrantVectorStore(
client=client,
collection_name=collection_name,
embedding=get_embedding_model(), # DashScope 嵌入模型(单例)
)
return vector_store
6.2 关键设计要点
| 设计点 | 说明 |
|---|---|
check_compatibility=False | 跳过客户端与服务端的版本兼容性检查,避免误报 |
timeout=30 | 创建集合约需 10-15 秒,默认 5 秒会超时 |
vector_size=1024 | DashScope text-embedding-v4 的固定维度,勿改 |
Distance.COSINE | 余弦距离,适合语义相似度计算 |
| 单例 embedding | get_embedding_model() 内部缓存,避免重复初始化 |
七、建库程序:文档入库全流程
7.1 核心流程
PDF 文件
|
v
PyPDFLoader(按页加载)
|
v
RecursiveCharacterTextSplitter(chunk_size=300, overlap=50)
|
v
get_qdrant_client(is_delete=True,强制重建集合)
|
v
vector_store.add_documents(写入向量)
|
v
校验 points_count 与文档块数量一致
7.2 关键代码(Qdrant vs Milvus 差异)
# Qdrant 版本
from DB.QdrantDB import get_qdrant_client
# 建库
vector_store = get_qdrant_client(COLLECTION_NAME, is_delete=True)
ids = vector_store.add_documents(chunks)
# 统计方式不同:Qdrant 用 points_count
from qdrant_client import QdrantClient
client = QdrantClient(url=os.getenv("QDRANT_URL"))
collection_info = client.get_collection(COLLECTION_NAME)
row_count = collection_info.points_count
7.3 运行验证
cd "F:\LangChain\Practice\07\0727_qdrant"
"F:\LangChain\.venv\Scripts\python.exe" "07_建库程序.py"
预期输出:
PDF 加载完成,共 3 页
文档切分完成,共 10 个文档块
已删除旧 collection: employee_handbook
已创建新 collection: employee_handbook (dim=1024)
写入返回 ID 数量:10
Collection 实际行数:10
建库成功:employee_handbook
八、检索程序:向量相似度检索
8.1 核心流程
- 获取 Qdrant 向量库实例(
is_delete=False,不删除已有数据) - 构建 Retriever(
search_kwargs={'k': 3}) - 检索与问题最相关的 3 个文档块
8.2 关键代码
from DB.QdrantDB import get_qdrant_client
vector_store = get_qdrant_client(COLLECTION_NAME, is_delete=False)
retriever = vector_store.as_retriever(search_kwargs={'k': 3})
documents = retriever.invoke(QUESTION)
8.3 运行验证
"F:\LangChain\.venv\Scripts\python.exe" "04_Retriever 基础检索.py"
预期输出:
问题:今天生病了,请了一天假,扣多少钱?
共检索到 3 个文档块
--- 查询结果 1 ---
来源:XX销售有限公司员工守则.pdf,第 1 页
业贿赂。
5. 维护公司利益...
--- 查询结果 2 ---
来源:XX销售有限公司员工守则.pdf,第 2 页
件。
2. 合同审批:...
--- 查询结果 3 ---
来源:XX销售有限公司员工守则.pdf,第 2 页
体现 professionalism 和敬业精神。
第二章 员工权利与义务...
九、RAG 完整服务架构
9.1 架构概览
用户提问
↓
Retriever(Qdrant 检索 top-3 文档块)
↓
format_documents(格式化为 [资料1]\n来源...\n内容...)
↓
PromptTemplate(System Prompt + 参考资料 + 用户问题)
↓
LLM(LongCat-2.0 / DeepSeek)
↓
StrOutputParser(解析为纯文本)
↓
返回 {answer, sources}
9.2 关键配置
COLLECTION_NAME = 'employee_handbook'
# 检索器配置
self.retriever = self.vector_store.as_retriever(search_kwargs={'k': 3})
# 大模型温度(temperature=0 保证回答稳定、不发散)
model = get_longcat_model(temperature=0)
# Prompt 核心规则
# 1. 不要编造参考资料中不存在的制度、时间、数字
# 2. 资料不足时回答"根据现有资料无法确定"
# 3. 简洁、清楚、分点
9.3 运行验证
from rag_service import RAGService
service = RAGService()
result = service.ask('病假扣多少钱')
print(result['answer'])
# 输出:根据现有资料无法确定。参考资料中仅提到...
十、交互式问答入口
"F:\LangChain\.venv\Scripts\python.exe" "09_问答入口.py"
交互示例:
企业知识库助手已启动,输入 exit 退出。
请输入问题:病假扣多少钱
回答:根据现有资料无法确定。参考资料中仅提到员工依法享有病假权利...
资料来源
1. XX销售有限公司员工守则.pdf,1页
2. XX销售有限公司员工守则.pdf,2页
请输入问题:exit
程序已退出
十一、常见问题排查
11.1 创建集合超时 TimeoutError
现象:07_建库程序.py 报 TimeoutError: Operation timed out
原因:create_collection 默认超时 5 秒,实际需 10-15 秒
解决:显式设置 timeout=30
client.create_collection(..., timeout=30)
11.2 集合不存在 404
现象:RuntimeError: Collection employee_handbook does not exist
原因:直接初始化 QdrantVectorStore 时集合不存在
解决:先用原生客户端 create_collection 创建,再初始化 QdrantVectorStore,或使用封装好的 get_qdrant_client(内部已处理自动创建逻辑)
11.3 DeepSeek 503/429 限流
现象:模型调用报 503 Service Unavailable 或 429 Too Many Requests
原因:DeepSeek 服务端高峰期过载
解决方案:
- 等 5-10 分钟重试
- 换非高峰时段(晚上/凌晨)测试
- 切换备用模型(如 LongCat-2.0,复用同一 API 平台密钥)
11.4 维度不匹配错误
现象:Vector dimension mismatch: expected 1024, got 1536
原因:建库和查询使用了不同的 embedding 模型
解决:确保所有代码调用同一个 get_embedding_model()(单例模式),模型固定为 text-embedding-v4
十二、快速命令速查表
| 操作 | 命令 |
|---|---|
| 启动 Qdrant | docker run -d --name qdrant -p 6333:6333 -p 6334:6334 -v "F:/LangChain/qdrant_data:/qdrant/storage" qdrant/qdrant:v1.12.0 |
| 查看容器 | docker ps --filter name=qdrant |
| 停止容器 | docker stop qdrant |
| 删除容器 | docker rm -f qdrant |
| 安装依赖 | pip install qdrant-client langchain-qdrant |
| 建库 | python "07_建库程序.py" |
| 检索 | python "04_Retriever 基础检索.py" |
| 完整 RAG | python "09_问答入口.py" |
十三、核心知识点总结
| 知识点 | 说明 |
|---|---|
| Qdrant 定位 | 轻量级向量数据库,单容器启动,适合本地开发和中小项目 |
| QdrantDB 封装层 | 屏蔽底层 API 差异,上层代码改 import 即可切换向量库 |
| 集合自动创建 | get_qdrant_client() 内部自动检测并创建集合,无需手动管理 |
| vector_size=1024 | DashScope text-embedding-v4 固定维度,建库和查询必须一致 |
| Distance.COSINE | 余弦距离,适合语义相似度计算 |
| timeout=30 | 创建集合耗时较长,必须显式设置超时 |
| is_delete 参数 | 建库时设 True 强制重建,检索时设 False 保留数据 |
完整数据流
PDF 文件
-> PyPDFLoader
-> RecursiveCharacterTextSplitter
-> Document 文档块
-> Embedding 向量化
-> Qdrant 向量数据库
-> Retriever 检索
-> LLM 生成回答
Milvus 与 Qdrant 共存策略
- Milvus 版本保留在
0727/目录 - Qdrant 版本在
0727_qdrant/目录 - 两者互不干扰,通过
DB/MilvusDB.py和DB/QdrantDB.py分别封装
高频踩坑清单
-
create_collection必须设置timeout=30,默认 5 秒会超时 -
QDRANT_URL不要带尾部路径,纯http://localhost:6333 - 建库和查询必须使用同一个 embedding 模型,否则维度不匹配
-
is_delete=True会清空集合数据,检索时务必设为False - Docker Desktop 未运行时,所有 Qdrant 操作会报连接拒绝
- DeepSeek 503/429 是模型服务端限流,与向量库无关,换模型或错峰即可
-
check_compatibility=False可跳过版本警告,不影响功能
问题排查顺序
容器状态 → 端口连通 → 集合存在 → embedding 维度 → 模型调用
配套 CSDN 封面图提示词
16:9,CSDN技术博客封面,极简科技蓝风格,扁平化UI,LangChain + Qdrant向量数据库,RAG知识库问答系统架构图,Docker容器,向量检索,代码元素,干净渐变背景,上方留白放标题,高清科技风
文末互动
本文完整覆盖了 Qdrant 在 Windows 环境下的 Docker 安装、Python 依赖配置、环境变量管理、QdrantDB 适配器封装、文档建库、向量检索、LCEL 链式 RAG 问答全链路,附带完整可运行代码和高频踩坑排查方案。
大家在搭建 RAG 知识库时,用的是 Milvus、Qdrant 还是其他向量数据库?遇到过哪些部署或检索效果的问题?欢迎评论区交流!
后续持续更新:Embedding 模型对比选型、RAG 检索效果优化、多轮对话记忆持久化、Agent 智能体开发。
点赞 + 收藏,持续更新大模型工程化干货!
更多推荐


所有评论(0)