本文属于机器翻译版本。若本译文内容与英语原文存在差异,则一律以英文原文为准。
开始在 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 定价
先决条件
-
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 代理和 Pythonlifecycle/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,客户端会执行以下步骤:
-
如果该角色
BmaSessionRole-<region>不存在,则由客户端创建它。 -
客户端将角色的信任策略和内联策略
BmaSession与policies/bma-session-trust.json和进行比较policies/bma-session-policy.json。如果策略不同,则客户端会将文件写入该角色。这些文件仅限于账户和运行时区域。 -
如果客户端更改了角色,则会等待 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 中的命令:
agentcore create --name MyManagedAgent --framework BedrockManagedAgents \ --session-storage-mount-path /mnt/home cd MyManagedAgent -
在中
agentcore/agentcore.json,将此变量添加到运行时条目中:"envVars": [{ "name": "BMA_HOME_DIR", "value": "/mnt/home" }] -
进
client.py来,设置WORKSPACE_DIRECTORY = "/mnt/home/workspace"。 -
部署并运行客户端。
有关会话存储的更多信息,请参阅 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" }。
| 变量 | 默认值 | 说明 |
|---|---|---|
|
|
未设置 |
设置 |
|
|
|
|
|
|
|
的目录 |
|
|
|
|
|
|
|
食典二进制文件。 |
|
|
|
最长回合租约,以秒为单位。 |
每个镜像版本都会安装最新的 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 日志组。仅删除项目的日志组。
如果您向项目添加了其他资源,例如网关或内存,请检查部署是否已将其删除。