当前位置: 首页 > news >正文

[LangChain] 15. 内存型向量库

回忆 RAG 关键步骤:

  1. 文本切割
  2. 嵌入处理
  3. 存储向量数据库

向量数据库可以分为这几种类型:

  1. 内存型
  2. 本地自托管
  3. 云托管

LangChain 内置了 MemoryVectorStore,这就是一个内存型向量库,用于将文档向量存储到内存中,适合本地调试、快速演示,零依赖、即插即用。

MemoryVectorStore 整体工作流:

  1. 把要检索的文本包装成 Document
  2. 调用 vectorstore.addDocuments() 触发嵌入;
  3. similaritySearch(...)similaritySearchWithScore(...) 做相似度检索。

1. 实例化内存向量库

import { MemoryVectorStore } from "langchain/vectorstores/memory";const store = new MemoryVectorStore();console.log(store)

效果:

MemoryVectorStore {lc_serializable: false,lc_kwargs: {},lc_namespace: [ 'langchain', 'vectorstores', 'memory' ],embeddings: undefined,memoryVectors: [],similarity: [Function: cosine]
}
  • embeddings:嵌入工具
  • memoryVectors:存储的内存向量

2. 指定嵌入工具

自定义嵌入类:NomicEmbeddings

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { NomicEmbeddings } from "./utils/embed.js"const embeddings = new NomicEmbeddings(4);const store = new MemoryVectorStore(embeddings);console.log(store)

效果:

MemoryVectorStore {lc_serializable: false,lc_kwargs: {},lc_namespace: [ 'langchain', 'vectorstores', 'memory' ],embeddings: NomicEmbeddings {caller: AsyncCaller {maxConcurrency: Infinity,maxRetries: 6,onFailedAttempt: [Function: defaultFailedAttemptHandler],queue: [PQueue]},model: 'nomic-embed-text',apiUrl: 'http://localhost:11434/api/embeddings',concurrency: 4},memoryVectors: [],similarity: [Function: cosine]
}

3. 添加文档

添加文档可以调用 vectorstore 实例的 addDocuments 方法,该方法接收一个数组,数组里面每一项是 Document 实例对象,之后会自动调用 embeddings.embedDocuments 生成向量并存入内存。

await vectorstore.addDocuments([new Document({pageContent: "Vue 是一个渐进式前端框架,易于上手。",metadata: { id: "a1", tag: "frontend" },}),new Document({pageContent: "React 通过 JSX 描述 UI,强调组件化与状态管理。",metadata: { id: "b2", tag: "frontend" },}),new Document({pageContent: "LangChain 提供 RAG 组件与向量检索工具。",metadata: { id: "c3", tag: "ai" },}),
]);

具体示例:

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { NomicEmbeddings } from "./utils/embed.js";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";const loader = new TextLoader("data/kong.txt");const docs = await loader.load();const splitter = new RecursiveCharacterTextSplitter({chunkSize: 64,chunkOverlap: 0,
});const splittedDocs = await splitter.splitDocuments(docs);const embeddings = new NomicEmbeddings(4);const store = new MemoryVectorStore(embeddings);await store.addDocuments(splittedDocs);console.log(store.memoryVectors);

4. 检索操作

首先创建一个检索器:

const retriever = vectorstore.asRetriever(2)

vectorstore.asRetriever(2) 是一个简写,等价于 vectorstore.asRetriever({ k: 2 }),表示创建一个检索器,每次查询返回前 2 条最相似的 Document。返回值是一个 VectorStoreRetriever

快速上手示例:

import { MemoryVectorStore } from "langchain/vectorstores/memory";
import { NomicEmbeddings } from "./utils/embed.js";
import { TextLoader } from "langchain/document_loaders/fs/text";
import { RecursiveCharacterTextSplitter } from "langchain/text_splitter";const loader = new TextLoader("data/kong.txt");const docs = await loader.load();const splitter = new RecursiveCharacterTextSplitter({chunkSize: 64,chunkOverlap: 0,
});const splittedDocs = await splitter.splitDocuments(docs);const embeddings = new NomicEmbeddings(4);const store = new MemoryVectorStore(embeddings);await store.addDocuments(splittedDocs);// 创建一个检索器,现在仓库已经有值了
const retriever = store.asRetriever(1);const res = await retriever.invoke("茴香豆是做什么用的");console.log(res);
store.asRetriever(1)
store.asRetriever({k : 1
})

配置对象支持如下的参数:

const retriever = vectorstore.asRetriever({k: 4,searchType: "mmr",searchKwargs: { fetchK: 20, lambda: 0.5 },filter: (doc) => doc.metadata?.source?.endsWith("data/kong.txt"),tags: ["demo", "kong"],metadata: { lesson: "RAG-intro" },verbose: true,
});
  • k:每次查询返回的文档条数;不填默认 4asRetriever(2)数字简写等价于 { k: 2 }

  • searchType:检索策略:

    • "similarity"(默认):按向量相似度排序返回前 k 条;
    • "mmr":最大边际相关性(Maximal Marginal Relevance),在相关性与多样性之间折中。
  • searchKwargs:MMR 的细化参数,仅当 searchType: "mmr" 时生效

    • fetchK:先抓取的候选集合规模(越大,MMR 可选空间越大)
    • lambda:0~1 的权衡系数;0 更偏向多样性、1 更偏向相关性
  • filter:用于预筛候选文档,返回 true 的文档才参与检索。

  • callbacks:检索过程中的回调钩子(开始/结束/错误等),与 LangChain 的可观测性机制对接。

  • tags:给该检索器打标签,便于在日志/跟踪里区分。

  • metadata:附加的上下文信息,会随运行一起记录,便于审计与调试。

  • verbose:是否开启详细日志,默认 false

另外配置项也支持数字简写,方法签名如下:

asRetriever(kOrFields?, filter?, callbacks?, tags?, metadata?, verbose?)

不过想跳过中间的参数再传后面的,就用 undefined 占位。例如:

const r3 = vectorstore.asRetriever(3, undefined, undefined, ["demo", "kong"]);

另外还有 similaritySearch 以及 similaritySearchWithScore 方法,用法也和上面类似。

平时在使用的时候更推荐使用 asRetriever 方法先创建一个检索器,后期进行检索的时候只需要传入检索文本即可。


-EOF-

http://www.jsqmd.com/news/35283/

相关文章:

  • 完整教程:从架构师视角看 RPC:分布式系统的灵魂纽带
  • 题解:qoj8047 DFS Order 4
  • Oracle数据库恢复检查脚本
  • 视野修炼-技术周刊第126期 | TypeScript #1
  • 详细介绍:FPGA 中的 AXI 总线介绍
  • 深入解析:眼控交互:ErgoLAB新一代人机交互方式
  • 大模型、智能体和MCP服务间的交互
  • 2025年国内成人自考机构口碑推荐排行榜单:权威解析与选择指南
  • 大信息领域列式存储与云存储的融合发展
  • 2025年六安市成人自考机构口碑推荐排行榜
  • 分享一个Oracle 数据库信息收集脚本
  • 2025年11月杭州集训记
  • Bash 入门指南-简介和常见命令
  • 最小多项式与线性递推
  • Zabbix服务告警:More than 75% used in the configuration cache
  • to kill a mocking bird
  • mounriver studio WINDOWS启动报错解决
  • Linux 内核启动日志输出阶段分析
  • Python 潮流周刊#126:新一代静态网站生成器
  • 第二章数据预处理:公式Python代码完成
  • 《代码大全 2》观后感(七):代码重构 —— 让代码 “永葆青春”
  • 吸哎四匹 2025 游击
  • 百度网盘把Windows下的习惯带进了Linux
  • 深入解析:MySQL 存储引擎深度解析:InnoDB 架构与配置优化指南
  • 做题记录(Nov.)
  • 2025年安徽猪肉批发厂家口碑排行TOP5
  • [国家集训队] 飞飞侠 题解
  • 插槽vue/react - 详解
  • AI元人文的思想锻造之路:从“空白承诺”到“动力之源”
  • 251108 会议整理