View a markdown version of this page

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

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

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

注意

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

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

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

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

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

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

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

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

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

先决条件

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

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

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

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

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

CLI 使用您的账户构建容器 AWS 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 使用 AWS 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助手使用您的 AWS 凭证为每个请求获取一个短暂的 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 存储库的 AWS KMS 密钥。密钥将保持 “待删除” 状态 30 天,然后 AWS KMS 会将其删除。

  • CDKToolkit堆栈(如果是第一次部署)引导了账户和区域。其他 AWS 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 日志组。仅删除项目的日志组。

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