Bedrock Knowledge Base Store
BedrockKnowledgeBaseStore is a MemoryStore backed by Amazon Bedrock Knowledge Bases.
Connect the store to a knowledge base you have already set up. Configure your store with its knowledge base ID and data source (see Data Source Types and Writability). A store with only a knowledge base ID is read-only. The store reaches Bedrock with the standard AWS credential chain, the same as the Amazon Bedrock model provider.
from strands import Agentfrom strands.memory import MemoryManagerfrom strands.vended_memory_stores import BedrockKnowledgeBaseStore
store = BedrockKnowledgeBaseStore( name="docs", description="Company documentation and policies.", config={"knowledge_base_id": "KB123"},)
agent = Agent(memory_manager=MemoryManager(stores=[store]))import { Agent, BedrockModel } from '@strands-agents/sdk'import { BedrockKnowledgeBaseStore } from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
const store = new BedrockKnowledgeBaseStore({ name: 'docs', description: 'Company documentation and policies.', config: { knowledgeBaseId: 'KB123' },})
const agent = new Agent({ model: new BedrockModel(), memoryManager: { stores: [store] },})To enable writing memories through the add_memory tool or automatic extraction, mark the store writable and point it at a data source that accepts ingestion:
from strands.vended_memory_stores import BedrockKnowledgeBaseStore
store = BedrockKnowledgeBaseStore( name="preferences", description="User preferences and stable facts.", writable=True, config={ "knowledge_base_id": "KB123", "data_source_type": "CUSTOM", "data_source_id": "DS456", },)import { BedrockKnowledgeBaseStore } from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
const store = new BedrockKnowledgeBaseStore({ name: 'preferences', description: 'User preferences and stable facts.', writable: true, config: { knowledgeBaseId: 'KB123', dataSourceType: 'CUSTOM', dataSourceId: 'DS456', },})Configuration
Section titled “Configuration”Scope and namespaces
Section titled “Scope and namespaces”scope isolates documents within a single knowledge base. It is stamped on every write (under scope_metadata_key scopeMetadataKey 'namespace') and applied as a metadata filter on search. Unlike name, scope is not a routing identity, so it never affects which store the MemoryManager targets. For per-tenant isolation, construct one store per scope; since they share a connection, this is cheap.
Store config
Section titled “Store config”The outer BedrockKnowledgeBaseStoreConfig carries the per-store identity and behavior, plus the shared MemoryStore fields (name, description, max_search_results maxSearchResults writable, extraction):
| Field | Purpose |
|---|---|
config | The knowledge base connection (see below). Reuse one across stores that differ only by scope. |
scope | Logical namespace isolating documents. Applied as a metadata filter on search and stamped on writes. |
filter | Explicit retrieval filter; overrides the auto-generated scope filter on search. |
Connection config
Section titled “Connection config”The inner BedrockKnowledgeBaseConfig is the reusable connection: which knowledge base, which data source, and the clients used to reach them:
| Field | Purpose |
|---|---|
knowledge_base_id knowledgeBaseId | The Bedrock Knowledge Base to query and ingest into. Required. |
data_source_type dataSourceType | 'CUSTOM', 'S3', or 'OTHER'. Governs whether and how the store can be written to. |
data_source_id dataSourceId | The data source to ingest into. Required for writes. |
s3 | S3 ingestion settings (bucket, prefix). Required when the data source type is 'S3'. |
scope_metadata_key scopeMetadataKey | Metadata attribute key used for scope filtering. Defaults to 'namespace'. |
runtime_client / agent_client runtimeClient / agentClient | Pre-constructed AWS clients. When omitted, default clients are constructed using the standard credential chain (the agent client lazily, on first write). |
Because the connection is a separate object, you build it once and vary only name and scope per store. This is the cheap way to give each tenant an isolated namespace over a single knowledge base:
from strands.vended_memory_stores import BedrockKnowledgeBaseStore
# Build the connection once, vary only name and scope per store.connection = { "knowledge_base_id": "KB123", "data_source_type": "CUSTOM", "data_source_id": "DS456",}
alice = BedrockKnowledgeBaseStore(name="alice", writable=True, scope="user-alice", config=connection)bob = BedrockKnowledgeBaseStore(name="bob", writable=True, scope="user-bob", config=connection)import { BedrockKnowledgeBaseStore, type BedrockKnowledgeBaseConfig,} from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
// Build the connection once, vary only name and scope per store.const connection: BedrockKnowledgeBaseConfig = { knowledgeBaseId: 'KB123', dataSourceType: 'CUSTOM', dataSourceId: 'DS456',}
const alice = new BedrockKnowledgeBaseStore({ name: 'alice', writable: true, scope: 'user-alice', config: connection,})
const bob = new BedrockKnowledgeBaseStore({ name: 'bob', writable: true, scope: 'user-bob', config: connection,})Data Source Types and Writability
Section titled “Data Source Types and Writability”Only data sources that accept direct ingestion can be written to. A store is writable only when you opt in and the backend supports ingestion: that is, the store is marked writable and the data source type is 'CUSTOM' or 'S3'.
| Data source type | Writable | How writes work |
|---|---|---|
CUSTOM | Yes | Ingests the content as inline text, with scope and metadata attached as inline attributes. |
S3 | Yes | Uploads the content to the configured s3 bucket and ingests that object. Requires an s3 config. |
OTHER | No | External backends such as Confluence, SharePoint, Salesforce, Web, or SQL/Redshift that sync from their own source or are query-only. Read-only. |
| omitted | No | Read-only. |
A writable CUSTOM store needs a data source ID. A writable S3 store needs a data source ID and an s3 config:
from strands.vended_memory_stores import BedrockKnowledgeBaseStore
store = BedrockKnowledgeBaseStore( name="preferences", writable=True, config={ "knowledge_base_id": "KB123", "data_source_type": "S3", "data_source_id": "DS789", "s3": {"bucket": "my-agent-memories", "prefix": "memories/"}, },)import { BedrockKnowledgeBaseStore } from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
const store = new BedrockKnowledgeBaseStore({ name: 'preferences', writable: true, config: { knowledgeBaseId: 'KB123', dataSourceType: 'S3', dataSourceId: 'DS789', s3: { bucket: 'my-agent-memories', prefix: 'memories/' }, },})How S3 writes work
Section titled “How S3 writes work”An S3 document can’t carry metadata inline, so when a scope or metadata are present a single write produces two objects: the content as a .txt object, and a <object-key>.metadata.json sidecar beside it (Bedrock’s convention for attaching attributes to an S3 object). The uploads are not transactional, so if a later step fails, any already-uploaded objects remain in the bucket un-ingested, where a future sync may pick them up or you can clean them up out of band.
A write ingests its object directly, regardless of where the data source is configured to scan. A later data-source sync reconciles the index to the scanned location, so a memory written outside that location is treated as deleted and removed. If you run periodic syncs against this data source, upload to the bucket and prefix it scans (the s3 config) so directly-ingested memories survive them.
Search and Ingestion
Section titled “Search and Ingestion”search runs the Bedrock Retrieve API and returns entries ordered by relevance, while add ingests new content and returns its document id:
from strands.memory.types import SearchOptionsfrom strands.vended_memory_stores import BedrockKnowledgeBaseStore
store = BedrockKnowledgeBaseStore( name="preferences", writable=True, config={ "knowledge_base_id": "KB123", "data_source_type": "CUSTOM", "data_source_id": "DS456", },)
results = await store.search("what are my preferences?", SearchOptions(max_search_results=5))for entry in results: print(entry.content, entry.metadata.get("_relevance_score"))
# add returns the new document's id (a UUID for CUSTOM, an s3:// URI for S3)result = await store.add("User prefers aisle seats", {"category": "travel"})print(result.document_id)import { BedrockKnowledgeBaseStore } from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
const store = new BedrockKnowledgeBaseStore({ name: 'preferences', writable: true, config: { knowledgeBaseId: 'KB123', dataSourceType: 'CUSTOM', dataSourceId: 'DS456' },})
const results = await store.search('what are my preferences?', { maxSearchResults: 5 })for (const entry of results) { console.log(entry.content, entry.metadata?._relevanceScore)}
// add returns the new document's id (a UUID for CUSTOM, an s3:// URI for S3)const { documentId } = await store.add('User prefers aisle seats', { category: 'travel',})The search result cap defaults to 10 when neither the call nor the store sets one. This 10 default applies only to direct calls on the store. Reached through a MemoryManager tool or its search method, the manager supplies its own per-call cap instead; set max_search_results maxSearchResults
Each entry’s metadata carries the document’s own attributes plus two reserved synthetic keys: _relevance_score _relevanceScore _source_location _sourceLocation scope is set, search filters to that namespace automatically; an explicit filter overrides the scope-derived one. The asymmetry is deliberate: an explicit filter affects search only, while writes always scope by scope.
The document id from add is the generated UUID for a CUSTOM document, or the s3:// URI of the uploaded object for S3. Writes require a data source ID (and an s3 config for S3 data sources); a write against a missing or read-only configuration raises.
Ingestion is eventually consistent: a successful write does not mean the content is immediately searchable.
Extraction
Section titled “Extraction”Enable automatic extraction on a writable store to capture memories from the conversation. By default it runs every 5 turns, distilling facts client-side with a ModelExtractor that uses the agent’s own model:
from strands.vended_memory_stores import BedrockKnowledgeBaseStore
store = BedrockKnowledgeBaseStore( name="preferences", writable=True, extraction=True, config={ "knowledge_base_id": "KB123", "data_source_type": "CUSTOM", "data_source_id": "DS456", },)import { BedrockKnowledgeBaseStore } from '@strands-agents/sdk/vended-memory-stores/bedrock-knowledge-base'
const store = new BedrockKnowledgeBaseStore({ name: 'preferences', writable: true, extraction: true, config: { knowledgeBaseId: 'KB123', dataSourceType: 'CUSTOM', dataSourceId: 'DS456' },})To change the cadence, swap the extractor, or extract server-side, see Automatic Extraction on the Memory page.
Required IAM Permissions
Section titled “Required IAM Permissions”The credentials the store uses must allow the Bedrock operations it calls, plus S3 writes when using an S3 data source:
bedrock:Retrieve- for search.bedrock:IngestKnowledgeBaseDocuments- for writes (CUSTOMandS3).s3:PutObject- for writes to anS3data source, on the configured bucket and prefix.
Here is a sample IAM policy for a writable store backed by a CUSTOM data source:
{ "Version": "2012-10-17", "Statement": [ { "Effect": "Allow", "Action": [ "bedrock:Retrieve", "bedrock:IngestKnowledgeBaseDocuments" ], "Resource": "arn:aws:bedrock:*:*:knowledge-base/KB123" } ]}For an S3 data source, add s3:PutObject on the bucket and prefix the store uploads to:
{ "Effect": "Allow", "Action": "s3:PutObject", "Resource": "arn:aws:s3:::my-agent-memories/memories/*"}Related
Section titled “Related”- Memory - the
MemoryManagerconcept this store plugs into, including the tools, extraction, and injection it enables. - Amazon Bedrock - credential and region setup shared with the Bedrock model provider.