当 AgentCore 代理和知识库位于不同 AWS 账户时,企业不必复制源数据,也不必把分析型数据迁移到代理所在账户。通过跨账户 IAM 授权,可以让一个账户中的 Amazon Bedrock AgentCore 代理调用另一个账户中的 Amazon Bedrock Knowledge Base,并从由 Amazon Redshift Serverless 支撑的知识库生成答案。
这类架构的重点不只是“能不能调用”,而是要明确数据边界、信任关系和代理编排方式。本文围绕一个典型场景展开:代理运行在账户 A,知识库和 Redshift Serverless 位于账户 B,回答过程通过受控的跨账户权限完成。
架构:代理账户与数据账户分离
可以把系统拆成两个 AWS 账户:
- 账户 A:代理账户,部署 Amazon Bedrock AgentCore agent,以及应用入口、会话管理和审计组件。
- 账户 B:数据账户,部署 Amazon Bedrock knowledge base,其数据访问层由 Amazon Redshift Serverless 支撑。
- 跨账户边界:账户 B 中的 IAM role 信任账户 A 中的代理执行身份,只授予调用指定知识库所需的权限。
请求流程可以概括为:
- 用户向账户 A 中的 AgentCore 代理提问。
- 代理判断需要检索企业知识。
- 代理通过跨账户角色获得账户 B 中的受限权限。
- 代理调用账户 B 中的 knowledge base 检索接口。
- knowledge base 从 Redshift Serverless 支撑的数据层获取相关内容,并返回检索结果。
- 代理结合检索结果生成最终答案。
源数据仍由账户 B 管理。账户 A 获得的是一次受控查询结果,而不是 Redshift 中的完整数据副本。这种分离适合数据平台团队和 AI 应用团队由不同组织负责的企业环境。
安全边界如何设计
跨账户访问通常需要两端配合:账户 B 的目标角色需要信任账户 A,账户 A 的代理身份需要被允许执行 sts:AssumeRole。获得临时凭证后,代理再调用知识库 API。
下面是一个可改造的目标账户 IAM trust policy。示例中的账号、角色名和外部 ID 都是假设值,部署前应替换为实际配置:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "TrustAgentCoreExecutionRole",
"Effect": "Allow",
"Principal": {
"AWS": "arn:aws:iam::111122223333:role/AgentCoreExecutionRole"
},
"Action": "sts:AssumeRole",
"Condition": {
"StringEquals": {
"sts:ExternalId": "agentcore-kb-prod"
}
}
}
]
}
账户 B 中的权限策略应尽量限制到目标 knowledge base,而不是授予整个 Bedrock 资源范围。例如,可以这样定义一条最小化的调用策略:
{
"Version": "2012-10-17",
"Statement": [
{
"Sid": "RetrieveFromOneKnowledgeBase",
"Effect": "Allow",
"Action": [
"bedrock:Retrieve",
"bedrock:RetrieveAndGenerate"
],
"Resource": "arn:aws:bedrock:us-east-1:444455556666:knowledge-base/KB_ID"
}
]
}
实际支持的动作和资源级约束应以目标区域及当前 AWS 服务权限模型为准。生产环境还应同步检查以下边界:
- 只信任明确的 AgentCore 执行角色,不要直接信任整个账户。
- 为跨账户角色设置短会话时长,并记录 AssumeRole 调用。
- 使用 CloudTrail 记录角色切换和 knowledge base 调用。
- 通过 VPC、私有网络路径和 Redshift 安全组控制数据层访问范围。
- 确认代理返回内容不会泄露不应暴露给调用者的字段。
- 将开发、测试和生产 knowledge base 使用不同的角色与资源 ARN 隔离。
两种代理编排方式
代码驱动:Strands agent
代码驱动方式适合需要精细控制工具选择、提示词、错误处理和会话状态的团队。Strands agent 可以把“查询跨账户知识库”封装成一个工具,由工具负责获取临时凭证并调用知识库 API。
下面是一个最小化的 Python 示例。它展示了调用链路,使用的角色 ARN、knowledge base ID 和区域需要替换为实际值。示例假设运行环境已经拥有调用 sts:AssumeRole 的权限,并且已安装 AWS SDK:
import boto3
REGION = "us-east-1"
TARGET_ROLE_ARN = "arn:aws:iam::444455556666:role/CrossAccountKnowledgeBaseRole"
KNOWLEDGE_BASE_ID = "KB_ID"
def retrieve_context(question: str) -> list[dict]:
sts = boto3.client("sts", region_name=REGION)
assumed = sts.assume_role(
RoleArn=TARGET_ROLE_ARN,
RoleSessionName="agentcore-kb-session",
ExternalId="agentcore-kb-prod",
)
credentials = assumed["Credentials"]
bedrock_agent_runtime = boto3.client(
"bedrock-agent-runtime",
region_name=REGION,
aws_access_key_id=credentials["AccessKeyId"],
aws_secret_access_key=credentials["SecretAccessKey"],
aws_session_token=credentials["SessionToken"],
)
response = bedrock_agent_runtime.retrieve(
knowledgeBaseId=KNOWLEDGE_BASE_ID,
retrievalQuery={"text": question},
retrievalConfiguration={
"vectorSearchConfiguration": {
"numberOfResults": 5
}
},
)
return response.get("retrievalResults", [])
if __name__ == "__main__":
question = "How is the quarterly sales forecast calculated?"
results = retrieve_context(question)
for item in results:
text = item.get("content", {}).get("text", "")
print(text)
在真实的 Strands agent 中,可以把 retrieve_context 注册为工具,再由代理决定何时调用。工具层应处理凭证过期、限流、超时和空结果;提示词层则应明确要求模型只使用检索到的证据回答,并在没有足够上下文时说明无法确认。
声明式编排:AgentCore harness
如果团队希望把代理流程、工具连接和运行时配置集中在声明式配置中,可以采用 AgentCore harness。它适合标准化程度较高的工作流:输入问题、调用指定 knowledge base、把检索结果交给模型生成答案。
下面是一个抽象的 YAML 示例,用于表达这种配置思路。具体字段名需要根据所使用的 AgentCore harness 版本和部署方式调整:
name: cross-account-knowledge-agent
runtime: agentcore
region: us-east-1
identity:
execution_role: arn:aws:iam::111122223333:role/AgentCoreExecutionRole
orchestration:
type: declarative
model:
provider: bedrock
id: YOUR_MODEL_ID
instructions: |
Answer only with evidence returned by the knowledge base.
If the retrieved context is insufficient, say that the answer cannot be confirmed.
tools:
- name: enterprise-knowledge-base
type: bedrock-knowledge-base
account: "444455556666"
knowledge_base_id: KB_ID
assume_role_arn: arn:aws:iam::444455556666:role/CrossAccountKnowledgeBaseRole
external_id: agentcore-kb-prod
retrieval:
number_of_results: 5
声明式方式减少了业务代码中的 AWS 身份和调用细节,但对配置校验、版本管理和故障诊断提出了更高要求。适合把同一套权限、模型和检索策略推广到多个代理的场景。
如何选择实现方式
可以按变化来源做选择:
| 需求 | 更适合的方式 |
|---|---|
| 工具调用逻辑复杂,需要条件分支 | Strands agent |
| 需要自定义重试、缓存或结果后处理 | Strands agent |
| 工作流固定,希望统一发布和审计 | AgentCore harness |
| 多个代理共享同一套知识库配置 | AgentCore harness |
| 团队已有 Python agent 工程体系 | Strands agent |
两种方式共享同一个核心原则:知识库所在账户掌握数据和授权,代理所在账户只获得完成任务所需的临时访问能力。编排方式可以变化,但信任策略、资源范围和日志审计不能被配置便利性替代。
上线前检查清单
部署前建议逐项验证:
- 代理执行角色是否能对目标角色执行
sts:AssumeRole。 - 目标角色 trust policy 是否只信任预期的 AgentCore 身份。
ExternalId是否唯一且不会写入公开配置。- knowledge base ARN、区域和账户 ID 是否完全匹配。
- Redshift Serverless 侧的网络和数据库权限是否满足检索链路要求。
- CloudTrail 是否能关联用户请求、角色切换和知识库调用。
- 无检索结果、权限拒绝、超时和模型生成失败时,代理是否返回可诊断的错误。
- 测试数据是否包含跨账户场景下的敏感字段和越权查询用例。
跨账户 knowledge base 的价值在于保留数据所有权边界,同时让 AI 应用按需使用企业知识。实践中应从最小权限的目标角色开始,再逐步加入网络隔离、审计、脱敏和成本监控。这样,AgentCore 代理可以独立迭代,数据平台也不必为了接入新的 AI 应用而复制或重构原有数据资产。