跳到正文
AWS Machine Learning Blog· Sundar Raghavan·· 2 小时前精选AI 评分58

Amazon Bedrock AgentCore runtime 如何用 Session endpoints 实时预览编码智能体构建的网页应用

Preview web apps live as your coding agent builds them with Amazon Bedrock AgentCore runtime

AI 导读

AWS 介绍 Amazon Bedrock AgentCore runtime 的 Session endpoints,可为每个会话提供带鉴权的 URL,把允许端口的 HTTP 与 WebSocket 请求转发到会话内运行的应用。

推荐理由

AWS 官方给出 Session endpoints 的端口、鉴权与拒绝规则,读者可据此搭出边改边看的编码智能体预览流程。

正文 · AI 翻译

编码智能体现在能构建可用的 Web 应用:一个仪表盘、一个产品页面、一个产品团队想要试用的原型。审查这些成果最快的方式是打开应用、使用它、提出修改请求,然后检查结果。当应用持续运行在智能体编辑它的地方时,这个循环运转良好,每次修改都能在几秒内出现在浏览器中。而当应用必须先复制出去并部署到别处时,每次修改都要等待一次部署,审查速度就会降到那个节奏。

Amazon Bedrock AgentCore 是一个用于大规模构建、连接和优化智能体的平台,你可以自选智能体框架和基础模型(FM)。AgentCore 运行时是 Amazon Bedrock AgentCore 的一项能力,它在各自隔离的 microVM 中运行每个智能体会话。借助会话端点,你可以从自己的浏览器打开在该会话中运行的应用。会话端点为每个会话提供一个经过身份验证的 URL,将每个请求的 HTTP 方法、路径、查询字符串和请求体,以及 WebSocket 连接,转发到你允许的端口。当智能体保存每个文件时,你可以看到页面随之更新。

在本文中,你将部署一个编码智能体,让一个 Vite 网站持续运行在其会话中,然后打开一个本地页面,左侧是聊天窗口,右侧是实时网站。你让智能体把网站切换为深色主题,跟随它逐步流式输出的步骤,并观察网站无需刷新即可发生变化。最后,你会了解内部发生了什么:同一会话中的第二个端口,以及会话端点拒绝的请求。

完整示例(包括本文所遵循的 notebook)位于 agentcore-samples GitHub 仓库的 14-remote-access 文件夹中。

会话端点的工作原理

每个会话都有自己的会话端点,有六个细节决定了它的使用方式。

你可以选择它可访问的端口。 在调用 CreateAgentRuntime 时设置 allowedPorts:1–5 个条目,每个条目为单个端口或 8000–12000 范围内的一个区间,不包括保留的平台端口。允许某个端口并不会启动服务器,因此你的应用必须在该端口上监听,并绑定到 0.0.0.0。

URL 随会话一起返回。InvokeAgentRuntime 的响应会在 X-Amzn-Bedrock-AgentCore-Runtime-Session-Endpoint-Url 头中携带它,为其建模的 SDK 会将其暴露为 sessionEndpointUrl。

每个请求都经过身份验证。对于使用 AWS Identity and Access Management (IAM) 的运行时,每个 HTTP 请求、HTTP/2 流和 WebSocket 握手都携带 Signature Version 4 (SigV4) 签名。调用方还需要在运行时及其运行时端点上拥有 bedrock-agentcore:InvokeAgentRuntimeProxy 权限。对于使用入站 JSON Web Token (JWT) 授权方的运行时,每个请求则携带 bearer token。知道 URL 并不等于获得访问权限。

主机名选择端口。无论目标端口是什么,你的客户端都通过 443 端口连接,而主机名上的前缀会选择会话内部的端口:

https://8090--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/index.html
https://8081--<session-endpoint-id>.runtime.bedrock-agentcore.<region>.on.aws/status

它承载你的服务器所支持的协议。HTTP/1.1 和 HTTP/2 请求(包括服务器发送事件和 gRPC)以及 WebSocket 连接都可以通过。本演练使用 HTTP/1.1 和 WebSocket。

它的作用范围仅限于单个会话。该 URL 需要在每次请求时携带凭证,并且仅在会话期间有效,因此请用它来构建、测试和审查你的 agent 所生成的内容。若要将应用提供给用户使用,请将其部署到托管服务,例如 AWS Amplify Hosting。

浏览器无法自行向页面发出的请求添加 SigV4 签名或 bearer token,因此 bedrock-agentcore SDK 中的 Session endpoint 客户端可以在你的机器上打开一个本地端点。你的浏览器打开 http://localhost:8088,本地端点会在转发每个请求和 WebSocket 握手之前为其添加你的凭证。

Session endpoint 与 AgentCore runtime 已提供的 runtime endpoint 不同。使用 runtime endpoint(例如 DEFAULT)来访问你的 agent,它控制调用方将访问哪个版本。InvokeAgentRuntime 调用通过它解析,因此你可以让开发和生产使用不同版本,并在不更改调用方的情况下进行升级或回滚。使用 Session endpoint 查看你的 agent 在其会话中运行的内容,例如 Web 预览。它是一个经过身份验证的 URL,仅能访问你允许的端口,可与会话运行的任意版本配合使用,并在会话结束时停止工作。完整文档请参阅通过 session endpoint 连接到运行时会话。

解决方案概述

该示例包含四个部分。一个编码 agent 在会话中运行于端口 8080,并使用四个工具编辑网站文件:list、read、write 和 edit。该 agent 在端口 8090 上启动一个 Vite 开发服务器,该服务器提供网站服务,并通过其热重载 WebSocket 将每次保存的更改推送到浏览器。在你的机器上,PreviewApp 提供预览页面,将你的提示发送到 InvokeAgentRuntime,并为网站打开一个本地端点。如图 1 所示,预览页面通过本地端点和 Session endpoint 从端口 8090 上的 Vite 开发服务器加载网站,并通过 InvokeAgentRuntime 将你的提示发送到端口 8080 上的 agent。数字表示单个请求的步骤顺序。

Architecture diagram: the preview page and local endpoint on your machine, the Session endpoint and InvokeAgentRuntime, and the agent and Vite development server in a runtime session, with Claude Haiku 5.5 in Amazon Bedrock.

图 1:解决方案架构

在步骤 1 之前,PreviewApp 已经调用过 InvokeAgentRuntime 一次以启动会话,这会启动 agent 和 Vite 开发服务器。PreviewApp 从该响应中读取 Session endpoint URL,并为端口 8090 打开了一个本地端点。然后,图 1 中的编号步骤遵循一次更改请求:

  1. 预览页面的站点窗格从 localhost:8088 上的本地端点加载网站。本地端点会为每个请求和 WebSocket 握手添加你的凭证,并将它们转发到 Session endpoint。Session endpoint 会根据 allowedPorts 检查签名和端口,然后将它们转发到端口 8090 上的 Vite 开发服务器。页面保持 Vite 热重载 WebSocket 打开。
  2. 你从聊天窗格发送提示。PreviewApp 将其作为使用你的 AWS 凭证签名的标准 AWS API 调用发送到 InvokeAgentRuntime,运行时将其传递到端口 8080 上的 agent。agent 的步骤会在其工作时流式返回到聊天窗格。
  3. agent 调用 Amazon Bedrock 中的 Claude Haiku 5.5 来决定要更改什么。
  4. agent 读取站点文件并保存其更改的文件。Vite 开发服务器提供这些文件并监视它们的更改。
  5. 当文件被保存时,Vite 通过步骤 1 中打开的 WebSocket 推送更改,经由 Session endpoint 和本地端点返回,站点窗格无需刷新即可更新。
  6. 在 notebook 中,PreviewApp 通过同一个 Session 端点读取代理在端口 8081 上的 /status 路由。只有端口发生变化。

端口 8080 不在 allowedPorts 中,因为 InvokeAgentRuntime 无需经过 Session 端点即可访问代理。

先决条件

要跟随本演练,你需要:

  • 一个位于提供 AgentCore 运行时 Session 端点的 AWS 区域中的 AWS 账户,并已配置凭证。
  • 创建 AWS Identity and Access Management (IAM) 角色的权限、上传到 Amazon Simple Storage Service (Amazon S3) 的权限,以及创建运行时的权限,另外还需要在该运行时及其 DEFAULT 运行时端点上具有 bedrock-agentcore:InvokeAgentRuntime 和 bedrock-agentcore:InvokeAgentRuntimeProxy 权限。详情请参阅 AgentCore 运行时的 IAM 权限。
  • Python 3.10 或更高版本,以及 bedrock-agentcore 1.25.2 或更高版本和 boto3 1.43.122 或更高版本。
  • Git,用于克隆示例仓库,以及一个 Jupyter 环境(例如 JupyterLab 或带 Jupyter 扩展的 Visual Studio Code),用于运行 notebook。
  • 在 Amazon Bedrock 中访问 Claude Haiku 5.5 的权限。有关各区域的模型可用性,请参阅 按模型划分的区域可用性。
  • Node.js 22 或更高版本以及 npm,部署脚本使用它们来打包代理和网站。

该示例使用 Node.js 的直接代码部署 将代理作为 zip 文件部署到 Amazon S3,因此你不需要 Docker 或 Amazon Elastic Container Registry (Amazon ECR) 仓库。Session 端点适用于 microVM 运行时,不适用于 Instances 计算类型,并且 Session 端点 URL 可通过公共 HTTPS 访问。入站连接不支持 AWS PrivateLink。

部署代理及其网站

首先,你部署运行时,你在此处选择的配置决定了 Session 端点可以访问哪些端口。部署脚本将代理打包为一个文件,为运行时的 Linux on Arm64 系统添加网站及其依赖项,将 zip 上传到 Amazon S3,并创建运行时。

以下摘自 deploy.py 的片段展示了本文关注的两项设置。protocolConfiguration 指定代理在何处监听 InvokeAgentRuntime,而 allowedPorts 列出了 Session 端点可以访问的端口:8090 用于网站,8081 用于代理的状态路由。端口 8080 不在列表中,因为 InvokeAgentRuntime 无需它即可访问代理。有关端口和路径设置,请参阅 配置代理的服务端口和调用路径。

agentRuntimeArtifact={"codeConfiguration": {
    "code": {"s3": {"bucket": code_bucket(), "prefix": S3_PREFIX}},
    "runtime": "NODE_22",
    "entryPoint": ["app.js"],
}},
protocolConfiguration={"serverProtocol": "HTTP", "port": 8080, "path": "/invocations"},
allowedPorts=[{"port": 8090}, {"port": 8081}],

网站的 Vite 配置使开发服务器可从 Session 端点访问。它监听 0.0.0.0 的端口 8090,并且不限制 Host 标头(server.allowedHosts 为 true),因为请求到达时使用的是运行时分配的主机名,而不是 localhost。Session 端点在请求到达服务器之前会对每个请求进行身份验证,因此服务器不需要自己的主机检查。

要部署运行时:

1. 克隆示例仓库并切换到示例文件夹:

git clone https://github.com/awslabs/agentcore-samples.git
cd agentcore-samples/01-features/02-host-your-agent/01-runtime/03-advanced/16-session-endpoints

2. 从示例文件夹打开 session_endpoints_preview.ipynb。

3. 运行安装单元格,它会安装 Python 依赖项。

4. 运行 %run deploy.py 单元格。部署需要几分钟,主要是等待运行时达到 READY 状态。

打开预览

运行时准备就绪后,你就可以启动预览。一次调用完成三件事:启动会话(这会启动网站)、为端口 8090 打开本地端点,并在 localhost:8087 上提供预览页面。

from preview_app import PreviewApp

app = PreviewApp().start()
print("Open", app.url)

在 start() 内部,使用 Session 端点的调用很简短。第一个 InvokeAgentRuntime 调用在响应头中返回 URL,session_endpoint_url 读取它,然后 Session 端点客户端为端口 8090 打开本地端点:

answer = client.invoke_agent_runtime(
    agentRuntimeArn=runtime_arn, runtimeSessionId=session_id,
    payload=json.dumps({"prompt": ""}).encode(), contentType="application/json",
)
endpoint = client.session_endpoint_client(session_endpoint_url(answer))
local = endpoint.open_local_endpoint(port=8090, local_port=8088).start()

要打开预览:

  1. 运行以 PreviewApp 开头的单元格。
  2. 在浏览器中打开打印出的链接 http://localhost:8087。

页面右侧显示的是该网站,由会话中的 8090 端口提供服务;左侧是一份简短指南,列出了建议的请求。

向 agent 请求一项更改

现在你请求一项更改,并观察它生效。每个提示都通过 InvokeAgentRuntime 发送给 agent。agent 读取它需要的文件,写入它更改的文件,并在每一步发生时进行报告。当文件被保存时,Vite 开发服务器会通过其 WebSocket,经由 Session 端点和本地端点推送更改,网站随即就地更新。

要请求一项更改:

  1. 在预览页面上,选择 Switch this website to a dark coffee-house color theme。
  2. 在聊天窗格中跟随 agent 的步骤,观察它读取和保存文件。
  3. 观察站点窗格。当 agent 保存样式表时,它会发生变化,并且会有一条横幅指明更改来自哪个文件。

以下视频展示了 agent 处理多个请求时的预览页面。选择一条建议的请求会将其发送给 agent,聊天窗格会列出 agent 读取和保存的每个文件,右侧的站点窗格无需刷新即可更新,从深色主题变为绿色的 Order ahead 按钮。

The preview page with a chat pane on the left and the live website on the right updating as the agent edits files

图 2:agent 工作时的预览页面

这些步骤会以流式传输,因为当你要求时,agent 会以服务器发送事件的形式作答。你可以用 Python 通过 app.ask 发送相同的提示,它会使用 iter_events SDK 中的 bedrock-agentcore 读取流。打开的页面会以相同方式更新:

for event in app.ask("Make the Order ahead button green"):
    if "step" in event:
        print("  ", event["step"])
    elif "done" in event:
        print(event["done"]["reply"])

此 Python 脚本的输出应类似于以下内容:

   Looking at the site's files
   Reading src/main.js
   Reading src/style.css
   Reading index.html
   Saved src/style.css
The Order ahead button is now green instead of brown, with white text kept for contrast. You can see it in the hero section, just below the "Small batch coffee, roasted every morning" heading at the top of the page.

在同一会话中访问第二个端口

该网站并不是你唯一可以访问的服务器。agent 在 8081 端口上提供 /status,其中列出了每个提示及其更改的文件。同一个 Session 端点可以访问它,唯一的区别是端口参数。

status = app.endpoint.request("GET", "/status", port=8081)
print("GET /status on port 8081: HTTP", status.status)
for edit in status.json()["edits"]:
    print("  ", edit["prompt"], "->", ", ".join(edit["files"]))

此 Python 脚本的输出应类似于以下内容:

GET /status on port 8081: HTTP 200
   Make the Order ahead button green -> src/style.css

Session 端点会拒绝什么

当运行时拒绝一个请求时,它会返回一个 HTTP 状态码、一个空响应体,并在响应头中给出错误代码,这样你就可以将其拒绝与你应用程序返回的错误区分开来。该 notebook 会向 allowedPorts 之外的端口发送请求,并发送一个没有凭据的请求,运行时对两者都以 403 AccessDenied 拒绝。

下表列出了你在使用 Session 端点构建时可能遇到的拒绝情况。

请求 运行时的响应
不在 allowedPorts 中的端口 403 AccessDenied
没有有效凭据的请求 403 AccessDenied 或 401 AuthenticationRequired
允许的端口但没有监听任何内容 502 PortNotReachable
会话已不存在的 URL 404 SessionNotFound

你的会话访问是如何受到保护的

运行时在转发请求之前会移除自己的身份验证头,因此网站不会收到你的签名。请求会作为 InvokeAgentRuntimeProxy 事件记录在 AWS CloudTrail 中,事件源为 bedrock-agentcore.amazonaws.com。本地端点以你的凭据行事,因此它限制了谁可以使用它。它仅监听 127.0.0.1,只应答发往其自身本地地址的请求,并拒绝来自其他来源的页面打开的 WebSocket 连接。仅在你使用预览时运行本地端点。有关更多信息,请参阅 Log session endpoint requests in CloudTrail。

访问控制不会将网站与代理隔离开。两者在同一会话中运行,因此请只授予执行角色代理所需的权限。如果运行时替换了会话的计算资源,已打开的连接会关闭,除非会话使用持久存储,否则代理的编辑可能无法保留。如果你需要文件在计算资源之后仍然存在,请参阅AgentCore 运行时的文件系统配置。

代理的文件工具会解析站点文件夹内的每个路径,并拒绝该文件夹之外的路径,因此提示词无法让代理更改会话中的其他文件。如果其他人可以向你的编码代理发送提示词,请考虑使用Amazon Bedrock Guardrails来过滤有害的提示词和响应,并在发布前审查代理的更改。

清理

为避免持续产生费用,请停止预览并删除示例创建的资源。代理编辑的网站位于会话中,因此会随会话一起删除。

清理步骤:

1. 运行 stop 单元格,并在笔记本提示时按 Enter。这会停止预览页面、本地端点和会话。

2. 运行 %run cleanup.py 单元格,这会删除运行时、上传的代码和 IAM 角色。

结论

会话端点让你可以通过 HTTP/1.1、HTTP/2 和 WebSocket,在你允许的端口上,从自己的工具以经过身份验证的方式访问 AgentCore 运行时会话中的应用程序。在本文中,你部署了一个编码代理,并在其会话中运行一个 Vite 网站,通过本地端点在浏览器中打开实时网站,要求代理提供深色主题,并观察代理保存文件时更改的到达。你还在同一会话中访问了第二个端口,并确认了会话端点会拒绝什么。

要进一步探索,请在 site 文件夹中放入你自己的网站并运行笔记本,或者更改代理的工具以匹配你的编码代理的工作方式。有关完整选项(包括端口范围、OAuth、HTTP/2 和 gRPC),请参阅通过会话端点连接到运行时会话。

要更改 InvokeAgentRuntime 在你自己的代理中使用的端口或路径,请参阅配置代理的服务端口和调用路径。如果你的代理还需要在同一会话中运行构建或测试命令,请参阅在 AgentCore 运行时会话中执行 shell 命令。要像本示例一样从 zip 文件部署你自己的 Node.js 代理,请参阅Node.js 的直接代码部署。有关该服务提供的其他所有功能,请从使用 Amazon Bedrock AgentCore 运行时托管代理或工具开始,并在 agentcore-samples GitHub 仓库中查找更多示例。


关于作者

Sundar Raghavan

Sundar Raghavan

Sundar 是 AWS Agentic AI Foundations 团队的高级解决方案架构师。他负责 Bedrock AgentCore 的开发者体验,掌管 SDK 和 CLI,并推动框架与生态系统集成策略。他专注于开发者如何在 AWS 上构建、部署和扩展生产 AI 代理。他还通过 Strands Robots 将同样的代理开发者体验带到 Physical AI。

来源:AWS Machine Learning Blog · aws.amazon.com