用 Amazon Bedrock AgentCore 运行时实时预览编码智能体构建的网页应用
在 AgentCore 运行时会话里部署编码智能体和 Vite 网站,经会话端点在浏览器中看热更新,并核对第二端口、拒绝情形与清理。

目录
#用 Amazon Bedrock AgentCore 运行时实时预览编码智能体构建的网页应用
编码智能体(coding agents)现在会做出能用的网页应用:一块仪表板、一个产品页、一份产品团队想试的原型。最快的复核方式是打开这个应用、使用它、提出一处修改,再核对结果。当应用一直跑在智能体编辑它的地方时,这个循环很顺,每一次修改都会在几秒内出现在浏览器里。如果必须先把应用复制出去、部署到别处,每一次修改都要等一次部署,复核速度就被拖成部署的节奏。
Amazon Bedrock AgentCore 是一个用于大规模构建、连接和优化智能体的平台,智能体框架和基础模型(foundation model,FM)可以由你选择。AgentCore 运行时(runtime)是 Amazon Bedrock AgentCore 的一项能力,它把每个智能体会话放在各自隔离的微型虚拟机(microVM)里运行。有了会话端点(Session endpoints),你可以从自己的浏览器打开那个会话里正在运行的应用。会话端点为每个会话提供一个经过身份验证的 URL,把每个请求的 HTTP 方法、路径、查询字符串和正文,以及 WebSocket 连接,转发到你允许的端口。智能体每保存一个文件,你都可以看着页面更新。
在本文中,你将部署一个编码智能体,让它在自己的会话里持续运行一个 Vite 网站,然后打开一个本地页面:左边是对话,右边是实时网站。你让智能体把网站换成深色主题,跟着它逐步流式输出的步骤,看着网站在不刷新的情况下发生变化。最后你看内部发生了什么:同一会话里的第二个端口,以及会话端点会拒绝的请求。
完整示例,包括本文所跟随的笔记本,位于 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 握手都携带签名版本 4(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 在每次请求上都需要凭据,并且只在会话存续期间有效,因此用它来构建、测试和复核智能体产出的内容。若要把应用提供给你的用户,请把它部署到托管服务,例如 AWS Amplify Hosting。
浏览器无法给页面自己发出的请求加上 SigV4 签名或持有者令牌,因此 bedrock-agentcore SDK 中的会话端点客户端可以在你的机器上打开一个本地端点。浏览器打开 http://localhost:8088,本地端点在转发之前,为每个请求和 WebSocket 握手加上你的凭据。
会话端点不同于运行时端点,后者是 AgentCore 运行时已经提供的。使用运行时端点(例如 DEFAULT)来到达你的智能体,它控制调用方会到达哪个版本。InvokeAgentRuntime 调用通过它解析,因此你可以把开发和生产放在不同版本上,并在不改变调用方的情况下晋升或回滚。使用会话端点来查看智能体在其会话中运行的内容,例如网页预览。它是一个经过身份验证的 URL,只到达你允许的端口,适用于该会话正在运行的任何版本,并在会话结束时停止工作。完整文档见 Connect to runtime sessions through a session endpoint。
解决方案概览
示例有四个部分。编码智能体在会话中的 8080 端口上运行,并用四个工具编辑网站文件:list、read、write 和 edit。智能体在 8090 端口启动 Vite 开发服务器,由它提供网站,并在每次保存后通过热重载 WebSocket 把变更推送到浏览器。在你的机器上,PreviewApp 提供预览页,把你的提示发送到 InvokeAgentRuntime,并为网站打开一个本地端点。如图 1 所示,预览页通过本地端点和会话端点,从 8090 端口上的 Vite 开发服务器加载网站,并通过 InvokeAgentRuntime 把你的提示发送到 8080 端口上的智能体。数字表示一次请求中各步骤的顺序。
[图:架构图:你机器上的预览页和本地端点,会话端点与 InvokeAgentRuntime,以及运行时会话中的智能体和 Vite 开发服务器,Amazon Bedrock 中的 Claude Haiku 5.5。]
图 1:解决方案架构
在步骤 1 之前,PreviewApp 已经调用过一次 InvokeAgentRuntime 来启动会话,这会启动智能体和 Vite 开发服务器。PreviewApp 从该响应中读取会话端点 URL,并为 8090 端口打开一个本地端点。图 1 中带编号的步骤随后跟随一次变更请求:
- 预览页的网站窗格从 localhost:8088 上的本地端点加载网站。本地端点为每个请求和 WebSocket 握手加上你的凭据,并把它们转发到会话端点。会话端点核对签名,并对照 allowedPorts 核对端口,然后把它们转发到 8090 端口上的 Vite 开发服务器。页面保持 Vite 热重载 WebSocket 打开。
- 你从对话窗格发送一条提示。PreviewApp 把它作为使用你的 AWS 凭据签名的标准 AWS API 调用发送到 InvokeAgentRuntime,运行时把它投递到 8080 端口上的智能体。智能体工作时,其步骤流式返回到对话窗格。
- 智能体调用 Amazon Bedrock 中的 Claude Haiku 5.5 来决定改什么。
- 智能体读取网站文件并保存它修改的文件。Vite 开发服务器提供这些文件并监视它们的变化。
- 文件被保存后,Vite 通过步骤 1 中打开的 WebSocket 推送变更,再经会话端点和本地端点返回,网站窗格在不刷新的情况下更新。
- 在笔记本中,PreviewApp 通过同一个会话端点读取智能体在 8081 端口上的 /status 路由。变化的只有端口。
8080 端口不在 allowedPorts 中,因为 InvokeAgentRuntime 到达智能体时不经过会话端点。
先决条件
要跟随本演练,你需要:
- 一个 AWS 账户,位于提供 AgentCore 运行时会话端点的 AWS 区域(Region),并且已配置凭据。
- 创建 AWS Identity and Access Management(IAM)角色、上传到 Amazon Simple Storage Service(Amazon S3)以及创建运行时的权限,外加对该运行时及其 DEFAULT 运行时端点的 bedrock-agentcore:InvokeAgentRuntime 和 bedrock-agentcore:InvokeAgentRuntimeProxy。详情见 IAM permissions for AgentCore runtime。
- Python 3.10 或更高版本,以及 bedrock-agentcore 1.25.2 或更高版本和 boto3 1.43.122 或更高版本。
- Git,用于克隆示例仓库;以及 Jupyter 环境,例如 JupyterLab 或带 Jupyter 扩展的 Visual Studio Code,用于运行笔记本。
- 可访问 Amazon Bedrock 中的 Claude Haiku 5.5。各区域的模型可用性见 Regional availability by models。
- Node.js 22 或更高版本以及 npm,部署脚本用它们来打包智能体和网站。
示例使用直接代码部署,把智能体作为 Amazon S3 中的 zip 文件部署为 Node.js,因此你不需要 Docker 或 Amazon Elastic Container Registry(Amazon ECR)仓库。会话端点适用于 microVM 运行时,不适用于 Instances 计算类型,并且会话端点 URL 可通过公共 HTTPS 到达。入站连接不支持 AWS PrivateLink。
部署智能体及其网站
首先部署运行时,你在这里选择的配置决定会话端点能到达哪些端口。部署脚本把智能体打成一个文件,为运行时的 Linux on Arm64 系统加入网站及其依赖,把 zip 上传到 Amazon S3,并创建运行时。
下面这段摘自 deploy.py 的内容展示了本文相关的两项设置。protocolConfiguration 说明智能体在何处监听 InvokeAgentRuntime,allowedPorts 列出会话端点可以到达的端口:8090 用于网站,8081 用于智能体的状态路由。8080 不在列表中,因为 InvokeAgentRuntime 到达智能体时不需要它。端口和路径设置见 Configure your agent’s serving port and invocation path。
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 配置使开发服务器可以从会话端点到达。它在 0.0.0.0 的 8090 端口上监听,并且不限制 Host 头(server.allowedHosts 为 true),因为请求到达时使用的是运行时分配的主机名,而不是 localhost。会话端点在请求到达服务器之前就对每个请求做了身份验证,因此服务器不需要自己的主机检查。
要部署运行时:
- 克隆示例仓库并进入示例文件夹:
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- 从示例文件夹打开 session_endpoints_preview.ipynb。
- 运行安装单元格,它会安装 Python 依赖。
- 运行 %run deploy.py 单元格。部署需要几分钟,大部分时间在等待运行时达到 READY 状态。
打开预览
运行时就绪后,你启动预览。一次调用做三件事:启动一个会话(这会启动网站),为 8090 端口打开一个本地端点,并在 localhost:8087 上提供预览页。
from preview_app import PreviewApp
app = PreviewApp().start()
print("Open", app.url)在 start() 内部,使用会话端点的调用很短。第一次 InvokeAgentRuntime 调用在响应头中返回 URL,session_endpoint_url 读取它,会话端点客户端为 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()要打开预览:
- 运行启动 PreviewApp 的单元格。
- 在浏览器中打开打印出的链接 http://localhost:8087。
页面右侧显示网站,由会话中的 8090 端口提供;左侧是一份简短指南和建议请求。
让智能体做一处修改
现在你提出一处修改并看着它到达。每条提示都通过 InvokeAgentRuntime 发给智能体。智能体读取它需要的文件,写入它修改的文件,并在发生时报告每一步。文件被保存后,Vite 开发服务器通过其 WebSocket、会话端点和本地端点推送变更,网站就地更新。
要提出一处修改:
- 在预览页上选择 “Switch this website to a dark coffee-house color theme”(把这个网站换成深咖啡屋配色)。
- 在对话窗格中跟随智能体读取和保存文件的步骤。
- 观察网站窗格。智能体保存样式表时它会变化,一条横幅会写出这次变更来自哪个文件。
下面的视频展示智能体处理若干请求时的预览页。选择一条建议请求会把它发给智能体,对话窗格列出智能体读取和保存的每个文件,右侧网站窗格在不刷新的情况下更新,从深色主题变到一个绿色的 Order ahead 按钮。
[图:预览页,左侧是对话窗格,右侧是实时网站,随智能体编辑文件而更新]
图 2:智能体工作时的预览页
步骤之所以流式输出,是因为你向智能体提问时,它用服务器发送事件作答。你可以用 app.ask 从 Python 发送同样的提示,它使用 bedrock-agentcore SDK 中的 iter_events 读取流。打开的页面以同样的方式更新:
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.在同一会话中访问第二个端口
网站不是你能到达的唯一服务器。智能体在 8081 端口上提供 /status,列出每条提示以及它改过的文件。同一个会话端点可以到达它,唯一的差别是端口参数。
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会话端点会拒绝什么
当运行时拒绝一个请求时,它回答一个 HTTP 状态、一个空正文,并在响应头中给出错误代码,这样你就能把它的拒绝和你的应用返回的错误区分开。笔记本向 allowedPorts 之外的端口发送一个请求,并发送一个没有凭据的请求,运行时对两者都以 403 AccessDenied 拒绝。
下表列出你在使用会话端点构建时很可能会遇到的拒绝。
| 请求 | 运行时的响应 |
|---|---|
| 不在 allowedPorts 中的端口 | 403 AccessDenied |
| 没有有效凭据的请求 | 403 AccessDenied 或 401 AuthenticationRequired |
| 已允许但上面没有进程在监听的端口 | 502 PortNotReachable |
| 其会话已不存在的 URL | 404 SessionNotFound |
如何保护对会话的访问
运行时在转发请求之前会去掉自己的身份验证头,因此网站收不到你的签名。请求在 AWS CloudTrail 中被记录为 InvokeAgentRuntimeProxy 事件,事件源为 bedrock-agentcore.amazonaws.com。本地端点使用你的凭据行事,因此它限制谁可以使用它。它只监听 127.0.0.1,只应答发往它自己本地地址的请求,并拒绝由其他来源的页面打开的 WebSocket 连接。只在你使用预览时运行本地端点。更多信息见 Log session endpoint requests in CloudTrail。
这些访问控制并不把网站和智能体分开。两者在同一会话中运行,因此只给执行角色智能体所需的权限。如果运行时替换会话的计算,已打开的连接会关闭,并且除非会话使用持久存储,智能体的编辑可能不会保留。如果你需要文件比计算存活得更久,请参阅 File system configurations for AgentCore runtime。
智能体的文件工具把每条路径都解析到网站文件夹内部,并拒绝其外部的路径,因此一条提示不能让智能体修改会话中的其他文件。如果其他人可以向你的编码智能体发送提示,请考虑使用 Amazon Bedrock Guardrails 过滤有害提示和响应,并在发布之前复核智能体的变更。
清理
为避免持续计费,停止预览并删除示例创建的资源。智能体编辑过的网站位于会话中,因此它会随会话一起消失。
要清理:
- 运行停止单元格,并在笔记本询问时按 Enter。这会停止预览页、本地端点和会话。
- 运行 %run cleanup.py 单元格,它会删除运行时、已上传的代码和 IAM 角色。
结论
会话端点让你通过 HTTP/1.1、HTTP/2 和 WebSocket,在你允许的端口上,用自己的工具对 AgentCore 运行时会话中的应用进行经过身份验证的访问。在本文中,你在会话里部署了带 Vite 网站的编码智能体,通过本地端点在浏览器中打开实时网站,让智能体换成深色主题,并在智能体保存文件时看着变更到达。你还到达了同一会话中的第二个端口,并确认了会话端点会拒绝什么。
要再进一步,把你自己的网站放进 site 文件夹来运行笔记本,或改智能体的工具以匹配你的编码智能体的工作方式。完整选项集,包括端口范围、OAuth、HTTP/2 和 gRPC,见 Connect to runtime sessions through a session endpoint。
要在你自己的智能体中更改 InvokeAgentRuntime 使用的端口或路径,见 Configure your agent’s serving port and invocation path。如果你的智能体还需要在同一会话中运行构建或测试命令,见 Execute shell commands in AgentCore runtime sessions。要按本示例的方式从 zip 文件部署你自己的 Node.js 智能体,见 Direct code deployment for Node.js。该服务提供的其他内容,从 Host agent or tools with Amazon Bedrock AgentCore runtime 开始,更多示例见 agentcore-samples GitHub 仓库。
PRIMARY_SOURCE: https://aws.amazon.com/blogs/machine-learning/preview-web-apps-live-as-your-coding-agent-builds-them-with-amazon-bedrock-agentcore-runtime
- #会话端点
- #实时预览
- #AgentCore
- #部署


