Skip to main content
If you’re deploying your project in a Cloudflare worker, you can use Cloudflare Vectorize with LangChain.js. It’s a powerful and convenient option that’s built directly into Cloudflare.

Setup

CompatibilityCloudflare Vectorize is currently in open beta, and requires a Cloudflare account on a paid plan to use.
After setting up your project, create an index by running the following Wrangler command:
$ npx wrangler vectorize create <index_name> --preset @cf/baai/bge-small-en-v1.5
You can see a full list of options for the vectorize command in the official documentation. You’ll then need to update your wrangler.toml file to include an entry for [[vectorize]]:
[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "<index_name>"
Finally, you’ll need to install the LangChain Cloudflare integration package:
npm
npm install @langchain/cloudflare @langchain/core

Usage

Below is an example worker that adds documents to a vectorstore, queries it, or clears it depending on the path used. It also uses Cloudflare Workers AI Embeddings.
If running locally, be sure to run wrangler as npx wrangler dev --remote!
name = "langchain-test"
main = "worker.ts"
compatibility_date = "2024-01-10"

[[vectorize]]
binding = "VECTORIZE_INDEX"
index_name = "langchain-test"

[ai]
binding = "AI"
// @ts-nocheck

import type {
  VectorizeIndex,
  Fetcher,
  Request,
} from "@cloudflare/workers-types";

import {
  CloudflareVectorizeStore,
  CloudflareWorkersAIEmbeddings,
} from "@langchain/cloudflare";

export interface Env {
  VECTORIZE_INDEX: VectorizeIndex;
  AI: Fetcher;
}

export default {
  async fetch(request: Request, env: Env) {
    const { pathname } = new URL(request.url);
    const embeddings = new CloudflareWorkersAIEmbeddings({
      binding: env.AI,
      model: "@cf/baai/bge-small-en-v1.5",
    });
    const store = new CloudflareVectorizeStore(embeddings, {
      index: env.VECTORIZE_INDEX,
    });
    if (pathname === "/") {
      const results = await store.similaritySearch("hello", 5);
      return Response.json(results);
    } else if (pathname === "/load") {
      // Upsertion by id is supported
      await store.addDocuments(
        [
          {
            pageContent: "hello",
            metadata: {},
          },
          {
            pageContent: "world",
            metadata: {},
          },
          {
            pageContent: "hi",
            metadata: {},
          },
        ],
        { ids: ["id1", "id2", "id3"] }
      );

      return Response.json({ success: true });
    } else if (pathname === "/clear") {
      await store.delete({ ids: ["id1", "id2", "id3"] });
      return Response.json({ success: true });
    }

    return Response.json({ error: "Not Found" }, { status: 404 });
  },
};
You can also pass a filter parameter to filter by previously loaded metadata. See the official documentation for information on the required format.
Connect these docs programmatically to Claude, VSCode, and more via MCP for real-time answers.
I