热榜全是 OpenClaw,但我用 50 行 Python 就造了个桌面 AI Agent 🤖

说真的,打开掘金看到热榜 6 条里 4 条是 OpenClaw,我心想:这玩意真有这么神?

下载试了一下------800MB 客户端、Electron 套壳、内存占用 1.2G 起步。就为了让 AI 帮我点点鼠标?

于是我花了一个下午,用 Python 写了个 50 行的"穷人版桌面 Agent"。核心原理其实很简单:截图 → 大模型看图理解 → 执行鼠标键盘操作 → 循环。跑起来之后我自己都没想到效果还不错。

先说结论

对比项 OpenClaw 自己搭(本文方案)
安装体积 800MB+ pip install 三个包
内存占用 1.2GB+ ~50MB
自定义程度 插件系统 代码随便改
模型选择 绑定特定模型 想用啥用啥
上手难度 开箱即用 需要会 Python
稳定性 成熟 自己兜底

如果你只是想理解桌面 Agent 的原理,或者有特定的自动化需求不想装个大家伙,往下看。

核心原理:截图-思考-行动 循环

所有桌面 Agent,不管是 OpenClaw 还是 Anthropic 的 Computer Use,核心都是一个 loop:

ini 复制代码
while True:
    screenshot = 截屏()
    action = 大模型看图分析(screenshot, "用户的指令")
    执行操作(action)  # 点击、输入、滚动...
    if action == "done":
        break

就这么简单。大模型的 Vision 能力负责"看懂屏幕",pyautogui 负责"动手操作"。

动手:50 行代码实现

环境准备

bash 复制代码
pip install pyautogui openai pillow

完整代码

python 复制代码
import pyautogui
import base64
import io
import json
from openai import OpenAI

# 初始化客户端(兼容 OpenAI 协议的接口都行)
client = OpenAI(
    api_key="your-api-key",
    base_url="https://api.ofox.ai/v1"  # 支持 50+ 模型的聚合接口
)

SYSTEM_PROMPT = """你是一个桌面操作助手。用户会给你一张屏幕截图和一个任务。
你需要分析截图,返回下一步操作。

返回 JSON 格式:
{"action": "click", "x": 100, "y": 200, "reason": "点击搜索框"}
{"action": "type", "text": "hello world", "reason": "输入搜索词"}
{"action": "scroll", "direction": "down", "reason": "向下滚动查看更多"}
{"action": "hotkey", "keys": ["command", "c"], "reason": "复制选中内容"}
{"action": "done", "reason": "任务完成"}

只返回 JSON,不要其他内容。"""

def screenshot_to_base64():
    """截屏并转为 base64"""
    img = pyautogui.screenshot()
    buffer = io.BytesIO()
    img.save(buffer, format="PNG")
    return base64.b64encode(buffer.getvalue()).decode()

def ask_model(image_b64, task, history=None):
    """让大模型看图决策"""
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if history:
        messages.extend(history)
    messages.append({
        "role": "user",
        "content": [
            {"type": "text", "text": f"任务:{task}\n请分析截图,返回下一步操作。"},
            {"type": "image_url", "image_url": {
                "url": f"data:image/png;base64,{image_b64}"
            }}
        ]
    })

    resp = client.chat.completions.create(
        model="anthropic/claude-sonnet-4-6",  # 也可以换 gpt-5.4、gemini-3-flash 等
        messages=messages,
        max_tokens=300,
        temperature=0
    )
    return json.loads(resp.choices[0].message.content)

def execute_action(action):
    """执行大模型返回的操作"""
    act = action["action"]
    if act == "click":
        pyautogui.click(action["x"], action["y"])
    elif act == "type":
        pyautogui.write(action["text"], interval=0.05)
    elif act == "scroll":
        pyautogui.scroll(-3 if action["direction"] == "down" else 3)
    elif act == "hotkey":
        pyautogui.hotkey(*action["keys"])
    elif act == "done":
        return False
    return True

def run_agent(task, max_steps=10):
    """主循环"""
    print(f"🤖 开始执行: {task}")
    history = []

    for step in range(max_steps):
        img_b64 = screenshot_to_base64()
        action = ask_model(img_b64, task, history)
        print(f"  Step {step+1}: {action.get('reason', '...')}")

        history.append({"role": "assistant", "content": json.dumps(action)})

        if not execute_action(action):
            print("✅ 任务完成!")
            return True

        pyautogui.sleep(1)  # 等 UI 响应

    print("⚠️ 达到最大步数,停止执行")
    return False

# 用法
if __name__ == "__main__":
    run_agent("打开浏览器,搜索今天的天气")

实测效果

我拿这个脚本试了几个场景:

场景 1:自动搜索

python 复制代码
run_agent("打开 Chrome,在百度搜索 Python 3.13 新特性")

执行过程:

vbnet 复制代码
🤖 开始执行: 打开 Chrome,在百度搜索 Python 3.13 新特性
  Step 1: 点击 Dock 栏的 Chrome 图标
  Step 2: 点击地址栏
  Step 3: 输入 baidu.com
  Step 4: 按回车键
  Step 5: 点击搜索框
  Step 6: 输入搜索词
  Step 7: 按回车执行搜索
✅ 任务完成!

7 步搞定,全程大概 15 秒(主要是等 API 返回)。

场景 2:文件整理

python 复制代码
run_agent("把桌面上所有 .tmp 文件拖到废纸篓")

这个任务模型理解得不错,但执行拖拽操作时翻车了------pyautogui 的 drag 在 macOS 上有些时候不太灵。后来换成 hotkey + delete 的方式才搞定。

场景 3:填表单

python 复制代码
run_agent("打开公司的 OA 系统,填写今天的日报,内容写'完成了桌面 Agent 的技术调研'")

这个效果最好,因为表单页面结构清晰,模型识别准确率很高。

踩坑记录

坑 1:分辨率问题

pyautogui 返回的坐标是逻辑像素,但 Retina 屏截图是物理像素。大模型看到的是 2x 分辨率的图,返回的坐标也是 2x 的。

python 复制代码
# 修复:截图时缩放到逻辑分辨率
def screenshot_to_base64():
    img = pyautogui.screenshot()
    # macOS Retina 需要缩放
    logical_size = (img.width // 2, img.height // 2)
    img = img.resize(logical_size)
    buffer = io.BytesIO()
    img.save(buffer, format="PNG")
    return base64.b64encode(buffer.getvalue()).decode()

坑 2:模型选择很关键

试了几个模型的表现:

模型 识别准确率 响应速度 适合场景
Claude Sonnet 4.6 ⭐⭐⭐⭐⭐ 1.5s 复杂页面
GPT-5.4 ⭐⭐⭐⭐⭐ 2s 通用场景
Gemini 3 Flash ⭐⭐⭐⭐ 0.8s 简单任务(快!)
Qwen-VL-Max ⭐⭐⭐ 1.2s 中文界面

我一般简单任务用 Gemini 3 Flash(便宜快),复杂任务用 Claude Sonnet。通过聚合 API 切换模型就改一行代码的事。

坑 3:JSON 解析失败

大模型偶尔会在 JSON 外面包一层 markdown 代码块,加个容错处理:

python 复制代码
import re

def parse_action(text):
    """容错解析 JSON"""
    # 去掉可能的 markdown 代码块标记
    text = re.sub(r'```json?\s*', '', text)
    text = re.sub(r'```\s*$', '', text)
    return json.loads(text.strip())

坑 4:安全防护必须加

pyautogui 有个 FAILSAFE 机制------鼠标移到屏幕左上角会触发异常停止。千万别关掉它:

python 复制代码
pyautogui.FAILSAFE = True  # 默认就是 True,别改成 False!

另外建议加个确认机制,敏感操作前先问一下:

python 复制代码
def execute_action(action):
    act = action["action"]
    # 危险操作确认
    if act == "hotkey" and "delete" in str(action.get("keys", [])):
        confirm = input(f"⚠️ 即将执行删除操作: {action['reason']},确认? (y/n) ")
        if confirm != 'y':
            return True  # 跳过这步
    # ... 其余执行逻辑

进阶:加上记忆和多轮对话

基础版只看当前截图,没有"记忆"。加上对话历史后,Agent 会聪明很多:

python 复制代码
def ask_model(image_b64, task, history=None):
    messages = [{"role": "system", "content": SYSTEM_PROMPT}]
    if history:
        # 只保留最近 5 轮,避免 token 爆炸
        messages.extend(history[-10:])
    # ... 其余逻辑不变

还可以加个"反思"机制------每次操作后截图对比,看有没有变化:

python 复制代码
def run_agent_with_reflection(task, max_steps=10):
    prev_img = None
    for step in range(max_steps):
        curr_img = screenshot_to_base64()
        if prev_img and curr_img == prev_img:
            print("⚠️ 屏幕没变化,可能操作没生效,重试...")
        # ...
        prev_img = curr_img

跟 OpenClaw 比到底差在哪

说实话,OpenClaw 之所以火是有道理的------它的 Skill 生态、权限管理、多 Agent 协作这些东西,50 行代码肯定搞不定。

但如果你的需求是:

  • 自动化一些固定流程(日报、数据抓取、定时截图)
  • 想深入理解桌面 Agent 原理
  • 不想装一个 800MB 的客户端
  • 需要自定义模型和 prompt

那自己搭完全够用。核心就是 pyautogui + Vision API,剩下的都是工程细节。

小结

桌面 Agent 说到底就是个"截图-看图-操作"的循环,原理一点不复杂。OpenClaw 的价值在于它把这个循环做得很工程化、很稳定,但底层逻辑跟我们这 50 行代码没本质区别。

我现在日常用这个脚本跑一些小任务------定时截图监控、自动填表单、批量文件操作。比起 OpenClaw 的全家桶,我更喜欢这种能完全掌控的方式。

代码已经贴全了,复制就能跑。如果你也想试试,建议从最简单的"打开浏览器搜索"开始,慢慢加功能。


对了,代码里 API 调用用的是兼容 OpenAI 协议的聚合接口,一个 key 能调几十个模型,切换模型改一行 model 参数就行,省得每家单独注册。

相关推荐
Hui Baby6 分钟前
MCP SSE协议发送注意
java
仙俊红12 分钟前
SpringBoot启动原理
java·spring boot·后端
星间都市山脉21 分钟前
Android STS(Security Test Suite)完整介绍与测试流程
android·java·linux·windows·ubuntu·android studio·androidx
namexingyun34 分钟前
拆解Fable 5三重安全护栏:模型路由、蒸馏防护与生物安全分类器的技术原理 - 微元算力(weytoken)
java·人工智能·python·安全·架构·ai编程
地铁潜行者44 分钟前
加了幂等表,为什么消息重试反而不执行了?聊聊 MQ 消费幂等的边界
java·后端
xiaofeichaichai1 小时前
ES 新特性九年速览:从 ES2016 到 ES2024
前端·javascript·es6
摇滚侠1 小时前
SpringMVC 入门到实战 视图解析器 44-48
java·spring·maven·intellij-idea
放下华子我只抽RuiKe51 小时前
FastAPI 全栈后端(四):认证与授权
开发语言·前端·javascript·python·深度学习·react.js·fastapi
記億揺晃着的那天2 小时前
告别误操作!Spring Boot 多环境配置隔离与启动守卫实战
java·spring boot·后端·环境隔离
我是唐青枫2 小时前
Java Spring Data JPA 实战指南:Repository 查询、分页与实体映射
java·开发语言