Claude Computer Use桌面自动化完全教程

教程简介

零基础Claude Computer Use桌面自动化完全教程,涵盖Computer Use技术原理、API接入实战、屏幕截图与视觉分析、鼠标键盘操作自动化、桌面应用场景(文件管理、数据录入、表单填写)、网页自动化操作、与Selenium/Playwright对比、安全防护与操作审计、企业级RPA集成方案、最佳实践与限制等核心技能,适合AI开发者和自动化工程师系统学习。

Claude Computer Use 桌面自动化完全教程

掌握 Claude Computer Use 技术,实现 AI 驱动的桌面自动化操作。


目录

  1. Computer Use 概述
  2. 技术原理:视觉理解 + 操作执行
  3. Claude Computer Use API 接入
  4. 屏幕截图与视觉分析
  5. 鼠标键盘操作自动化
  6. 桌面应用场景
  7. 网页自动化操作
  8. 与 Selenium/Playwright 对比
  9. 安全防护与操作审计
  10. 企业级 RPA 集成方案
  11. Computer Use 最佳实践与限制
  12. 总结

1. Computer Use 概述

1.1 什么是 Computer Use

Claude Computer Use 是 Anthropic 推出的一项革命性功能,让 AI 模型能够像人类一样直接操作计算机——观看屏幕、移动鼠标、点击按钮、输入文字、浏览网页。它不是通过 API 接口与软件交互,而是通过视觉感知 + 操作执行的方式,直接操控桌面环境。

这意味着 Claude 可以:

  • 看到屏幕上的所有内容(通过截图)
  • 理解界面元素和它们的含义
  • 操作鼠标和键盘来完成任务
  • 验证操作结果(再次截图确认)

1.2 与传统自动化的本质区别

维度 传统 RPA Claude Computer Use
工作方式 基于固定脚本/规则 基于视觉理解 + AI 决策
适应性 界面变化需重写脚本 自动适应界面变化
开发成本 需要专业 RPA 开发 自然语言描述任务即可
维护成本 高(脚本需持续维护) 低(AI 自动适应)
适用场景 固定流程自动化 灵活、非结构化任务
错误处理 预定义异常处理 AI 理解上下文自主处理

1.3 核心优势

  1. 零脚本开发:用自然语言描述任务,无需编写自动化脚本
  2. 界面自适应:UI 变化不影响任务执行,AI 会"看懂"新界面
  3. 跨应用操作:可以在多个应用程序之间无缝切换操作
  4. 智能错误恢复:遇到意外情况能自主判断和处理

2. 技术原理:视觉理解 + 操作执行

2.1 工作流程

┌──────────────────────────────────────────────────┐
│                  Claude Computer Use              │
│                                                   │
│  ┌─────────┐    ┌─────────┐    ┌─────────┐      │
│  │ 截图模块 │───→│ 视觉理解 │───→│ 决策引擎 │      │
│  └─────────┘    └─────────┘    └────┬────┘      │
│       ↑                              │            │
│       │                              ▼            │
│  ┌────┴────┐                   ┌─────────┐      │
│  │ 结果验证 │←──────────────────│ 操作执行 │      │
│  └─────────┘                   └─────────┘      │
│                                    │              │
│                              ┌─────┴─────┐       │
│                              │  鼠标/键盘  │       │
│                              └───────────┘       │
└──────────────────────────────────────────────────┘

2.2 视觉理解能力

Claude 的视觉理解基于多模态大语言模型,能够:

  • 元素识别:识别按钮、输入框、菜单、图标等 UI 元素
  • 文字识别(OCR):读取屏幕上的所有文字内容
  • 布局理解:理解页面结构和元素之间的关系
  • 状态判断:判断当前页面状态(加载中、已登录、错误等)
  • 坐标定位:精确计算需要点击/操作的屏幕坐标

2.3 操作执行机制

Claude Computer Use 通过以下工具(tools)与计算机交互:

# Claude 可调用的三种核心工具

# 1. computer - 计算机操作(鼠标、键盘、截图)
computer_tool = {
    "type": "computer_20250124",
    "name": "computer",
    "display_width_px": 1920,
    "display_height_px": 1080,
}

# 2. text_editor - 文本文件编辑
text_editor_tool = {
    "type": "text_editor_20250124",
    "name": "str_replace_editor",
}

# 3. bash - 命令行执行
bash_tool = {
    "type": "bash_20250124",
    "name": "bash",
}

3. Claude Computer Use API 接入

3.1 环境准备

# 安装依赖
pip install anthropic pillow

3.2 基础调用示例

import anthropic
import base64
from PIL import Image
import io

client = anthropic.Anthropic()

def take_screenshot() -> str:
    """获取屏幕截图并转为 base64"""
    import subprocess
    # Linux 使用 scrot 或 gnome-screenshot
    subprocess.run(["scrot", "/tmp/screenshot.png"], check=True)
    
    with open("/tmp/screenshot.png", "rb") as f:
        return base64.standard_b64encode(f.read()).decode("utf-8")

def computer_use_demo():
    """Computer Use 基础示例"""
    screenshot_b64 = take_screenshot()
    
    response = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=4096,
        tools=[
            {
                "type": "computer_20250124",
                "name": "computer",
                "display_width_px": 1920,
                "display_height_px": 1080,
                "display_number": 0,
            },
            {
                "type": "text_editor_20250124",
                "name": "str_replace_editor",
            },
            {
                "type": "bash_20250124",
                "name": "bash",
            }
        ],
        messages=[
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {
                            "type": "base64",
                            "media_type": "image/png",
                            "data": screenshot_b64,
                        },
                    },
                    {
                        "type": "text",
                        "text": "请打开系统自带的计算器应用,计算 123 * 456 的结果。"
                    }
                ]
            }
        ]
    )
    
    return response

# 执行
response = computer_use_demo()
print(response)

3.3 完整的 Agent 循环

Computer Use 的核心是一个交互循环:截图 → 分析 → 操作 → 再截图 → 验证 → 继续...

import anthropic
import base64
import subprocess
import time

class ComputerUseAgent:
    """Computer Use Agent - 完整的交互循环"""
    
    def __init__(self, display_size: tuple = (1920, 1080)):
        self.client = anthropic.Anthropic()
        self.display_size = display_size
        self.conversation_history = []
        self.max_iterations = 50
        self.tools = [
            {
                "type": "computer_20250124",
                "name": "computer",
                "display_width_px": display_size[0],
                "display_height_px": display_size[1],
                "display_number": 0,
            },
            {
                "type": "text_editor_20250124",
                "name": "str_replace_editor",
            },
            {
                "type": "bash_20250124",
                "name": "bash",
            }
        ]
    
    def take_screenshot(self) -> str:
        """获取屏幕截图"""
        subprocess.run(["scrot", "/tmp/screenshot.png"], check=True)
        with open("/tmp/screenshot.png", "rb") as f:
            return base64.standard_b64encode(f.read()).decode("utf-8")
    
    def execute_tool(self, tool_use) -> dict:
        """执行工具调用"""
        tool_name = tool_use.name
        tool_input = tool_use.input
        
        if tool_name == "computer":
            return self._execute_computer_action(tool_input)
        elif tool_name == "bash":
            return self._execute_bash(tool_input)
        elif tool_name == "str_replace_editor":
            return self._execute_editor(tool_input)
        else:
            return {"error": f"Unknown tool: {tool_name}"}
    
    def _execute_computer_action(self, action_input: dict) -> dict:
        """执行计算机操作"""
        action = action_input.get("action")
        
        if action == "screenshot":
            screenshot = self.take_screenshot()
            return {
                "type": "image",
                "source": {
                    "type": "base64",
                    "media_type": "image/png",
                    "data": screenshot,
                }
            }
        
        elif action == "mouse_move":
            x, y = action_input["coordinate"]
            subprocess.run(["xdotool", "mousemove", str(x), str(y)], check=True)
            return {"result": f"鼠标移动到 ({x}, {y})"}
        
        elif action == "left_click":
            x, y = action_input["coordinate"]
            subprocess.run(["xdotool", "mousemove", str(x), str(y), "click", "1"], check=True)
            return {"result": f"左键点击 ({x}, {y})"}
        
        elif action == "type":
            text = action_input["text"]
            subprocess.run(["xdotool", "type", "--clearmodifiers", text], check=True)
            return {"result": f"输入文字: {text}"}
        
        elif action == "key":
            key = action_input["key"]
            subprocess.run(["xdotool", "key", key], check=True)
            return {"result": f"按键: {key}"}
        
        elif action == "left_click_drag":
            start = action_input["start_coordinate"]
            end = action_input["end_coordinate"]
            subprocess.run([
                "xdotool", "mousemove", str(start[0]), str(start[1]),
                "mousedown", "1", "mousemove", str(end[0]), str(end[1]),
                "mouseup", "1"
            ], check=True)
            return {"result": f"拖拽 ({start[0]},{start[1]}) → ({end[0]},{end[1]})"}
        
        return {"error": f"未支持的操作: {action}"}
    
    def _execute_bash(self, bash_input: dict) -> dict:
        """执行 Bash 命令"""
        command = bash_input.get("command", "")
        try:
            result = subprocess.run(
                command, shell=True, capture_output=True, text=True, timeout=30
            )
            return {
                "stdout": result.stdout,
                "stderr": result.stderr,
                "returncode": result.returncode
            }
        except subprocess.TimeoutExpired:
            return {"error": "命令执行超时"}
    
    def _execute_editor(self, editor_input: dict) -> dict:
        """执行文本编辑操作"""
        # 简化实现,实际需要完整支持 view/create/str_replace 等
        command = editor_input.get("command")
        path = editor_input.get("path")
        
        if command == "view":
            try:
                with open(path, "r") as f:
                    return {"content": f.read()}
            except FileNotFoundError:
                return {"error": f"文件不存在: {path}"}
        
        return {"error": f"未支持的编辑命令: {command}"}
    
    def run(self, task: str) -> str:
        """执行任务的完整 Agent 循环"""
        print(f"开始执行任务: {task}")
        
        # 初始截图
        screenshot = self.take_screenshot()
        
        self.conversation_history = [
            {
                "role": "user",
                "content": [
                    {
                        "type": "image",
                        "source": {
                            "type": "base64",
                            "media_type": "image/png",
                            "data": screenshot,
                        },
                    },
                    {"type": "text", "text": task}
                ]
            }
        ]
        
        for iteration in range(self.max_iterations):
            print(f"\n--- 迭代 {iteration + 1} ---")
            
            # 调用 Claude
            response = self.client.messages.create(
                model="claude-sonnet-4-20250514",
                max_tokens=4096,
                tools=self.tools,
                messages=self.conversation_history
            )
            
            # 检查是否完成
            if response.stop_reason == "end_turn":
                # 提取最终文本回复
                for block in response.content:
                    if block.type == "text":
                        print(f"任务完成: {block.text}")
                        return block.text
                return "任务完成"
            
            # 处理工具调用
            tool_results = []
            for block in response.content:
                if block.type == "tool_use":
                    print(f"调用工具: {block.name} → {block.input}")
                    result = self.execute_tool(block)
                    tool_results.append({
                        "type": "tool_result",
                        "tool_use_id": block.id,
                        "content": [result] if isinstance(result, dict) else [result],
                    })
            
            # 更新对话历史
            self.conversation_history.append({"role": "assistant", "content": response.content})
            self.conversation_history.append({"role": "user", "content": tool_results})
            
            # 短暂等待,让操作生效
            time.sleep(0.5)
        
        return "达到最大迭代次数,任务未完成"

# 使用示例
agent = ComputerUseAgent()
result = agent.run("打开 Firefox 浏览器,访问 google.com,搜索 'Claude Computer Use'")
print(result)

4. 屏幕截图与视觉分析

4.1 截图方案对比

平台 工具 命令 特点
Linux scrot scrot /tmp/screenshot.png 轻量、快速
Linux gnome-screenshot gnome-screenshot -f /tmp/screenshot.png 支持窗口截图
macOS screencapture screencapture /tmp/screenshot.png 系统自带
Windows PIL/PyScreeze pyautogui.screenshot() 跨平台兼容

4.2 高效截图实现

import platform
import subprocess
import base64
from PIL import Image
import io

class ScreenCapture:
    """跨平台截图工具"""
    
    def __init__(self):
        self.system = platform.system()
    
    def capture(self, save_path: str = "/tmp/screenshot.png") -> str:
        """截图并返回 base64 编码"""
        if self.system == "Linux":
            self._capture_linux(save_path)
        elif self.system == "Darwin":
            self._capture_macos(save_path)
        elif self.system == "Windows":
            self._capture_windows(save_path)
        
        return self._to_base64(save_path)
    
    def capture_region(self, x: int, y: int, width: int, height: int,
                       save_path: str = "/tmp/screenshot_region.png") -> str:
        """截取指定区域"""
        # 先全屏截图
        full_path = "/tmp/screenshot_full.png"
        self.capture(full_path)
        
        # 裁剪
        img = Image.open(full_path)
        cropped = img.crop((x, y, x + width, y + height))
        cropped.save(save_path)
        
        return self._to_base64(save_path)
    
    def _capture_linux(self, save_path: str):
        subprocess.run(["scrot", save_path], check=True)
    
    def _capture_macos(self, save_path: str):
        subprocess.run(["screencapture", save_path], check=True)
    
    def _capture_windows(self, save_path: str):
        import pyautogui
        screenshot = pyautogui.screenshot()
        screenshot.save(save_path)
    
    def _to_base64(self, path: str) -> str:
        with open(path, "rb") as f:
            return base64.standard_b64encode(f.read()).decode("utf-8")

4.3 视觉分析提示词设计

def build_analysis_prompt(task: str, context: str = "") -> str:
    """构建视觉分析提示词"""
    prompt = f"""你正在操作一台计算机。当前屏幕截图已提供。

任务:{task}

请分析当前屏幕状态,决定下一步操作。

操作选项:
1. 点击某个元素 → 使用 computer 工具的 left_click 操作,提供精确坐标
2. 输入文字 → 使用 computer 工具的 type 操作
3. 按键 → 使用 computer 工具的 key 操作(如 Enter、Tab 等)
4. 截图查看 → 使用 computer 工具的 screenshot 操作
5. 执行命令 → 使用 bash 工具

注意:
- 坐标必须精确,基于屏幕分辨率
- 每次只执行一个操作
- 操作后需要截图验证结果
- 如果任务已完成,请说明完成情况
"""
    
    if context:
        prompt += f"\n上下文信息:{context}"
    
    return prompt

5. 鼠标键盘操作自动化

5.1 鼠标操作详解

class MouseController:
    """鼠标控制器"""
    
    @staticmethod
    def move(x: int, y: int):
        """移动鼠标"""
        subprocess.run(["xdotool", "mousemove", str(x), str(y)])
    
    @staticmethod
    def click(x: int, y: int, button: int = 1):
        """点击(1=左键, 2=中键, 3=右键)"""
        subprocess.run(["xdotool", "mousemove", str(x), str(y), "click", str(button)])
    
    @staticmethod
    def double_click(x: int, y: int):
        """双击"""
        subprocess.run(["xdotool", "mousemove", str(x), str(y), "click", "--repeat", "2", "1"])
    
    @staticmethod
    def right_click(x: int, y: int):
        """右键点击"""
        subprocess.run(["xdotool", "mousemove", str(x), str(y), "click", "3"])
    
    @staticmethod
    def drag(start_x: int, start_y: int, end_x: int, end_y: int):
        """拖拽"""
        subprocess.run([
            "xdotool", "mousemove", str(start_x), str(start_y),
            "mousedown", "1",
            "mousemove", str(end_x), str(end_y),
            "mouseup", "1"
        ])
    
    @staticmethod
    def scroll(x: int, y: int, direction: str = "up", clicks: int = 3):
        """滚动(direction: up/down)"""
        button = "4" if direction == "up" else "5"
        subprocess.run(["xdotool", "mousemove", str(x), str(y)])
        for _ in range(clicks):
            subprocess.run(["xdotool", "click", button])

5.2 键盘操作详解

class KeyboardController:
    """键盘控制器"""
    
    @staticmethod
    def type_text(text: str, delay: int = 0):
        """输入文字"""
        if delay > 0:
            for char in text:
                subprocess.run(["xdotool", "type", "--clearmodifiers", char])
                time.sleep(delay / 1000.0)
        else:
            subprocess.run(["xdotool", "type", "--clearmodifiers", text])
    
    @staticmethod
    def press_key(key: str):
        """按下按键"""
        subprocess.run(["xdotool", "key", key])
    
    @staticmethod
    def hotkey(*keys: str):
        """组合键"""
        combo = "+".join(keys)
        subprocess.run(["xdotool", "key", combo])
    
    @staticmethod
    def press_enter():
        KeyboardController.press_key("Return")
    
    @staticmethod
    def press_tab():
        KeyboardController.press_key("Tab")
    
    @staticmethod
    def press_escape():
        KeyboardController.press_key("Escape")
    
    @staticmethod
    def select_all():
        KeyboardController.hotkey("ctrl", "a")
    
    @staticmethod
    def copy():
        KeyboardController.hotkey("ctrl", "c")
    
    @staticmethod
    def paste():
        KeyboardController.hotkey("ctrl", "v")
    
    @staticmethod
    def undo():
        KeyboardController.hotkey("ctrl", "z")

# 常用按键映射
KEY_MAP = {
    "enter": "Return",
    "return": "Return",
    "tab": "Tab",
    "escape": "Escape",
    "esc": "Escape",
    "space": "space",
    "backspace": "BackSpace",
    "delete": "Delete",
    "up": "Up",
    "down": "Down",
    "left": "Left",
    "right": "Right",
    "home": "Home",
    "end": "End",
    "pageup": "Page_Up",
    "pagedown": "Page_Down",
    "f1": "F1", "f2": "F2", "f3": "F3", "f4": "F4",
    "f5": "F5", "f6": "F6", "f7": "F7", "f8": "F8",
    "f9": "F9", "f10": "F10", "f11": "F11", "f12": "F12",
}

5.3 等待与同步

import time

class WaitHelper:
    """等待辅助工具"""
    
    @staticmethod
    def wait(seconds: float):
        """简单等待"""
        time.sleep(seconds)
    
    @staticmethod
    def wait_for_pixel_color(
        x: int, y: int, 
        target_color: tuple, 
        timeout: float = 10.0,
        tolerance: int = 10
    ) -> bool:
        """等待像素变为指定颜色"""
        import pyautogui
        start = time.time()
        while time.time() - start < timeout:
            pixel = pyautogui.pixel(x, y)
            if all(abs(pixel[i] - target_color[i]) <= tolerance for i in range(3)):
                return True
            time.sleep(0.2)
        return False
    
    @staticmethod
    def wait_for_stable_screen(interval: float = 0.5, stable_count: int = 3) -> bool:
        """等待屏幕稳定(连续多次截图相同)"""
        import hashlib
        previous_hash = None
        stable = 0
        
        for _ in range(20):  # 最多等待 10 秒
            screenshot = ScreenCapture().capture()
            current_hash = hashlib.md5(screenshot.encode()).hexdigest()
            
            if current_hash == previous_hash:
                stable += 1
                if stable >= stable_count:
                    return True
            else:
                stable = 0
            
            previous_hash = current_hash
            time.sleep(interval)
        
        return False

6. 桌面应用场景

6.1 文件管理自动化

def automate_file_management():
    """文件管理自动化示例"""
    agent = ComputerUseAgent()
    
    tasks = [
        # 任务1:整理下载文件夹
        "打开文件管理器,进入下载文件夹,将所有 PDF 文件移动到 '文档' 文件夹,"
        "将所有图片文件(jpg/png)移动到 '图片' 文件夹",
        
        # 任务2:批量重命名
        "在当前文件夹中,将所有 .txt 文件重命名,添加日期前缀(格式:YYYY-MM-DD_原文件名)",
        
        # 任务3:创建报告目录结构
        "在桌面创建一个名为 '2024年度报告' 的文件夹,"
        "里面包含 '数据'、'图表'、'文档'、'最终版' 四个子文件夹"
    ]
    
    for task in tasks:
        print(f"\n执行任务: {task}")
        result = agent.run(task)
        print(f"结果: {result}")

6.2 数据录入自动化

def automate_data_entry(data_source: str, target_app: str):
    """数据录入自动化"""
    agent = ComputerUseAgent()
    
    # 读取数据源
    import csv
    with open(data_source, "r") as f:
        reader = csv.DictReader(f)
        rows = list(reader)
    
    for i, row in enumerate(rows):
        task = f"""
        当前需要录入第 {i+1}/{len(rows)} 条数据:
        - 姓名: {row['name']}
        - 邮箱: {row['email']}
        - 电话: {row['phone']}
        - 地址: {row['address']}
        
        请在当前打开的表单中依次填入以上信息,然后点击"保存"按钮。
        保存后点击"新建"按钮准备录入下一条。
        """
        
        result = agent.run(task)
        print(f"第 {i+1} 条录入完成: {result}")

6.3 表单填写自动化

def automate_form_filling():
    """表单填写自动化"""
    agent = ComputerUseAgent()
    
    form_data = {
        "company": "示例科技有限公司",
        "contact": "张三",
        "email": "zhangsan@example.com",
        "phone": "13800138000",
        "address": "北京市海淀区中关村大街1号",
        "description": "这是一份自动生成的商业合作提案..."
    }
    
    task = f"""
    请在当前网页表单中填写以下信息:
    
    1. 公司名称:{form_data['company']}
    2. 联系人:{form_data['contact']}
    3. 邮箱:{form_data['email']}
    4. 电话:{form_data['phone']}
    5. 地址:{form_data['address']}
    6. 描述:{form_data['description']}
    
    填写完成后,请检查所有字段是否正确,然后点击提交按钮。
    """
    
    result = agent.run(task)
    return result

6.4 应用间协作

def cross_app_workflow():
    """跨应用协作工作流"""
    agent = ComputerUseAgent()
    
    task = """
    请执行以下跨应用工作流:
    
    1. 打开浏览器,访问 weather.com,获取今天北京的天气信息
    2. 打开备忘录应用,创建一个新笔记
    3. 在笔记中记录今天的天气情况
    4. 打开邮件客户端,创建一封新邮件
    5. 将天气信息作为邮件内容,发送给 team@example.com
    6. 主题为"今日天气播报"
    """
    
    result = agent.run(task)
    return result

7. 网页自动化操作

7.1 浏览器操作

def web_automation_example():
    """网页自动化示例"""
    agent = ComputerUseAgent()
    
    # 示例:在线购物比价
    task = """
    请帮我完成以下网页操作:
    
    1. 打开浏览器,访问 jd.com
    2. 在搜索框中搜索 "机械键盘"
    3. 按价格从低到高排序
    4. 记录前 5 个商品的名称和价格
    5. 然后访问 taobao.com,搜索同样的商品
    6. 比较两个平台的价格,给出推荐
    """
    
    result = agent.run(task)
    return result

7.2 网页数据采集

def web_scraping_with_computer_use():
    """使用 Computer Use 进行网页数据采集"""
    agent = ComputerUseAgent()
    
    task = """
    请在当前网页上:
    1. 读取页面标题
    2. 找到所有新闻标题和链接
    3. 将信息整理为表格格式
    4. 保存到桌面的 news_data.txt 文件中
    """
    
    result = agent.run(task)
    return result

7.3 表单提交与验证

def form_submission_workflow():
    """表单提交工作流"""
    agent = ComputerUseAgent()
    
    task = """
    请在当前网页表单中完成以下操作:
    
    1. 填写用户名:admin_test
    2. 填写密码:********
    3. 填写邮箱:test@example.com
    4. 选择用户类型为"企业用户"
    5. 勾选"同意服务条款"
    6. 上传桌面上的 logo.png 文件作为头像
    7. 点击注册按钮
    8. 检查是否出现注册成功的提示
    9. 如果有错误,截图记录并报告
    """
    
    result = agent.run(task)
    return result

8. 与 Selenium/Playwright 对比

8.1 技术对比

维度 Claude Computer Use Selenium Playwright
工作原理 视觉理解 + 模拟操作 WebDriver 协议 CDP 协议
元素定位 视觉识别(坐标) CSS/XPath 选择器 CSS/XPath 选择器
跨应用 ✅ 支持桌面任意应用 ❌ 仅浏览器 ❌ 仅浏览器
维护成本 低(AI 自适应) 高(选择器需维护) 中等
执行速度 较慢(需截图分析)
可靠性 中等(依赖视觉识别) 高(精确定位)
开发难度 低(自然语言) 中等 中等
适用场景 复杂 UI、跨应用 Web 自动化 Web 自动化

8.2 混合方案

class HybridAutomation:
    """混合自动化方案 - 结合 Computer Use 与 Playwright"""
    
    def __init__(self):
        self.computer_agent = ComputerUseAgent()
        self.playwright = None  # Playwright 实例
    
    async def init_playwright(self):
        """初始化 Playwright"""
        from playwright.async_api import async_playwright
        self.playwright = await async_playwright().start()
        self.browser = await self.playwright.chromium.launch(headless=False)
        self.page = await self.browser.new_page()
    
    async def smart_automate(self, task: str):
        """智能选择自动化方式"""
        
        # 判断任务类型
        if self._is_web_task(task):
            # Web 任务优先使用 Playwright(更可靠、更快)
            return await self._playwright_execute(task)
        elif self._is_desktop_task(task):
            # 桌面任务使用 Computer Use
            return self.computer_agent.run(task)
        else:
            # 混合任务:先用 Playwright 打开网页,再用 Computer Use 操作
            return await self._hybrid_execute(task)
    
    def _is_web_task(self, task: str) -> bool:
        """判断是否为纯 Web 任务"""
        web_keywords = ["网页", "浏览器", "网站", "URL", "http"]
        return any(kw in task for kw in web_keywords)
    
    def _is_desktop_task(self, task: str) -> bool:
        """判断是否为纯桌面任务"""
        desktop_keywords = ["桌面", "文件", "应用", "窗口", "系统设置"]
        return any(kw in task for kw in desktop_keywords)
    
    async def _playwright_execute(self, task: str):
        """使用 Playwright 执行 Web 任务"""
        # Playwright 代码执行逻辑
        pass
    
    async def _hybrid_execute(self, task: str):
        """混合执行"""
        # 先用 Playwright 打开目标网页
        await self.page.goto("https://example.com")
        
        # 再用 Computer Use 进行复杂操作
        result = self.computer_agent.run(task)
        return result

8.3 选择建议

任务是否涉及桌面应用?
├── 是 → Claude Computer Use
└── 否 → 任务是否为 Web 自动化?
    ├── 是 → 是否需要频繁维护?
    │   ├── 是 → Claude Computer Use(自适应)
    │   └── 否 → Playwright(性能更好)
    └── 否 → 根据具体场景选择

9. 安全防护与操作审计

9.1 安全风险

Computer Use 的安全风险主要来自:

  1. 误操作风险:AI 可能误点击导致数据丢失
  2. 权限提升:自动化操作可能绕过人工确认
  3. 数据泄露:截图可能包含敏感信息
  4. 恶意利用:被用于自动化攻击

9.2 安全防护层

class SecurityGuard:
    """安全防护层"""
    
    def __init__(self):
        self.dangerous_actions = [
            "delete", "remove", "format", "shutdown",
            "restart", "logout", "drop", "truncate"
        ]
        self.sensitive_patterns = [
            "password", "密码", "secret", "密钥",
            "token", "credit card", "信用卡"
        ]
        self.allowed_apps = [
            "firefox", "chrome", "terminal", "calculator",
            "text_editor", "file_manager"
        ]
    
    def check_action(self, action: str, context: str = "") -> dict:
        """检查操作安全性"""
        result = {"safe": True, "warnings": [], "blocked": False}
        
        # 检查危险操作
        action_lower = action.lower()
        for dangerous in self.dangerous_actions:
            if dangerous in action_lower:
                result["warnings"].append(f"检测到潜在危险操作: {dangerous}")
        
        # 检查敏感信息
        for pattern in self.sensitive_patterns:
            if pattern in context.lower():
                result["warnings"].append(f"可能涉及敏感信息: {pattern}")
        
        # 高风险操作需要人工确认
        if result["warnings"]:
            result["safe"] = False
        
        return result
    
    def require_confirmation(self, action: str) -> bool:
        """要求人工确认"""
        print(f"\n⚠️  安全确认")
        print(f"即将执行操作: {action}")
        response = input("是否继续?(yes/no): ")
        return response.lower() in ["yes", "y", "是"]
    
    def sanitize_screenshot(self, screenshot_b64: str) -> str:
        """对截图进行脱敏处理"""
        # 在实际应用中,可以使用 OCR + 正则表达式
        # 识别并遮盖敏感信息(密码框、信用卡号等)
        return screenshot_b64  # 简化示例

9.3 操作审计系统

import json
import datetime
from dataclasses import dataclass, asdict
from typing import List

@dataclass
class AuditRecord:
    """审计记录"""
    timestamp: str
    action_type: str
    action_detail: dict
    screenshot_before: str  # base64
    screenshot_after: str   # base64
    result: str
    risk_level: str  # low/medium/high
    user_confirmed: bool

class AuditSystem:
    """操作审计系统"""
    
    def __init__(self, log_path: str = "/var/log/computer_use_audit.jsonl"):
        self.log_path = log_path
        self.records: List[AuditRecord] = []
    
    def log_action(self, record: AuditRecord):
        """记录操作"""
        self.records.append(record)
        
        # 写入日志文件
        with open(self.log_path, "a") as f:
            f.write(json.dumps(asdict(record), ensure_ascii=False) + "\n")
    
    def create_record(
        self,
        action_type: str,
        action_detail: dict,
        screenshot_before: str = "",
        screenshot_after: str = "",
        result: str = "",
        risk_level: str = "low",
        user_confirmed: bool = False
    ) -> AuditRecord:
        """创建审计记录"""
        return AuditRecord(
            timestamp=datetime.datetime.now().isoformat(),
            action_type=action_type,
            action_detail=action_detail,
            screenshot_before=screenshot_before,
            screenshot_after=screenshot_after,
            result=result,
            risk_level=risk_level,
            user_confirmed=user_confirmed
        )
    
    def get_summary(self, hours: int = 24) -> dict:
        """获取审计摘要"""
        cutoff = datetime.datetime.now() - datetime.timedelta(hours=hours)
        
        recent = [
            r for r in self.records
            if datetime.datetime.fromisoformat(r.timestamp) > cutoff
        ]
        
        return {
            "total_actions": len(recent),
            "risk_distribution": {
                "low": sum(1 for r in recent if r.risk_level == "low"),
                "medium": sum(1 for r in recent if r.risk_level == "medium"),
                "high": sum(1 for r in recent if r.risk_level == "high"),
            },
            "confirmed": sum(1 for r in recent if r.user_confirmed),
            "action_types": list(set(r.action_type for r in recent))
        }

9.4 沙箱环境

class SandboxEnvironment:
    """沙箱环境 - 限制 Computer Use 的操作范围"""
    
    def __init__(self):
        self.restricted_paths = [
            "/etc", "/usr", "/var", "/boot",
            "~/.ssh", "~/.gnupg", "~/.aws"
        ]
        self.restricted_commands = [
            "rm -rf", "sudo", "chmod 777", "mkfs",
            "dd if=", "shutdown", "reboot"
        ]
        self.screen_regions = {
            "allowed": None,  # None 表示全屏允许
            "blocked": []     # 需要屏蔽的区域(如密码输入框)
        }
    
    def check_path_access(self, path: str) -> bool:
        """检查路径是否允许访问"""
        import os
        abs_path = os.path.abspath(path)
        for restricted in self.restricted_paths:
            if abs_path.startswith(os.path.expanduser(restricted)):
                return False
        return True
    
    def check_command_safety(self, command: str) -> bool:
        """检查命令安全性"""
        for restricted in self.restricted_commands:
            if restricted in command:
                return False
        return True
    
    def get_safe_region(self, screenshot: Image.Image) -> Image.Image:
        """遮盖屏幕上的敏感区域"""
        # 在实际应用中,使用 OCR 检测密码框等敏感区域并遮盖
        return screenshot

10. 企业级 RPA 集成方案

10.1 架构设计

┌───────────────────────────────────────────────────────────┐
│                    企业 RPA 平台                            │
│                                                           │
│  ┌──────────┐  ┌──────────┐  ┌──────────┐               │
│  │ 任务调度  │  │ 流程管理  │  │ 监控告警  │               │
│  └─────┬────┘  └─────┬────┘  └─────┬────┘               │
│        │             │             │                      │
│  ┌─────┴─────────────┴─────────────┴─────┐               │
│  │          Claude Computer Use           │               │
│  │  ┌─────────────────────────────────┐  │               │
│  │  │   Agent 执行层                   │  │               │
│  │  │  - 截图 → 视觉分析 → 操作执行    │  │               │
│  │  └─────────────────────────────────┘  │               │
│  │  ┌─────────────────────────────────┐  │               │
│  │  │   安全防护层                      │  │               │
│  │  │  - 权限控制 → 操作审计 → 沙箱     │  │               │
│  │  └─────────────────────────────────┘  │               │
│  │  ┌─────────────────────────────────┐  │               │
│  │  │   集成适配层                      │  │               │
│  │  │  - API 网关 → 消息队列 → 缓存     │  │               │
│  │  └─────────────────────────────────┘  │               │
│  └───────────────────────────────────────┘               │
└───────────────────────────────────────────────────────────┘

10.2 任务调度系统

from enum import Enum
from dataclasses import dataclass
from typing import Optional, Callable
import asyncio
from datetime import datetime

class TaskStatus(Enum):
    PENDING = "pending"
    RUNNING = "running"
    COMPLETED = "completed"
    FAILED = "failed"
    CANCELLED = "cancelled"

@dataclass
class RPATask:
    id: str
    name: str
    description: str
    priority: int  # 1-10
    status: TaskStatus = TaskStatus.PENDING
    created_at: datetime = None
    started_at: datetime = None
    completed_at: datetime = None
    result: Optional[str] = None
    error: Optional[str] = None
    retry_count: int = 0
    max_retries: int = 3

class TaskScheduler:
    """任务调度器"""
    
    def __init__(self, max_concurrent: int = 3):
        self.task_queue = asyncio.PriorityQueue()
        self.running_tasks = {}
        self.completed_tasks = {}
        self.max_concurrent = max_concurrent
        self.agent = ComputerUseAgent()
    
    async def submit_task(self, task: RPATask):
        """提交任务"""
        task.created_at = datetime.now()
        await self.task_queue.put((task.priority, task))
        print(f"任务已提交: {task.name} (优先级: {task.priority})")
    
    async def run(self):
        """运行调度器"""
        while True:
            if len(self.running_tasks) < self.max_concurrent:
                try:
                    priority, task = await asyncio.wait_for(
                        self.task_queue.get(), timeout=1.0
                    )
                    asyncio.create_task(self._execute_task(task))
                except asyncio.TimeoutError:
                    continue
            
            # 清理已完成任务
            done = [t for t, s in self.running_tasks.items() 
                   if s.done()]
            for t in done:
                del self.running_tasks[t]
            
            await asyncio.sleep(0.1)
    
    async def _execute_task(self, task: RPATask):
        """执行任务"""
        task.status = TaskStatus.RUNNING
        task.started_at = datetime.now()
        
        try:
            result = await asyncio.to_thread(
                self.agent.run, task.description
            )
            task.result = result
            task.status = TaskStatus.COMPLETED
        except Exception as e:
            task.error = str(e)
            if task.retry_count < task.max_retries:
                task.retry_count += 1
                task.status = TaskStatus.PENDING
                await self.task_queue.put((task.priority, task))
                print(f"任务重试: {task.name} (第 {task.retry_count} 次)")
            else:
                task.status = TaskStatus.FAILED
        
        task.completed_at = datetime.now()
        self.completed_tasks[task.id] = task

10.3 流程编排

class WorkflowEngine:
    """流程编排引擎"""
    
    def __init__(self):
        self.scheduler = TaskScheduler()
    
    def create_workflow(self, steps: list) -> list:
        """创建工作流"""
        tasks = []
        for i, step in enumerate(steps):
            task = RPATask(
                id=f"workflow_step_{i}",
                name=step.get("name", f"步骤 {i+1}"),
                description=step["description"],
                priority=step.get("priority", 5),
                max_retries=step.get("max_retries", 3)
            )
            tasks.append(task)
        return tasks
    
    async def execute_workflow(self, workflow: list):
        """顺序执行工作流"""
        for task in workflow:
            print(f"\n{'='*50}")
            print(f"执行: {task.name}")
            print(f"{'='*50}")
            
            await self.scheduler.submit_task(task)
            
            # 等待任务完成
            while task.status in [TaskStatus.PENDING, TaskStatus.RUNNING]:
                await asyncio.sleep(1)
            
            if task.status == TaskStatus.FAILED:
                print(f"任务失败: {task.error}")
                # 可以选择继续或中断
                break
            
            print(f"完成: {task.result[:200] if task.result else '无结果'}...")

# 使用示例
async def main():
    engine = WorkflowEngine()
    
    workflow = engine.create_workflow([
        {
            "name": "打开浏览器",
            "description": "打开 Firefox 浏览器,等待加载完成",
            "priority": 10
        },
        {
            "name": "访问目标网站",
            "description": "在地址栏输入 https://example.com 并回车",
            "priority": 9
        },
        {
            "name": "登录",
            "description": "找到登录按钮并点击,输入用户名和密码",
            "priority": 8
        },
        {
            "name": "导出数据",
            "description": "进入数据页面,点击导出按钮,选择 CSV 格式,保存到桌面",
            "priority": 7
        }
    ])
    
    await engine.execute_workflow(workflow)

# asyncio.run(main())

10.4 监控与告警

class RPAMonitor:
    """RPA 监控系统"""
    
    def __init__(self):
        self.metrics = {
            "tasks_submitted": 0,
            "tasks_completed": 0,
            "tasks_failed": 0,
            "avg_execution_time": 0,
            "success_rate": 0.0
        }
        self.execution_times = []
        self.alerts = []
    
    def record_task_completion(self, task: RPATask):
        """记录任务完成"""
        self.metrics["tasks_completed"] += 1
        
        if task.started_at and task.completed_at:
            duration = (task.completed_at - task.started_at).total_seconds()
            self.execution_times.append(duration)
            self.metrics["avg_execution_time"] = (
                sum(self.execution_times[-100:]) / len(self.execution_times[-100:])
            )
        
        # 更新成功率
        total = self.metrics["tasks_completed"] + self.metrics["tasks_failed"]
        if total > 0:
            self.metrics["success_rate"] = self.metrics["tasks_completed"] / total
        
        # 检查告警条件
        self._check_alerts(task)
    
    def _check_alerts(self, task: RPATask):
        """检查告警条件"""
        # 连续失败告警
        if task.status == TaskStatus.FAILED:
            self.metrics["tasks_failed"] += 1
            if self.metrics["tasks_failed"] >= 3:
                self._alert("连续任务失败超过 3 次")
        
        # 执行时间过长告警
        if task.started_at and task.completed_at:
            duration = (task.completed_at - task.started_at).total_seconds()
            if duration > 300:  # 超过 5 分钟
                self._alert(f"任务执行时间过长: {task.name} ({duration:.0f}s)")
    
    def _alert(self, message: str):
        """发送告警"""
        alert = {
            "timestamp": datetime.now().isoformat(),
            "message": message
        }
        self.alerts.append(alert)
        print(f"[ALERT] {message}")
        # 集成实际告警系统(Slack、邮件、短信等)
    
    def get_dashboard(self) -> dict:
        """获取监控面板数据"""
        return {
            **self.metrics,
            "recent_alerts": self.alerts[-10:],
            "total_tasks": (
                self.metrics["tasks_submitted"] + 
                self.metrics["tasks_completed"] + 
                self.metrics["tasks_failed"]
            )
        }

11. Computer Use 最佳实践与限制

11.1 最佳实践

实践一:任务拆分

# ❌ 不推荐:一次性描述复杂任务
bad_task = "帮我完成整个电商订单处理流程,包括登录、查看订单、处理退款、更新库存、发送通知"

# ✅ 推荐:拆分为小步骤
good_tasks = [
    "打开浏览器,访问电商后台管理系统",
    "使用管理员账号登录系统",
    "进入订单管理页面,找到待处理退款的订单",
    "点击退款按钮,填写退款原因,确认退款",
    "进入库存管理页面,更新相关商品的库存数量",
]

实践二:明确的验证点

task = """
请执行以下操作,并在每一步后验证结果:

1. 打开计算器应用
   验证:确认计算器窗口已打开
   
2. 计算 123 * 456
   验证:确认显示结果为 56088
   
3. 将结果记录到记事本
   验证:确认记事本中已保存结果
   
4. 保存记事本文件为 calculation.txt
   验证:确认文件已成功保存
"""

实践三:错误处理指导

task = """
请打开邮箱客户端并发送一封邮件。

如果遇到以下情况,请按对应方式处理:
- 如果邮箱客户端未安装 → 报告"邮箱客户端未安装"并停止
- 如果需要登录 → 使用保存的凭据自动登录
- 如果网络连接失败 → 等待 30 秒后重试,最多重试 3 次
- 如果发送失败 → 截图记录错误信息并报告
"""

实践四:使用结构化指令

task = """
## 任务
在 Excel 中创建月度销售报表

## 步骤
1. 打开桌面上的 "sales_data.xlsx" 文件
2. 在 A1 单元格输入标题 "月度销售报表"
3. 在第 3 行创建表头:日期 | 产品 | 数量 | 金额
4. 从第 4 行开始填入数据
5. 在最后一行添加合计公式
6. 保存文件

## 约束
- 使用微软雅黑字体
- 标题字号 16,表头字号 12
- 金额列使用货币格式
- 合计行使用黄色背景

## 验证
完成后截图确认报表格式正确
"""

11.2 当前限制

限制 说明 影响
执行速度 每次操作需要截图-分析-执行循环 不适合高频实时操作
准确性 视觉识别可能存在误差 复杂 UI 可能误操作
成本 每次操作消耗 API Token 大规模任务成本较高
延迟 网络延迟 + 模型推理时间 单次操作 2-5 秒
复杂 UI 动态渲染、Canvas 等可能识别困难 特定应用兼容性问题
多显示器 多屏幕场景支持有限 需要额外配置
无障碍 依赖视觉,无法操作无界面程序 命令行任务需用 bash

11.3 常见问题排查

# 问题1:点击位置不准确
# 解决:检查屏幕分辨率设置是否匹配
agent = ComputerUseAgent(display_size=(1920, 1080))  # 确保与实际分辨率一致

# 问题2:操作后界面未更新
# 解决:增加等待时间
task = """
点击按钮后,等待 2 秒让页面加载完成,然后再截图确认结果。
"""

# 问题3:文字输入乱码
# 解决:使用 xdotool 的 --clearmodifiers 参数
# 或使用剪贴板粘贴方式输入

# 问题4:弹窗干扰
# 解决:在任务描述中加入弹窗处理逻辑
task = """
执行任务过程中,如果出现任何弹窗或对话框:
- 如果是更新提示 → 点击"稍后"或关闭
- 如果是权限请求 → 点击"允许"
- 如果是错误提示 → 截图并报告
"""

12. 总结

12.1 核心要点回顾

  1. Computer Use 的本质:通过视觉理解 + 操作执行实现真正的桌面自动化
  2. 三大核心工具:computer(鼠标键盘)、text_editor(文件编辑)、bash(命令行)
  3. Agent 循环:截图 → 分析 → 操作 → 验证的闭环
  4. 安全第一:必须建立完善的权限控制、操作审计和沙箱机制
  5. 混合方案:与传统自动化工具(Selenium/Playwright)结合使用效果最佳

12.2 适用场景推荐

场景 推荐度 说明
非结构化数据录入 ⭐⭐⭐⭐⭐ AI 理解能力强
跨应用工作流 ⭐⭐⭐⭐⭐ 不受应用限制
网页表单填写 ⭐⭐⭐⭐ 适合复杂表单
文件管理 ⭐⭐⭐⭐ 简单高效的替代方案
高频批量操作 ⭐⭐ 速度和成本限制
精确像素级操作 ⭐⭐ 视觉识别精度有限

12.3 快速开始清单

  • 安装 Python 依赖:pip install anthropic pillow
  • 配置 Anthropic API Key
  • 安装系统工具:xdotool(Linux)或 pyautogui(跨平台)
  • 运行第一个基础示例
  • 实现截图 → 分析 → 操作的完整循环
  • 添加安全防护层
  • 实现操作审计日志
  • 根据业务需求扩展功能

提示:本教程基于 Claude Computer Use 的公开文档和实践经验编写。由于技术持续迭代,具体 API 参数和功能请以 Anthropic 官方文档 为准。Computer Use 处于 Beta 阶段,生产环境使用请充分评估风险。

内容声明

本文内容为AI技术学习教程,仅供学习参考。如涉及技术问题,欢迎通过 xurj005@163.com 与我们交流。

目录