Skip to content

Python: add Amazon Bedrock Knowledge Base context provider - #9782

Open
Vidyadhar Pogul (PVidyadhar) wants to merge 3 commits into
microsoft:mainfrom
PVidyadhar:bmkb-managed-kb-support
Open

Vidyadhar Pogul (PVidyadhar) wants to merge 3 commits into
microsoft:mainfrom
PVidyadhar:bmkb-managed-kb-support

Conversation

@PVidyadhar

@PVidyadhar Vidyadhar Pogul (PVidyadhar) commented Oct 28, 2026 •

Copy link
Copy Markdown

Motivation & Context

Enables Agent Framework agents to retrieve context from Amazon Bedrock managed Knowledge Bases, adding RAG on AWS's managed infrastructure without users running their own vector stores or embedding pipelines. This contributes the Amazon Bedrock Knowledge Base scenario to the Bedrock connector.

Continues #8173, which could not be reopened after rebasing onto current main (GitHub blocks reopening a closed PR once its branch has been force-pushed). Same branch, rebased with conflicts resolved, carrying forward everything addressed in #8173's review.

Description & Review Guide

  • What are the major changes?
    • BedrockKnowledgeBaseProvider (subclasses ContextProvider) is the single public entry point. Its mode selects how the KB is used: "inject" (before_run() retrieves passages and injects them as an untrusted user-role message via extend_messages), "tool" (exposes a KB search tool the model can call on demand via extend_tools), or "both" (default).
    • Agentic retrieval (AgenticRetrieveStream: query decomposition + managed reranking, generateResponse=False) with fallback to standard Retrieve, on both paths (use_agentic_retrieval, default True). Agentic results expose no numeric score, so min_score applies only to scored (standard Retrieve) passages.
    • Retrieved images are injected as image Content (Content.from_data with a concrete gif/jpeg/png/webp MIME type, so BedrockChatClient sends them to Converse). Other image formats become a text placeholder that names the source. Audio/video use their transcription/summary text, and SQL ROW results are rendered as column: value text.
    • The KB tool name is derived from source_id (default bedrock_knowledge_base), so several providers on one agent don't collide. It can be overridden with tool_name / tool_description.
    • Region and credentials resolve through the shared Bedrock settings path (explicit args, then .env file, then BEDROCK_* env vars; optional boto3_session), with the same region precedence as BedrockChatClient. BedrockKnowledgeBaseSettings is public.
    • Exported from agent_framework_bedrock and agent_framework.amazon (BedrockKnowledgeBaseProvider, BedrockKnowledgeBaseSettings); the search tool is internal.
    • Raises the boto3/botocore floor to 1.43.32, the first release with AgenticRetrieveStream; uv.lock regenerated.
  • What is the impact of these changes?
    • Additive: new files under python/packages/bedrock/, two namespace exports, and the boto floor bump. No change to shared serialization or the function-calling loop.
  • What do you want reviewers to focus on?
    • The single-class mode design and its use of extend_messages / extend_tools in before_run().
    • Prompt-injection posture: retrieved content stays in the untrusted user channel. This reduces but does not eliminate the risk, as documented.

All review findings on #8173 are addressed here, including the Sep 21 design review (single public provider with mode, agentic retrieval on the provider, multi-modal Content, public settings, inline JSON schema, standalone .md removed) and the later Copilot findings (agentic results vs. min_score, region precedence vs. a supplied session, load_settings precedence wording, agent_framework.amazon exports, README naming the internal tool). The Copilot review on this PR is addressed too: unique tool names across providers, and images reaching the Converse request.

Validation: ruff check / ruff format --check clean (ruff 0.16.5 and 0.17.3). Strict Pyright reports 0 errors on the package source (pyright 1.1.414). The test/sample checkers (mypy, zuban, pyrefly, ty, pyright tests config) are clean on the bedrock tests and the amazon samples. Bedrock package tests pass against current main's core (1 integration test skipped without credentials). An end-to-end run against a live managed KB confirms all three modes, the sample configuration (min_score=0.3), two tool-mode providers on one agent, and BEDROCK_REGION resolution.

Related Issue

Fixes #9786

The design direction (single public provider with mode) came out of Eduard van Valkenburg (@eavanvalkenburg)'s review of #8173. #9786 was filed to record the problem under the issue-first policy; I'm happy to adjust scope based on feedback there. Supersedes closed #8173 (and #7066 before it); there is no other open PR for this issue.

AI Assistance

  • No material AI assistance was used.
  • This is an AI-assisted contribution. I reviewed, understood, and verified all submitted content and accept responsibility for it.

AI assistance details: implementation, unit tests, samples and documentation, addressing review feedback, and this PR description were prepared with an AI coding assistant. I reviewed all changes, ran the builds, linters and tests, and verified behavior end-to-end against a live Bedrock managed Knowledge Base.

Contribution Checklist

  • The code builds clean without any errors or warnings
  • All unit tests pass, and I have added new tests where possible
  • The PR follows the Contribution Guidelines
  • This PR links to an agreed issue with no competing open PR, or the Related Issue section documents a trivial-change or repository-automation exception.
  • This is not a breaking change. If it is a breaking change, add the breaking change label (or add "[BREAKING]" to the title prefix, before or after any language prefix) — a workflow keeps the label and title prefix in sync automatically.

Adds BedrockKnowledgeBaseProvider, the single public entry point for using an
Amazon Bedrock managed Knowledge Base with an agent. Its mode selects how the KB
is used: 'inject' (retrieve passages and inject them as context), 'tool' (expose a
KB search tool the model can call), or 'both' (default).

- Agentic retrieval (AgenticRetrieveStream: query decomposition + managed
  reranking) with fallback to standard Retrieve, on both the inject and tool paths.
- Image/audio/video results are injected as multi-modal Content; SQL ROW results
  are rendered as column/value text.
- Region and credentials resolve via BEDROCK_* settings / boto3 session, matching
  BedrockChatClient and the embedding client. BedrockKnowledgeBaseSettings is public.
- Retrieved content is injected as an untrusted user-role message.
- Raises the boto3/botocore floor to 1.43.32 (first release with AgenticRetrieveStream).

Rebased onto current main as a single commit. Also exports BedrockKnowledgeBaseSettings
(instead of the now-internal tool) from the agent_framework.amazon lazy-import shim.

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🟡 Changes recommended

Multiple knowledge-base providers generate duplicate tool names, causing tool-map validation to raise ValueError and preventing searches when providers are attached in tool or default both mode.

4 open issues
What changed in this PR

Adds Amazon Bedrock Knowledge Base retrieval to the Python connector through a single context provider, supporting automatic context injection, model-driven search, or both.

Changes:

  • Adds shared agentic retrieval with standard retrieval fallback, passage formatting, and region/credential resolution.
  • Exports the provider and settings through both public namespaces and raises the AWS SDK minimum versions.
  • Adds unit tests, usage samples, and setup documentation.
File Description
python/​uv.lock Updates AWS SDK dependency constraints.
python/​samples/​02-agents/​providers/​amazon/​README.md Documents modes, samples, and retrieval permissions.
python/​samples/​02-agents/​providers/​amazon/​bedrock_kb_tool.py Demonstrates model-driven Knowledge Base search.
python/​samples/​02-agents/​providers/​amazon/​bedrock_kb_context_provider.py Demonstrates automatic context injection.
python/​packages/​core/​agent_framework/​amazon/​__init__.pyi Adds typed provider and settings exports.
python/​packages/​core/​agent_framework/​amazon/​__init__.py Adds lazy provider and settings exports.
python/​packages/​bedrock/​tests/​test_bedrock_knowledge_base.py Tests retrieval, provider modes, filtering, and content handling.
python/​packages/​bedrock/​README.md Links Knowledge Base examples.
python/​packages/​bedrock/​pyproject.toml Raises boto3 and botocore minimums to 1.43.32.
python/​packages/​bedrock/​AGENTS.md Describes the new provider and settings.
python/​packages/​bedrock/​agent_framework_bedrock/​_knowledge_base.py Implements shared retrieval helpers and the internal search tool.
python/​packages/​bedrock/​agent_framework_bedrock/​_knowledge_base_provider.py Implements injection, tool, and combined modes.
python/​packages/​bedrock/​agent_framework_bedrock/​__init__.py Exports the public provider and settings.

Review effort: Balanced

Comment on lines +142 to +143
self._tool = BedrockKnowledgeBaseTool(
knowledge_base_id=self.knowledge_base_id,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8229f1e. The tool name now comes from source_id: the default source_id="bedrock-kb" still gives bedrock_knowledge_base, and any other value gives bedrock_knowledge_base_<sanitized source_id>, truncated to 64 characters. So several providers on one agent no longer collide. I also added tool_name / tool_description overrides, validated against the Bedrock tool-name pattern [a-zA-Z0-9_-]{1,64}. A test checks that two providers pass _ensure_unique_tool_names, and I ran a live check with two tool-mode providers on a single agent.


return boto3_session.client(
"bedrock-agent-runtime",
region_name=boto3_session.region_name or resolved_region,

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7ead64f (this thread is now outdated).

Comment on lines +224 to +225
if p.score < self.min_score:
continue

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Addressed in 7ead64f (this thread is now outdated).

if content == f"[{media_type_name} content omitted]" and passage.source:
# e.g. IMAGE -> "image/*". Bedrock does not return an exact mime type here, so
# use the broad top-level type; multi-modal models resolve the concrete format.
return Content.from_uri(uri=passage.source, media_type=f"{media_type_name}/*")

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Fixed in 8229f1e. Images now become Content.from_data(bytes, "image/<fmt>") with a concrete MIME type. That is the only image form BedrockChatClient serializes, so they reach Converse. Standard Retrieve data URIs and agentic byteContent + mimeType are both decoded. Formats Converse does not accept (anything other than gif/jpeg/png/webp) become a text placeholder that includes the source, so they are not silently dropped. Audio/video results use their transcription / summary text. Tests check that the image block reaches the Converse request.

…e and docs

Addresses review findings from microsoft#8173 that were not yet handled:

- Agentic retrieval exposes no numeric score; it was normalized to 0, so any positive
  min_score (the inject sample uses 0.3) filtered out every agentic passage and injected
  no context. Represent the missing score as None and apply min_score only to scored
  (standard Retrieve) passages. Adds a regression test.
- A resolved region (argument / .env / BEDROCK_REGION) now takes precedence over a
  supplied boto3_session's default region, matching BedrockChatClient. Adds tests.
- Docstrings now state load_settings' actual order (arguments, then .env file, then
  BEDROCK_* environment variables) and that before_run runs once per agent run.
- Package README describes the provider's tool/inject modes instead of the internal tool.
- Derive the KB tool name from source_id (default stays bedrock_knowledge_base)
  so several providers on one agent no longer collide; add tool_name and
  tool_description overrides, validated against the Bedrock tool-name pattern.
- Inject retrieved images as data Content with a concrete image MIME type
  (gif/jpeg/png/webp) so BedrockChatClient actually sends them; other formats
  become a text placeholder. Audio/video use their transcription/summary text.
- Make the KB modules pass strict Pyright: typed views of the untyped
  bedrock-agent-runtime responses, non-private cross-module helpers, and
  direct boto3 imports (boto3 is a required dependency).

This branch was previously deployed

1 inactive deployment
github-app-auth — 8229f1e5 Deployed Oct 28, 2026 by PVidyadhar via add_label #26386
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

documentation Usage: [Issues, PRs], Target: documentation in the code base and learn docs python Usage: [Issues, PRs], Target: Python

Projects

None yet

Development

Successfully merging this pull request may close these issues.

.NET: Python: [Feature]: Amazon Bedrock managed Knowledge Base retrieval for agents

2 participants