RAG, Vectorize, and AI Search
Use this skill for retrieval augmented generation, semantic search, and document Q&A.
Choose AI Search vs Vectorize
- Use AI Search when you want managed ingestion, retrieval, hybrid search/reranking features, and simpler RAG setup.
- Use Vectorize when you need direct control over embedding generation, chunking, metadata, index operations, and query flow.
- Store source documents and metadata outside the index. Retrieval indexes are derived data.
RAG pipeline
Upload document
-> R2 stores original bytes
-> D1 stores document metadata and ingestion status
-> Queue/Workflow parses and chunks
-> Workers AI embeds chunks
-> Vectorize or AI Search indexes chunks with metadata
-> Query embeds/retrieves top chunks
-> LLM answers only from retrieved context
-> Response includes citations/source IDs
Chunking rules
- Chunk by semantic boundaries when possible: headings, paragraphs, sections.
- Include overlap for long passages.
- Store
documentId, chunkId, tenantId, sourceUrl, title, and offsets/section metadata.
- Keep chunks short enough to fit prompt budgets after retrieving multiple results.
- Re-embed when chunking, model, or source text changes.
Vectorize index sketch
export interface Env {
AI: Ai;
VECTORIZE: VectorizeIndex;
}
export async function indexChunk(env: Env, chunk: {
id: string;
tenantId: string;
documentId: string;
text: string;
}) {
const embedding = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: chunk.text });
await env.VECTORIZE.upsert([
{
id: chunk.id,
values: embedding.data[0],
metadata: {
tenantId: chunk.tenantId,
documentId: chunk.documentId,
text: chunk.text
}
}
]);
}
Query sketch
export async function retrieve(env: Env, tenantId: string, question: string) {
const embedding = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: question });
return env.VECTORIZE.query(embedding.data[0], {
topK: 6,
returnMetadata: true,
filter: { tenantId }
});
}
Verify filter syntax and model dimensions against current docs and the configured index.
Grounded answer prompt
You answer using only the supplied context.
If the context does not contain the answer, say you do not know.
Cite the chunk IDs used.
Context:
{{retrieved_chunks}}
Question:
{{question}}
Quality checks
- Test retrieval separately from generation.
- Inspect failed questions: no retrieval, wrong retrieval, or bad synthesis.
- Add metadata filters for tenant/user permissions before generation.
- Do not put private chunks from other tenants into the prompt.
- Track retrieval hit rate and answer abstention rate.
Cost controls
- Embed once during ingestion, not on every answer except the query embedding.
- Limit retrieved chunks.
- Use reranking only when it improves quality enough to justify cost.
- Use smaller models for query rewriting/classification and larger models only for final answers when needed.
Anti-patterns
- Model answers without retrieved context for factual document QA.
- Index contains text but no source/citation metadata.
- Tenant filter applied after retrieval instead of during retrieval.
- Entire documents pasted into prompts.
- RAG output claims citations that were not retrieved.
1---2name: rag-vectorize-ai-search3description: Build retrieval augmented generation on Cloudflare with AI Search, Vectorize, Workers AI embeddings, chunking, metadata filters, citations, ingestion pipelines, reranking, and grounded answer generation. Use when implementing RAG, semantic search, or document QA.4---5# RAG, Vectorize, and AI Search67Use this skill for retrieval augmented generation, semantic search, and document Q&A.89## Choose AI Search vs Vectorize1011- Use **AI Search** when you want managed ingestion, retrieval, hybrid search/reranking features, and simpler RAG setup.12- Use **Vectorize** when you need direct control over embedding generation, chunking, metadata, index operations, and query flow.13- Store source documents and metadata outside the index. Retrieval indexes are derived data.1415## RAG pipeline1617```text18Upload document19 -> R2 stores original bytes20 -> D1 stores document metadata and ingestion status21 -> Queue/Workflow parses and chunks22 -> Workers AI embeds chunks23 -> Vectorize or AI Search indexes chunks with metadata24 -> Query embeds/retrieves top chunks25 -> LLM answers only from retrieved context26 -> Response includes citations/source IDs27```2829## Chunking rules3031- Chunk by semantic boundaries when possible: headings, paragraphs, sections.32- Include overlap for long passages.33- Store `documentId`, `chunkId`, `tenantId`, `sourceUrl`, `title`, and offsets/section metadata.34- Keep chunks short enough to fit prompt budgets after retrieving multiple results.35- Re-embed when chunking, model, or source text changes.3637## Vectorize index sketch3839```ts40export interface Env {41 AI: Ai;42 VECTORIZE: VectorizeIndex;43}4445export async function indexChunk(env: Env, chunk: {46 id: string;47 tenantId: string;48 documentId: string;49 text: string;50}) {51 const embedding = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: chunk.text });5253 await env.VECTORIZE.upsert([54 {55 id: chunk.id,56 values: embedding.data[0],57 metadata: {58 tenantId: chunk.tenantId,59 documentId: chunk.documentId,60 text: chunk.text61 }62 }63 ]);64}65```6667## Query sketch6869```ts70export async function retrieve(env: Env, tenantId: string, question: string) {71 const embedding = await env.AI.run("@cf/baai/bge-base-en-v1.5", { text: question });7273 return env.VECTORIZE.query(embedding.data[0], {74 topK: 6,75 returnMetadata: true,76 filter: { tenantId }77 });78}79```8081Verify filter syntax and model dimensions against current docs and the configured index.8283## Grounded answer prompt8485```text86You answer using only the supplied context.87If the context does not contain the answer, say you do not know.88Cite the chunk IDs used.8990Context:91{{retrieved_chunks}}9293Question:94{{question}}95```9697## Quality checks9899- Test retrieval separately from generation.100- Inspect failed questions: no retrieval, wrong retrieval, or bad synthesis.101- Add metadata filters for tenant/user permissions before generation.102- Do not put private chunks from other tenants into the prompt.103- Track retrieval hit rate and answer abstention rate.104105## Cost controls106107- Embed once during ingestion, not on every answer except the query embedding.108- Limit retrieved chunks.109- Use reranking only when it improves quality enough to justify cost.110- Use smaller models for query rewriting/classification and larger models only for final answers when needed.111112## Anti-patterns113114- Model answers without retrieved context for factual document QA.115- Index contains text but no source/citation metadata.116- Tenant filter applied after retrieval instead of during retrieval.117- Entire documents pasted into prompts.118- RAG output claims citations that were not retrieved.