快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南
快速上手:LangChain + AgentRun 浏览器沙箱极简集成指南
前言
在 Agentic AI 时代,智能体需要与真实世界交互,而浏览器是连接虚拟世界与现实世界的重要桥梁。AgentRun Browser Sandbox 为智能体提供了安全、高性能、免运维的浏览器执行环境,让 AI Agent 真正具备"上网"的能力——从网页抓取、信息提取到表单填写、自动化操作,一切皆可实现。
AgentRun Browser Sandbox 介绍
什么是 Browser Sandbox?
Browser Sandbox 是 AgentRun 平台提供的云原生无头浏览器沙箱服务,基于阿里云函数计算(FC)构建。它为智能体提供了一个安全隔离的浏览器执行环境,支持通过标准的 Chrome DevTools Protocol (CDP) 远程控制浏览器实例。
核心特性
无头浏览器能力
- 内置 Chromium/Chrome 浏览器,支持完整的 Web 标准
- 原生兼容 Puppeteer、Playwright 等主流自动化框架
- 支持通过 CDP 协议进行精细化控制
实时可视化
- 内置 VNC 服务,支持实时查看浏览器界面
- 提供操作录制功能,方便调试和回放
- 支持通过 noVNC 客户端在网页中直接观看
安全与隔离
- 每个沙箱实例运行在独立的容器环境中
- 文件系统和进程空间完全隔离
- 支持 WSS 加密传输,确保数据安全
Serverless 架构
- 按需创建,按量付费,无需提前预置资源
- 快速弹性伸缩,支持高并发场景
- 零运维,无需管理服务器和浏览器依赖
主要应用场景
- AI Agent 赋能: 为大模型提供"眼睛"和"手",执行网页浏览、信息提取、在线操作等任务
- 自动化测试: 在云端运行端到端(E2E)测试和视觉回归测试
- 数据采集: 稳定、高效地进行网页抓取,应对动态加载和反爬虫挑战
- 内容生成: 自动化生成网页截图或 PDF 文档
上手使用 Agentrun Browser Sandbox
AgentRun SDK 快速介绍
后续的内容将基于 Agentrun SDK 进行,因此我们先对 SDK 进行简要介绍
AgentRun SDK 是一个开源的 Python 工具包,旨在简化智能体与 AgentRun 平台各种服务(包括 Browser Sandbox)的集成。它提供了统一的接口,让您可以用几行代码就将沙箱能力集成到现有的 Agent 框架中。SDK 的核心功能如下:
统一集成接口
- 提供对 LangChain、AgentScope 等主流框架的开箱即用支持
- 统一的模型代理接口,简化多模型管理
- 标准化的工具注册机制
Sandbox 生命周期管理
- 自动创建和销毁沙箱实例
- 支持会话级别的状态保持
- 灵活的资源配置和超时控制
安装 AgentRun SDK
pip install agentrun-sdk[playwright,server]
注意: 确保您的 Python 环境版本在 3.10 及以上。
基本使用示例
以下是使用 AgentRun SDK 创建和管理 Browser Sandbox 的核心代码:
from agentrun.sandbox import Sandbox, TemplateType
from playwright.sync_api import sync_playwright
# 创建 Browser Sandbox
sandbox = Sandbox.create(
template_type=TemplateType.BROWSER,
template_name="your-template-name",
sandbox_idle_timeout_seconds=300
)
# 获取 CDP URL(用于 Playwright 连接)
cdp_url = sandbox.get_cdp_url()
# 使用 Playwright 连接并操作
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
page = browser.contexts[0].pages[0]
page.goto("https://www.example.com")
page.screenshot(path="screenshot.png")
browser.close()
# 销毁 Sandbox
sandbox.delete()
关键概念:
- template_name: 控制台创建的浏览器环境模板
- cdp_url: 用于 Playwright/Puppeteer 连接
- vnc_url: 用于实时查看浏览器画面(可通过
sandbox.get_cdp_url()获取)
注意: 由于所有浏览器操作都在云端进行,您无需在本地安装浏览器。Playwright 仅用于通过 CDP 协议连接到云端的浏览器实例。
如何创建 sandbox 模板
使用 Browser Sandbox 需要新建 Sandbox 模板,您需要访问 Agentrun 控制台网站,并按照如下步骤创建模板:
- 在顶部菜单栏选择“运行时与沙箱”;
- 在左侧边栏选择“Sandbox沙箱”;
- 点击右上角“创建沙箱模板”;

- 选择“浏览器”;

- 在弹出的抽屉对话框中填写和选择您的模板的规格、网络等配置,并复制模板名称;

6. 点击“创建浏览器” 等待其就绪即可。
从零开始用 LangChain 创建 Browser Sandbox 智能体
本教程将指导您从零开始创建一个完整的 Browser Sandbox 智能体项目。
基于 LangChain 集成 Browser Sandbox
本教程将详细讲解如何使用 LangChain 创建 Browser Sandbox 相关的 tools 并集成到 Agent 中。
项目结构
为了保持代码的内聚性和可维护性,我们将代码拆分为以下模块:
模块职责划分:
- sandbox_manager.py: 负责 Sandbox 的创建、管理和销毁,提供统一的接口
- langchain_agent.py: 负责创建 LangChain tools 和 Agent,集成 VNC 信息
- main.py: 作为入口文件,演示如何使用上述模块
步骤 1: 创建项目并安装依赖
首先创建项目目录(如果还没有):
mkdir -p langchain-demo
cd langchain-demo
创建 requirements.txt 文件,内容如下:
# LangChain 核心库
langchain>=0.1.0
langchain-openai>=0.0.5
langchain-community>=0.0.20
# AgentRun SDK
agentrun-sdk[playwright,server]>=0.0.8
# 浏览器自动化
playwright>=1.40.0
# 环境变量管理
python-dotenv>=1.0.0
然后安装依赖:
pip install -r requirements.txt
主要依赖说明:
- langchain 和 langchain-openai: LangChain 核心库
- agentrun-sdk[playwright,server]: AgentRun SDK,用于 Sandbox 管理
- playwright: 浏览器自动化库 python-dotenv: 环境变量管理
步骤 2: 配置环境变量
在项目根目录创建 .env 文件,配置以下环境变量:
# 阿里云百炼平台的 API Key,用于调用大模型能力
# 请前往 https://bailian.console.aliyun.com/?tab=app#/api-key 创建和查看
DASHSCOPE_API_KEY=sk-your-bailian-api-key
# 阿里云账号的访问密钥 ID 和访问密钥 Secret,用于 AgentRun SDK 鉴权
ALIBABA_CLOUD_ACCESS_KEY_ID=your-ak
ALIBABA_CLOUD_ACCESS_KEY_SECRET=your-sk
ALIBABA_CLOUD_ACCOUNT_ID=your-main-account-id
ALIBABA_CLOUD_REGION=cn-hangzhou
# browser sandbox 模板的名称,可以在 https://functionai.console.aliyun.com/cn-hangzhou/agent/runtime/sandbox 控制台创建
BROWSER_TEMPLATE_NAME=sandbox-your-template-name
# agentrun 的控制面和数据面的 API 端点请求地址,默认cn-hangzhou
AGENTRUN_CONTROL_ENDPOINT=agentrun.cn-hangzhou.aliyuncs.com
AGENTRUN_DATA_ENDPOINT=https://${your-main-account-id}.agentrun-data.cn-hangzhou.aliyuncs.com
步骤 3: 创建 Sandbox 生命周期管理模块
创建 sandbox_manager.py 文件,负责 Sandbox 的创建、管理和销毁。核心代码如下:
"""
Sandbox 生命周期管理模块
负责 AgentRun Browser Sandbox 的创建、管理和销毁。
提供统一的接口供 LangChain Agent 使用。
"""
import os
from typing import Optional, Dict, Any
from dotenv import load_dotenv
# 加载环境变量
load_dotenv()
class SandboxManager:
"""Sandbox 生命周期管理器"""
def __init__(self):
self._sandbox: Optional[Any] = None
self._sandbox_id: Optional[str] = None
self._cdp_url: Optional[str] = None
self._vnc_url: Optional[str] = None
def create(
self,
template_name: Optional[str] = None,
idle_timeout: int = 3000
) -> Dict[str, Any]:
"""
创建或获取一个浏览器 sandbox 实例
Args:
template_name: Sandbox 模板名称,如果为 None 则从环境变量读取
idle_timeout: 空闲超时时间(秒),默认 3000 秒
Returns:
dict: 包含 sandbox_id, cdp_url, vnc_url 的字典
Raises:
RuntimeError: 创建失败时抛出异常
"""
try:
from agentrun.sandbox import Sandbox, TemplateType
# 如果已有 sandbox,直接返回
if self._sandbox is not None:
return self.get_info()
# 从环境变量获取模板名称
if template_name is None:
template_name = os.getenv(
"BROWSER_TEMPLATE_NAME",
"sandbox-browser-demo"
)
# 创建 sandbox
self._sandbox = Sandbox.create(
template_type=TemplateType.BROWSER,
template_name=template_name,
sandbox_idle_timeout_seconds=idle_timeout
)
self._sandbox_id = self._sandbox.sandbox_id
self._cdp_url = self._get_cdp_url()
self._vnc_url = self._get_vnc_url()
return self.get_info()
except ImportError as e:
print(e)
raise RuntimeError(
"agentrun-sdk 未安装,请运行: pip install agentrun-sdk[playwright,server]"
)
except Exception as e:
raise RuntimeError(f"创建 Sandbox 失败: {str(e)}")
def get_info(self) -> Dict[str, Any]:
"""
获取当前 sandbox 的信息
Returns:
dict: 包含 sandbox_id, cdp_url, vnc_url 的字典
Raises:
RuntimeError: 如果没有活动的 sandbox
"""
if self._sandbox is None:
raise RuntimeError("没有活动的 sandbox,请先创建")
return {
"sandbox_id": self._sandbox_id,
"cdp_url": self._cdp_url,
"vnc_url": self._vnc_url,
}
def get_cdp_url(self) -> Optional[str]:
"""获取 CDP URL"""
return self._sandbox.get_cdp_url()
def get_vnc_url(self) -> Optional[str]:
"""获取 VNC URL"""
return self._sandbox.get_vnc_url()
def get_sandbox_id(self) -> Optional[str]:
"""获取 Sandbox ID"""
return self._sandbox_id
def destroy(self) -> str:
"""
销毁当前的 sandbox 实例
Returns:
str: 操作结果描述
"""
if self._sandbox is None:
return "没有活动的 sandbox"
try:
sandbox_id = self._sandbox_id
# 尝试销毁 sandbox
if hasattr(self._sandbox, 'delete'):
self._sandbox.delete()
elif hasattr(self._sandbox, 'stop'):
self._sandbox.stop()
elif hasattr(self._sandbox, 'destroy'):
self._sandbox.destroy()
# 清理状态
self._sandbox = None
self._sandbox_id = None
self._cdp_url = None
self._vnc_url = None
return f"Sandbox 已销毁: {sandbox_id}"
except Exception as e:
# 即使销毁失败,也清理本地状态
self._sandbox = None
self._sandbox_id = None
self._cdp_url = None
self._vnc_url = None
return f"销毁 Sandbox 时出错: {str(e)}"
def is_active(self) -> bool:
"""检查 sandbox 是否活跃"""
return self._sandbox is not None
def __enter__(self):
"""上下文管理器入口"""
return self
def __exit__(self, exc_type, exc_val, exc_tb):
"""上下文管理器退出,自动销毁"""
self.destroy()
return False
# 全局单例(可选,用于简单场景)
_global_manager: Optional[SandboxManager] = None
def get_global_manager() -> SandboxManager:
"""获取全局 SandboxManager 单例"""
global _global_manager
if _global_manager is None:
_global_manager = SandboxManager()
return _global_manager
def reset_global_manager():
"""重置全局 SandboxManager"""
global _global_manager
if _global_manager:
_global_manager.destroy()
_global_manager = None
关键功能:
- 创建 Sandbox: 使用 AgentRun SDK 创建浏览器 Sandbox
- 获取连接信息: 自动获取 CDP URL 和 VNC URL,支持多种属性名兼容
- 生命周期管理: 提供销毁方法,确保资源正确释放
步骤 4: 创建 LangChain Tools 和 Agent
创建 langchain_agent.py 文件,定义 LangChain tools 并创建 Agent。核心代码如下:
"""
LangChain Agent 和 Tools 注册模块
负责创建 LangChain Agent,注册 Sandbox 相关的 tools,并集成 VNC 可视化。
本模块使用 sandbox_manager.py 中封装的 SandboxManager 来管理 sandbox 生命周期。
"""
import os
from dotenv import load_dotenv
from langchain.tools import tool
from langchain_openai import ChatOpenAI
from langchain.agents import create_agent
from pydantic import BaseModel, Field
# 导入 sandbox 管理器
from sandbox_manager import SandboxManager
# 加载环境变量
load_dotenv()
# 全局 sandbox 管理器实例(单例模式)
_sandbox_manager: SandboxManager | None = None
def get_sandbox_manager() -> SandboxManager:
"""获取 sandbox 管理器实例(单例模式)"""
global _sandbox_manager
if _sandbox_manager is None:
_sandbox_manager = SandboxManager()
return _sandbox_manager
# ============ LangChain Tools 定义 ============
@tool
def create_browser_sandbox(
template_name: str = None,
idle_timeout: int = 3000
) -> str:
"""创建或获取一个浏览器 sandbox 实例。
当需要访问网页、执行浏览器操作时,首先需要创建 sandbox。
创建成功后,会返回 sandbox 信息,包括 VNC URL 用于可视化。
Args:
template_name: Sandbox 模板名称,如果不提供则从环境变量 BROWSER_TEMPLATE_NAME 读取
idle_timeout: 空闲超时时间(秒),默认 3000 秒
Returns:
Sandbox 信息字符串,包括 ID、CDP URL、VNC URL
"""
try:
manager = get_sandbox_manager()
# 如果 template_name 为空字符串,转换为 None 以便从环境变量读取
if template_name == "":
template_name = None
info = manager.create(template_name=template_name, idle_timeout=idle_timeout)
result = f"""✅ Sandbox 创建成功!
📋 Sandbox 信息:
- ID: {info['sandbox_id']}
- CDP URL: {info['cdp_url']}
"""
vnc_url = info.get('vnc_url')
if vnc_url:
result += f"- VNC URL: {vnc_url}\n\n"
result += "提示: VNC 查看器应该已自动打开,您可以在浏览器中实时查看浏览器操作。"
else:
result += "\n警告: 未获取到 VNC URL,可能无法使用可视化功能。"
return result
except Exception as e:
return f" 创建 Sandbox 失败: {str(e)}"
@tool
def get_sandbox_info() -> str:
"""获取当前 sandbox 的详细信息,包括 ID、CDP URL、VNC URL 等。
当需要查看当前 sandbox 状态或获取 VNC 连接信息时使用此工具。
Returns:
Sandbox 信息字符串
"""
try:
manager = get_sandbox_manager()
info = manager.get_info()
result = f"""📋 当前 Sandbox 信息:
- Sandbox ID: {info['sandbox_id']}
- CDP URL: {info['cdp_url']}
"""
if info.get('vnc_url'):
result += f"- VNC URL: {info['vnc_url']}\n\n"
result += "您可以使用 VNC URL 在浏览器中实时查看操作过程。\n"
result += " 推荐使用 vnc.html 文件或 noVNC 客户端。"
return result
except RuntimeError as e:
return f" {str(e)}"
except Exception as e:
return f" 获取 Sandbox 信息失败: {str(e)}"
class NavigateInput(BaseModel):
"""浏览器导航输入参数"""
url: str = Field(description="要访问的网页 URL,必须以 http:// 或 https:// 开头")
wait_until: str = Field(
default="load",
description="等待页面加载的状态: load, domcontentloaded, networkidle"
)
timeout: int = Field(
default=30000,
description="超时时间(毫秒),默认 30000"
)
@tool(args_schema=NavigateInput)
def navigate_to_url(url: str, wait_until: str = "load", timeout: int = 30000) -> str:
"""使用 sandbox 中的浏览器导航到指定 URL。
当用户需要访问网页时使用此工具。导航后可以在 VNC 中实时查看页面。
Args:
url: 要访问的网页 URL
wait_until: 等待页面加载的状态(load/domcontentloaded/networkidle)
timeout: 超时时间(毫秒)
Returns:
导航结果描述
"""
try:
manager = get_sandbox_manager()
if not manager.is_active():
return " 错误: 请先创建 sandbox"
# 验证 URL
if not url.startswith(("http://", "https://")):
return f" 错误: 无效的 URL 格式: {url}"
cdp_url = manager.get_cdp_url()
if not cdp_url:
return " 错误: 无法获取 CDP URL"
# 使用 Playwright 连接浏览器并导航
try:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
pages = browser.contexts[0].pages if browser.contexts else []
if pages:
page = pages[0]
else:
page = browser.new_page()
page.goto(url, wait_until=wait_until, timeout=timeout)
title = page.title()
return f"已成功导航到: {url}\n📄 页面标题: {title}\n💡 您可以在 VNC 中查看页面内容。"
except ImportError:
return f"导航指令已发送: {url}\n💡 提示: 安装 playwright 以启用实际导航功能 (pip install playwright)"
except Exception as e:
return f" 导航失败: {str(e)}"
except Exception as e:
return f" 操作失败: {str(e)}"
@tool("browser_screenshot", description="在浏览器 sandbox 中截取当前页面截图")
def take_screenshot(filename: str = "screenshot.png") -> str:
"""截取浏览器当前页面的截图。
Args:
filename: 截图文件名,默认 "screenshot.png"
Returns:
操作结果
"""
try:
manager = get_sandbox_manager()
if not manager.is_active():
return " 错误: 请先创建 sandbox"
cdp_url = manager.get_cdp_url()
if not cdp_url:
return " 错误: 无法获取 CDP URL"
try:
from playwright.sync_api import sync_playwright
with sync_playwright() as p:
browser = p.chromium.connect_over_cdp(cdp_url)
pages = browser.contexts[0].pages if browser.contexts else []
if pages:
page = pages[0]
else:
return " 错误: 没有打开的页面"
page.screenshot(path=filename)
return f"截图已保存: {filename}"
except ImportError:
return " 错误: 需要安装 playwright (pip install playwright)"
except Exception as