@langchain/qdrant 集成指南:在 LangChain.js 中使用 Qdrant 向量数据库
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
本篇指南以langchainjs仓库中 @langchain/qdrant 包 为对象,系统讲解该 LangChain.js 官方 Qdrant 向量数据库集成包的安装方式、核心 API 能力与配置参数,并结合仓库源码与测试用例剖析其底层实现原理,同时完整覆盖该包的本地开发、构建、测试与发布工作流。读完本文,你将掌握如何在自己的应用中完成 Qdrant 的安装接入、向量写入与相似度检索,以及如何以贡献者身份在该仓库中开发、验证并扩展@langchain/qdrant。
一、包定位与核心能力
@langchain/qdrant是 LangChain.js 官方维护的 Qdrant 向量数据库集成包。Qdrant 是一个高性能向量搜索引擎与相似度检索引擎,而本包通过 LangChain.js 统一的VectorStore抽象,将 Qdrant 无缝接入到 RAG、语义搜索、文档问答等应用中。
从源码结构看,该包的导出全部集中在 src/index.ts,它只做了一件事:export * from "./vectorstores.js",即对外暴露 vectorstores.ts 中定义的QdrantVectorStore类及配套类型。包的核心能力包括:
- 写入:
addDocuments/addVectors,将文档及其向量写入 Qdrant 集合; - 检索:
similaritySearch、similaritySearchVectorWithScore、maxMarginalRelevanceSearch(MMR 最大边际相关性检索); - 删除:
delete,支持按 ID 或按过滤器批量删除; - 集合管理:
ensureCollection,集合不存在时自动创建; - 工厂方法:
fromTexts、fromDocuments、fromExistingCollection三种快速初始化路径。
依赖方面,包在运行时仅依赖@qdrant/js-client-rest(版本^1.19.0),并将@langchain/core作为 peerDependency,相关声明可见 package.json。
二、安装与前置要求
在你的 LangChain.js 项目中安装该集成包:
npm install @langchain/qdrant由于@langchain/core是 peerDependency,通常需要一并安装@langchain/core与具体的 Embeddings 模型包(如 OpenAI、Anthropic 等)才能完整运行。此外,根据 package.json 中的engines字段,该包要求Node.js >= 20。
三、核心 API 与配置参数详解
QdrantVectorStore的构造函数签名为constructor(embeddings, args),其中args的类型是QdrantLibArgs,其字段定义见 vectorstores.ts:
| 参数 | 类型 | 说明 | 默认值 |
|---|---|---|---|
client | QdrantClient | 直接传入已配置好的 Qdrant 客户端实例 | 无(与url二选一) |
url | string | Qdrant 服务地址 | 环境变量QDRANT_URL |
apiKey | string | Qdrant API Key | 环境变量QDRANT_API_KEY |
collectionName | string | 目标集合名称 | "documents" |
collectionConfig | QdrantSchemas["CreateCollection"] | 创建集合时的配置(向量维度、距离度量等) | 自动探测维度 +Cosine距离 |
customPayload | Record<string, any>[] | 附加到每个点的自定义载荷数组,与文档一一对应 | 无 |
contentPayloadKey | string | 存储文档正文的 payload 键名 | "content" |
metadataPayloadKey | string | 存储文档元数据的 payload 键名 | "metadata" |
构造函数内部(vectorstores.ts)的解析逻辑如下:
url与apiKey优先取构造参数,其次回退到环境变量QDRANT_URL/QDRANT_API_KEY;- 若既未传入
client也未解析到url,直接抛出"Qdrant client or url address must be set."; - 若传入了
client,则直接复用,否则内部new QdrantClient({ url, apiKey }); - 同时,
lc_secrets声明了apiKey与url对应的环境变量名,这使得该 store 可以配合 LangChain 的序列化/追踪机制安全地处理密钥。
连接方式一:URL + API Key
import { QdrantVectorStore } from "@langchain/qdrant"; import { OpenAIEmbeddings } from "@langchain/openai"; const store = new QdrantVectorStore(new OpenAIEmbeddings(), { url: "http://localhost:6333", apiKey: process.env.QDRANT_API_KEY, collectionName: "my_documents", });连接方式二:直接传入 QdrantClient
import { QdrantClient } from "@qdrant/js-client-rest"; import { QdrantVectorStore } from "@langchain/qdrant"; const client = new QdrantClient({ url: process.env.QDRANT_URL, apiKey: process.env.QDRANT_API_KEY, }); const store = new QdrantVectorStore(new OpenAIEmbeddings(), { client, collectionName: "my_documents", });连接方式三:通过环境变量
// 设置环境变量后即可省略 url / apiKey // export QDRANT_URL=http://localhost:6333 // export QDRANT_API_KEY=your-key const store = new QdrantVectorStore(new OpenAIEmbeddings(), { collectionName: "my_documents", });四、文档写入:从文本到 Qdrant 点
4.1 addDocuments 的完整链路
addDocuments(documents, documentOptions?)的执行流程(vectorstores.ts)为:
- 提取所有文档的
pageContent文本; - 调用
this.embeddings.embedDocuments(texts)批量生成向量; - 将向量与文档一起交给
addVectors。
addVectors(vectorstores.ts)在写入前会先调用ensureCollection()确保集合存在,随后将每个向量构造成 Qdrant 的 point:
const points = vectors.map((embedding, idx) => ({ id: documents[idx].id ?? documentOptions?.ids?.[idx] ?? uuid(), vector: embedding, payload: { [this.contentPayloadKey]: documents[idx].pageContent, [this.metadataPayloadKey]: documents[idx].metadata, customPayload: documentOptions?.customPayload?.[idx], }, })); await this.client.upsert(this.collectionName, { wait: true, points });关键细节:
- Point ID 优先级:
Document.id>documentOptions.ids[idx]> 自动生成的uuid()(来自@langchain/core/utils/uuid); - 同步等待:
upsert使用wait: true,确保写入落盘后才返回,保证后续检索的强一致性; - 错误包装:写入失败时会将 HTTP 状态码与错误消息包装成统一
Error抛出; - 自定义载荷:
customPayload数组与文档一一对应,可写入检索时不参与向量比较、但用于过滤的额外业务字段。
4.2 三个工厂方法
| 工厂方法 | 适用场景 | 行为 |
|---|---|---|
fromTexts(texts, metadatas, embeddings, dbConfig) | 从纯文本数组快速初始化 | 逐条构造Document并调用fromDocuments |
fromDocuments(docs, embeddings, dbConfig) | 从Document数组初始化 | 构造 store 实例并写入全部文档 |
fromExistingCollection(embeddings, dbConfig) | 连接已存在的集合 | 只做ensureCollection,不写入任何文档 |
其中fromDocuments(vectorstores.ts)在dbConfig携带customPayload时会自动将其作为documentOptions传入addDocuments。集成测试 vectorstores.int.test.ts 演示了用fromDocuments配合显式QdrantClient、使用与默认不同维度(384 维)的 embedding 创建独立集合的用法。
五、相似度检索:向量查询与 MMR
5.1 similaritySearchVectorWithScore
这是所有相似度检索的底层实现(vectorstores.ts):
const results = ( await this.client.query(this.collectionName, { query, limit: k, filter, with_payload: [this.metadataPayloadKey, this.contentPayloadKey], with_vector: false, }) ).points;其要点:
- 通过 Qdrant REST 客户端的
query接口执行近邻检索,limit为返回条数k; - 仅回传
content与metadata两个 payload 字段,with_vector: false不返回向量,降低带宽开销; - 结果被映射为
[Document, number][],即每个文档附带相似度得分score,Document.id取自 Qdrant point 的id; - 检索前同样会调用
ensureCollection(),避免集合缺失时报错。
单元测试 vectorstores.test.ts 用 mock client 验证了「写入后调用similaritySearch」的完整调用链,集成测试则验证了写入后能精确检索回原文档(含id、metadata、pageContent完全一致)。
5.2 MMR 最大边际相关性检索
maxMarginalRelevanceSearch(query, options)(vectorstores.ts)在相似度的基础上引入多样性,避免返回内容高度重复的结果:
const results = ( await this.client.query(this.collectionName, { query: { nearest: queryEmbedding, mmr: { diversity: options.lambda ?? null, candidates_limit: options?.fetchK ?? 20, }, }, limit: options.k, filter: options?.filter, with_payload: [this.metadataPayloadKey, this.contentPayloadKey], with_vector: true, }) ).points;MMR 是 Qdrant 服务端原生支持的检索模式,本包通过query.nearest + query.mmr的组合直接透传:
k:最终返回的文档数量;fetchK:先取多少个候选再执行 MMR 重排,默认20;lambda:0~1 之间控制多样性程度,0对应最大多样性,1对应最小多样性(最接近纯相似度),不传时为null;- 与普通检索不同,MMR 需要
with_vector: true回传向量供服务端计算多样性。
单元测试 vectorstores.test.ts 精确断言了 MMR 模式下client.query的入参结构;集成测试 vectorstores.int.test.ts 验证了在语义差异明显的文档集上执行maxMarginalRelevanceSearch能返回预期的多样结果。
5.3 过滤与删除
QdrantVectorStore的FilterType直接复用了 Qdrant 的过滤类型QdrantSchemas["Filter"],因此可以构造任意复杂的条件过滤查询(字段条件、must / should / must_not 组合等),filter参数被原样透传给服务端。
delete(params)(vectorstores.ts)支持两种删除方式,且二者互斥(ids与filter只能选其一,否则抛错):
- 按 ID 删除:
{ ids: string[], shardKey? },内部按每批 1000 个 ID 分批调用 Qdrant 的delete接口; - 按过滤器删除:
{ filter: object, shardKey? },一次调用删除所有匹配的点。
两种方式都使用wait: true与ordering: "weak"确保删除即时生效。
六、集合自动创建机制
ensureCollection()(vectorstores.ts)是写入与检索前都会执行的自愈逻辑:
const response = await this.client.getCollections(); const collectionNames = response.collections.map((c) => c.name); if (!collectionNames.includes(this.collectionName)) { const collectionConfig = this.collectionConfig ?? { vectors: { size: (await this.embeddings.embedQuery("test")).length, distance: "Cosine", }, }; await this.client.createCollection(this.collectionName, collectionConfig); }若目标集合不存在,它会:
- 调用当前 Embeddings 实例对
"test"做一次查询嵌入,自动探测向量维度; - 默认使用Cosine 余弦距离作为相似度度量;
- 调用
createCollection创建集合。
如果你对维度、距离度量(如Dot、Euclid)或量化配置有特殊要求,可通过collectionConfig参数传入完整的 QdrantCreateCollection配置覆盖默认行为,避免自动创建的默认配置与模型维度不匹配。
七、本地开发与贡献指南
7.1 安装依赖
该包属于 pnpm workspace 的一部分,在仓库根目录执行:
pnpm install按仓库约定(见 AGENTS.md),建议先构建核心包再开发依赖它的集成包:
pnpm --filter @langchain/core build7.2 构建包
在包目录内构建:
pnpm build或从仓库根目录按 filter 构建(这也是 README 推荐的等价写法):
pnpm build --filter @langchain/qdrant构建由 tsdown.config.ts 驱动,入口为./src/index.ts,并通过cjsCompatPlugin同步产出 ESM 与 CJS 双格式产物(见 package.json 中exports的import/require映射)。
7.3 运行测试
该包遵循仓库统一的测试命名约定:
- 单元测试:以
.test.ts结尾,位于src/tests/下,不依赖外部服务; - 集成测试:以
.int.test.ts结尾,需要可用的 Qdrant 实例。
# 运行单元测试 pnpm test # 运行集成测试(需要 Qdrant 服务与 QDRANT_URL 等环境变量) pnpm test:int本仓库中现成的测试文件分别是 vectorstores.test.ts(mock client + FakeEmbeddings 的单元测试,覆盖写入、customPayload、MMR 参数)与 vectorstores.int.test.ts(真实 Qdrant 实例上的端到端验证,默认连接http://localhost:6333,也支持QDRANT_URL、QDRANT_API_KEY、QDRANT_COLLECTION环境变量)。如果你本机通过 Docker 启动了 Qdrant,直接运行pnpm test:int即可复现上述集成测试。
7.4 代码规范检查
开发完成后运行 lint 与格式化,保证代码符合仓库标准:
pnpm lint && pnpm formatlint会依次执行 ESLint 检查与 dpdm 循环依赖检测(见 package.json 的 scripts)。
7.5 新增导出入口
如果新增了需要对外暴露的模块:
- 在
src/index.ts中import并re-export; - 或在 package.json 的
exports字段中登记新的入口; - 重新执行
pnpm build生成新的 entrypoint 产物。
八、小结
@langchain/qdrant以一个轻量的QdrantVectorStore类,将 Qdrant 的能力完整封装进 LangChain.js 的VectorStore生态:自动建集合、向量写入、相似度检索、MMR 多样检索、按 ID/过滤器删除、三种工厂方法一应俱全。无论你是想快速接入现有 Qdrant 集合,还是希望为集成包的开发贡献力量,都可以从 vectorstores.ts 的源码和 vectorstores.int.test.ts 的测试入手,结合本文的配置参数表与实践示例,快速落地你的语义检索应用。
【免费下载链接】langchainjsThe agent engineering platform项目地址: https://gitcode.com/GitHub_Trending/la/langchainjs
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考