Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
66 changes: 66 additions & 0 deletions BEDROCK_MANAGED_KB.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,66 @@
# Bedrock Managed Knowledge Base Support

## Changes
- CDK `bedrock-stack.ts` updated to create managed KB with `addPropertyOverride`
- Knowledge Base tool uses `managedSearchConfiguration` for retrieval by default
- Added `MANAGED_KNOWLEDGE_BASE_CONNECTOR` data source in CDK stack
- Agent `knowledge_base.py` tool updated to branch on KB type for search config
- AgentCore memory integration unchanged; KB retrieval is separate path

## Design
- MANAGED is the default for KB creation in CDK stack; VECTOR via config toggle
- CDK uses `addPropertyOverride` since L2 constructs don't support managed type natively
- AgenticRetrieveStream available for enhanced retrieval quality
- Backward compatible: existing VECTOR deployments unaffected

## API Shapes
- KB Creation: `type: MANAGED` + `managedKnowledgeBaseConfiguration.embeddingModelType: MANAGED`
- Data Source: `type: MANAGED_KNOWLEDGE_BASE_CONNECTOR`
- Retrieval: `managedSearchConfiguration` (not `vectorSearchConfiguration`)
- Agentic: `AgenticRetrieveStream` with `foundationModelType: MANAGED`, `rerankingModelType: MANAGED`

## Configuration
| Variable | Description | Default |
|---|---|---|
| KNOWLEDGE_BASE_TYPE | MANAGED or VECTOR | MANAGED |
| USE_AGENTIC_RETRIEVAL | Enable agentic retrieval | true |
| KNOWLEDGE_BASE_ID | KB identifier (from CDK output) | (required) |

## SDK Requirements
- boto3 >= 1.43 for managed search and agentic retrieval
- aws-cdk-lib >= 2.170.0 for KB L1 constructs

## Required IAM Permissions
```json
{
"Effect": "Allow",
"Action": [
"bedrock:Retrieve",
"bedrock:AgenticRetrieveStream"
],
"Resource": "arn:aws:bedrock:<region>:<account-id>:knowledge-base/<kb-id>"
}
```

## Direct Ingestion (DLA API)

When a CUSTOM data source is configured on the KB, documents can be ingested directly without triggering a full S3 sync:

```bash
# Enable direct ingestion (opt-in)
export USE_DIRECT_INGESTION=true
```

With direct ingestion enabled, the Knowledge Base Explorer's upload feature will:
1. Try `IngestKnowledgeBaseDocuments` API first (immediate, no full sync)
2. Fall back to S3 upload + `StartIngestionJob` if no CUSTOM data source exists

Supported content: text files, PDFs, DOCX, HTML, CSV, and binary files (with appropriate mimeType).

> **Prerequisite:** Add a CUSTOM data source to your KB via the AWS console (Knowledge Bases → your KB → Add data source → Custom).

**References:**
- [Ingest documents directly into a knowledge base](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-direct-ingestion.html)
- [IngestKnowledgeBaseDocuments API](https://docs.aws.amazon.com/bedrock/latest/APIReference/API_agent_IngestKnowledgeBaseDocuments.html)
- [Connect to a custom data source](https://docs.aws.amazon.com/bedrock/latest/userguide/custom-data-source-connector.html)

44 changes: 42 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,9 +37,13 @@ Skip weeks of infrastructure setup and go straight to validating your agentic AI
- 👍 **User feedback capture** with sentiment ratings and comments
- 🛡️ **Guardrails analytics** with violation tracking and content filtering
- 🔧 **Tool usage analytics** with per-tool invocation metrics and success rates
- 🔬 **Automated evaluations** of every response (answer quality, faithfulness, tool selection) with CloudWatch trace deep links

**Infrastructure**
- ☁️ **Flexible deployment options** - ECS Express Mode or CloudFront + Lambda Web Adapter
**Agent Capabilities**
- 🧠 **Amazon Bedrock AgentCore** with Strands Agents SDK
- 🌐 **Amazon Bedrock Mantle** - OpenAI-compatible endpoint with 30+ models across Anthropic, OpenAI, Google, Mistral, DeepSeek, Qwen, and more
- 📚 **Knowledge Base integration** for semantic search over your documents — supports both **Managed Knowledge Bases** (recommended, no vector store needed) and S3 Vectors
- 🛠️ **Pre-built tools** - web search, URL fetcher, weather, calculator, current time
- 💸 **Cost-optimized** - Serverless options with pay-per-use pricing
- 🔐 **Cognito authentication** with secure token management
- 📡 **OpenTelemetry and Bedrock AgentCore Observability** with logs, traces, and metrics
Expand Down Expand Up @@ -518,6 +522,42 @@ are wired automatically by CDK). Uploads are admin-only.
> You can also upload and ingest documents directly from the Knowledge Base Explorer; the
> steps below are the manual CLI equivalent.

#### Managed Knowledge Bases (Recommended)

Managed knowledge bases let Bedrock handle embedding, storage, and retrieval automatically — no external vector store required:

```bash
# In your .env or CDK context:
KNOWLEDGE_BASE_TYPE=MANAGED
```

The CDK stack creates a managed knowledge base by default. Managed KBs support agentic retrieval with intelligent query decomposition and managed reranking.

To use a vector knowledge base instead (requires OpenSearch Serverless or similar):
```bash
KNOWLEDGE_BASE_TYPE=VECTOR
```

> **SDK requirements:** `boto3 >= 1.43` for managed search and agentic retrieval.

**Reranking options** for managed search: `MANAGED` (default — automatic), `NONE` (disable reranking), `CUSTOM` (your own Bedrock reranking model e.g. Cohere Rerank v3.5).

**Required IAM Permissions:**
```json
{
"Effect": "Allow",
"Action": [
"bedrock:Retrieve",
"bedrock:AgenticRetrieveStream"
],
"Resource": "arn:aws:bedrock:<region>:<account-id>:knowledge-base/<kb-id>"
}
```

**Resources:** [Build a Managed KB](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-build-managed.html) | [Retrieve API](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-test-retrieve.html) | [Agentic Retrieval](https://docs.aws.amazon.com/bedrock/latest/userguide/kb-test-agentic.html)

## Adding Documents to the Knowledge Base

1. **Upload documents to S3**:
```bash
# Get the source bucket name from CDK outputs
Expand Down
2 changes: 2 additions & 0 deletions agent/.env.example
Original file line number Diff line number Diff line change
Expand Up @@ -23,5 +23,7 @@ GUARDRAIL_ENABLED=true
# Knowledge Base Configuration (optional)
# Set KB_ID from setup-knowledgebase.sh output
KB_ID=
# Knowledge Base type: MANAGED (default for new deployments) or VECTOR (legacy S3 Vectors)
KNOWLEDGE_BASE_TYPE=MANAGED
KB_MAX_RESULTS=5
KB_MIN_SCORE=0.5
74 changes: 67 additions & 7 deletions agent/tools/knowledge_base.py
Original file line number Diff line number Diff line change
Expand Up @@ -15,8 +15,22 @@
def _get_kb_client():
"""Get boto3 bedrock-agent-runtime client."""
import boto3
from botocore.config import Config
region = os.getenv("AWS_REGION", "us-east-1")
return boto3.client("bedrock-agent-runtime", region_name=region)
return boto3.client(
"bedrock-agent-runtime",
region_name=region,
config=Config(user_agent_extra="aws-agentcore-starter/bedrock-kb"),
)


def _get_kb_type() -> str:
"""Get the Knowledge Base type from environment.

Returns:
'MANAGED' or 'VECTOR' (default 'MANAGED')
"""
return os.getenv("KNOWLEDGE_BASE_TYPE", "MANAGED").upper()


def _parse_retrieve_response(response: dict) -> list[dict]:
Expand Down Expand Up @@ -105,16 +119,62 @@ def search_knowledge_base(

try:
client = _get_kb_client()

# Call retrieve API
response = client.retrieve(
knowledgeBaseId=kb_id,
retrievalQuery={"text": query.strip()},
retrievalConfiguration={
kb_type = _get_kb_type()

# Build retrieval configuration based on KB type
if kb_type == "MANAGED":
# Primary: AgenticRetrieveStream (disable with USE_AGENTIC_RETRIEVAL=false)
use_agentic = os.getenv("USE_AGENTIC_RETRIEVAL", "true").lower() == "true"
if use_agentic:
try:
response = client.agentic_retrieve_stream(
messages=[{"content": {"text": query.strip()}, "role": "user"}],
retrievers=[{
"configuration": {
"knowledgeBase": {
"knowledgeBaseId": kb_id,
"retrievalOverrides": {"maxNumberOfResults": max_results},
}
}
}],
agenticRetrieveConfiguration={
"foundationModelType": "MANAGED",
"rerankingModelType": "MANAGED",
},
generateResponse=os.getenv("GENERATE_RESPONSE", "false").lower() == "true",
)
results = []
for event in response.get("stream", []):
if "result" in event:
results = event["result"].get("results", [])
if results:
return _parse_retrieve_response({"retrievalResults": results})
except Exception:
pass # Fall through to standard Retrieve

# Fallback: Retrieve with managedSearchConfiguration
retrieval_configuration = {
"managedSearchConfiguration": {
"numberOfResults": max_results,
"rerankingConfiguration": {
"type": "BEDROCK_RERANKING_MODEL"
}
}
}

else:
# VECTOR type (default for backward compatibility)
retrieval_configuration = {
"vectorSearchConfiguration": {
"numberOfResults": max_results
}
}

# Call retrieve API
response = client.retrieve(
knowledgeBaseId=kb_id,
retrievalQuery={"text": query.strip()},
retrievalConfiguration=retrieval_configuration
)

# Parse response
Expand Down
1 change: 1 addition & 0 deletions cdk/lib/agent-stack.ts
Original file line number Diff line number Diff line change
Expand Up @@ -520,6 +520,7 @@ def handler(event, context):
GUARDRAIL_ID: guardrailId,
GUARDRAIL_VERSION: guardrailVersion,
KB_ID: knowledgeBaseId,
KNOWLEDGE_BASE_TYPE: (this.node.tryGetContext('knowledgeBaseType') || 'MANAGED').toUpperCase(),
// Mantle inference region — defaults to us-east-1 for broadest model availability.
// Override via MANTLE_REGION env var at CDK synth time.
MANTLE_REGION: config.mantleRegion,
Expand Down
Loading