这段时间AI Agent的话题特别热,但很多朋友问我:Agent到底能帮我们干什么?说实话,早期接触Agent的时候,我也觉得它有点“纸上谈兵”——能写代码、能回答问题,但真要让它去完成一个实际操作,比如帮我查个资料、填个表单、对比几个网页的价格,它就没辙了。原因很简单:Agent的“手”没伸出来,它只能通过API跟外部世界对话,真实世界的浏览器它根本碰不到。
browser-use 就是我这段时间实测下来非常好用的一个开源项目。它把大语言模型和浏览器控制彻底打通:给Agent一个浏览器,让它可以像人一样点击、输入、滚动、翻页、提取内容,从“只能说说”变成“真的去做”。如果你正在研究AI Agent怎么落地,或者想从0到1搭建属于自己的AI Agent应用,这个项目值得认真玩一玩。
这篇文章我会从原理拆解、环境搭建、核心实操、服务化改造、常见坑位几个方面,把browser-use讲透。不管你是刚接触Agent的新手,还是已经在做AI应用落地的开发者,这篇都能帮你少走弯路。
1. 为什么需要browser-use:AI Agent的“最后一公里”
1.1 传统Agent做不到的事
先聊聊背景。现在各种“AI助手”满天飞,但它们能做的事其实非常有限:写文案、总结文档、回答百科类问题。这些任务有一个共同点——只发生在“对话”内部,不需要操控外部工具。
一旦任务变成“帮我去某某网站查一下今天的报价”、“帮我把这个表单填了并提交”、“把这个页面里的数据抓下来整理成表格”,传统Agent就露馅了。
问题在于它没有“手”。
有一些Agent为了弥补这个短板,会通过API去调第三方服务,比如天气API、新闻API。但这有个很明显的问题:API是别人规定好的接口,功能写死了。网站没有开放API怎么办?网站每天都在改版,接口参数变了怎么办?数据分散在不同网页结构里,API拿不到怎么办?
这时候就需要Agent能像人一样,直接打开浏览器,看页面、点按钮、填信息。这不是“调接口”,这是“用人操控电脑的方式去完成任务”。
1.2 browser-use的定位:给Agent装上一双“眼睛”和“手”
browser-use的核心思路,是把浏览器的能力抽象成一套“动作空间”,然后交给大语言模型去决策。
具体来说,它干了两件事:
- 让LLM“看懂”网页。通过视觉截图和DOM结构提取,把浏览器里呈现的内容转成LLM能处理的语言信息。
- 让LLM“操作”浏览器。定义了点击、输入、滚动、跳转、提取等原子动作,LLM每次输出一个结构化的动作指令,由底层代码去执行。
这是个“观察-决策-执行-再观察”的循环,一直持续到任务完成。
我用一个生活化的类比解释:browser-use相当于给你请了一个“远程操控手”。你通过对话告诉它“去京东搜一下XX,把前五条的价格列出来”,它理解需求后,自己打开京东,在搜索框输入关键词,点搜索,滚动页面,把结果标题和价格读出来,整理成表格交给你。
对你来说,整个过程就是一句话的事。
1.3 它和Selenium/Playwright这类自动化工具的区别
这一块很多人容易混淆,我提前说清楚。Selenium和Playwright也是浏览器自动化工具,但它们和browser-use完全不是一个物种。
Selenium/Playwright解决的是“自动化执行固定脚本”的问题。你要先写清楚步骤:打开网址、等待元素出现、输入用户名、点击登录按钮。每一步都是写死的,页面一变脚本就废了。
browser-use解决的是“让AI自主完成动态任务”的问题。你不需要把每一步都写下来,只需要告诉它“你想干什么”,它自己判断每一步怎么走。底层虽然也用到了Playwright来操控浏览器,但决策层完全是LLM在驱动。
简单说:Selenium是“遥控器”,browser-use是“驾驶员”。遥控器得由人一步步按按钮,驾驶员自己看路、自己打方向盘、自己踩油门。
这个差异非常关键,它决定了browser-use适合解决“非确定性”任务——那些没有固定步骤、需要临场判断的操作。
2. browser-use核心原理拆解:它是怎么“看懂”网页并决策的
2.1 双通道状态感知:视觉与DOM结合
要让LLM操作浏览器,第一步是让它“理解”当前页面内容。browser-use采用两条通道感知页面状态:
第一是视觉通道。系统会对当前页面截图,把截图作为图像输入发送给多模态大模型。大模型能看到页面的布局、按钮的位置、颜色、图标,这相当于“人眼看到的样子”。
第二是DOM通道。系统会把关键DOM元素(按钮、输入框、链接、文本节点)的位置和属性提取出来,构建一个可访问性树,再转换成文本输入发送给大模型。这相当于“在后台读页面的HTML源码”。
为什么要双通道?因为视觉信息适合理解大体布局,但细节(比如一个链接的href、一个输入框的name属性)视觉看不清楚;DOM信息很精确,但纯文本形式很难理解页面布局的层次。两者结合起来,LLM对页面的理解才足够完整。
这里有个细节值得注意:browser-use对DOM的处理不是把整个HTML直接扔给LLM。HTML动辄几百KB,Token根本不够用,而且噪音很大。它会做智能裁剪,只保留与交互相关的可操作元素。这个设计大大降低了Token消耗,也提高了决策准确率。
2.2 动作空间设计:LLM输出就是“操作指令”
理解页面之后,LLM要输出动作。browser-use定义了一套JSON格式的动作指令集,我列举几个常用的:
[ {"action": "go_to_url", "params": {"url": "https://example.com"}}, {"action": "click_element", "params": {"index": 5}}, {"action": "type_text", "params": {"index": 3, "text": "关键词"}}, {"action": "scroll", "params": {"direction": "down", "amount": 500}}, {"action": "extract_content", "params": {"description": "提取页面上所有商品的价格"}}, {"action": "switch_tab", "params": {"page_id": 2}} ]每个动作对应浏览器里的一个真实操作。LLM每次输出一个JSON,browser-use解析后执行,执行完把新的页面状态反馈给LLM,LLM再输出下一个动作。如此循环,直到LLM判断任务完成,输出结束标记。
这套设计的妙处在于:LLM不需要“写代码”来控制浏览器,它只需要“描述动作”。无论底层浏览器有多少按钮、输入框,在LLM的视角里,所有页面元素都被编号了,它只需要说“点击元素3”“在元素5里输入文字”,大幅降低了决策难度。
2.3 记忆与任务管理:多步骤任务是怎么串起来的
单一的“观察-决策-执行”循环只能处理简单的单步任务。真实场景下,任务往往是多步骤的,比如“先搜索,再点进第一个结果,提取正文,返回搜索页,搜索另一个关键词,对比结果”。
为了解决这个问题,browser-use引入了类似Agent的记忆机制:
- 短期记忆:当前页面的状态、最近的几次操作记录,放在上下文里,保证LLM知道“我现在到哪一步了”。
- 任务规划:LLM会先对整体任务做一个拆解,形成一个计划列表,每完成一步就在计划上打勾,更新剩余步骤。
- 错误恢复:如果某个动作执行失败(比如点击目标不存在),LLM会收到错误信息,它能自行调整策略,换个方式继续。
这套机制在代码层面的体现,就是Prompt模板中嵌入了“当前任务描述+已完成步骤+页面状态+可用元素列表+风险提示”等模块。browser-use对Prompt工程的处理比很多同类项目细致,这也是它效果好的原因之一。
2.4 同类方案横向对比:为什么我最终选了browser-use
现在做AI操控浏览器的方案并不只有browser-use一个。OpenAI的Operator、Anthropic的Computer Use、开源的Skyvern等,都在做类似的事。我做个简单的横向对比:
| 方案 | 开源 | 定位 | 优点 | 局限 |
|---|---|---|---|---|
| browser-use | 是 | 浏览器自动化专用 | 开源免费、动作定义清晰、社区活跃、可深度定制 | 依赖外部LLM API,Token成本需自控 |
| OpenAI Operator | 否 | 通用计算机操作 | 闭源但体验完整 | 区域受限、不可定制、成本高 |
| Anthropic Computer Use | 否 | 通用桌面操作 | 模型能力强 | API费用高、偏桌面场景 |
| Skyvern | 是 | 自动化流程引擎 | 偏向固定流程执行 | 对LLM自主决策的支持不如browser-use灵活 |
对比一圈下来,browser-use最大的优势是“专注”。它把浏览器相关的动作抽象得足够精细,又有很好的扩展机制,加上开源、社区有大量案例,所以最终我选择它作为主力工具。
3. 环境准备与快速上手:从0到1跑通你的第一个浏览Agent
3.1 环境依赖清单
动手之前先把环境准备清楚。browser-use基于Python 3.11+(推荐3.11或3.12),依赖Playwright控制浏览器,同时需要你有大模型API的访问权限。
我实测下来,完整的环境准备分三步:
第一,创建独立的Python虚拟环境。AI项目依赖经常有冲突,用venv或conda建一个独立环境是基本素质。
python -m venv browser-env source browser-env/bin/activate # Windows上执行 browser-env\Scripts\activate第二,安装browser-use主包和Playwright内核:
pip install browser-use playwright playwright install chromium这里有个小坑:playwright install chromium在国内网络环境下可能下载很慢,偶尔还会失败。如果遇到超时,可以设置镜像源重试,实在不行就多试几次,或者手动下载浏览器包放到缓存目录。
第三,配置大模型API。browser-use默认支持OpenAI接口,也支持Anthropic以及国内很多兼容OpenAI协议的服务。先用环境变量配置最省事:
export OPENAI_API_KEY="你的key"如果你用的是国内模型服务,在初始化Agent时直接传对应的base_url和模型名即可,这一点比很多只绑定OpenAI的框架友好很多。
3.2 最小可用示例:让它去完成任务
装好之后,写一个最小的Agent脚本感受一下效果。下面这段代码是我第一次跑通的版本,非常简单:
import asyncio from browser_use import Agent, Browser async def main(): agent = Agent( task="打开百度首页,在搜索框输入'AI Agent',点击搜索,然后把搜索结果第一页的前五个结果标题列出来", browser=Browser() ) result = await agent.run(max_steps=20) print(result) if __name__ == "__main__": asyncio.run(main())这段代码的含义很直白:
- task是你要Agent做的事,用自然语言描述就行
- max_steps限制最大操作步数,防止它陷入死循环
- run()会执行整个任务循环,返回最终结果
很多第一次跑browser-use的朋友,看到的效果都会有点震撼:浏览器真的自己开了、真的自己往搜索框里敲字、真的自己点了搜索结果、然后规规矩矩地把结果列表提取了出来。
整个过程没有写任何选择器、没有写任何XPath、没有写任何“点击某个坐标”之类的指令,全都是Agent自己判断的。
3.3 核心参数配置:模型、步数与成本控制
跑通最小示例之后,你可能会遇到几个问题:Token消耗太快、等待时间太长、经常在某一步卡住。
这些问题大多可以通过调参解决。browser-use的核心配置项有几个:
| 参数 | 作用 | 我的建议值 |
|---|---|---|
| max_steps | 最大操作步数 | 简单任务10~20,复杂任务30~50 |
| max_retries | 失败动作重试次数 | 2~3 |
| model | 使用的LLM模型 | 预算充足用强模型,测试用小模型 |
| temperature | 模型温度 | 0.1左右,越低越稳定 |
特别提醒:browser-use一次任务会多次调用LLM API,每一步决策都是一次调用。所以如果你用的是按Token计费的模型,一个复杂任务跑下来,Token消耗相当可观。我建议前期测试阶段,尽量用便宜的模型跑通流程,确认效果后再切到强模型。
另外,并发这一块要提前规划。browser-use本身是单任务执行的设计,一个Agent实例操作一个浏览器页面。如果你要扛并发,比如同时跑10个Agent做批量任务,需要考虑几个层面:
- 浏览器实例隔离:用Playwright的BrowserContext隔离多个会话,每个Agent用独立的上下文,避免互相干扰。
- 任务队列调度:并发请求不可能是无限的。用一个消息队列(如Celery+Redis)把任务排队,控制同时运行的Agent数量。
- API限流控制:LLM API有每分钟调用次数限制,你需要算自己的并发上限。比如你的模型API每分钟允许60次请求,每个任务平均15步(一步一次调用),那同时跑4个任务就是极限了,超过必然报限流错误。
4. 核心功能实战:让Agent完成真实的业务任务
4.1 实战一:自动采集商品信息并整理成表格
先来看一个贴近生活的例子:采集某电商平台的商品信息。
假设你要做市场调研,需要搜集某个品类下前20个商品的名称、价格、销量和店铺名。手动操作,一个人起码要忙半小时。用browser-use,一段代码就搞定:
import asyncio from browser_use import Agent, Browser async def main(): agent = Agent( task="""去某电商平台搜索'机械键盘',按销量排序, 打开前3个商品详情页,分别提取商品名称、价格、销量、优惠信息, 最后汇总成JSON列表返回""", browser=Browser() ) result = await agent.run(max_steps=30) print(result)这里有个关键点:Agent在提取数据时,不会像爬虫那样去解析特定的HTML结构。它会调用extract_content动作,用自然语言描述“提取什么”,browser-use会把页面上相关内容作为上下文发回LLM,让LLM整理出结构化的JSON。
这种方式的优点是:页面改版了,爬虫代码就废了,但browser-use不会——它每次都是“现看现提取”,页面怎么改都不影响它提取“价格”“名称”这类语义信息。
4.2 实战二:自动填写并提交表单
表单填写是另一个高频场景。现实中有大量网站没有开放API,用户只能手动填。browser-use在这方面非常好使:
await agent.run( task="""在注册页面填写表单:姓名填'张三',邮箱填'zhangsan@example.com', 手机号填'13800138000',勾选同意用户协议,点击提交按钮, 如果出现错误提示,把错误信息打印出来""", max_steps=25 )我用这个场景做过大量测试,发现一个规律:如果页面表单有明确的label文字(比如“姓名”“邮箱”),Agent的成功率很高,基本90%以上。但如果表单是纯图标式设计,只有图标没有文字label,Agent容易判断错误。所以遇到这种页面,我会在task描述里写得更具体些,比如“在页面上部找到输入框”。
另外涉及验证码的场景,目前browser-use还没有内置的验证码识别能力。图形验证码需要外接OCR服务,滑块验证码就更复杂。这部分大家在实际使用中要有预期,别拿它去做对抗验证码的任务。
4.3 实战三:UI自动化测试的“另类玩法”
browser-use在UI测试领域也有一个很有意思的应用方式。
传统UI测试是写死脚本后反复执行,维护成本高。browser-use可以当作“探索性测试助手”:你告诉它“这个页面有个登录表单,帮我测试用户名密码错误时会不会出现提示”,它会自己尝试输入错误信息、点击登录、观察页面变化、最后告诉你测试结果。
这种“AI驱动的测试”目前还不够成熟,不能完全替代传统自动化测试,但作为冒烟测试和探索性测试的补充,效率提升非常明显。特别适合产品快速迭代、没有时间维护繁琐测试脚本的小团队。
4.4 实战四:把browser-use嵌入更大的Agent框架
browser-use还有一个重要的打开方式:嵌入更大的Agent框架中。
现在很多开发者在用LangChain/LangGraph搭建Agent应用。browser-use可以作为其中的一个“工具节点”,负责所有需要浏览器操作的任务。比如:
- 数据分析Agent需要抓取实时数据时,调用browser-use节点去执行
- 邮件Agent收到用户需求后,拆解任务,把需要查询网页的部分交给browser-use处理
- 个人AI助手需要帮用户订票、查快递、比价时,底层都是browser-use在工作
这种“工具化嵌入”的思路,让browser-use的价值不止于一个独立脚本,而是成为整个自动化系统的“执行器官”。
如果你正在规划AI Agent学习路线,我建议把browser-use这样的“工具类项目”作为一个重要的实践环节。光会写Prompt、调API不够,真正让Agent做实事,必须给它接上工具。
5. 服务化改造:用FastAPI把browser-use变成一个任务接口
5.1 为什么需要服务化改造
跑通几个Demo之后,你会发现一个问题:脚本是脚本,应用是应用。想让browser-use真正成为产品的一部分,不能只是本地跑脚本,得把它封装成一个服务,对外提供HTTP接口。
这样做有几个明显的好处:业务方不需要知道browser-use怎么用,只需要提交任务描述;服务端可以做并发控制和资源管理;多个业务方可以共享同一个Agent服务。
方案上,我用FastAPI做了一层薄封装,任务进队列后异步执行,前端通过轮询或WebSocket拿结果。代码不复杂,但工程上很实用。
5.2 一个简单的任务服务Demo
下面这个示例,是一个最基础的任务接口服务:
import asyncio from datetime import datetime from fastapi import FastAPI, BackgroundTasks from pydantic import BaseModel from browser_use import Agent, Browser app = FastAPI() tasks_db = {} class TaskRequest(BaseModel): task: str max_steps: int = 20 async def run_task(task_id: str, task_desc: str, max_steps: int): try: agent = Agent(task=task_desc, browser=Browser()) result = await agent.run(max_steps=max_steps) tasks_db[task_id] = {"status": "done", "result": str(result)} except Exception as e: tasks_db[task_id] = {"status": "error", "error": str(e)} @app.post("/agent/task") async def submit_task(req: TaskRequest, background_tasks: BackgroundTasks): task_id = datetime.now().strftime("%Y%m%d%H%M%S%f") tasks_db[task_id] = {"status": "running"} background_tasks.add_task(run_task, task_id, req.task, req.max_steps) return {"task_id": task_id} @app.get("/agent/task/{task_id}") async def get_task(task_id: str): return tasks_db.get(task_id, {"status": "not_found"})这个Demo有几点需要注意:
- BackgroundTasks是FastAPI内置的轻量后台任务机制,适合开发调试;生产环境建议换成Celery,任务可靠性和持久化会好很多。
- 每个任务都new一个Browser实例,开销很大。更好的做法是用浏览器连接池,复用Playwright的BrowserContext。
- 任务并发数要加信号量限制,否则几十个任务同时进来,服务器内存直接爆掉。
5.3 并发调度与资源管理方案
关于“AI Agent怎么扛并发”,我在这块踩过不少坑,总结一下自己的处理方案。
第一层是并发上限控制。我在任务入口加了一个asyncio.Semaphore,限制同时运行的Agent数量。假设服务器内存是8GB,每个浏览器上下文大约占300MB,那同时跑4到6个Agent比较安全。
第二层是LLM API限流。前面说过,LLM API是并发链路中最容易被打爆的一环。我的做法是建立一个请求计数器,在把任务交给Agent之前,先估算它的步数上限,乘以每步的API调用次数,判断是否会超过分钟限流。超了就排队等下一轮。
第三层是浏览器资源释放。browser-use每个任务开启一个浏览器上下文,如果不显式关闭,内存占用会持续增长。长时间跑任务的机器,我会定期重启任务进程,避免内存泄漏导致的崩溃。
下面是我常用的一段BrowserContext池化逻辑的参考思路:
# 思路示例:复用BrowserContext而不是每次新建 class BrowserPool: def __init__(self, max_contexts=4): self.max_contexts = max_contexts self.available = [] self.lock = asyncio.Lock() async def acquire(self): async with self.lock: if self.available: return self.available.pop() # 如果池中没有空闲,等待或者新建(受max限制) # 这里省略具体的context创建逻辑 pass async def release(self, context): async with self.lock: self.available.append(context)当然,如果你的并发量不是很大,直接用最朴素的“每次新建+用完释放”也能跑,只是要注意监控内存。
6. 我踩过的坑与排查指南
6.1 坑一:Token消耗比想象中大得多
第一个让我印象深刻的坑是Token。第一次跑一个10步左右的任务,我以为消耗不了多少Token,结果账单出来吓了我一跳。
问题出在哪?前面讲过,browser-use每一步决策都要调用LLM,而且每次调用要携带页面截图和DOM信息。多模态模型的图像Token比文本Token贵得多,一个截图动辄上千Token。10步任务,保守估计要消耗几万Token。
我的优化经验:
- 设置合理的max_steps,别让Agent“自由发挥”太多步。
- 对于不依赖视觉信息的页面,可以关闭视觉通道,只用DOM信息,能省不少Token。
- 用价格低的模型跑流程验证,最后再切强模型。
- 把常见操作固化成快捷方式,减少不必要的决策步数。
6.2 坑二:并发一高就报限流错误
“AI Agent怎么扛并发”这个问题在社区里讨论得很激烈。browser-use的并发瓶颈主要是LLM API限流。
我自己测试过:4个Agent并发跑,每个任务约15步,共用同一个API Key,不到两分钟就会触发限流。
解决方案我用下来比较有效的有三个:
- 给每个Agent实例设置请求间隔,错峰调用。
- 用多个API Key做负载均衡。
- 接一层缓存,对相同或相似的页面状态,直接复用之前的决策结果,减少LLM调用。
如果用的是自建模型服务,把并发队列和速率限制配置好,别让下游把上游打爆。
6.3 坑三:页面元素找不到、点击无效
另一个高频问题:Agent明明“看”到了页面上有个按钮,执行点击时却提示元素不存在。
排查下来,最常见的原因有三个:
一是页面还在加载中,元素是动态渲染出来的,Agent截图时看到了,但执行点击时DOM还没准备好。解决办法是增加动作间等待时间,或者在任务描述里提醒Agent“等待页面加载完成”。
二是页面有弹窗或遮罩层,点击被遮挡了。browser-use有时识别不出页面上有个弹窗挡住按钮,会去点底下的元素。这种情况下,我会在任务里明确要求“先检查是否有弹窗,有就关闭”。
三是元素在iframe里。browser-use对iframe的支持目前不够完善,跨iframe的元素定位容易出错。如果你经常需要操作iframe里的内容,建议在任务描述里写清楚“这个元素在iframe中”,Agent处理起来会更有预期。
6.4 坑四:网站风控与合规边界
做浏览器自动化,风控是绕不开的话题。browser-use是真实浏览器行为,比requests爬虫隐蔽得多,但并不是万无一失。
一些风控严格的网站,会检测自动化特征:异常的鼠标轨迹、极快的操作速度、非人类的行为模式。我遇到过几次被拦截的情况:同一个IP短时间内多次运行Agent,网站直接弹出滑块验证。
我的应对策略很简单:
- 控制运行频率,别同一时间扎堆跑。
- 设置合理的动作间隔,让Agent的操作节奏看起来更像真人。
- 必要时使用合规的代理IP池分散请求。
- 对频繁被风控的站点,降低任务强度。
这里特别提醒一句:做浏览器自动化,一定要遵守目标网站的robots协议和用户协议,只做合法的数据采集和自动化操作。别拿browser-use去做违规的事情,风险很大,不值得。
6.5 常见问题速查表
| 问题 | 可能原因 | 解决方案 |
|---|---|---|
| 任务执行到一半报错退出 | 浏览器崩溃或LLM API超时 | 增加重试次数,检查网络,换稳定模型 |
| Agent一直重复同一个动作 | 页面状态没变化,LLM误判 | 增加等待时间,修改任务描述,增加max_steps |
| 提取的数据格式不对 | LLM没有完全理解需求 | 在task里把期望的JSON结构写清楚 |
| 中文页面支持不好 | 模型对中文DOM理解弱 | 换支持中文更好的模型,或提示词中强调用中文 |
| 浏览器窗口一闪而过 | Playwright内核未正确安装 | 重新执行playwright install chromium |
| 本地运行出现SSL证书报错 | 部分网站证书链不完整 | 在Playwright配置里设置ignore_https_errors |
7. 几点实操体会
文章写到这里,最后分享几个我个人用得比较多的技巧和心得。
第一,任务描述一定要具体。browser-use对模糊指令的理解不如对明确指令好。“去搜索一个东西”这种描述,Agent会懵。但“打开某网站,在搜索框输入某关键词,点击第一个结果,提取页面上的价格”这种具体描述,它的表现会好很多。本质上,LLM擅长的是执行,不是猜你的意图。
第二,browser-use的Prompt模板是可以自定义的。如果你希望Agent在某些特殊场景下有不同的行为习惯,比如更谨慎的点击、更详细的日志输出,可以去改它的系统提示词模板。这个项目比较开放,很多行为逻辑都能调整。
第三,如果要上生产环境,建议把browser-use封装成任务管理服务,放到消息队列后面,通过API对外提供服务。这样每个业务方只需要提交任务描述,服务端负责调度、并发、结果汇总,整个系统的稳定性和可维护性会高很多。
第四,注意浏览器资源的释放。browser-use每个任务开启一个浏览器上下文,如果不显式关闭,内存占用会持续增长。长时间跑任务的机器,我会定期重启任务进程,避免内存泄漏导致的崩溃。
根据我的经验,browser-use这类“让LLM操控真实工具”的思路,后续还有很大的扩展空间。比如跟本地文件系统打通、跟命令行打通、跟更多专业软件打通。AI Agent的“手脚”会越来越齐全,未来一定会有更多“把AI撒出去干活”的落地场景。
如果你正在做AI Agent相关的项目,browser-use值得认真研究一下。它可能不是你想象中的那种“全自动万能机器人”,但它确实能把AI从“聊天框”里放出来,让它真正碰一碰真实世界里的网页。