Skip to content

Vercel

This guide demonstrates how to integrate vectorstores with Vercel’s AI SDK. The @vectorstores/vercel package provides two key utilities:

  • vercelEmbedding: Use any Vercel AI SDK embedding model with vectorstores
  • vercelTool: Wrap a vectorstores retriever as a Vercel AI SDK tool for agentic workflows
Terminal window
npm install @vectorstores/vercel @vectorstores/core ai @ai-sdk/openai

The vercelEmbedding function wraps any Vercel AI SDK embedding model to make it compatible with vectorstores:

import { openai } from "@ai-sdk/openai";
import { Document, VectorStoreIndex } from "@vectorstores/core";
import { vercelEmbedding } from "@vectorstores/vercel";
// Create a vector index using Vercel AI SDK embeddings
const index = await VectorStoreIndex.fromDocuments(documents, {
embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),
});
// Query the index
const retriever = index.asRetriever();
const results = await retriever.retrieve({ query: "What is AI?" });

This works with any Vercel AI SDK compatible embedding provider (OpenAI, Cohere, etc.).

The vercelTool function creates a Vercel AI SDK tool from a vectorstores retriever, enabling agentic RAG workflows:

import { openai } from "@ai-sdk/openai";
import { Document, VectorStoreIndex } from "@vectorstores/core";
import { vercelEmbedding, vercelTool } from "@vectorstores/vercel";
import { stepCountIs, streamText } from "ai";
// Create index and retriever
const index = await VectorStoreIndex.fromDocuments(documents, {
embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),
});
const retriever = index.asRetriever();
// Use the retriever as a tool in streamText
const result = streamText({
model: openai("gpt-5-mini"),
prompt: "What are the key concepts in AI?",
tools: {
queryKnowledge: vercelTool({
retriever,
description: "Search the AI knowledge base for information.",
}),
},
stopWhen: stepCountIs(5),
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
OptionTypeRequiredDescription
retrieverBaseRetrieverYesThe vectorstores retriever to wrap
descriptionstringYesDescription for the LLM to understand when to use the tool
noResultsMessagestringNoMessage returned when no results are found (default: “No results found in documents.”)

Here’s a complete example showing how to use vercelEmbedding and vercelTool together:

import { openai } from "@ai-sdk/openai";
import { Document, VectorStoreIndex } from "@vectorstores/core";
import { vercelEmbedding, vercelTool } from "@vectorstores/vercel";
import { stepCountIs, streamText } from "ai";
import fs from "node:fs/promises";
async function main() {
// Load document
const essay = await fs.readFile("./data/essay.txt", "utf-8");
const document = new Document({ text: essay, id_: "essay" });
// Create index with Vercel AI SDK embeddings
const index = await VectorStoreIndex.fromDocuments([document], {
embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),
});
// Create retriever from index
const retriever = index.asRetriever();
const result = streamText({
model: openai("gpt-5-mini"),
prompt: "Cost of moving cat from Russia to UK?",
tools: {
queryTool: vercelTool({
retriever,
description: "get information from your knowledge base to answer questions.",
}),
},
stopWhen: stepCountIs(5),
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
}
main().catch(console.error);

The agentic RAG pattern uses vercelTool to give the LLM autonomous access to your knowledge base:

  1. The LLM receives the user’s question
  2. It decides whether to use the vercelTool to search the knowledge base
  3. If it calls the tool, the retriever searches the indexed documents
  4. The retrieved information is formatted and returned to the LLM
  5. The LLM uses this information to generate a response
  6. The process can repeat for multi-step reasoning (limited by stepCountIs)
  7. The final response is streamed to the user

This example demonstrates building an agent with long-term memory using vectorstores. The agent can store and retrieve memories about the user:

import { openai } from "@ai-sdk/openai";
import { VectorStoreIndex } from "@vectorstores/core";
import { vercelEmbedding, vercelTool } from "@vectorstores/vercel";
import { stepCountIs, streamText, tool } from "ai";
import { z } from "zod";
async function main() {
// Create an empty vector store index for storing memories
const index = await VectorStoreIndex.init({
embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),
});
const retriever = index.asRetriever({ similarityTopK: 3 });
const result = streamText({
model: openai("gpt-5-mini"),
system: "You are a helpful assistant that can store and retrieve memories about the user.",
prompt: "My name is Alice and I love hiking in the mountains.",
tools: {
addMemory: tool({
description: "Store important information about the user in long-term memory.",
inputSchema: z.object({
memory: z.string().describe("The information to remember."),
}),
execute: async ({ memory }: { memory: string }) => {
await index.insertText(memory, {
timestamp: new Date().toISOString(),
});
return `Memory stored: ${memory}`;
},
}),
retrieveMemories: vercelTool({
retriever,
description: "Retrieve relevant memories from long-term storage based on a query.",
noResultsMessage: "No relevant memories found in storage",
}),
},
stopWhen: stepCountIs(5),
});
for await (const textPart of result.textStream) {
process.stdout.write(textPart);
}
}
main().catch(console.error);

Combine vectorstores retrieval with Vercel AI SDK’s reranking for improved accuracy:

import { cohere } from "@ai-sdk/cohere";
import { openai } from "@ai-sdk/openai";
import { Document, MetadataMode, VectorStoreIndex } from "@vectorstores/core";
import { vercelEmbedding } from "@vectorstores/vercel";
import { rerank } from "ai";
async function main() {
const document = new Document({ text: essay });
const index = await VectorStoreIndex.fromDocuments([document], {
embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),
});
const retriever = index.asRetriever({ similarityTopK: 5 });
const query = "What did the author do growing up?";
// Retrieve nodes
const nodes = await retriever.retrieve({ query });
// Rerank using Vercel AI SDK
const { ranking } = await rerank({
model: cohere.reranking("rerank-v3.5"),
query,
documents: nodes.map((n) => n.node.getContent(MetadataMode.ALL)),
topN: 2,
});
// Map reranked results back to NodeWithScore format
const rerankedNodes = ranking.map((r) => ({
node: nodes[r.originalIndex].node,
score: r.score,
}));
console.log("Reranked results:", rerankedNodes);
}
main().catch(console.error);
  1. Experiment with different retrieval strategies and tool configurations
  2. Try using different Vercel AI model providers