本节摘要:本节把全书的环境一次备齐。先给 Python 与 TypeScript 双栈的安装清单——browser-use 与其依赖的 Playwright 浏览器、Stagehand 及其依赖的 Node 工具链,并说明模型 API 密钥的准备。然后搭起全书共用的合规靶场:一个本地待办清单测试页(描述结构、不贴页面源码)加一个本地静态服务,所有涉及「点按钮、填表单」的示例都打在它身上,不碰第三方站点。最后用 browser-use 写下第一个智能体:打开本地测试页、提取页面标题并返回——三十行以内的代码,跑通「感知、决策、行动」的第一圈循环。附常见故障排查表与版本锁定建议。
全书示例同时给 Python 与 TypeScript 两种写法,两边都装最好;只装一边也能读完对应章节。
| 栈 | 核心组件 | 服务章节 |
|---|---|---|
| Python 栈 | Python 3.10 以上、browser-use、langchain-openai、Playwright 浏览器 | 第 1、2 章,第 5 章 Python 用例 |
| TypeScript 栈 | Node 18 以上(建议 20 以上)、@browserbasehq/stagehand、zod、Playwright | 第 1、3 章,第 5 章 JS 用例 |
| 两者共用 | 模型 API 密钥(环境变量注入),本地测试页靶场 | 全书 |
Python 栈安装(Windows 用户在 Git Bash 里同样可执行;路径示例以 macOS 与 Linux 风格为准):
# setup_python.sh —— Python 栈安装(写法示意,以官方文档为准) python -m pip install "browser-use==0.13.13" langchain-openai python -m playwright install chromium
TypeScript 栈安装:
# setup_node.sh —— Node 栈安装(写法示意,以官方文档为准) npm init -y npm install @browserbasehq/stagehand@3.7.3 zod playwright npx playwright install chromium
模型密钥用环境变量注入,不写进代码与任务文本(这是第 2.2 节敏感数据机制的伏笔):
# setup_env.sh —— 模型密钥环境变量(写法示意,按你的模型供应商调整) export OPENAI_API_KEY="sk-..." export ANTHROPIC_API_KEY="sk-ant-..." # 使用兼容接口时可另行指定地址 export OPENAI_BASE_URL="https://your-gateway.example/v1"
两处提醒:其一,browser-use 迭代接近日更(写作口径 2026-10:v0.13.13,2026-10-15 发布),命令与 API 以其官方文档为准,本书示例均标「写法示意」;其二,本书不指定唯一模型,能可靠输出结构化动作的对话模型皆可,模型选择在第 2.3 节展开。
涉及「点按钮、填表单、读列表」的示例一律打在本地测试页上——它就是你拥有全部权限的站点,天然合规。请在工作目录下新建 demo-site 子目录,放入自制的 demo_todo.html(用任意编辑器手工创建即可,样式随意),页面结构按下表约定:
| 元素 | 语义角色 | 可见文本或标签 | 说明 |
|---|---|---|---|
| 页面标题 | 文档标题 | 「待办清单演示」 | 放在浏览器标签页上 |
| 一级标题 | 标题 | 「今天要做的事」 | 页面主视觉 |
| 文本输入框 | 文本框,关联标签「新待办」 | 标签「新待办」 | 尽量用 label 正确关联 |
| 按钮 | 按钮 | 「添加」 | 提交一条新待办 |
| 列表 | 列表 | 初始显示「暂无待办」 | 添加后逐条列出 |
| 页脚链接 | 链接 | 「关于」 | 指向同目录 about.html |
结构约定比像素外观重要:后续章节的元素定位、快照、视觉识别示例都按这张表引用元素。启动本地服务并自检:
# serve_local.sh —— 启动本地静态服务并自检 cd demo-site python -m http.server 8080 # 另开终端自检,能返回页面字节即通 curl -s http://127.0.0.1:8080/demo_todo.html | head -n 1
如果不想手写页面,也可以把任意自己拥有的本地页面放进 demo-site 目录替换之,只要元素语义与上表一致,全书示例无需改动。
目标:智能体自己打开测试页、读出标题、把标题作为最终结果返回。代码不到三十行:
# first_agent.py —— browser-use 首个任务(写法示意,以官方文档为准) import asyncio from browser_use import Agent from langchain_openai import ChatOpenAI async def main() -> None: agent = Agent( task=( "打开 http://127.0.0.1:8080/demo_todo.html," "读取页面标题(浏览器标签页上的那个),并原样返回标题文本。" ), llm=ChatOpenAI(model="gpt-4o"), ) result = await agent.run() print("最终结果:", result.final_result()) asyncio.run(main())
按任务、模型、循环、结果四件事读它:task 只写目标不写步骤——没有「先 goto、再取 title」这样的路径指令;llm 由你指定,browser-use 通过 langchain 生态接入多种模型;agent.run() 内部跑的就是第 2.1 节将解剖的 Agent 循环(感知页面、模型决策、执行动作、判断终止);result.final_result() 取最终产物。运行成功的输出形如:
# first_agent_output.txt —— 运行输出示意 最终结果: 待办清单演示
这三十行里发生了什么:智能体启动一个受控浏览器,感知本地页面并把可交互元素整理成带编号的候选清单(第 1.2 节的元素标注索引),模型判断「取标题」不需要任何页面动作、直接从已感知的状态作答,循环一轮即终止。你刚刚跑通了全书最小的一圈「感知、决策、行动」。
| 现象 | 常见原因 | 处理 |
|---|---|---|
| 启动即报找不到浏览器 | Playwright 浏览器未安装 | 重跑 python -m playwright install chromium |
| 模型调用 401 或 403 | 密钥未导出或写错 | 检查环境变量;兼容接口确认地址配置 |
| 打开页面超时 | 本地服务未启动或端口不符 | 确认 8080 端口在服务、地址用 127.0.0.1 |
| 元素定位不稳定 | 测试页结构与靶场约定不一致 | 对照第二节结构表修正页面 |
| 升级依赖后示例报错 | browser-use API 变化 | 见下方版本纪律 |
版本纪律三条规定:依赖锁定——requirements 与 package.json 里写死版本号(如 browser-use==0.13.13、@browserbasehq/stagehand@3.7.3),不追最新;升级走流程——先读官方更新日志,再跑自己的回归用例(第 6 章),后换版本;示例免责——本书所有浏览器智能体框架代码均为「写法示意」,参数名与导入路径以各官方文档为准。这不是推卸:browser-use 历史上经历过 3.x 到 0.x 的重构式换代,版本号回退正是重构痕迹,任何教程若声称永久有效都是在骗你。
环境与靶场都有了,但刚才那三十行代码里,「智能体到底怎么理解页面」被一个函数调用藏了起来。下一章把引擎盖打开:act、extract、observe 三个动词,是所有浏览器智能体框架共同的语法。