作者:张富春(ahfuzhang),转载时请注明作者和引用链接,谢谢!
背景
为了早点搞懂公司的百万行 C# 的祖传代码,我想在缺乏文档、缺乏帮手的情况下,先建立一个 企业知识库 来快速帮我理清头绪。
一开始,我是打算以 weaviate 来作为向量数据库,然后把已有的文档和代码信息都写入向量数据库中;
最后,配合本地的大模型来写提示词进行 AI 总结就行了。
第一期,我先整理了文档,并写入 weaviate。
并且打算也做一个拟人化的 AI 问答助手。
终于在上周,实现了这个问答助手。长这样:
(这个形象一看就给人一种聪明绝顶的感觉......)
实际使用者发现 AI 汇总功能执行得非常慢,且结果也差强人意。
通过思考过程发现,codex 使用了 BM25(Best Matching 25)来在 weaviate 中检索。这也难怪,我为了导入方便,直接把整个文档导入到了 weaviate,没有先为文档计算向量。
于是,我尝试使用了 qdrant 向量数据库。
直观的感受上,查询速度和查询结果都好了很多。
下面是我部署的细节:
Cooking 搞起
qdrant 服务器
docker 命令如下:
bash
docker run -it --rm \
--name qdrant \
-p 6333:6333 \
-p 6334:6334 \
-v "/Users/ahfu/Downloads/temp/2026/qdrant_storage:/qdrant/storage" \
-e QDRANT__SERVICE__API_KEY='my-secret-key' \
qdrant/qdrant:v1.15.4
- 6333 是 http 端口
- 6334 是 grpc 端口
QDRANT__SERVICE__API_KEY来为服务器设置一个 api key
但是,这个服务器并不提供 MCP 的接口,为了方便文档导入 + AI 检索,还需要再部署 MCP 服务器。
mcp-server-qdrant
官方提供的 MCP 服务器没有提供镜像,需要自己 clone 仓库并自己进行 docker build.
仓库地址是:https://github.com/qdrant/mcp-server-qdrant
此外,还需要一个对中文友好的用于对文件计算向量值的工具。mcp-server-qdrant 内置了 FastEmbed 运行环境,可以在启动时下载 BAAI/bge-small-zh-v1.5 模型来做向量计算。
启动方法如下:
bash
docker build -t mcp-server-qdrant .
docker run -it --rm \
--name mcp-server-qdrant \
-p 8098:8080 \
-e QDRANT_URL=http://host.docker.internal:8099 \
-e QDRANT_API_KEY=my-super-secret-key \
-e FASTMCP_SERVER_HOST="0.0.0.0" \
-e FASTMCP_SERVER_PORT="8080" \
-e EMBEDDING_MODEL="BAAI/bge-small-zh-v1.5" \
-e QDRANT_READ_ONLY=false \
-e QDRANT_CREATE_COLLECTION=true \
mcp-server-qdrant \
uvx mcp-server-qdrant --transport streamable-http
测试一下:
bash
curl -i \
-X POST \
http://127.0.0.1:8098/mcp/ \
-H 'Content-Type: application/json' \
-H 'Accept: application/json, text/event-stream' \
-d '{
"jsonrpc": "2.0",
"id": 1,
"method": "initialize",
"params": {
"protocolVersion": "2025-06-18",
"capabilities": {},
"clientInfo": {
"name": "curl",
"version": "1.0"
}
}
}'
但是, MCP 服务有两个问题:
- MCP 服务不提供 API KEY 的校验,部署后直接通过 qdrant 的 key 访问到后端,直接就裸奔了;
- 每次启动都要花时间去下载模型,提早打包在镜像内更好
因此,我 folk 了这个仓库,增加了上述功能。地址在:https://github.com/ahfuzhang/mcp-server-qdrant/tree/dev
也可以直接使用我构建好的镜像:https://hub.docker.com/repository/docker/ahfuzhang/mcp-server-qdrant/tags
增加 MCP API KEY 校验方法的启动方式为:
bash
docker run -d --rm \
--name mcp-server-qdrant \
-p 8098:8080 \
-e QDRANT_URL=http://host.docker.internal:6333 \
-e QDRANT_API_KEY=my-secret-key \
-e FASTMCP_SERVER_HOST="0.0.0.0" \
-e FASTMCP_SERVER_PORT="8080" \
-e EMBEDDING_MODEL="BAAI/bge-small-zh-v1.5" \
-e QDRANT_READ_ONLY=false \
-e QDRANT_CREATE_COLLECTION=true \
-e MCP_API_KEY="ahfu_mcp_key" \
ahfuzhang/mcp-server-qdrant:v0.1.0 \
mcp-server-qdrant --transport streamable-http
在 K8s 中部署
可以使用 sidecar 的方式,把 qdrant 和 mcp-server-qdrant 部署在一个 stateful set 之中:
yaml
apiVersion: v1
kind: Secret
metadata:
name: qdrant-secrets
namespace: our-team
type: Opaque
stringData:
QDRANT_API_KEY: "my-secret-key"
MCP_API_KEY: "ahfu_mcp_key"
----
apiVersion: apps/v1
kind: StatefulSet
metadata:
name: qdrant-0
labels:
app: qdrant
namespace: our-team
spec:
serviceName: qdrant-headless
replicas: 1
podManagementPolicy: Parallel
selector:
matchLabels:
app: qdrant
template:
metadata:
labels:
app: qdrant
spec:
containers:
- name: qdrant
image: qdrant/qdrant:v1.15.4
imagePullPolicy: IfNotPresent
ports:
- name: http
containerPort: 6333
- name: grpc
containerPort: 6334
env:
- name: QDRANT__SERVICE__API_KEY
valueFrom:
secretKeyRef:
name: qdrant-secrets
key: QDRANT_API_KEY
readinessProbe:
httpGet:
path: /readyz
port: 6333
initialDelaySeconds: 10
periodSeconds: 10
livenessProbe:
httpGet:
path: /livez
port: 6333
initialDelaySeconds: 30
periodSeconds: 20
resources:
limits:
cpu: "8"
memory: 8Gi
requests:
cpu: "8"
memory: 8Gi
volumeMounts:
- name: qdrant-data
mountPath: /qdrant/storage
- name: mcp-server-qdrant
image: ahfuzhang/mcp-server-qdrant:v0.1.0
imagePullPolicy: IfNotPresent
command:
- mcp-server-qdrant
- --transport
- streamable-http
ports:
- name: mcp-http
containerPort: 8080
env:
- name: QDRANT_URL
value: "http://localhost:6333"
- name: QDRANT_API_KEY
valueFrom:
secretKeyRef:
name: qdrant-secrets
key: QDRANT_API_KEY
- name: MCP_API_KEY
valueFrom:
secretKeyRef:
name: qdrant-secrets
key: MCP_API_KEY
- name: FASTMCP_SERVER_HOST
value: "0.0.0.0"
- name: FASTMCP_SERVER_PORT
value: "8080"
- name: EMBEDDING_MODEL
value: "BAAI/bge-small-zh-v1.5"
- name: QDRANT_READ_ONLY
value: "false"
- name: QDRANT_CREATE_COLLECTION
value: "true"
resources:
limits:
cpu: "2"
memory: 2Gi
requests:
cpu: "1"
memory: 1Gi
volumeClaimTemplates:
- metadata:
name: qdrant-data
spec:
accessModes: ["ReadWriteOnce"]
storageClassName: alicloud-disk
resources:
requests:
storage: 20Gi
----
apiVersion: v1
kind: Service
metadata:
name: qdrant-headless
namespace: our-team
labels:
app: qdrant
spec:
clusterIP: None
publishNotReadyAddresses: true
selector:
app: qdrant
ports:
- name: http
port: 6333
- name: grpc
port: 6334
----
apiVersion: v1
kind: Service
metadata:
name: qdrant
namespace: our-team
labels:
app: qdrant
spec:
type: NodePort
selector:
app: qdrant
ports:
- name: mcp-http
protocol: TCP
port: 8080
targetPort: 8080
nodePort: 30313
配置到 codex
在 $CODEX_HOME 的 config.toml 中增加:
toml
[mcp_servers.qdrant]
url = "http://10.105.xx.xx:30313/mcp"
bearer_token_env_var = "MCP_API_KEY"
然后 shell 中增加:
bash
export MCP_API_KEY=ahfu_mcp_key
提示词中指明需要使用向量数据库:
text
回答下面的问题时,必须优先查询 MCP 中的企业知识库。
步骤:
1. 查看可用 collection。
2. 找到包含企业文档/代码知识的 collection。
3. 使用 qdrant_qdrant-find 搜索相关内容。(支持向量搜索)
4. 如果第一次结果不足,修改关键词再次搜索。
5. 基于检索到的内容回答。
6. 告诉我答案依据了哪些文件/path/document。
7. 如果查不到就返回查不到,不要做猜测
问题:
/GetUserInfo 这条接口,有哪些请求参数?
实在是太爽了,如果自己亲手去找,不知道要找多久!
总结
本文简单的尝试了一下 qdrant 数据库,初步的感觉是好于 weaviate 数据库的,只是部署和使用上比 weaviate 稍麻烦一些。
- 导入到 qdrant 中的文档,先经过 MCP 服务器内的
BAAI/bge-small-zh-v1.5模型来为中文文本计算向量值 - 支持向量值的搜索,其速度和质量比
BM25(Best Matching 25)算法更好。
Have Fun.
😃