前端转agent-【python】-18 Agent 与本地应用结合:让 AI 操作你的浏览器

34 阅读6分钟

前端转agent-【python】-18 Agent 与本地应用结合:让 AI 操作你的浏览器

前面的 Agent 只能活在终端里,今天让它“走出”命令行,直接操控你电脑上的浏览器——打开网页、填表单、点按钮、抓数据。
Playwright 当手,Ollama + Qwen3:4b 当脑,LangGraph 当神经,一步步做一个能帮你干活的自动化助手。
如果你写过前端 E2E 测试(Cypress / Playwright),这简直一模一样,只不过测试脚本现在由 AI 自动生成。

为什么 Agent 需要操作本地应用?

  • 自动完成重复性工作:填报销单、批量截图、数据采集
  • 打通线上信息与本地操作:查完天气自动生成 Excel 报表
  • 让 Agent 成为真正的“数字员工”

Vue 3 类比:前端用 Playwright 写 E2E 测试,是“脚本模拟用户操作”;Agent 做同样的事,只是脚本由 LLM 实时生成,并根据结果动态调整。

环境准备

pip install ollama langgraph playwright
playwright install chromium   # 安装浏览器内核

模型:

ollama pull qwen3:4b

第一步:给 Agent 一双“手”——浏览器工具

先把 Playwright 的常用操作封装成工具函数,供 LLM 调用。

# browser_tools.py
from playwright.sync_api import sync_playwright
import base64
from typing import Optional

# 全局 Playwright 实例(简单起见)
_playwright = None
_browser = None
_page = None

def start_browser():
    global _playwright, _browser, _page
    _playwright = sync_playwright().start()
    _browser = _playwright.chromium.launch(headless=False)  # 显示浏览器方便观察
    _page = _browser.new_page()
    return "浏览器已启动"

def goto_url(url: str) -> str:
    _page.goto(url)
    return f"已打开 {_page.title()}"

def fill_input(selector: str, text: str) -> str:
    _page.fill(selector, text)
    return f"已在 {selector} 输入: {text}"

def click_button(selector: str) -> str:
    _page.click(selector)
    return f"已点击 {selector}"

def get_page_text() -> str:
    return _page.inner_text("body")[:2000]   # 返回前2000字符,避免超长

def take_screenshot() -> str:
    """截图并返回 base64(可传给视觉模型分析)"""
    b64 = base64.b64encode(_page.screenshot()).decode("utf-8")
    return b64

def close_browser():
    global _playwright
    _browser.close()
    _playwright.stop()
    return "浏览器已关闭"

第二步:用 LangGraph 搭建“浏览器操作 Agent”

LLM 根据用户指令,生成一系列浏览器操作(类似 Function Calling),Agent 依次执行并反馈结果。

# browser_agent.py
import json, ollama
from typing import TypedDict, Literal
from langgraph.graph import StateGraph, END
from browser_tools import (
    start_browser, goto_url, fill_input, click_button,
    get_page_text, take_screenshot, close_browser
)

MODEL = "qwen3:4b"

# 工具描述(喂给 LLM)
TOOLS_DESC = """
可用工具:
1. goto_url(url) - 打开网页
2. fill_input(selector, text) - 在输入框填入内容
3. click_button(selector) - 点击按钮
4. get_page_text() - 获取当前页面文本
5. take_screenshot() - 截图(返回base64)
6. close_browser() - 关闭浏览器

当你需要操作浏览器时,输出JSON格式的步骤列表:
{"steps": [{"tool": "工具名", "args": {...}}, ...]}

如果用户问题不需要浏览器,直接回答。
"""

class BrowserState(TypedDict):
    user_input: str
    steps: list[dict]      # 待执行的浏览器操作步骤
    current_step: int
    final_answer: str

def plan_steps(state: BrowserState) -> dict:
    """LLM 生成操作计划"""
    prompt = f"""{TOOLS_DESC}

用户需求:{state['user_input']}

请决定是否需要浏览器操作。需要则输出JSON:{{"steps": [...]}};不需要则直接回答。"""
    res = ollama.generate(model=MODEL, prompt=prompt)
    text = res["response"].strip()
    try:
        plan = json.loads(text)
        if "steps" in plan:
            return {"steps": plan["steps"], "current_step": 0}
    except:
        pass
    return {"final_answer": text}

def execute_step(state: BrowserState) -> dict:
    """执行当前步骤"""
    steps = state["steps"]
    idx = state["current_step"]
    if idx >= len(steps):
        return {}
    step = steps[idx]
    tool_name = step["tool"]
    args = step.get("args", {})

    # 根据工具名调用对应函数(安全起见,生产环境需要严格校验)
    if tool_name == "goto_url":
        result = goto_url(**args)
    elif tool_name == "fill_input":
        result = fill_input(**args)
    elif tool_name == "click_button":
        result = click_button(**args)
    elif tool_name == "get_page_text":
        result = get_page_text()
    elif tool_name == "take_screenshot":
        result = "截图已生成(base64省略)"  # 实际可保存或分析
        take_screenshot()
    elif tool_name == "close_browser":
        result = close_browser()
    else:
        result = f"未知工具:{tool_name}"

    # 把执行结果追加到步骤信息中
    steps[idx]["result"] = result
    return {"steps": steps, "current_step": idx + 1}

def check_done(state: BrowserState) -> Literal["execute", "summarize"]:
    if state["current_step"] < len(state["steps"]):
        return "execute"
    return "summarize"

def summarize(state: BrowserState) -> dict:
    """所有步骤执行完后,让LLM根据结果生成最终回复"""
    report = "\n".join(
        f"步骤{i+1}: {s['tool']} -> {s.get('result','')}"
        for i, s in enumerate(state["steps"])
    )
    prompt = f"""用户需求:{state['user_input']}
操作记录:{report}
请用自然语言总结操作结果。"""
    res = ollama.generate(model=MODEL, prompt=prompt)
    return {"final_answer": res["response"].strip()}

# 构建图
builder = StateGraph(BrowserState)
builder.add_node("plan", plan_steps)
builder.add_node("execute", execute_step)
builder.add_node("summarize", summarize)

builder.set_entry_point("plan")
builder.add_conditional_edges("plan", lambda s: "execute" if s.get("steps") else "end", {
    "execute": "execute",
    "end": END
})
builder.add_conditional_edges("execute", check_done, {
    "execute": "execute",
    "summarize": "summarize"
})
builder.add_edge("summarize", END)

agent = builder.compile()

# 运行前先启动浏览器
start_browser()

if __name__ == "__main__":
    while True:
        user = input("\n🧑 你: ")
        if user == "/bye":
            close_browser()
            break
        state = {"user_input": user, "steps": [], "current_step": 0, "final_answer": ""}
        result = agent.invoke(state)
        print(f"🤖 Agent: {result.get('final_answer')}")

运行效果:

🧑 你: 打开百度,搜索“Python教程”,然后告诉我第一个结果的标题
(浏览器自动打开百度,输入搜索词,点击搜索,截图,获取文本)
🤖 Agent: 百度已打开,搜索"Python教程"后,第一个结果是"Python基础教程 | 菜鸟教程"

整个过程无需手动操作,Agent 自动规划步骤并执行。

Vue 3 对比:从 E2E 测试到 AI 测试

前端工程师写 Playwright 测试通常是预先定义好步骤:

// e2e.spec.ts
test('搜索 Python 教程', async ({ page }) => {
  await page.goto('https://baidu.com');
  await page.fill('#kw', 'Python教程');
  await page.click('#su');
  await expect(page.locator('.result')).toContainText('菜鸟教程');
});

AI Agent 把“写死步骤”变成“根据自然语言生成步骤并执行”,本质上是动态生成测试脚本
你的 Vue 组件经验帮你理解:页面上的元素就是 selector,表单交互就是 fill + click,Agent 只是把用户的话翻译成这些操作。

安全与最佳实践

  1. 沙盒环境:务必在虚拟机或隔离环境中运行,避免误删文件或泄露隐私。
  2. 审批机制:结合第 16 篇的人机协同,对危险操作(close_browser、修改文件)加入 interrupt
  3. 操作日志:每一步都记录 result,方便回溯。
  4. 视觉反馈:用截图 + 视觉模型实现“页面理解”,比如“找到‘登录’按钮并点击”而不是硬编码 selector,这需要再接入视觉模型(如 llama3.2-vision)分析截图给出坐标。

拓展思路

  • 表格填写自动化:读取 Excel → 逐条填入 Web 表单
  • 价格监控:每天定时抓取电商价格,存入 CSV
  • 一键部署脚本:Agent 操作 VPS 管理面板,完成网站部署
  • 前端 Bug 复现:描述 bug,Agent 自动打开页面复现并截图

这些能力结合你的前端背景,可以做出非常惊艳的内部工具。

总结

  • 用 Playwright 给 Agent 装上“手”,让它能像人一样操作浏览器。
  • LangGraph 负责将用户指令翻译成操作步骤并逐条执行,形成“规划-执行-总结”闭环。
  • 对前端开发者来说,这套思路就是 E2E 测试的 AI 增强版,而且可以和 Vue 组件无缝集成(比如在管理后台嵌入一个“语音助手”直接操控后台页面)。
  • 安全第一,务必在可控环境中测试。

现在,试着让你的 Agent 帮你打开公司后台,自动导出今天的报表吧!

python browser_agent.py