Bedrock Knowledge Bases for RAG
Bedrock Knowledge Bases is the managed RAG service in AWS — point it at an S3 bucket (or other data source), pick a chunking strategy and embedding model, choose a vector store, and Bedrock handles ingestion + retrieval + (optional) response generation. The two main retrieval-and-generation entry points are Retrieve (returns chunks) and RetrieveAndGenerate (returns a synthesized answer with citations). Since 2024–2025 the supported feature set has expanded to include hybrid (semantic + keyword) search, Cohere Rerank 3.5 reranking, graph-based knowledge bases (Neptune), structured-data knowledge bases (Redshift), and customizable chunking strategies (hierarchical, semantic, custom).
See also
- bedrock-agents — agents can have a knowledge base attached as a retrieval source
- bedrock-models-and-providers — embedding model choices (Titan V2 default, Cohere Embed V3, Amazon Nova Embeddings)
- rag-embeddings-vector-search — vendor-neutral RAG architecture deep dive
- citations-and-grounding — Claude’s native citation block format (used when generation is via Claude)
1. Supported vector stores
Per docs.aws.amazon.com/bedrock/latest/userguide/knowledge-base-setup.html:
| Vector store | Type | Auth | Best for |
|---|---|---|---|
| OpenSearch Serverless (AOSS) | AWS-native | IAM | Default. Auto-scaling, fully managed. ~$0.24 / OCU-hour. Hybrid search supported. |
| OpenSearch Managed Cluster | AWS-native | IAM | Fixed-cost, you manage scaling. Hybrid search supported. |
| Aurora PostgreSQL pgvector | AWS-native | IAM | If you already have Aurora. Cheap per-row storage. Semantic only. |
| Neptune Analytics (Graph) | AWS-native | IAM | GraphRAG — combine vector search with graph traversal over entity relationships. |
| Redshift | AWS-native | IAM | ”Structured-data knowledge base” — query SQL data via natural language (text-to-SQL). |
| Pinecone | Third-party | API key (Secrets Manager) | If you’re already on Pinecone. Serverless or Pod. |
| Redis Enterprise Cloud | Third-party | API key | In-memory vector search. Fastest reads. |
| MongoDB Atlas | Third-party | API key | If you’re already on Atlas. Combines vector + document queries. |
Default recommendation: OpenSearch Serverless. AWS-native, IAM auth, hybrid search supported, no per-query egress to a third-party provider.
2. Supported data sources
| Source | Notes |
|---|---|
| Amazon S3 | Default. Any file format in supported list: PDF, MD, TXT, HTML, DOC, DOCX, CSV, XLS, XLSX. Up to 50 MB per file. |
| Confluence | Cloud only. Authenticated via Atlassian API token in Secrets Manager. |
| SharePoint | Microsoft 365 / SharePoint Online. OAuth 2.0. |
| Salesforce | Documents + Knowledge articles. OAuth 2.0. |
| Web crawler | Crawls public web pages up to depth N from a list of seed URLs. |
| Custom | Upload chunks directly via Ingest API for sources Bedrock doesn’t natively support (Notion, Linear, internal tools). |
3. Chunking strategies
Per docs.aws.amazon.com/bedrock/latest/userguide/kb-chunking-parsing.html:
| Strategy | What it does | When to use |
|---|---|---|
| Default | Fixed-size chunks of 300 tokens with 20% overlap | Generic text. Sensible default. |
| Fixed-size | Configurable chunk size (20–8192 tokens) and overlap (0–99%) | When you’ve tuned for your content |
| Hierarchical | Two levels: parent chunks (1500 tokens) + child chunks (300 tokens). Retrieve children, return parents to LLM. | Long-form documents where context around each chunk matters |
| Semantic | Splits on semantic boundaries via sentence embeddings (similarity threshold configurable) | Mixed-content documents (code + prose + tables) |
| Custom (Lambda) | You write a Lambda that returns chunks | When none of the above fit |
| No chunking | Each file is one chunk | Very small files (FAQs, individual articles) |
Parsing: Bedrock’s default parser handles plain text + simple PDFs. For PDFs with tables / images, enable Foundation Model parsing — Bedrock invokes Claude or Nova to extract structured content before chunking. Costs additional model invocations (~$0.02–$0.10 per page).
4. Embedding model choices
| Model | Bedrock ID | Dimensions | Price |
|---|---|---|---|
| Titan Text Embeddings V2 | amazon.titan-embed-text-v2:0 | 1024 (default), 512, 256 | $0.02 / MTok |
| Titan Text Embeddings V1 | amazon.titan-embed-text-v1 | 1536 | $0.10 / MTok |
| Cohere Embed English V3 | cohere.embed-english-v3 | 1024 | $0.10 / MTok |
| Cohere Embed Multilingual V3 | cohere.embed-multilingual-v3 | 1024 | $0.10 / MTok |
| Amazon Nova Embeddings (2026) | amazon.nova-embed-v1:0 | 1024 (configurable down to 256) | $0.02 / MTok |
Default: Titan V2 at 1024 dimensions — cheapest, fully AWS-managed. Cohere V3 has slightly better quality on multi-language benchmarks per Cohere’s public evals.
5. Creating a knowledge base — Python walkthrough
import boto3
ctl = boto3.client("bedrock-agent", region_name="us-east-1")
# 1. Create the knowledge base
kb = ctl.create_knowledge_base(
name="company-docs-kb",
description="Internal documentation",
roleArn="arn:aws:iam::123456789012:role/AmazonBedrockExecutionRoleForKnowledgeBase",
knowledgeBaseConfiguration={
"type": "VECTOR",
"vectorKnowledgeBaseConfiguration": {
"embeddingModelArn": (
"arn:aws:bedrock:us-east-1::foundation-model/"
"amazon.titan-embed-text-v2:0"
),
"embeddingModelConfiguration": {
"bedrockEmbeddingModelConfiguration": {
"dimensions": 1024,
"embeddingDataType": "FLOAT32",
}
},
},
},
storageConfiguration={
"type": "OPENSEARCH_SERVERLESS",
"opensearchServerlessConfiguration": {
"collectionArn": "arn:aws:aoss:us-east-1:123456789012:collection/abc123",
"vectorIndexName": "kb-docs-index",
"fieldMapping": {
"vectorField": "embedding",
"textField": "text",
"metadataField": "metadata",
},
},
},
)
kb_id = kb["knowledgeBase"]["knowledgeBaseId"]
# 2. Attach an S3 data source
ds = ctl.create_data_source(
knowledgeBaseId=kb_id,
name="docs-bucket",
dataSourceConfiguration={
"type": "S3",
"s3Configuration": {
"bucketArn": "arn:aws:s3:::company-docs",
"inclusionPrefixes": ["docs/", "specs/"],
},
},
vectorIngestionConfiguration={
"chunkingConfiguration": {
"chunkingStrategy": "HIERARCHICAL",
"hierarchicalChunkingConfiguration": {
"levelConfigurations": [
{"maxTokens": 1500},
{"maxTokens": 300},
],
"overlapTokens": 60,
},
},
# Enable foundation-model parsing for PDFs with tables / images
"parsingConfiguration": {
"parsingStrategy": "BEDROCK_FOUNDATION_MODEL",
"bedrockFoundationModelConfiguration": {
"modelArn": (
"arn:aws:bedrock:us-east-1::foundation-model/"
"anthropic.claude-sonnet-4-6-20260119-v1:0"
),
"parsingPrompt": {
"parsingPromptText": (
"Transcribe the page accurately, preserving tables as "
"markdown and describing any images."
)
},
},
},
},
)
ds_id = ds["dataSource"]["dataSourceId"]
# 3. Start ingestion (one-time; re-run when content changes)
ingestion = ctl.start_ingestion_job(
knowledgeBaseId=kb_id,
dataSourceId=ds_id,
)
print(f"Ingestion job: {ingestion['ingestionJob']['ingestionJobId']}")Ingestion is asynchronous. Poll with get_ingestion_job or set up an EventBridge rule on Knowledge Base Ingestion Job State Change.
6. Querying — Retrieve vs RetrieveAndGenerate
6.1 Retrieve — return chunks only
Returns raw retrieval results. Use when you want to feed them into your own prompt or do further processing.
runtime = boto3.client("bedrock-agent-runtime", region_name="us-east-1")
resp = runtime.retrieve(
knowledgeBaseId=kb_id,
retrievalQuery={"text": "What is the parental leave policy?"},
retrievalConfiguration={
"vectorSearchConfiguration": {
"numberOfResults": 5,
"overrideSearchType": "HYBRID", # or "SEMANTIC"
# Reranking (additional cost)
"rerankingConfiguration": {
"type": "BEDROCK_RERANKING_MODEL",
"bedrockRerankingConfiguration": {
"modelConfiguration": {
"modelArn": (
"arn:aws:bedrock:us-east-1::foundation-model/"
"cohere.rerank-v3-5:0"
),
},
"numberOfRerankedResults": 3,
},
},
# Filter by metadata (e.g. only docs from HR)
"filter": {
"equals": {"key": "department", "value": "HR"}
},
}
},
)
for r in resp["retrievalResults"]:
print(f"[score={r['score']:.3f}] {r['content']['text'][:200]}...")
print(f" source: {r['location']}")
print(f" metadata: {r['metadata']}")6.2 RetrieveAndGenerate — managed end-to-end RAG
Retrieves + generates an answer with citations in one call.
resp = runtime.retrieve_and_generate(
input={"text": "What is the parental leave policy?"},
retrieveAndGenerateConfiguration={
"type": "KNOWLEDGE_BASE",
"knowledgeBaseConfiguration": {
"knowledgeBaseId": kb_id,
"modelArn": (
"arn:aws:bedrock:us-east-1::foundation-model/"
"anthropic.claude-sonnet-4-6-20260119-v1:0"
),
"retrievalConfiguration": {
"vectorSearchConfiguration": {
"numberOfResults": 5,
"overrideSearchType": "HYBRID",
"rerankingConfiguration": {
"type": "BEDROCK_RERANKING_MODEL",
"bedrockRerankingConfiguration": {
"modelConfiguration": {
"modelArn": (
"arn:aws:bedrock:us-east-1::foundation-model/"
"cohere.rerank-v3-5:0"
)
}
},
},
},
},
"generationConfiguration": {
"inferenceConfig": {
"textInferenceConfig": {
"temperature": 0.0,
"maxTokens": 1024,
}
},
# Optional: custom prompt template
"promptTemplate": {
"textPromptTemplate": (
"You are an HR assistant. Answer using ONLY the "
"following context:\n$search_results$\n\nQuestion: "
"$query$\nAnswer:"
)
},
"guardrailConfiguration": {
"guardrailId": "abc-123",
"guardrailVersion": "1",
},
},
},
},
sessionConfiguration={
# Optional — multi-turn conversation
"kmsKeyArn": None,
},
)
print(resp["output"]["text"])
for c in resp["citations"]:
print(f" Citation: {c['generatedResponsePart']['textResponsePart']['text']}")
for ref in c["retrievedReferences"]:
print(f" Source: {ref['location']}, score: {ref.get('score')}")The response includes structured citations — each citation links a span of the generated text to the retrieved chunk it came from.
7. Hybrid vs semantic search
Per docs.aws.amazon.com/bedrock/latest/userguide/kb-test.html:
- Semantic search (default) — vector similarity only. Best for conceptual queries (“what’s our paid time off policy”) where exact wording doesn’t matter.
- Hybrid search — combines vector similarity + BM25 keyword matching. Better for queries containing identifiers, proper nouns, or technical terms (“error code 7281”, “Section 4(b)”). Required when your queries contain product names, employee IDs, or other exact-match-critical terms.
Hybrid is only supported on OpenSearch Serverless and OpenSearch Managed as of 2026-05. Pinecone and pgvector are semantic-only.
Override per-query with overrideSearchType: "HYBRID" (default uses what’s configured on the KB).
8. Reranking
Two reranker options:
cohere.rerank-v3-5:0(Cohere Rerank 3.5) — multilingual, 4096-doc input limit.amazon.rerank-v1:0(Amazon Rerank) — AWS-native, English-only.
Both priced at $1 / 1k queries. Reranking adds ~150-300ms latency but typically improves top-3 precision by 20-40%. Always enable for production RAG.
The reranker is invoked after the vector store returns its top-K results. Typical pattern: retrieve top-25, rerank to top-5.
9. Multi-turn conversation with citations
RetrieveAndGenerate supports session-based conversations. Pass sessionId and the API maintains conversation context server-side:
session_id = None
while True:
user_input = input("You: ")
if not user_input:
break
kwargs = {
"input": {"text": user_input},
"retrieveAndGenerateConfiguration": {...},
}
if session_id:
kwargs["sessionId"] = session_id
resp = runtime.retrieve_and_generate(**kwargs)
session_id = resp["sessionId"]
print(f"Assistant: {resp['output']['text']}")Session state has a 24-hour TTL by default and is held in Bedrock’s managed store (not exposed to you).
10. GraphRAG with Neptune Analytics
Per re:Invent 2024. A Neptune-backed knowledge base extracts entities and relationships from your documents at ingestion time, building a knowledge graph alongside the vector index. At query time, retrieval traverses the graph to find related entities even when their chunks have low vector similarity.
ctl.create_knowledge_base(
name="company-graph-kb",
knowledgeBaseConfiguration={
"type": "VECTOR",
"vectorKnowledgeBaseConfiguration": {
"embeddingModelArn": "...",
"embeddingModelConfiguration": {...},
# ↓ enables GraphRAG
"supplementalDataStorageConfiguration": {
"supplementalDataStorageLocations": [
{
"supplementalDataStorageLocationType": "S3",
"s3Location": {"uri": "s3://my-graph-staging/"},
}
]
},
},
},
storageConfiguration={
"type": "NEPTUNE_ANALYTICS",
"neptuneAnalyticsConfiguration": {
"graphArn": "arn:aws:neptune-graph:us-east-1:...:graph/g-abc123",
"fieldMapping": {
"textField": "text",
"metadataField": "metadata",
},
},
},
roleArn="...",
)Cost: Neptune Analytics charges per memory-optimized neptune-graph m-NCU at ~$0.16/hour. Worth it when your data has rich entity relationships (e.g. legal documents referencing other cases, scientific papers citing other papers, codebases with cross-module dependencies).
11. Structured-data knowledge base (Redshift)
Per re:Invent 2024. A “structured-data KB” lets users query a Redshift cluster via natural language — Bedrock translates the question to SQL using a model. No vectors involved.
ctl.create_knowledge_base(
name="sales-data-kb",
knowledgeBaseConfiguration={
"type": "SQL",
"sqlKnowledgeBaseConfiguration": {
"type": "REDSHIFT",
"redshiftConfiguration": {
"queryEngineConfiguration": {
"type": "SERVERLESS",
"serverlessConfiguration": {
"workgroupArn": "arn:aws:redshift-serverless:...:workgroup/abc",
"authConfiguration": {"type": "IAM"},
},
},
"storageConfigurations": [...],
"queryGenerationConfiguration": {
"executionTimeoutSeconds": 60,
"generationContext": {
"tables": [
{
"name": "sales.transactions",
"description": "Daily sales by region",
"columns": [
{"name": "region", "description": "ISO country code"},
{"name": "amount_usd", "description": "Transaction amount in USD"},
{"name": "date", "description": "Transaction date"},
],
}
]
},
},
},
},
},
roleArn="...",
storageConfiguration={...},
)Pricing: $0.002 per query (regardless of complexity).
12. Costs and limits
| Cost | Rate |
|---|---|
| Embedding generation (one-time during ingestion) | Per embedding model (Titan V2: $0.02 / MTok input) |
| Vector store storage | OpenSearch Serverless: $0.24 / OCU-hour (~$175/month minimum) + storage |
| Retrieval queries | Free (you pay only the model+storage costs) |
| Reranking | $1 / 1k queries |
| Generation | Per-token cost of the chosen generation model |
| Structured-data KB queries | $0.002 / query |
| Foundation model parsing | Per-token cost of the chosen parsing model |
| Limit | Value |
|---|---|
| Max file size for ingestion | 50 MB |
| Max files per data source sync | 5 million |
| Max KBs per account per region | 50 |
| Max data sources per KB | 5 |
| Ingestion job concurrency | 1 per KB at a time |
RetrieveAndGenerate request rate | Inherits underlying model’s rate limit |