热榜全是 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 参数就行,省得每家单独注册。

相关推荐
Nyarlathotep01132 小时前
LinkedList源码分析
java·后端
用户8307196840822 小时前
Java 告别繁琐数据统计代码!MySQL 8 窗口函数真香
java·sql·mysql
前端Hardy3 小时前
别再忽略 Promise 拒绝了!你的 Node.js 服务正在“静默自杀”
前端·javascript·面试
前端Hardy3 小时前
别再被setTimeout闭包坑了!90% 的人都写错过这个经典循环
前端·javascript·vue.js
前端Hardy3 小时前
你的 Vue 组件正在偷偷吃掉内存!5 个常见的内存泄漏陷阱与修复方案
前端·javascript·面试
前端人类学3 小时前
深入解析JavaScript中的null与undefined:区别、用法及判断技巧
前端·javascript
带刺的坐椅3 小时前
SolonCode v0.0.20 发布 - 编程智能体(新增子代理和浏览器能力)
java·ai·agent·solon·solon-ai·claude-code·openclaw
会员源码网4 小时前
数字格式化陷阱:如何优雅处理 NumberFormatException
java
孔明click335 小时前
Sa-Token v1.45.0 发布 🚀,正式支持 Spring Boot 4、新增 Jackson3/Snack4 插件适配
java·sa-token·开源·springboot·登录·权限认证