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 vectorstoresvercelTool: Wrap a vectorstores retriever as a Vercel AI SDK tool for agentic workflows
Installation
Section titled “Installation”npm install @vectorstores/vercel @vectorstores/core ai @ai-sdk/openaiUsing vercelEmbedding
Section titled “Using vercelEmbedding”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 embeddingsconst index = await VectorStoreIndex.fromDocuments(documents, { embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),});
// Query the indexconst 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.).
Using vercelTool
Section titled “Using vercelTool”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 retrieverconst index = await VectorStoreIndex.fromDocuments(documents, { embedFunc: vercelEmbedding(openai.embedding("text-embedding-3-small")),});const retriever = index.asRetriever();
// Use the retriever as a tool in streamTextconst 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);}vercelTool Options
Section titled “vercelTool Options”| Option | Type | Required | Description |
|---|---|---|---|
retriever | BaseRetriever | Yes | The vectorstores retriever to wrap |
description | string | Yes | Description for the LLM to understand when to use the tool |
noResultsMessage | string | No | Message returned when no results are found (default: “No results found in documents.”) |
Agentic RAG Example
Section titled “Agentic RAG Example”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);How Agentic RAG Works
Section titled “How Agentic RAG Works”The agentic RAG pattern uses vercelTool to give the LLM autonomous access to your knowledge base:
- The LLM receives the user’s question
- It decides whether to use the
vercelToolto search the knowledge base - If it calls the tool, the retriever searches the indexed documents
- The retrieved information is formatted and returned to the LLM
- The LLM uses this information to generate a response
- The process can repeat for multi-step reasoning (limited by
stepCountIs) - The final response is streamed to the user
Agent Memory Example
Section titled “Agent Memory Example”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);Reranking with Cohere
Section titled “Reranking with Cohere”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);Next Steps
Section titled “Next Steps”- Experiment with different retrieval strategies and tool configurations
- Try using different Vercel AI model providers