Skip to content

04-vector-store.ts

VectorStore 示例,将文本向量化并存入内存向量库进行相似度检索。

功能介绍

这个示例演示了如何使用 OpenAIEmbeddings 将文档向量化,并用 MemoryVectorStore 存储与检索。

使用场景

  • 将文档转换为向量存储
  • 计算文本之间的相似度
  • 构建语义搜索系统
  • 文本聚类和分类
  • 基于向量库的检索增强生成(RAG)

学习要点

  1. 使用 OpenAIEmbeddings 创建向量化器
  2. 使用 model 而不是 modelName 参数
  3. embedQuery() 用于向量化单个查询文本
  4. embedDocuments() 用于批量向量化多个文档
  5. 向量是浮点数数组,维度取决于模型
  6. 进行环境变量检查和错误处理
  7. 使用 MemoryVectorStore.fromDocuments() 创建内存向量库
  8. 使用 similaritySearch() 进行相似度检索
  9. fromDocuments() 内部会自动调用 embeddings.embedDocuments(),VectorStore 演示部分无需再手动调用

源码

typescript
import "dotenv/config";
import { Document } from "@langchain/core/documents";
import { RecursiveCharacterTextSplitter } from "@langchain/textsplitters";
import { OpenAIEmbeddings } from "@langchain/openai";
import { MemoryVectorStore } from "@langchain/classic/vectorstores/memory";

if (!process.env.ZHIPUAI_API_KEY) {
  throw new Error("ZHIPUAI_API_KEY is not set in environment variables");
}

async function main() {
  try {
    console.log("=== VectorStore 示例 ===\n");

    // 创建示例文档
    const docs = [
      new Document({
        pageContent: "LangChain 是一个用于开发由语言模型驱动的应用程序的框架,提供了模块化的组件设计。",
        metadata: { topic: "intro" },
      }),
      new Document({
        pageContent: "LangChain 的核心组件包括 Models、Prompts、Chains、Agents 和 Memory,各自负责不同职责。",
        metadata: { topic: "components" },
      }),
      new Document({
        pageContent: "LangChain 常用于构建客服机器人、文档问答系统、代码分析工具等场景。",
        metadata: { topic: "use-cases" },
      }),
      new Document({
        pageContent: "相比直接调用 OpenAI API,LangChain 提供了更高级的抽象和生态,适合复杂的多步推理任务。",
        metadata: { topic: "comparison" },
      }),
    ];

    const splitter = new RecursiveCharacterTextSplitter({
      chunkSize: 100,
      chunkOverlap: 20,
    });

    const chunks: Document[] = await splitter.splitDocuments(docs);

    // 创建 embeddings
    const embeddings = new OpenAIEmbeddings({
      model: "embedding-3",
      configuration: {
        baseURL: "https://ark.cn-beijing.volces.com/api/coding/v3/",
        apiKey: process.env.ZHIPUAI_API_KEY,
      },
    });

    // 嵌入单个文本
    const query = "LangChain 的主要概念有哪些?";
    const queryEmbedding = await embeddings.embedQuery(query);

    console.log("Query:", query);
    console.log("Embedding dimension:", queryEmbedding.length);
    console.log("First 5 values:", queryEmbedding.slice(0, 5));
    console.log("\n");

    // 嵌入文档块
    const chunkTexts = chunks.map((chunk: Document) => chunk.pageContent);
    const chunkEmbeddings = await embeddings.embedDocuments(chunkTexts);

    console.log("Embedded", chunkEmbeddings.length, "chunks");
    chunkTexts.forEach((text: string, i: number) => {
      console.log(`Chunk ${i + 1}: "${text.slice(0, 50)}..."`);
    });

    // 创建内存向量库并存入文档
    const vectorStore = await MemoryVectorStore.fromDocuments(chunks, embeddings);

    // 相似度检索
    const searchQuery = "LangChain 有哪些组件?";
    const results = await vectorStore.similaritySearch(searchQuery, 2);
    console.log("\n");
    console.log(`检索: ${searchQuery}`);
    console.log("Top 2 结果:");
    results.forEach((doc: Document, i: number) => {
      console.log(`${i + 1}. [topic=${doc.metadata.topic}] ${doc.pageContent.slice(0, 50)}...`);
    });
  } catch (error) {
    console.error("Error during vector store example:", error);
    process.exit(1);
  }
}

main().catch(console.error);

运行方式

bash
npm run dev src/04-rag/04-vector-store.ts