> ## Documentation Index
> Fetch the complete documentation index at: https://vibes-sdk.a7ul.com/llms.txt
> Use this file to discover all available pages before exploring further.

# RAG (Retrieval-Augmented Generation)

> Retrieval-augmented generation using a Vibes tool for vector search - swap the mock retriever for any real vector DB.

RAG in Vibes is a tool pattern: the agent calls a retrieval tool that searches a knowledge base, then uses the retrieved context to answer the question. This example uses an in-memory mock  -  replace `vectorSearch()` with your actual vector DB client.

## What you'll learn

* Using `plainTool()` for tools without dependency injection
* Passing retrieved context to the model via tool results
* Structuring a RAG pipeline with Vibes

## Prerequisites

* `ANTHROPIC_API_KEY` set in your environment
* Vibes installed (`deno add jsr:@vibesjs/sdk npm:@ai-sdk/anthropic npm:zod`)

## Complete example

```typescript theme={null}
import { Agent, plainTool } from "jsr:@vibesjs/sdk";
import { anthropic } from "npm:@ai-sdk/anthropic";
import { z } from "npm:zod";

// --- Mock knowledge base ---
// In production: replace with calls to Pinecone, pgvector, Qdrant, etc.
const documents = [
  {
    id: "1",
    content: "Vibes is a TypeScript agent framework built on the Vercel AI SDK.",
    metadata: { source: "overview" },
  },
  {
    id: "2",
    content: "Vibes supports dependency injection via RunContext, passed to all tools and prompts.",
    metadata: { source: "concepts" },
  },
  {
    id: "3",
    content: "The Graph API uses BaseNode classes with next() and output() free functions.",
    metadata: { source: "graph" },
  },
  {
    id: "4",
    content: "Vibes agents can be wrapped with A2AAdapter to expose them as A2A-compatible servers.",
    metadata: { source: "integrations" },
  },
];

// Mock vector search - replace with real vector DB in production
async function vectorSearch(query: string, topK = 3): Promise<string[]> {
  // Naive keyword overlap scoring (real impl uses embedding similarity)
  const queryWords = query.toLowerCase().split(/\s+/);
  const scored = documents.map((doc) => {
    const docWords = doc.content.toLowerCase().split(/\s+/);
    const overlap = queryWords.filter((w) => docWords.includes(w)).length;
    return { content: doc.content, score: overlap };
  });
  return scored
    .sort((a, b) => b.score - a.score)
    .slice(0, topK)
    .map((d) => d.content);
}

// Retrieval tool using plainTool (no deps needed)
const searchDocs = plainTool({
  name: "search_docs",
  description: "Search the Vibes documentation knowledge base for relevant information",
  parameters: z.object({
    query: z.string().describe("The search query"),
  }),
  execute: async ({ query }) => {
    const results = await vectorSearch(query);
    if (results.length === 0) {
      return "No relevant documents found.";
    }
    return results.map((r, i) => `[${i + 1}] ${r}`).join("\n\n");
  },
});

// RAG agent
const ragAgent = new Agent({
  model: anthropic("claude-sonnet-4-6"),
  systemPrompt:
    "You are a documentation assistant. Always use the search_docs tool to find relevant " +
    "information before answering. Base your answer on the retrieved documents.",
  tools: [searchDocs],
});

// Run
const result = await ragAgent.run("How does dependency injection work in Vibes?");
console.log(result.output);
```

## Run it

```bash theme={null}
deno run --allow-net --allow-env rag.ts
```

## How it works

**`plainTool()`**: A simpler variant of `tool()`  -  no `RunContext`, the execute function receives args directly. Use `plainTool()` when your tool doesn't need access to deps. Use `tool()` (or `tool<TDeps>()`) when it does.

**Tool result as context**: When the agent calls `search_docs`, Vibes executes `vectorSearch()` and passes the result back to the model as a tool response. The model uses this retrieved context to form its answer  -  no prompt engineering needed.

**Plugging in a real vector DB**: Replace the `vectorSearch()` function body with your vector DB client. The Vibes pattern is identical regardless of the underlying store. For dependency-injected DB clients (e.g., a shared connection pool), use `tool<Deps>()` and access the client via `ctx.deps`.

<Info>
  The retrieval quality in this example is intentionally minimal (keyword overlap). A real RAG system uses embedding-based semantic search. The Vibes pattern  -  tool calls retriever, model uses results  -  is identical.
</Info>

## Next steps

* [Tools concept page](/concepts/tools)  -  `plainTool`, `tool`, `fromSchema`
* [Dependencies concept page](/concepts/dependencies)  -  for injecting DB clients into tools
