Using AWS SDK with TypeScript to Query a Bedrock Knowledge Base
Introduction
In this blog post, we’ll walk through how to retrieve a document from an AWS Bedrock Knowledge Base, extract relevant context using Amazon OpenSearch Serverless, and send a context-aware query to Claude Sonnet (via Amazon Bedrock).
This post walks through the manual setup of an AWS OpenSearch Serverless vector store via the AWS Console and the creation of a single TypeScript script to retrieve data from the vector database and invoke a model in Amazon Bedrock. The goal is to provide a simple, standalone code example demonstrating how to use the AWS SDK to interact with both a Bedrock Knowledge Base and a foundation model.
In a production environment, infrastructure would typically be provisioned using Infrastructure as Code (IaC), such as AWS CDK, and integrated into a service layer that encapsulates business logic — potentially exposed via an API for structured access. However, this post focuses purely on a basic reference implementation to illustrate the core concepts.
We’ll use The DynamoDB book PDF stored in Amazon S3 as the knowledge source, configure Amazon OpenSearch Serverless as a vector database, and leverage Bedrock Knowledge Bases for retrieval.
What is RAG (Retrieval-Augmented Generation)?
Retrieval-Augmented Generation (RAG) is an advanced AI technique that combines retrieval-based search with generative AI models to improve response accuracy and relevance. Instead of relying solely on a model’s pre-trained knowledge, RAG dynamically retrieves external documents or domain-specific data and integrates this information into the model’s response.
How RAG Works
- User Prompt — The user submits a query to the AI model.
- Context Retrieval — The system searches a knowledge base (e.g., OpenSearch or other vector databases) for relevant documents.
- Context-Enhanced Prompt — The retrieved information is injected into the prompt to provide additional context.
- Model Response Generation — The AI model processes the augmented prompt and generates a more accurate, grounded, and relevant response.
By enriching prompts with real-time, authoritative data, RAG overcomes hallucination (incorrect AI-generated information) and extends the model’s knowledge beyond its pre-trained dataset.
How RAG Augments a Prompt
A standard AI model generates responses based solely on its training data, which remains static. With RAG, the model dynamically integrates external knowledge into its reasoning process.
Example Without RAG:
🚀 User Input: “What is AWS Bedrock?”
🤖 Model Response: “AWS Bedrock is a managed AI service by Amazon that hosts foundation models.” (May lack real-time updates)
Example With RAG:
🚀 User Input: “What is AWS Bedrock?”
📚 Knowledge Base Search (retrieved document from AWS Docs):
“Amazon Bedrock is a managed service that allows users to build and scale generative AI applications with foundation models from various providers. It supports RAG, knowledge bases, and model fine-tuning.”
🤖 Final Model Response (Augmented):
“AWS Bedrock is a fully managed AI service that enables enterprises to build generative AI applications with multiple foundation models, including support for RAG, knowledge bases, and fine-tuning. You can integrate it with OpenSearch Serverless for vector search and real-time document retrieval.”
By augmenting the prompt with real-time context, RAG ensures responses remain accurate, complete, and domain-specific.
Benefits of Using RAG with Amazon Bedrock
✅ Real-Time Knowledge — Fetch the latest company documents, FAQs, or industry updates.
✅ Domain-Specific Intelligence — Provide custom knowledge tailored to business needs.
✅ Reduced Hallucination — Ensure AI-generated responses are grounded in factual data.
✅ Scalable & Automated — Amazon Bedrock automates data ingestion, retrieval, and integration with AI models.
Let’s explore how to leverage AWS Bedrock to create a vector data store and utilise the AWS SDK to implement a Retrieval-Augmented Generation (RAG) workflow efficiently.
1️⃣ Pre-requisites: Setting Up OpenSearch Vector Database via AWS Bedrock Console
To use a Bedrock Knowledge Base, we need to:
- Store the DynamoDB book PDF in Amazon S3.
- Create an OpenSearch Serverless vector database through the AWS Bedrock Console.
- Enable automatic document ingestion from S3 to OpenSearch.
Step 1: Upload the DynamoDB Book PDF to S3
- Go to the AWS S3 Console.
- Create a new S3 Bucket (e.g.,
dynamodb-book-knowledge
). - Upload the DynamoDB Book PDF to this bucket.
- Copy the S3 URI (e.g.,
s3://dynamodb-book-knowledge/dynamodb-book.pdf
).
Step 2: Create a Bedrock Knowledge Base with OpenSearch Serverless
Now, we’ll set up a Bedrock Knowledge Base that automatically ingests documents into an OpenSearch vector database.
Open the AWS Bedrock Console
- Go to the AWS Bedrock Console → Knowledge Bases.
- Click Create -> Knowledge Base with vector store.
Configure Knowledge Base Details
- Name:
DynamoDBBookKB
- Description: Knowledge Base for DynamoDB book
Configure Data Source
- Under Data Source, select:
- “Amazon S3” as the data source.
- Click the Browse S3 bucket and select the DynamoDB book bucket (
s3://dynamodb-book-knowledge
). - Choose the Amazon Bedrock default parser.
- Choose “Automatic Sync” to keep OpenSearch updated with new files.
Set IAM Permissions
- Allow Bedrock to access OpenSearch and S3.
- Click Create.
Select Embedding Model
- Under Embedding Model, select:
- “Amazon Titan Embeddings G1” (recommended for OpenSearch).
- This converts PDF text into vector embeddings for search.
Select Vector Database
- Under the Vector Database section select:
- Quick create a new vector store.
- Select Amazon OpenSearch Serverless as the vector store database.
Copy the Knowledge Base ID
- Firstly, manually sync the knowledge base to ensure the document is indexed in the vector database by selecting the Sync button in the AWS Console.
- Once sync’d, copy the Knowledge Base ID (e.g.,
"34MADLGRCJ"
). - We’ll use this in our TypeScript script.
2️⃣ Setting Up AWS SDK Clients
Now that our vector database is ready, we create a Typescript script. For this example I have chosen to create a single script that can be run in the console but for production systems we would look at creating a service, potentially with AWS Lambda.
With our script create, we configure the AWS SDK to interact with Amazon Bedrock.
import { BedrockRuntimeClient, InvokeModelCommand } from "@aws-sdk/client-bedrock-runtime";
import { BedrockAgentRuntimeClient, RetrieveCommand } from "@aws-sdk/client-bedrock-agent-runtime";
// Configure AWS SDK
const config = { region: "us-east-1" };
const bedrockRuntimeClient = new BedrockRuntimeClient(config);
const bedrockAgentRuntimeClient = new BedrockAgentRuntimeClient(config);
const jsonContentType = "application/json";
3️⃣ Define Knowledge Base & Model Details
Next, we specify the Knowledge Base ID and Claude Sonnet model ID.
// Replace with your Knowledge Base ID
const KNOWLEDGE_BASE_ID: string = "REPLACE WITH YOUR KNOWLEDGE BASE ID";
// Replace with your Bedrock model (e.g., Claude, Titan)
const MODEL_ID: string = "anthropic.claude-v2";
4️⃣ Retrieve Data from the Knowledge Base
The script defines a function to query the Bedrock Knowledge Base. We use the bedrockAgentRuntimeClient to send a RetrieveCommand to bedrock to query the vector data store.
async function queryBedrockKnowledgeBase(userInput: string, maxTokens: number = 300): Promise<void> {
try {
// Step 1: Retrieve relevant context from the Knowledge Base
const retrieveCommand = new RetrieveCommand({
knowledgeBaseId: KNOWLEDGE_BASE_ID,
retrievalQuery: userInput,
});
const retrievalResponse = await bedrockAgentRuntimeClient.send(retrieveCommand);
console.log("Retrieved Context:", retrievalResponse);
5️⃣ Extract Retrieved Documents
Once the Knowledge Base returns relevant documents, we extract the content.
// Step 2: Extract relevant retrieved documents
const retrievedDocuments = retrievalResponse.retrievalResults?.map(doc => doc.content).join("\n") || "";
console.log("Retrieved Documents:", retrievedDocuments);
6️⃣ Send Prompt to Claude Sonnet
After retrieving relevant context, we send a context-aware query to Claude Sonnet.
// Step 3: Construct the prompt for the foundation model
const prompt: string =
`Human: Use the following context to answer the user question:
Context:
${retrievedDocuments}
User Question:
${userInput}
Assistant:
`;
// Step 4: Send the prompt to the Bedrock model
const invokeCommand = new InvokeModelCommand({
modelId: MODEL_ID,
contentType: jsonContentType,
accept: jsonContentType,
body: JSON.stringify({ prompt, max_tokens: maxTokens }),
});
const modelResponse = await bedrockRuntimeClient.send(invokeCommand);
const modelOutput = JSON.parse(new TextDecoder().decode(modelResponse.body));
console.log("AI Response:", modelOutput);
} catch (error) {
console.error("Error querying Bedrock Knowledge Base:", error);
}
}
7️⃣ Example Usage
Finally, the function is called with user input asking to “Summarise single table design”.
queryBedrockKnowledgeBase("Summarize single table design");
The function calls retrieves relevant data from the vector store before using it in the contextual prompt to Amazon Bedrock, resulting in the following response.
AI Response: {
type: 'completion',
completion: ' Here is a summary of single table design based on the given context:\n' +
'\n' +
'- Single table design involves using as few tables as possible in DynamoDB, ideally just one table per application or microservice. \n' +
'\n' +
'- It originated due to the need to model data differently in DynamoDB compared to relational databases, which typically use multiple normalized tables.\n' +
'\n' +
'- The main benefit of single table design is faster performance by retrieving all needed items in one request. Other smaller benefits are reduced operations burden and potentially lower costs.\n' +
'\n' +
'- Downsides include a steep learning curve, inflexibility in adding new access patterns, and difficulty exporting data for analytics. \n' +
'\n' +
'- Single table design may not be suitable when query flexibility and ease of analytics are more important than raw performance.\n' +
'\n' +
'- Overall, single table design is a powerful and scalable pattern for DynamoDB, but requires learning a new modeling approach compared to traditional normalized databases.',
stop_reason: 'stop_sequence',
stop: '\n\nHuman:'
}
🎯 Summary
✅ What We Did
- Configured OpenSearch Serverless via AWS Bedrock Console.
- Ingested the DynamoDB book PDF from S3.
- Set up Bedrock Knowledge Base with Titan Embeddings.
- Queried the Knowledge Base using the AWS SDK (
RetrieveCommand
). - Sent the retrieved data as part of a structured prompt to Claude Sonnet.
- Retrieved an AI-generated summary of the query.