NovuSpark
All articles

December 5, 2025 · NovuSpark Team

Amazon Bedrock Knowledge Bases: Building RAG Without Managing Infrastructure

This is the second post in our Amazon Bedrock series, building on getting started with Bedrock. It also assumes the RAG concepts from our OpenAI and LangChain series.

We've now built a RAG pipeline twice in this blog — first from raw embeddings and manual similarity search, then again with LangChain's document loaders, text splitters, and vector stores. Both versions require you to actually run and maintain the underlying infrastructure: a vector database, an embedding pipeline, a re-indexing process for updated documents. A Bedrock Knowledge Base manages that entire infrastructure layer for you, directly integrated with S3 as the document source.

Setting up a Knowledge Base

aws bedrock-agent create-knowledge-base \
  --name "novuspark-handbook-kb" \
  --role-arn "arn:aws:iam::008971632408:role/bedrock-kb-role" \
  --knowledge-base-configuration '{
    "type": "VECTOR",
    "vectorKnowledgeBaseConfiguration": {
      "embeddingModelArn": "arn:aws:bedrock:eu-west-2::foundation-model/amazon.titan-embed-text-v2:0"
    }
  }' \
  --storage-configuration '{
    "type": "OPENSEARCH_SERVERLESS",
    "opensearchServerlessConfiguration": {
      "collectionArn": "arn:aws:aoss:eu-west-2:008971632408:collection/abc123",
      "vectorIndexName": "handbook-index",
      "fieldMapping": {
        "vectorField": "embedding",
        "textField": "text",
        "metadataField": "metadata"
      }
    }
  }'
aws bedrock-agent create-data-source \
  --knowledge-base-id "KB123ABC" \
  --name "handbook-docs" \
  --data-source-configuration '{
    "type": "S3",
    "s3Configuration": {
      "bucketArn": "arn:aws:s3:::novuspark-internal-docs"
    }
  }'

This is the exact same underlying architecture as the RAG pipelines built earlier in this blog — an embedding model (Amazon Titan Embeddings here, specified by ARN, the same "provider behind a consistent interface" swap covered in our LangChain series), a vector store (OpenSearch Serverless, in this configuration), and a document source. The genuine difference: AWS provisions and operates the vector store itself — no self-managed Chroma instance, no separately-run vector database to patch, scale, or back up.

Ingestion: chunking and embedding, managed automatically

aws bedrock-agent start-ingestion-job \
  --knowledge-base-id "KB123ABC" \
  --data-source-id "DS456DEF"

Triggering an ingestion job is the managed equivalent of the manual "load documents, split into chunks, embed each chunk" pipeline built by hand in our LangChain RAG post — Bedrock handles document loading directly from S3, chunking (with configurable chunk size and overlap, the same trade-off flagged in our earlier RAG posts), and embedding, without you writing or maintaining that pipeline code yourself. Adding a new document is as simple as uploading it to the source S3 bucket and re-running an ingestion job — no code deployment required for new content.

Querying and generating in one call

client = boto3.client("bedrock-agent-runtime", region_name="eu-west-2")
 
response = client.retrieve_and_generate(
    input={"text": "How many vacation days do employees get?"},
    retrieveAndGenerateConfiguration={
        "type": "KNOWLEDGE_BASE",
        "knowledgeBaseConfiguration": {
            "knowledgeBaseId": "KB123ABC",
            "modelArn": "arn:aws:bedrock:eu-west-2::foundation-model/anthropic.claude-3-5-sonnet-20241022-v2:0",
        },
    },
)
 
print(response["output"]["text"])
According to the employee handbook, full-time employees receive 25
days of paid vacation per year, accrued monthly.

retrieve_and_generate collapses the entire retrieve-then-generate pattern — built manually with raw embeddings, then again with LangChain's composed chains, earlier in this blog — into a single API call: retrieval against the Knowledge Base, followed by generation using the retrieved context, both handled server-side by Bedrock.

Retrieval only, when you need more control over generation

response = client.retrieve(
    knowledgeBaseId="KB123ABC",
    retrievalQuery={"text": "How many vacation days do employees get?"},
)
 
for result in response["retrievalResults"]:
    print(result["content"]["text"], result["score"])

For applications that need to combine retrieved context with additional custom logic before generation — the multi-agent coordination patterns covered in our LangGraph series, for instance — the separate retrieve call returns just the relevant passages and their similarity scores, leaving the generation step, and everything you do with the retrieved context before that step, fully under your own application's control.

The genuine trade-off versus a self-managed pipeline

A Bedrock Knowledge Base trades some flexibility for meaningfully less operational burden. Fine-grained control over chunking strategy, a custom re-ranking step between retrieval and generation, or a vector store Bedrock doesn't directly support are all easier to implement in a self-managed LangChain pipeline. For a large share of real internal-knowledge RAG use cases — genuinely most of them — that additional flexibility isn't actually needed, and the operational savings of not running your own vector database infrastructure are the more consequential factor in the decision.

What to actually remember from this post

  • A Knowledge Base is the same RAG architecture built earlier in this blog — embedding model, vector store, document source — with AWS operating the vector store infrastructure for you.
  • Ingestion jobs handle chunking and embedding automatically from an S3 source — no self-managed pipeline code to maintain.
  • retrieve_and_generate collapses retrieval and generation into one call; retrieve alone gives you retrieved context to combine with custom logic yourself.
  • The real trade-off is flexibility versus operational burden — less fine-grained control than a self-managed pipeline, in exchange for not running vector database infrastructure yourself.

Next in the series: Amazon Bedrock Agents: Automating Multi-Step Tasks, where Bedrock provides a managed equivalent of the LangChain and LangGraph agent patterns covered earlier in this blog.

Ready when you are

Want training built around your team's real work?

Tell us about your team and what you're trying to solve — we'll recommend a program that fits.