RAG / vector search
Three independently swappable pieces: an EmbeddingProvider (text → vectors), a VectorStore (stores/searches vectors), and createRetrievalTool() (wires them into something the model can call).
rag.ts
import {
createClient, anthropic, defineAgent, runAgent,
openaiEmbeddings, InMemoryVectorStore, createRetrievalTool, embedChunks,
} from "samai-sdk";
const embeddings = openaiEmbeddings({ apiKey: process.env.OPENAI_API_KEY }); // needs `openai` installed
const store = new InMemoryVectorStore(); // or `new PineconeVectorStore({ indexHost: "..." })` for production
// Ingest: embed your chunks once, upsert into the store.
const records = await embedChunks(embeddings, [
{ id: "doc-1", text: "Refunds are processed within 3-5 business days." },
{ id: "doc-2", text: "Reset your password from Settings > Security." },
]);
await store.upsert(records);
// Give the agent a tool that can search what you just ingested.
const supportAgent = defineAgent({
name: "support_agent",
instructions: "Use retrieve_knowledge to ground answers in the docs before replying.",
model: "claude-sonnet-4-6",
tools: [createRetrievalTool({ embeddings, store, options: { topK: 3 } })],
});
const client = createClient({ provider: anthropic({ apiKey: process.env.ANTHROPIC_API_KEY }) });
const result = await runAgent(client, supportAgent, "How long do refunds take?");The pieces
| Piece | Notes |
|---|---|
InMemoryVectorStore | Brute-force cosine similarity, zero setup — fine for prototyping and a few thousand vectors. |
PineconeVectorStore({ indexHost, apiKey }) | Talks to Pinecone's REST API directly over fetch, no extra SDK dependency. |
| Custom “VectorStore” | Three methods (upsert/query/delete) — same shape as SessionStore — for pgvector, Qdrant, Weaviate, etc. |
openaiEmbeddings() | Default EmbeddingProvider, via the OpenAI embeddings endpoint. |
Scoping retrieval
createRetrievalTool() accepts topK and a metadata filter (e.g. { tenantId: "acme" }) to scope retrieval — both apply on every call the model makes to the tool.