最省事的是 qdrant 或 milvus——二者均有官方 go sdk,支持 http/grpc,文档完备;qdrant 适合中小规模,milvus 适合横向扩展,但需锁死 sdk 版本至 v2.4.5。

用什么向量数据库搭配 Go 最省事
Go 原生不带向量检索能力,得靠外部服务或库。直接上 qdrant 或 milvus 是最稳的选择——它们都有官方维护的 Go SDK,HTTP + gRPC 双支持,文档里连 Upsert 和 Search 的完整调用链都写清楚了。
别碰纯内存向量库(比如 annoy 的 Go 绑定),不是不能用,是它没持久化、没并发控制、没分片逻辑,上线后查三次崩两次。
-
qdrant适合中小规模:单节点扛万级向量没问题,collection创建时指定hnsw参数就能开加速,不用调参 -
milvus适合要横向扩展的场景:但 Go client 对search_with_expression这类高级查询的支持滞后,建议锁死 SDK 版本到v2.4.5再用 - 本地测试可用
chroma,但它 Go client 是社区维护的,GetCollection返回 nil 不报错,得自己判空
文本切块不能只按字数切
用户问“怎么把 PDF 转成能问答的 chunk”,很多人直接上 strings.Split 按换行或 512 字符切,结果模型答非所问——因为语义被硬生生劈开了。
真正有效的切法得保上下文:用 textsplitter 类库(比如 github.com/tmc/langchaingo/textsplitter)里的 RecursiveCharacterTextSplitter,它会优先在 \n\n、\n、 处断,而不是死卡长度。
- PDF 解析推荐
unidoc(商业授权)或pdfcpu(MIT),别用gofpdf——它不提取文本,只画 PDF - chunk size 设 256–512 token,对应 embedding 模型输入上限;
overlap至少设 64,否则段落衔接处信息丢失严重 - 切完必须去重:
md5.Sum([]byte(chunk))存 map 判重,PDF 里常有重复页眉页脚
embedding 调用失败八成是 context deadline exceeded
Go 里调 OpenAI / Ollama / 本地 bert-base-zh 做 embedding,最常见的错误不是 API key 错,而是 context.DeadlineExceeded——尤其用 http.DefaultClient 默认 30 秒超时,大 batch 向量化直接跪。
必须显式控制超时和重试:
- 用
http.Client{Timeout: 120 * time.Second},别依赖默认值 - 对
EmbedDocuments这类批量接口,拆成每 10 条一组发请求,避免单次 payload 过大触发 nginx 413 - Ollama 本地部署时,确认
OLLAMA_HOST环境变量指向http://localhost:11434,不是127.0.0.1——Docker 容器内解析不到 - 错误日志里看到
EOF或connection refused,先curl -v http://localhost:11434/health看服务是否真活着
问答时 query embedding 和 chunk embedding 必须同源
线上最隐蔽的 bug:query 用 text-embedding-3-small 编码,chunk 却用 multilingual-e5-large 存进 Qdrant——余弦相似度算出来全是噪声,返回结果看着像人话,实际驴唇不对马嘴。
解决方法就一条铁律:embedding 模型、tokenizer、归一化方式,三者必须完全一致。
- 存 chunk 前记下模型名,写进 Qdrant
collection的metadata字段,比如{"embedding_model": "bge-m3"} - query 请求进来时,先读 collection metadata,动态选 client;别写死
client.Embed调用 - 如果要用多个模型做 A/B 测试,必须建不同
collection,别试图在同一个 collection 里混用 - 本地验证时,拿一个固定句子跑两次 embedding,用
reflect.DeepEqual对比输出 slice,不相等立刻停机检查
向量对齐这事没法“差不多就行”,差一个归一化参数,召回结果就全偏了。上线前务必拿 10 个真实 query 手动比对原始 chunk 和返回 chunk 的语义匹配度,别光看 top1 准确率。
golang免费学习笔记(深入):立即使用
在学习笔记中,你将探索golang的核心概念和高级技巧!











