在 Serverless Framework 中使用自定义 Bedrock AgentCore 浏览器:LangGraph-Browser-Custom 实战解析 📅 发布时间:2026/9/9 19:14:27 👁 浏览次数: 在 Serverless Framework 中使用自定义 Bedrock AgentCore 浏览器LangGraph-Browser-Custom 实战解析【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless导读本指南基于 Serverless Framework 官方示例仓库中的 LangGraph Custom Browser 示例位于packages/serverless/lib/plugins/aws/bedrock-agentcore/examples/javascript/langgraph-browser-custom/深入讲解如何在 Bedrock AgentCore 应用中摆脱 AWS 托管默认浏览器aws.browser.v1的限制在serverless.yml中声明自己的自定义浏览器实现 S3 会话录制、浏览器请求签名降低验证码出现频率以及 PUBLIC/VPC 网络配置。读完本文你将掌握自定义浏览器的完整配置方式、LangGraph JS Agent 的调用链路以及配套的端到端测试方法。特性概览该示例是一个使用自定义 AgentCore 浏览器并将浏览器会话录制到 S3 的 LangGraph JavaScript Agent核心特性如下自定义浏览器Custom Browser使用自定义浏览器配置取代 AWS 托管的默认浏览器会话录制Session Recording浏览器会话被录制并上传到 S3可用于调试与审计请求签名Request Signing为浏览器请求启用签名降低遇到验证码CAPTCHA的概率LangGraph JS以createAgent搭建 ReAct Agent并将自定义浏览器封装为工具tool。示例目录结构对应仓库实际文件serverless.yml —— 声明浏览器、S3 桶、Agent 及其 IAM 权限index.js —— Agent 运行时逻辑Node ESM 模块test-invoke.js —— 本地调用 Runtime 的冒烟测试脚本package.json —— 声明type: module及 LangChain / bedrock-agentcore / playwright 依赖。自定义浏览器与默认浏览器的区别示例 README 用一张表清晰对比了默认浏览器与自定义浏览器在关键维度上的差异这是选择自定义方案的核心决策依据Aspect维度Default Browser默认浏览器Custom Browser自定义浏览器Identifier标识符aws.browser.v1自定义浏览器 IDRecording录制不支持S3 录制前缀可配置Signing签名不可配置默认启用降低验证码频率Network网络默认可配置PUBLIC/VPC关于默认浏览器可对照同目录下的 langgraph-browser 示例 README它只需在serverless.yml中写ai: { agents: { browserAgent: {} } }一行声明即可获得navigate、click、type_text、get_text、get_html、screenshot、evaluate、wait_for_element等内置浏览器工具但其标识符固定为aws.browser.v1且不支持录制与签名配置。自定义浏览器的价值正在于当默认浏览器无法满足网络、合规或审计需求时把浏览器资源接管到你的账户下。如何在 Serverless Framework 中声明一个自定义浏览器在 Serverless Framework 的框架语法v4ai原生能力下自定义浏览器通过serverless.yml顶层ai.browsers声明。以下为示例中的完整配置service: langgraph-browser-custom provider: name: aws region: us-east-1 resources: Resources: # S3 bucket for browser session recordings RecordingsBucket: Type: AWS::S3::Bucket Properties: BucketName: ${self:service}-recordings-${sls:stage} PublicAccessBlockConfiguration: BlockPublicAcls: true BlockPublicPolicy: true IgnorePublicAcls: true RestrictPublicBuckets: true LifecycleConfiguration: Rules: - Id: DeleteOldRecordings Status: Enabled ExpirationInDays: 7 ai: # Custom browser with session recording enabled browsers: customBrowser: description: Custom browser with session recording for validation network: mode: PUBLIC signing: enabled: true recording: enabled: true s3Location: bucket: ${self:service}-recordings-${sls:stage} prefix: browser-sessions/ role: statements: - Effect: Allow Action: - s3:PutObject - s3:GetObject - s3:ListBucket - s3:AbortMultipartUpload - s3:ListMultipartUploadParts Resource: - !GetAtt RecordingsBucket.Arn - !Sub ${RecordingsBucket.Arn}/* # Runtime agent that uses the custom browser agents: browserAgent: environment: CUSTOM_BROWSER_ID: !GetAtt CustomBrowserBrowser.BrowserId RECORDINGS_BUCKET: ${self:service}-recordings-${sls:stage} role: statements: - Effect: Allow Action: - bedrock-agentcore:StartBrowserSession - bedrock-agentcore:StopBrowserSession - bedrock-agentcore:UpdateBrowserStream - bedrock-agentcore:ConnectBrowserAutomationStream Resource: !GetAtt CustomBrowserBrowser.BrowserArnai.browsers声明剖析示例中的customBrowser涉及四个关键配置组其语义与底层映射如下network —— 网络模式。mode: PUBLIC表示浏览器在公共网络中运行。由仓库中负责将该声明编译为 CloudFormation 的 compilers/browser.js 可知network.mode会被统一转为大写Browser资源只支持PUBLIC与VPC两种模式不支持 SANDBOX当为VPC且提供了network.subnets时编译函数会进一步组装出VpcConfig含Subnets与SecurityGroups未显式填写securityGroups时默认为空数组。signing —— 浏览器请求签名。enabled: true对应底层BrowserSigning: { Enabled: true }配置见 compilers/browser.js。签名机制使浏览器发出的自动化请求带有可信签名从而降低被目标站点识别为机器流量、触发验证码的概率。注意默认浏览器不支持该配置只有自定义浏览器可以开启。recording —— 会话录制。enabled: true配合s3Location.bucket桶名与s3Location.prefix对象前缀开启录制。编译函数buildRecordingConfig见 compilers/browser.js将其映射为RecordingConfigS3Location中Bucket为必填Prefix可选。示例将录制对象写入langgraph-browser-custom-recordings-stage桶下的browser-sessions/前缀。role —— 浏览器执行角色。role.statements中的 S3 权限会被编译为浏览器资源自带的ExecutionRoleArn见 compilers/browser.js因为录制动作是浏览器侧发起的 S3 写入权限应挂在浏览器执行角色上而非仅挂在 Agent 上。S3 录制桶与生命周期resources.Resources.RecordingsBucket定义了存储录制的 S3 桶桶名${self:service}-recordings-${sls:stage}由服务名与部署阶段动态拼装通过PublicAccessBlockConfiguration全部置为true强制禁止公共读写LifecycleConfiguration设置 7 天过期删除规则避免录制文件无限累积产生成本。ai.agents运行时 Agent 与权限隔离ai.agents.browserAgent定义承载 LangGraph 逻辑的运行时 Agent重点是两条环境变量与一组 API 权限CUSTOM_BROWSER_ID: !GetAtt CustomBrowserBrowser.BrowserId通过 CloudFormationFn::GetAtt从浏览器资源获取BrowserId将其注入 Agent 运行时环境供代码读取。浏览器资源AWS::BedrockAgentCore::BrowserCustom的只读属性包括BrowserId、BrowserArn、Status、FailureReason、CreatedAt、LastUpdatedAt见 compilers/browser.js。RECORDINGS_BUCKET桶名注入环境变量用于在返回结果中回显录制位置。Agent 自身的role.statements只授予对该浏览器资源 ARN!GetAtt CustomBrowserBrowser.BrowserArn的四个会话类操作StartBrowserSession、StopBrowserSession、UpdateBrowserStream、ConnectBrowserAutomationStream。这种浏览器自带 S3 写权限 Agent 只握有会话 API 权限的设计实现了最小权限原则Agent 代码无法直接读写 S3录制上传完全由托管浏览器会话生命周期驱动。底层资源映射小结从 compilers/browser.js 的compileBrowser可以看到一条ai.browsers.customBrowser声明最终被编译为一个AWS::BedrockAgentCore::BrowserCustomCloudFormation 资源其Name由getResourceName(serviceName, name, stage)规范化生成Description、BrowserSigning、RecordingConfig、Tags均为可选属性全部配置仅在创建时生效Create-Only因此修改浏览器配置后需要重新创建资源。浏览器资源状态机为CREATING → READY失败时进入CREATE_FAILED并可通过FailureReason查看原因。LangGraph JS Agent 是如何使用自定义浏览器的index.js 演示了一条完整的调用链路可归纳为三步初始化浏览器工具 → 组装 LangGraph Agent → 挂接到 AgentCore Runtime。第一步从环境变量读取部署产物const AWS_REGION process.env.AWS_REGION || us-east-1 const MODEL_ID process.env.MODEL_ID || us.anthropic.claude-sonnet-4-5-20250929-v1:0 const CUSTOM_BROWSER_ID process.env.CUSTOM_BROWSER_ID const RECORDINGS_BUCKET process.env.RECORDINGS_BUCKET if (!CUSTOM_BROWSER_ID) { console.warn(CUSTOM_BROWSER_ID not set - will use default browser) }CUSTOM_BROWSER_ID来自serverless.yml中的!GetAtt CustomBrowserBrowser.BrowserId注入。代码以环境变量是否为空作为降级开关未注入时回退到默认浏览器已注入则使用自定义浏览器。第二步把浏览器封装成browse_webpage工具browse_webpage工具内部完成了自定义浏览器的核心操作其调用顺序正是会话的生命周期构造 Browser 客户端并携带自定义浏览器标识符const browserClient new Browser({ region: AWS_REGION, ...(CUSTOM_BROWSER_ID { identifier: CUSTOM_BROWSER_ID }), })只有当CUSTOM_BROWSER_ID存在时才会传入identifier字段这保证了回退默认浏览器场景下代码仍然可用。启动会话await browserClient.startSession()以自定义浏览器 ID 启动一次受管浏览器会话取得 WebSocket 连接信息browserClient.generateWebSocketUrl()返回{ url: wsUrl, headers }用于后续 CDP 接入通过 Playwright 接入使用chromium.connectOverCDP(wsUrl, { headers, timeout: 30000 })连接然后从browser.contexts()[0]与context.pages()[0]取到页面实例导航与内容提取page.goto(url, { waitUntil: domcontentloaded, timeout: 30000 })打开目标地址读取page.title()并通过page.evaluate截取document.body.innerText前 2000 字符返回给模型关闭浏览器并停止会话await browser.close()之后在finally中执行browserClient.stopSession()—— 注释明确提示停止会话将触发录制上传至 S3Stop the session - triggers recording upload to S3。工具声明中还使用zod对入参建模url: z.string().describe(The URL to navigate to)让 LLM 获得参数 schema 提示const browseWebpage tool( async ({ url }) { /* ... */ }, { name: browse_webpage, description: Navigate to a webpage and extract its content using a custom browser with session recording., schema: z.object({ url: z.string().describe(The URL to navigate to), }), }, )第三步组装 Agent 并挂接 Runtime模型采用ChatBedrockConverse默认模型us.anthropic.claude-sonnet-4-5-20250929-v1:0随后用createAgent构造 ReAct 风格 Agentconst model new ChatBedrockConverse({ model: MODEL_ID, region: AWS_REGION, }) const agent createAgent({ model, tools: [browseWebpage], })最后通过BedrockAgentCoreApp来自bedrock-agentcore/runtime把 Agent 包装成 AgentCore Runtime。invocationHandler.process(request, context)在每次调用时取出context?.sessionId将用户prompt交给agent.invoke(...)并返回 JSON 结构的结果返回体中特意带上了browser_id与recordings_bucket字段便于在调用结果里直接看到本次会话使用的浏览器与录制去向return JSON.stringify({ result: response, browser_id: CUSTOM_BROWSER_ID, recordings_bucket: RECORDINGS_BUCKET, })process内对异常做了兜底出错时返回{ error: err.message }而非抛断整个调用文件末尾以app.run()启动运行时事件循环。依赖清单package.json依赖用途bedrock-agentcore^0.2.0提供runtime与browser客户端langchain^1.2.27createAgent装配 Agentlangchain/aws^1.2.5ChatBedrockConverse模型通道langchain/core^1.1.28tool工具定义playwright^1.58.2chromium.connectOverCDP接入浏览器zod^4.3.6工具入参与请求 Schema 校验工程要求 Node.js24.xpackage.json中type: module全部代码以 ESM 编写。部署、验证与清理的完整流程前置条件Node.js 24 及以上版本已配置 AWS 凭证具备部署权限已安装 Serverless Framework CLIsls。部署npm install sls deploy部署成功后Serverless Framework 会根据serverless.yml编译并创建自定义浏览器资源、录制 S3 桶与 Agent Runtime。部署输出会包含 Runtime ARN对应下面测试需要的RUNTIME_ARN。端到端测试示例提供了 test-invoke.js通过 AWS SDK v3 直接向 Runtime 发起调用RUNTIME_ARNyour-runtime-arn node test-invoke.js测试脚本的行为可细读源码确认它要求RUNTIME_ARN环境变量必须存在否则打印用法并以退出码 1 终止随后构造BedrockAgentCoreClient以随机生成的SESSION_IDrandomUUID()发起InvokeAgentRuntimeCommand其中payload为{ prompt: inputText }的 JSON 缓冲contentType设为application/jsonaccept为application/json, text/event-stream兼容流式与一次性响应。脚本内置的测试用例是让 Agent 打开https://example.com并汇报标题与内容Browse to https://example.com and tell me the page title and content.这正好完整走一遍Agent 决策 → 调用browse_webpage→ 自定义浏览器录制会话 → 返回页面摘要的链路。响应体以 async iterable 方式被逐块消费并拼接、解析后打印便于阅读。清理sls remove该命令会删除部署创建的资源。由于录制桶带有 7 天生命周期规则正常使用期间无需手工清理录制文件若需保留录制审计可在删除前自行从 S3 下载。更进一步同族示例与参考实现该示例并非孤立存在bedrock-agentcore 示例目录packages/serverless/lib/plugins/aws/bedrock-agentcore/examples/还提供了一批可直接对照的同族工程langgraph-browser默认浏览器版使用 AWS 托管默认浏览器的 LangGraph JS Agent配置最小化仅ai.agents.browserAgent一行声明内置 8 种网页工具是与自定义浏览器做差异对比的首选参照strands-browser把浏览器能力接入 Strands Agents 框架的变体Python 侧还有同主题实现 python/langgraph-browser-custom含agent.py与配套serverless.yml便于多语言团队对齐同一份基础设施配置。此外bedrock-agentcore 插件 README 与 浏览器编译实现 是理解ai.browsers语法如何映射到底层 CloudFormation 资源AWS::BedrockAgentCore::BrowserCustom的一手源码资料可作为把该示例落地到自有业务时的配置参考。小结LangGraph Browser Custom 示例完整展示了 Serverless Framework 在 Bedrock AgentCore 场景下的自定义浏览器落地路径在ai.browsers中声明浏览器资源网络 / 签名 / 录制 / 角色在ai.agents中声明带环境变量注入与最小权限的运行时 Agent再以bedrock-agentcore的BrowserSDK Playwright 的 CDP 接入完成浏览器会话的生命周期管理。相比默认浏览器自定义浏览器在不增加 Agent 代码复杂度的前提下换来了录制审计与签名能力的确定性控制适用于需要合规审计、网络隔离或降低验证码干扰的生产场景。【免费下载链接】serverless⚡ Serverless Framework – Effortlessly build apps that auto-scale, incur zero costs when idle, and require minimal maintenance using AWS Lambda and other managed cloud services.项目地址: https://gitcode.com/GitHub_Trending/se/serverless创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考