View a markdown version of this page

开始在 Runtime 上使用亚马逊 Bedrock 托管代理(使用 OpenAI) AgentCore - Amazon Bedrock AgentCore
Amazon Web Services 文档中描述的 Amazon Web Services 服务或功能可能因区域而异。要查看适用于中国区域的差异,请参阅 中国的 Amazon Web Services 服务入门 (PDF)。

本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。

开始在 Runtime 上使用亚马逊 Bedrock 托管代理(使用 OpenAI) AgentCore

注意

亚马逊 Bedrock 托管代理(带有 OpenAI)已进入预览版。功能和 API 可能会在正式发布之前发生变化。

Amazon Bedrock Managed Agents 在上面运行 OpenAI Codex 工具。 Amazon安全带在模型和工具之间循环,保持会话,并随着对话的增长压缩上下文。当代理必须运行命令或处理文件时,Bedrock Managed Agents 会将工作发送到环境。您可以决定该环境的运行位置。

你可以在自己的计算机上运行 Codex exec-server 进行本地开发。对于其他工作负载,Bedrock 托管代理会在您的账户中调用 AgentCore 运行时。运行时为每个会话提供自己的 microVM。会话在您控制的执行角色下运行,运行时可以连接到您的 VPC,以便代理可以访问私有资源。模型调用保留在 Bedrock 托管代理中,因此容器仅运行代理发送的命令。

在本教程中,您将执行以下任务:

  • 使用 AgentCore CLI 创建和部署运行时。

  • 使用 OpenAI 软件开发工具包开始会话。代理在您的运行时中使用示例技能。

  • (可选)添加自己的技能。

步骤 1 到 4 大约需要 15 分钟。

您在本教程中创建的 Amazon 资源可能会导致您的 Amazon 账户产生费用。这些资源包括运行时、 Amazon CodeBuild 映像版本和 Bedrock Managed Agents 模型调用。有关更多信息,请参阅AgentCore 定价。要停止收费,请移除中的资源步骤 8:清除。

先决条件

  • Node.js 20 或更高版本。C AgentCore LI 以 npm 包的形式分发。请与... 核node --version对。

  • 紫外线。示例客户端使用 uv 来安装其 Python 依赖项。

  • 配置了凭据的 Amazon 账户。要创建账户,请参阅Amazon 账户入门。要配置凭据,请参阅配置 Amazon CLI。

  • IAM 权限。您的身份需要权限才能进行 AgentCore API 调用和代入部署期间使用的 CDK 引导角色。请参见使用 C AgentCore LI。示例客户端还需要 IAM 权限。请参阅会话角色。

  • 模型访问权限。您的账户需要访问 Bedrock 托管代理模型openai.gpt-5.6-luna。

CLI 使用您的账户构建容器 Amazon CodeBuild 镜像。

步骤 1:创建项目

安装 AgentCore CLI,然后设置您的凭据和区域:

npm install -g @aws/agentcore agentcore --version export AWS_PROFILE=your-profile export AWS_REGION=us-east-1

使用BedrockManagedAgents框架创建项目。你也可以在没有旗帜agentcore create的情况下跑步。选择 “代理”,然后选择 Bedrock 托管代理作为框架。

agentcore create --name MyManagedAgent --framework BedrockManagedAgents cd MyManagedAgent

该项目的运行时配置位于中agentcore/agentcore.json,容器源位于中app/MyManagedAgent/。容器运行codex exec-server,它连接到 Bedrock 托管代理并运行代理的命令。

该项目使用以下默认值配置运行时:

  • 空闲超时时间为 30 分钟,最长使用寿命为 8 小时。请参阅配置生命周期设置。

  • 具有中权限的执行角色policies/bma-acr-policy.json。

MyManagedAgent/ ├── agentcore/ │ ├── agentcore.json │ └── cdk/ └── app/MyManagedAgent/ ├── Dockerfile ├── lifecycle/server.py ├── otel/collector.yaml ├── plugins/acr-report/ ├── policies/ │ ├── bma-acr-policy.json │ ├── bma-session-trust.json │ └── bma-session-policy.json ├── pyproject.toml ├── client.py └── README.md

关键文件:

  • lifecycle/server.py-生命周期服务器。Bedrock Managed Agents 调用它来启动codex exec-server你的运行时会话。请勿更改此文件。

  • Dockerfile-安装 Codex、 CloudWatch 代理和 Python lifecycle/otel/,并将和复制plugins/到。/opt/bma

  • otel/collector.yaml-将 exec 服务器的跨度和日志发送到。 CloudWatch

  • plugins/acr-report/-具有一项技能的示例插件。技能保存在工作区acr-report.txt中。

  • policies/bma-acr-policy.json-运行时执行角色的策略。允许 bedrock-mantle:RegisterEnvironment 和 bedrock-mantle:ConnectEnvironment。要将其限制为一个项目,Resource请更改为arn:aws:bedrock-mantle:<region>:<account-id>:project/<project-id>。

  • pyproject.toml-Python 依赖关系。该dev小组client.py仅供参加。

  • policies/bma-session-trust.json和 policies/bma-session-policy.json-信任策略和会话角色的权限。请参阅会话角色。

  • client.py-启动会话的示例客户端。你在步骤 3 中运行它。

将网络选项添加到agentcore create:

agentcore create --name MyManagedAgent --framework BedrockManagedAgents \ --network-mode VPC --vpc-id <vpc-id> --subnets <subnet-ids> \ --security-groups <security-group-ids>

VPC 必须有通往 Bedrock Managed Agents 端点的路由,因为执行服务器与之相连。镜像版本会下载 Codex 和 Python,因此它还需要一条上网的路径。请参见为 VPC AgentCore 进行配置。

相同的项目在实例计算类型上运行。向项目添加容量提供者,然后使用容量提供者添加代理:

agentcore create --name MyManagedAgent --no-agent cd MyManagedAgent agentcore add capacity-provider --name MyCapacityProvider \ --subnets <subnet-ids> --security-groups <security-group-ids> \ --os LINUX_ARM64 --instance-types c7g.large agentcore add agent --name MyManagedAgent --framework BedrockManagedAgents \ --capacity-provider MyCapacityProvider

然后继续步骤 2:部署。 agentcore deploy还会创建容量提供者及其操作员角色。

  • 使用LINUX_ARM64和 Graviton 实例类型,因为镜像版本会生成一个 ARM64 镜像。

  • 容量提供商提供网络。子网必须有通往 Bedrock 托管代理端点的路由。

要连接不在项目中的容量提供商,请将其的 ARN 提供给。agentcore create --framework BedrockManagedAgents --capacity-provider <capacity-provider-arn>请参阅运行时实例和容量提供商。

步骤 2:部署

agentcore deploy agentcore status

CLI 使用 Amazon CodeBuild 您的账户构建镜像,并部署运行时及其执行角色。Bedrock 托管代理会为您调用运行时。

保存以下输出中的运行时 ARN:agentcore status

arn:aws:bedrock-agentcore:us-east-1:<account-id>:runtime/<runtime-id>

步骤 3:运行会话

Bedrock Managed Agents 使用会话角色来调用模型和调用你的运行时。会话角色不是运行时执行角色。当你运行时client.py,它会在你的账户中创建会话角色。 agentcore deploy不会创建会话角色,agentcore remove也不会将其删除。请参阅会话角色。

从代理目录运行客户端:

cd app/MyManagedAgent uv run client.py --runtime <runtime-arn>

客户端创建会话并打印会话 ID、每条命令及其输出以及代理的答案。默认情况下,代理使用该acr-report技能在工作区acr-report.txt中进行保存。

下一节将告诉您客户端如何管理会话角色,以及运行该客户端需要哪些 IAM 权限。

会话角色不是运行时执行角色。 agentcore deploy使用创建执行角色policies/bma-acr-policy.json。客户端在创建会话时将会话角色授予role_arn现场的 Bedrock 托管代理。

当您开始新会话但不给出时--role-arn,客户端会执行以下步骤:

  1. 如果该角色BmaSessionRole-<region>不存在,则由客户端创建它。

  2. 客户端将角色的信任策略和内联策略BmaSession与policies/bma-session-trust.json和进行比较policies/bma-session-policy.json。如果策略不同,则客户端会将文件写入该角色。这些文件仅限于账户和运行时区域。

  3. 如果客户端更改了角色,则会等待 15 秒。IAM 需要这段时间,Bedrock Managed Agent 才可以使用此更改。

要更改角色,请更改文件。客户端不会移除其他人添加到角色中的其他策略。当你赋予角色时,它不会检查角色--session-id,也不会改变你赋予的角色--role-arn。

在生产环境中,为客户端指定一个运行时角色和一个网关角色--role-arn。要扮演角色,请使用中的两个文件policies/。输入您的分区、区域和账户 ID,然后将输入和更改gateway/*为运行时 ID 和网关 ID。 runtime/请勿更改项目中的文件,因为该区域中的所有项目都是共享的BmaSessionRole-<region>。

运行客户端的身份需要 Bedrock Managed Agents 客户端权限和iam:PassRole会话角色。bedrock-mantle:CallWithBearerToken要让客户端创建和修复角色,还需要提供iam:GetRoleiam:CreateRole、iam:UpdateAssumeRolePolicyiam:GetRolePolicy、、iam:PutRolePolicy等arn:aws:iam::<account-id>:role/BmaSessionRole-*。如果您给出--role-arn,则客户端不需要这五个权限。

有关信任策略、会话角色权限和客户端权限,请参阅 A mazon Bedrock 用户指南中的安全和 IAM 角色。

客户端使用openai软件包的client.beta.agents资源。Bedrock 托管代理运行代理循环。

当客户端创建会话时,它会在以下位置设置这些值environment:

  • type-aws_bedrock_agentcore,它告诉 Bedrock 托管代理使用 AgentCore 运行时。

  • runtime_arn-你的运行时间。会话在运行时区域中运行。

  • workspace_directory-代理运行其命令的目录。客户使用/home/app/workspace。生命周期服务器创建该目录。

  • runtime_qualifier-运行时的端点。客户使用DEFAULT。

  • capability_directories-Bedrock Managed Agents 在其中找到技能的目录。客户使用/opt/bma/plugins。

客户端还会设置extra_body会role_arn话角色。该openai软件包没有该字段的参数。

provide_token助手使用您的 Amazon 凭证为每个请求获取一个短暂的 Amazon Bedrock 持有者令牌。

如果您向项目添加网关,请从的输出中给出其 ARN。agentcore deploy --gateway仅在新会话中使用该标志。客户端将网关添加为带有 ARN 的mcp工具。connector_idBedrock 托管代理使用会话角色调用网关。网关必须支持 MCP 版本2025-03-26。否则,代理将无法获得网关工具,Bedrock Managed Agents 也不会显示错误。

"""Send an input to a Bedrock Managed Agents session that uses this project's ACR.""" import argparse import json import time from pathlib import Path from typing import Any import boto3 from aws_bedrock_token_generator import provide_token from botocore.exceptions import ClientError from openai import NotFoundError, OpenAI BMA_MODEL_ID = "openai.gpt-5.6-luna" # The agent runs its commands in this directory. The lifecycle server creates it. WORKSPACE_DIRECTORY = "/home/app/workspace" # Plugins and skills that the agent can use. The image has the acr-report plugin # at this path. Add the path of an S3 Files mount to use the skills in a bucket. CAPABILITY_DIRECTORIES = ["/opt/bma/plugins"] TURN_END = ("completed", "failed", "cancelled") TOOL_CALLS = ("mcp_call", "function_call", "web_search_call") POLICIES = Path(__file__).parent / "policies" SESSION_ROLE = "BmaSessionRole-{region}" SESSION_POLICY = "BmaSession" def show(data: dict[str, Any]) -> None: """Prints the session ID, the commands, the tool calls, and the answer.""" kind = data["type"].removeprefix("agent.session.") item = data.get("item") or {} if kind == "created": print(f"Session {data['session']['id']}") elif kind == "turn.output_text.delta": print(data["delta"], end="", flush=True) elif kind == "turn.item.done" and item.get("type") == "command_execution": print(f"\n$ {item['command']}\n{item.get('output') or ''}".rstrip()) elif kind == "turn.item.done" and item.get("type") in TOOL_CALLS: print(f"\nTool {item.get('name') or item['type']} {item.get('status')}") elif kind == "error" or kind.split(".")[-1] in TURN_END: source = data.get("turn") or data.get("environment") or data.get("session") print(f"\n{kind} {(source or data).get('error') or ''}".rstrip()) def load_policy(name: str, partition: str, region: str, account: str) -> str: """Reads a policy file and puts in the partition, the Region, and the account.""" text = (POLICIES / name).read_text() for key, value in (("Partition", partition), ("Region", region), ("AccountId", account)): text = text.replace("${AWS::" + key + "}", value) return text def session_role(runtime_arn: str) -> str: """Creates or repairs the session role, and returns its ARN. If the trust policy or the policy of the role is not the same as the file in `policies/`, the client writes the file to the role. """ _, partition, _, region, account = runtime_arn.split(":")[:5] name = SESSION_ROLE.format(region=region) trust = load_policy("bma-session-trust.json", partition, region, account) policy = load_policy("bma-session-policy.json", partition, region, account) iam = boto3.client("iam") changed = False try: role = iam.get_role(RoleName=name)["Role"] except iam.exceptions.NoSuchEntityException: role = iam.create_role(RoleName=name, AssumeRolePolicyDocument=trust)["Role"] print(f"Created the session role {name}") changed = True else: if role["AssumeRolePolicyDocument"] != json.loads(trust): iam.update_assume_role_policy(RoleName=name, PolicyDocument=trust) print(f"Updated the trust policy of {name}") changed = True try: current = iam.get_role_policy(RoleName=name, PolicyName=SESSION_POLICY)["PolicyDocument"] except iam.exceptions.NoSuchEntityException: current = None if current != json.loads(policy): iam.put_role_policy(RoleName=name, PolicyName=SESSION_POLICY, PolicyDocument=policy) if not changed: print(f"Updated the policy of {name}") changed = True if changed: # IAM needs some seconds before Bedrock Managed Agents can use a new or changed role. time.sleep(15) return role["Arn"] def main() -> None: parser = argparse.ArgumentParser(description=__doc__) parser.add_argument("--runtime", required=True, help="The ACR ARN.") parser.add_argument( "--session-id", help="The BMA session ID. If it does not exist, the client creates a session.", ) parser.add_argument( "--input", default="Use the acr-report skill to save an ACR report in the workspace.", ) parser.add_argument( "--gateway", help="The Gateway ARN from the output of `agentcore deploy`.", ) parser.add_argument( "--role-arn", help="The session role that BMA assumes. If you do not give it, the client creates a role.", ) parser.add_argument("--delete", action="store_true", help="Delete the session.") parser.add_argument("--raw", action="store_true", help="Print events as JSON.") args = parser.parse_args() # BMA must run in the Region of the ACR. region = args.runtime.split(":")[3] with OpenAI( api_key=lambda: provide_token(region=region), base_url=f"https://bedrock-mantle.{region}.api.aws/openai/v1", ) as client: sessions = client.beta.agents.sessions session_id = args.session_id if session_id: try: session = sessions.retrieve(session_id).model_dump(warnings=False) except NotFoundError: print(f"Session {session_id} does not exist.") session_id = None else: if session["environment"].get("runtime_arn") != args.runtime: raise ValueError(f"Session {session_id} uses another ACR.") if not session_id and not args.role_arn: try: args.role_arn = session_role(args.runtime) except ClientError as error: parser.error( f"The client cannot create or check the session role: {error}. " "Get the IAM permissions in README.md, or give --role-arn." ) print(f"Session role {args.role_arn}") if session_id: # BMA opens the stream only with stream=true, and the SDK does not send it. events = sessions.events.stream(session_id, extra_query={"stream": "true"}) message = { "role": "user", "content": [{"type": "input_text", "text": args.input}], } sessions.events.create( session_id, events=[{"type": "agent.session.input.message", "input": [message]}], ) else: agent: dict[str, Any] = { "model": BMA_MODEL_ID, "instructions": "Use the available tools to complete the task.", } if args.gateway: # Bedrock Managed Agents calls Gateway with the session role from the service side. agent["tools"] = [ {"type": "mcp", "server_label": "team_tools", "connector_id": args.gateway} ] args.input += " Then list the tools that the Gateway gives you." events = sessions.create( agent=agent, environment={ "type": "aws_bedrock_agentcore", "runtime_arn": args.runtime, "runtime_qualifier": "DEFAULT", "workspace_directory": WORKSPACE_DIRECTORY, "capability_directories": CAPABILITY_DIRECTORIES, }, input=args.input, stream=True, # The SDK has no role_arn parameter. BMA assumes this role to call the ACR. extra_body={"role_arn": args.role_arn}, ) with events: for event in events: data = event.model_dump(mode="json", warnings=False) session_id = session_id or (data.get("session") or {}).get("id") if args.raw: print(json.dumps(data), flush=True) else: show(data) if data["type"].removeprefix("agent.session.turn.") in TURN_END: break if args.delete: sessions.delete(session_id) print(f"\nDeleted session {session_id}") if __name__ == "__main__": main()

步骤 4:继续会话

要向同一个会话发送其他输入,请添加会话 ID。转弯使用相同的工作空间。要在空闲停止后保留工作空间,请添加会话存储,如所示闲置停止后保留文件。

uv run client.py --runtime <runtime-arn> --session-id <session-id> \ --input "Run cat acr-report.txt and show the output."

如果会话不存在,则客户端会创建一个新会话。添加--delete以在回合后删除会话,或者--raw将每个事件打印为 JSON。

在 microVM 运行时中,将执行服务器的主目录放在会话存储器上。然后是工作空间、连接状态,并在空闲停止后CODEX_HOME保持不变。

  1. 使用会话存储创建项目,而不是步骤 1 中的命令:

    agentcore create --name MyManagedAgent --framework BedrockManagedAgents \ --session-storage-mount-path /mnt/home cd MyManagedAgent
  2. 在中agentcore/agentcore.json,将此变量添加到运行时条目中:

    "envVars": [{ "name": "BMA_HOME_DIR", "value": "/mnt/home" }]
  3. 进client.py来,设置WORKSPACE_DIRECTORY = "/mnt/home/workspace"。

  4. 部署并运行客户端。

有关会话存储的更多信息,请参阅 AgentCore Runtime 的文件系统配置。

步骤 5:(可选)添加技能

要向图像添加技能,请在下方添加插件plugins/并部署。插件有一个.codex-plugin/plugin.json文件和一个skills/目录。该skills/目录为每项技能都有一个子目录,里面有一个SKILL.md文件。映像将其复制到/opt/bma/plugins,客户端已经将其提供给 Bedrock 托管代理。

要启动plugins/acr-report/、复制和重命名插件目录,skills/acr-report/并重命名为插件名称和技能。在plugin.json、设置nameversion、description、和"skills": "./skills/"。每个都SKILL.md从前面内容开始,前面有name和description。部署完成后,使用启动新会话--input "Use the <skill-name> skill to …​"。

在运行时中挂载 S3 文件接入点。然后,当存储桶发生变化时,技能会发生变化,图像保持不变。有关 S3 Files 文件系统、接入点和安全组规则,请参阅 AgentCore 运行时的文件系统配置。

S3 文件挂载需要在 VPC 网络模式下运行时。使用中的网络选项创建项目在 VPC 中部署运行时。

在存储桶中,将每个插件放在接入点根目录下的各自目录中。使用与plugins/acr-report/:<plugin>/.codex-plugin/plugin.json和相同的布局<plugin>/skills/<skill>/SKILL.md。

将挂载添加到运行时条目中agentcore/agentcore.json:

{ "filesystemConfigurations": [ { "s3FilesAccessPoint": { "accessPointArn": "arn:aws:s3files:us-east-1:111122223333:file-system/fs-0123456789abcdef0/access-point/fsap-0123456789abcdef0", "mountPath": "/mnt/skills" } } ] }

然后设置CAPABILITY_DIRECTORIESclient.py到["/opt/bma/plugins", "/mnt/skills"]并部署。

步骤 6:查看日志和跟踪

agentcore logs --since 15m

第一次部署会在您的账户中开启 CloudWatch 交易搜索。大约 10 分钟后,痕迹就会出现。要查看跟踪,请打开 CloudWatch 控制台并选择 GenAI 可观察性。从 Bedrock 托管代理到生命周期服务器的每次调用都有一个bma.invocation跨度。有关更多信息,请参阅查看 Amazon Bedrock AgentCore 代理的可观测性数据。

交易搜索设置适用于整个账户

交易搜索及其跨度索引适用于该地区的整个账户,并且可能会收取额外费用。要保留当前设置,请在部署~/.agentcore/config.json前添加"disableTransactionSearch": true到。

步骤 7:更新和重新部署

更改中的agentcore/agentcore.json运行时设置或映像的文件,然后重新部署。例如,此设置会在 10 分钟后停止空闲会话。这些值以秒为单位。

{ "lifecycleConfiguration": { "idleRuntimeSessionTimeout": 600, "maxLifetime": 28800 } }
agentcore deploy

这些更改适用于新会话。

例如,envVars在运行时条目中添加一个变量{ "name": "DISABLE_ADOT_OBSERVABILITY", "value": "true" }。

变量 默认值 说明

DISABLE_ADOT_OBSERVABILITY

未设置

设置true为可关闭跟踪和执行服务器日志。生命周期服务器仍将自己的日志写入运行时的日志组。

BMA_HOME_DIR

/home/app

HOME执行服务器的。

BMA_STATE_DIR

.bma中的BMA_HOME_DIR

的目录state.json,用于保存会话的连接状态。

BMA_CODEX_HOME

.codex中的BMA_HOME_DIR

CODEX_HOME执行服务器的。

BMA_CODEX_BINARY

/opt/bma/bin/codex

食典二进制文件。

BMA_MAX_TURN_LEASE

300

最长回合租约,以秒为单位。

每个镜像版本都会安装最新的 Codex 版本。生命周期服务器需要 Codex 0.154.0 或更高版本。要固定发行版,请在CODEX_RELEASE=<version>旁CODEX_NON_INTERACTIVE=1边添加Dockerfile。

步骤 8:清除

要删除会话,请--delete添加到该会话的客户端上次运行中。然后移除项目的资源,然后部署以删除运行时、其执行角色和堆栈。

agentcore remove all agentcore deploy

部署不会删除以下资源:

  • 运行时、生成映像的 CodeBuild 项目和启动构建的 Lambda 函数的 CloudWatch 日志组。

  • 亚马逊 ECR 存储库的 Amazon KMS 密钥。密钥将保持 “待删除” 状态 30 天,然后 Amazon KMS 会将其删除。

  • CDKToolkit堆栈(如果是第一次部署)引导了账户和区域。其他 Amazon CDK 应用程序可以使用此堆栈。只有在没有其他应用程序使用它时才将其删除。

  • 步骤 6 中的交易搜索设置。

  • 在步骤 3 中client.py创建的会话角色。

要删除会话角色,请运行以下命令:

aws iam delete-role-policy --role-name BmaSessionRole-<region> --policy-name BmaSession aws iam delete-role --role-name BmaSessionRole-<region>

要查找日志组,请运行以下命令。然后删除每个日志组。

aws logs describe-log-groups --log-group-name-prefix /aws/bedrock-agentcore/runtimes/<project-name>_<agent-name>- --query 'logGroups[].logGroupName' aws logs describe-log-groups --log-group-name-prefix /aws/codebuild/AgentCore-<project-name>-<target-name>- --query 'logGroups[].logGroupName' aws logs describe-log-groups --log-group-name-prefix /aws/lambda/AgentCore- --query 'logGroups[].logGroupName' aws logs delete-log-group --log-group-name <log-group-name>

替换以下值:

  • <project-name>-项目名称。在步骤 1 中,确实如此MyManagedAgent。

  • <agent-name>-代理人的名字。在步骤 1 中,它也是MyManagedAgent。

  • <target-name>-中部署目标的名称agentcore/aws-targets.json。默认值为 default。在 CodeBuild 名称中,项目名称和目标名称中的每个下划线 (_) 都更改为连字符 () -。

Lambda 日志组的名称被缩短,如下例所示:

/aws/lambda/AgentCore-MyManagedAgent--ApplicationAgentMyManage-<suffix>

该命令列出了该地区所有 CL AgentCore I 项目的 Lambda 日志组。仅删除项目的日志组。

如果您向项目添加了其他资源,例如网关或内存,请检查部署是否已将其删除。