让浏览器AI起来:基于大模型Agent的浏览器自动化工具

698 阅读5分钟

最近有个非常火的项目,利用大模型Agent驱动浏览器完成各种操作,如网页搜索、爬虫分析、机票酒店预定、股票监控等,号称全面替代所有在浏览器上的操作,试用方式还是比较简单的,以下将进行简单介绍。

快速开始

通过pip安装:

pip install browser-use

安装web自动化框架:

playwright install

Playwright微软开源的一个浏览器自动化框架,主要用于浏览器自动化执行web测试,提供强大的 API 集,适用于所有现代浏览器。

设置好大模型API KEY,填入.env文件:

OPENAI_API_KEY=

创建智能体,指定命令:

from langchain_openai import ChatOpenAI
from browser_use import Agent
import asyncio
from dotenv import load_dotenv
load_dotenv()

async def main():
    agent = Agent(
        task="Go to Reddit, search for 'browser-use', click on the first post and return the first comment.",
        llm=ChatOpenAI(model="gpt-4o"),
    )
    result = await agent.run()
    print(result)

asyncio.run(main())

模型支持

API

所有适配LangChain chat接口并且支持工具调用的模型理论上都支持,但小模型在解析过程中错误率不可忽视。GPT-4o和DeepSeek-V3这类模型比较合适,推荐DeepSeek-V3,价格更加便宜。

from langchain_openai import ChatOpenAI
from browser_use import Agent
from pydantic import SecretStr

# Initialize the model
llm=ChatOpenAI(base_url='https://api.deepseek.com/v1', model='deepseek-chat', api_key=SecretStr(api_key))

# Create agent with the model
agent = Agent(
    task="Your task here",
    llm=llm,
    use_vision=False
)

本地模型

本地大模型可以使用Ollama,需要从Ollama官网选择支持工具调用的大模型。 在这里插入图片描述

调用方式同样非常简单,使用langchain_ollama加载模型即可:

from langchain_ollama import ChatOllama
from browser_use import Agent
from pydantic import SecretStr


# Initialize the model
llm=ChatOllama(model="qwen2.5", num_ctx=32000)

# Create agent with the model
agent = Agent(
    task="Your task here",
    llm=llm
)

设置

Agent设置

Agent支持如下参数: ● task:需要大模型完成的基本指令 ● llm:大模型,需要支持工具调用,并且适配langchain_chat相关的接口 ● controller:大模型可选的工具集 ● use_vision:是否开启视觉检测 ● save_conversation_path:log的存放路径,用于保存模型每次交互的产生的对话

浏览器设置

browser支持如下参数: ● headless:是否打开浏览器tab并显示 ● disable_security : 浏览器安全设置,比如跨域等 ● proxy :设置代理

from browser_use import BrowserConfig

# Basic configuration
config = BrowserConfig(
    headless=False,
    disable_security=True
)

本地浏览器

除了用Playwright启动Chromium之外,也支持使用用户实际的浏览器,如:chrome。这样的话agent可以实际操作用户需要登陆账户的一些网站。

# 需要设置app的路径
from browser_use import Agent, Browser, BrowserConfig
from langchain_openai import ChatOpenAI
import asyncio
# Configure the browser to connect to your Chrome instance
browser = Browser(
    config=BrowserConfig(
        # Specify the path to your Chrome executable
        chrome_instance_path='/Applications/Google Chrome.app/Contents/MacOS/Google Chrome',  # macOS path
        # For Windows, typically: 'C:\\Program Files\\Google\\Chrome\\Application\\chrome.exe'
        # For Linux, typically: '/usr/bin/google-chrome'
    )
)

# Create the agent with your configured browser
agent = Agent(
    task="Your task here",
    llm=ChatOpenAI(model='gpt-4o'),
    browser=browser,
)

async def main():
    await agent.run()

    input('Press Enter to close the browser...')
    await browser.close()

if __name__ == '__main__':
    asyncio.run(main())

自定义输出格式

agent默认的输出结果是文本,同时也支持自定义输出格式,实现结构化输出。

from pydantic import BaseModel
# Define the output format as a Pydantic model
class Post(BaseModel):
	post_title: str
	post_url: str
	num_comments: int
	hours_since_post: int


class Posts(BaseModel):
	posts: List[Post]


controller = Controller(output_model=Posts)


async def main():
	task = 'Go to hackernews show hn and give me the first  5 posts'
	model = ChatOpenAI(model='gpt-4o')
	agent = Agent(task=task, llm=model, controller=controller)

	history = await agent.run()

	result = history.final_result()
	if result:
		parsed: Posts = Posts.model_validate_json(result)

		for post in parsed.posts:
			print('\n--------------------------------')
			print(f'Title:            {post.post_title}')
			print(f'URL:              {post.post_url}')
			print(f'Comments:         {post.num_comments}')
			print(f'Hours since post: {post.hours_since_post}')
	else:
		print('No result')


if __name__ == '__main__':
	asyncio.run(main())

系统提示词

与普通调用大模型情况类似,agent也支持系统提示词,用于给大模型设置好一些基本要求。

系统提示词会显示影响agent的准确率和性能,需要选择性使用

from browser_use import Agent, SystemPrompt

class MySystemPrompt(SystemPrompt):
    def important_rules(self) -> str:
        # Get existing rules from parent class
        existing_rules = super().important_rules()

        # Add your custom rules
        new_rules = """
9. MOST IMPORTANT RULE:
- ALWAYS open first a new tab and go to wikipedia.com no matter the task!!!
"""

        # Make sure to use this pattern otherwise the exiting rules will be lost
        return f'{existing_rules}\n{new_rules}'
from langchain_openai import ChatOpenAI

# Initialize the model
model = ChatOpenAI(model='gpt-4o')

# Create agent with custom system prompt
agent = Agent(
    task="Your task here",
    llm=model,
    system_prompt_class=MySystemPrompt
)

敏感信息隐藏

通过sensitive_data参数可以进行敏感信息隐藏,这样在调用大模型API的时候不会把用户隐私暴露出去。大模型只会收集到设置好的参数名,具体的参数内容由本地进行字符串替换。

from dotenv import load_dotenv
from langchain_openai import ChatOpenAI
from browser_use import Agent

load_dotenv()

# Initialize the model
llm = ChatOpenAI(
    model='gpt-4o',
    temperature=0.0,
)

# Define sensitive data
# The model will only see the keys (x_name, x_password) but never the actual values
sensitive_data = {'x_name': 'magnus', 'x_password': '12345678'}

# Use the placeholder names in your task description
task = 'go to x.com and login with x_name and x_password then write a post about the meaning of life'

# Pass the sensitive data to the agent
agent = Agent(task=task, llm=llm, sensitive_data=sensitive_data)

async def main():
    await agent.run()

if __name__ == '__main__':
    asyncio.run(main())

如果开启了视觉检测,则页面中的隐私内容有可能会被识别到

基本操作

定义了一些模型的基本动作,如谷歌搜索、打开url、组件点击等,用于对浏览器或者web进行操作。

# Action Input Models
class SearchGoogleAction(BaseModel):
	query: str


class GoToUrlAction(BaseModel):
	url: str


class ClickElementAction(BaseModel):
	index: int
	xpath: Optional[str] = None


class InputTextAction(BaseModel):
	index: int
	text: str
	xpath: Optional[str] = None


class DoneAction(BaseModel):
	text: str


class SwitchTabAction(BaseModel):
	page_id: int


class OpenTabAction(BaseModel):
	url: str


class ScrollAction(BaseModel):
	amount: Optional[int] = None  # The number of pixels to scroll. If None, scroll down/up one page


class SendKeysAction(BaseModel):
	keys: str

class ExtractPageContentAction(BaseModel):
	value: str

最后

整个项目实际测试下来实用性不是很强,甚至连完成简单的谷歌搜索都得好一会儿,从后端的日志看应该是模型一些思考过程太多、步骤太冗余导致的。不过页面的html结构识别还比较完善,这对于精确触发一些页面事件应该是个好事。 目前看来比较实用的agent就是Deep Research这类项目,利用推理模型的推理能力+联网搜索整合出完善的研究报告。随着越来越多强大的推理模型的诞生,2025年应该会有更多类似的大模型agent应用爆发出来,希望不再局限于网页搜索和爬虫这类toy项目。