首页 / AI工具实战 / Claude Code 多模态 Agent 开发实战:构建能看屏幕、操作浏览器的 AI 助手 8 次阅读
Claude Code 多模态 Agent 开发实战:构建能看屏幕、操作浏览器的 AI 助手
AI 工具实战

Claude Code 多模态 Agent 开发实战

构建能看屏幕、操作浏览器的 AI 助手

2026 年 3 月 21 日 · 约 12 分钟阅读

为什么需要多模态 Agent?

想象一个场景:你需要定期从后台导出用户数据、整理成报表、再上传到共享文档。传统自动化脚本只能处理结构化 API,一旦涉及网页操作就束手无策。

多模态 Agent(Multimodal Agent)的出现改变了这一局面。它结合了视觉理解工具调用能力,能够像人类一样"看"屏幕、"操作"浏览器,完成端到端的自动化任务。

本教程将带你使用 Claude Code 的 Computer Use API,从零构建一个能自主操作浏览器的 AI 助手。

多模态 Agent 架构示意图:视觉输入、决策引擎、工具执行三层流程

核心概念:Computer Use API 如何工作

Claude 的 Computer Use API 基于三个核心组件:

👁️
视觉输入
屏幕截图作为观察输入,Claude 识别界面元素与状态
🧠
决策引擎
基于目标分析当前状态,规划下一步操作
🖱️
工具执行
调用点击、输入、滚动等原子操作完成交互

整个流程形成一个闭环:观察 → 分析 → 行动 → 再观察,直到任务完成。

准备工作:环境与依赖

开始之前,确保你的开发环境满足以下要求:

🔑
Anthropic API Key
需要 Claude 3.7 Sonnet 或更高版本访问权限
🐍
Python 3.10+
运行控制脚本与浏览器自动化
🌐
Playwright
无头浏览器控制,支持截图与 DOM 操作

安装依赖

# 创建项目目录
mkdir claude-computer-use && cd claude-computer-use

# 初始化 Python 虚拟环境
python3 -m venv .venv
source .venv/bin/activate

# 安装核心依赖
pip install anthropic playwright selenium
playwright install chromium
提示:Computer Use API 目前处于测试阶段,建议先在隔离环境中测试,避免在生产系统直接运行。

实战步骤:构建浏览器自动化 Agent

我们将构建一个完整的多模态 Agent,能够自动登录指定网站并抓取数据。以下是详细的 7 个步骤:

1

配置 API 客户端

首先创建与 Claude API 的连接:

import os
from anthropic import Anthropic

# 初始化客户端
client = Anthropic(api_key=os.environ["ANTHROPIC_API_KEY"])

# 验证连接
print(f"Connected: {client.models.list().models[0].id}")
API 客户端配置流程图:密钥管理、客户端初始化、连接验证
2

设置 Playwright 浏览器

启动无头浏览器并配置截图能力:

from playwright.sync_api import sync_playwright
import base64
import time

class BrowserController:
    def __init__(self):
        self.playwright = sync_playwright().start()
        self.browser = self.playwright.chromium.launch(headless=True)
        self.page = self.browser.new_page()

    def navigate(self, url):
        self.page.goto(url)
        time.sleep(2)  # 等待页面加载

    def capture_screenshot(self) -> str:
        """截取当前屏幕并返回 base64 编码"""
        screenshot = self.page.screenshot()
        return base64.standard_b64encode(screenshot).decode('utf-8')

    def click(self, selector: str):
        self.page.click(selector)
        time.sleep(1)

    def type_text(self, selector: str, text: str):
        self.page.fill(selector, text)

    def close(self):
        self.browser.close()
        self.playwright.stop()
3

定义工具函数

将浏览器操作封装为 Claude 可调用的工具:

tools = [
    {
        "name": "navigate",
        "description": "导航到指定 URL",
        "input_schema": {
            "type": "object",
            "properties": {
                "url": {"type": "string", "description": "目标网址 URL"}
            },
            "required": ["url"]
        }
    },
    {
        "name": "click",
        "description": "点击页面元素",
        "input_schema": {
            "type": "object",
            "properties": {
                "selector": {"type": "string", "description": "CSS 选择器"}
            },
            "required": ["selector"]
        }
    },
    {
        "name": "type_text",
        "description": "在输入框中填写文本",
        "input_schema": {
            "type": "object",
            "properties": {
                "selector": {"type": "string", "description": "CSS 选择器"},
                "text": {"type": "string", "description": "要输入的文本"}
            },
            "required": ["selector", "text"]
        }
    },
    {
        "name": "screenshot",
        "description": "截取当前页面屏幕",
        "input_schema": {"type": "object", "properties": {}}
    },
    {
        "name": "extract_text",
        "description": "提取页面中指定元素的文本",
        "input_schema": {
            "type": "object",
            "properties": {
                "selector": {"type": "string", "description": "CSS 选择器"}
            },
            "required": ["selector"]
        }
    }
]
工具函数架构图:5 个核心操作工具的输入输出流程
4

构建工具执行器

将工具定义与实际浏览器操作关联:

class ToolExecutor:
    def __init__(self, browser: BrowserController):
        self.browser = browser

    def execute(self, name: str, inputs: dict) -> str:
        if name == "navigate":
            self.browser.navigate(inputs["url"])
            return f"已导航到 {inputs['url']}"

        elif name == "click":
            self.browser.click(inputs["selector"])
            return f"已点击 {inputs['selector']}"

        elif name == "type_text":
            self.browser.type_text(inputs["selector"], inputs["text"])
            return f"已输入文本到 {inputs['selector']}"

        elif name == "screenshot":
            img_data = self.browser.capture_screenshot()
            return f"截图完成 (base64 长度:{len(img_data)})"

        elif name == "extract_text":
            text = self.browser.page.text_content(inputs["selector"])
            return f"提取文本:{text}"

        return f"未知工具:{name}"
5

实现 Agent 循环

核心逻辑:发送截图给 Claude → 接收工具调用 → 执行 → 重复直到完成:

import json

class ComputerUseAgent:
    def __init__(self, browser: BrowserController, executor: ToolExecutor):
        self.browser = browser
        self.executor = executor
        self.client = client
        self.conversation_history = []

    def run(self, goal: str, max_turns: int = 10):
        """执行任务直到完成或达到最大回合数"""
        system_prompt = f"""你是一个自动化助手,能够操作浏览器完成网页任务。
当前任务目标:{goal}

请分析屏幕截图,决定下一步操作。可用工具:
- navigate(url): 导航到网址
- click(selector): 点击元素
- type_text(selector, text): 输入文本
- screenshot(): 截屏
- extract_text(selector): 提取文本

每次只调用一个工具,用 JSON 格式回复:
{{"tool": "工具名", "inputs": {{参数}}}}

当任务完成时回复:{{"done": true, "result": "结果描述"}}

        for turn in range(max_turns):
            # 1. 截取当前屏幕
            screenshot = self.browser.capture_screenshot()

            # 2. 发送截图给 Claude
            response = self.client.messages.create(
                model="claude-sonnet-4-6-20260620",
                max_tokens=1024,
                system=system_prompt,
                messages=[
                    *self.conversation_history,
                    {
                        "role": "user",
                        "content": [
                            {
                                "type": "image",
                                "source": {
                                    "type": "base64",
                                    "media_type": "image/png",
                                    "data": screenshot
                                }
                            },
                            {"type": "text", "text": "请分析当前屏幕并决定下一步操作"}
                        ]
                    }
                ],
                tools=tools
            )

            # 3. 解析响应并执行工具
            tool_call = response.content[0]
            if tool_call.type == "tool_use":
                result = self.executor.execute(
                    tool_call.name,
                    tool_call.input
                )
                self.conversation_history.append({
                    "role": "assistant",
                    "content": response.content
                })
                self.conversation_history.append({
                    "role": "user",
                    "content": f"工具执行结果:{result}"
                })

                # 检查是否完成
                if "done" in result.lower():
                    break

        return self.conversation_history[-1]["content"]
Agent 循环流程图:截图→发送 Claude→解析工具调用→执行→循环
6

实战演练:自动登录并抓取数据

完整示例:登录 GitHub 并获取仓库列表:

# 主程序
if __name__ == "__main__":
    # 初始化组件
    browser = BrowserController()
    executor = ToolExecutor(browser)
    agent = ComputerUseAgent(browser, executor)

    # 定义任务
    goal = """
    1. 导航到 github.com
    2. 点击右上角 Sign in
    3. 输入用户名和密码(从环境变量读取)
    4. 登录后导航到用户的 Repositories 页面
    5. 提取前 5 个仓库的名称和 star 数
    6. 返回 JSON 格式结果
    """

    # 执行任务
    result = agent.run(goal, max_turns=15)
    print(f"任务完成:{result}")

    # 清理资源
    browser.close()
安全警告:不要在代码中硬编码密码!使用环境变量 GITHUB_USERNAMEGITHUB_PASSWORD 存储敏感信息。
7

调试与日志

添加可视化调试能力:

import logging
from pathlib import Path

# 配置日志
logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s'
)
logger = logging.getLogger(__name__)

# 截图保存调试
class DebugBrowserController(BrowserController):
    def __init__(self, debug_dir: str = "./debug"):
        super().__init__()
        self.debug_dir = Path(debug_dir)
        self.debug_dir.mkdir(exist_ok=True)
        self.turn_count = 0

    def capture_screenshot(self) -> str:
        self.turn_count += 1
        screenshot = super().capture_screenshot()

        # 保存调试截图
        debug_path = self.debug_dir / f"turn_{self.turn_count:03d}.png"
        with open(debug_path, "wb") as f:
            f.write(base64.b64decode(screenshot))

        logger.info(f"截图已保存:{debug_path}")
        return screenshot
调试日志输出示例:回合计数、工具调用、执行结果

常见问题与解决方案

Agent 陷入循环无法完成任务怎么办?

设置合理的 max_turns 限制(建议 10-15 回合),并在系统提示词中强调"每次操作应使任务向前推进"。还可以添加超时机制,检测重复操作。

截图太大导致 API 超时可以吗?

可以缩放截图尺寸(建议 1024x768),或者使用滚动截图截取可见区域。另一个方案是使用 DOM 提取代替截图,仅在选择器定位失败时才用视觉辅助。

如何处理动态加载的内容?

navigate()click() 后添加智能等待:使用 Playwright 的 wait_for_selector() 或检测网络空闲状态,而不是固定 sleep()

能否同时操作多个标签页?

可以。扩展 BrowserController 添加 new_tab()switch_tab(index) 方法,并将当前 tab 索引作为工具参数。注意 Claude 每次只能"看到"一个 tab 的截图。

进阶技巧与最佳实践

  • 选择器优先策略:优先使用 CSS 选择器定位,截图仅作为后备方案,减少 token 消耗
  • 操作原子化:每个工具调用只做一件事(如只点击或只输入),便于 Claude 精确控制
  • 错误恢复:在工具执行器中添加重试逻辑,遇到 ElementNotFound 时先截图再分析
  • 会话记忆:使用 conversation_history 保存上下文,避免重复说明当前状态
  • 并行验证:关键操作(如登录)执行后立即截图验证,确认成功后再继续

总结

通过本教程,你完成了从零构建多模态 Agent 的完整流程:

  • ✓ 理解 Computer Use API 的核心原理与工作流程
  • ✓ 使用 Playwright 搭建浏览器自动化环境
  • ✓ 封装工具函数并实现 Agent 循环
  • ✓ 完成登录抓取的实战案例
  • ✓ 掌握调试技巧与常见问题排查方法

多模态 Agent 是 2026 年自动化领域的重要趋势,掌握了这项技术,你就能构建真正"看懂"屏幕、"操作"界面的智能助手,突破传统 RPA 的边界。

选择栏目
今日简报 播客电台 实战教程 AI挣钱计划 关于我
栏目
全球AI日报国内AI日报全球金融日报国内金融日报全球大新闻日报国内大新闻日报Claude Code 玩法日报OpenClaw 动态日报GitHub 热门项目日报AI工具实战AI应用开发编程实战工作流自动化AI原理图解AI Agent开发AI变现案例库AI工具创收AI内容变现AI接单提效变现前沿研究
我的收藏