Chapter 12 · RAG: Retrieval-Augmented Generation
Chapter goals: Master Mastra's RAG pipeline: document chunking, embedding, ingestion, retrieval, and reranking — inject私有 knowledge into Agent context.
12.1 RAG Five-Step Pipeline
The model doesn't know your internal documents. The standard RAG (Retrieval-Augmented Generation) flow:
- Load — convert Markdown/PDF/HTML to
MDocument; - Chunk — split by token count or semantic boundary;
- Embed — use an embedding model to turn chunks into vectors and write to a vector store;
- Retrieve — on query, embed the question too, fetch the top-K most similar;
- Inject — concatenate retrieved results into the prompt for the model to answer.
12.2 Document Chunking and Embedding
typescript
// src/rag/ingest.ts
import { MDocument } from '@mastra/rag'
import { embedMany } from 'ai'
import { openai } from '@ai-sdk/openai'
// Create a document object from Markdown text (also supports fromPDF / fromHTML etc.)
const doc = MDocument.fromText(`
# Refund Policy
No-questions-asked refund within 7 days of ordering.
# Shipping Timeline
In-stock items ship within 48 hours.
`)
// Chunk by heading structure; each chunk ≤ 512 tokens, 50-token overlap
const chunks = await doc.chunk({
strategy: 'markdown',
size: 512,
overlap: 50,
})
// Batch-generate vectors (embedding dimension determined by the model)
const { embeddings } = await embedMany({
model: openai.embedding('text-embedding-3-small'),
values: chunks.map((c) => c.text),
})12.3 Writing to the Vector Store
Mastra provides多种 Vector adapters; here using LibSQL's vector extension:
typescript
// src/rag/store.ts
import { LibSQLVector } from '@mastra/libsql'
const vector = new LibSQLVector({ url: 'file:./vectors.db' })
// Create index: dimension must match the embedding model output
await vector.createIndex({
indexName: 'kb_docs',
dimension: 1536, // text-embedding-3-small outputs 1536 dimensions
})
// Upsert vectors with原文 metadata
await vector.upsert({
indexName: 'kb_docs',
vectors: embeddings,
metadata: chunks.map((c) => ({ text: c.text })),
})12.4 Retrieving and Injecting Context
typescript
// src/rag/query.ts
import { embed } from 'ai'
import { openai } from '@ai-sdk/openai'
export async function retrieve(question: string): Promise<string[]> {
// Embed the question
const { embedding } = await embed({
model: openai.embedding('text-embedding-3-small'),
value: question,
})
// Cosine similarity; take top 3
const results = await vector.query({
indexName: 'kb_docs',
queryVector: embedding,
topK: 3,
})
return results.map((r) => r.metadata?.text ?? '')
}
// Usage: pass retrieved results as context to the Agent
const context = (await retrieve('How long does a return take?')).join('\n---\n')
const answer = await agent.generate(
`Answer the customer question参考 the following materials:\n${context}\n\nQuestion: How long does a return take?`,
)12.5 Reranking and Advanced Techniques
rerank()uses a cross-encoder to re-sort初筛 results, significantly improving precision;Metadata Filters支持按类别、时间等字段过滤;- For large datasets, explore GraphRAG (knowledge-graph-enhanced retrieval).
Rerank Example
Vector初筛 is fast but粗; use a cross-encoder to精排 the top-20 then取前 3:
typescript
// src/rag/rerank.ts
import { rerank } from '@mastra/rag'
const candidates = await retrieveAll(question, 20) // Expandrecall for初筛
const reranked = await rerank({
query: question,
results: candidates,
topK: 3, // Keep only the top 3 after精排
})12.6 Chapter Summary
- RAG = chunk → embed → ingest → retrieve → inject (five steps);
MDocument.chunk()supports smart splitting by markdown structure;- Vector dimension must match the embedding model (1536 for text-embedding-3-small);
- Retrieval quality determines the answer ceiling; add rerank and metadata filters when needed.
🧪 随堂测验
点击你认为正确的选项。答错时会展示正确答案与原因解析。
1. What is the main purpose of "chunking" in the RAG pipeline?
2. When creating a vector index, what condition must the dimension parameter satisfy?
3. What does topK: 3 in vector.query()表示?
4. What does rerank() do in the RAG pipeline?
🛠️ Hands-On Exercises
- Turn your真实 product FAQ doc into a RAG pipeline; ask 5 questions and check hit rate.
- Compare the effect on answer quality between
size: 256andsize: 1024chunking. - Add a rerank step after retrieval; observe the top-3 order change.