1. 项目概述为什么我们需要一个本地的AI自动化助手如果你尝试过用Claude的Computer Use功能或者任何依赖云端截图的AI助手来自动化Windows桌面操作那你一定对那2-4秒的等待时间印象深刻。想象一下你让AI帮你填写一个表单它每点一个输入框、每输入一个字符都要先花几秒钟“看看”屏幕——这种延迟感就像是用远程桌面操作一台远在另一个星球的电脑体验非常割裂。这正是eyehands诞生的初衷它把截图、点击、输入这些最基础的交互从云端拉回了你的本地机器将一次截图的时间从秒级压缩到了毫秒级实测57毫秒让AI代理的“思考-行动”循环变得真正流畅。eyehands本质上是一个运行在你Windows电脑上的本地HTTP服务器。它接管了屏幕捕捉和输入模拟这两大核心任务并通过一套简洁的API包括一个方便的Python SDK暴露给外部的AI模型或自动化脚本。这意味着你可以继续使用你喜欢的任何AI模型无论是OpenAI的GPT、Anthropic的Claude还是本地的Llama只需让它们通过HTTP请求来“指挥”eyehands操作你的电脑就能实现高速、精准的桌面自动化。它的核心价值在于极致的速度和完全的本地化。所有屏幕数据都留在你的机器上只有你明确发送给AI模型的指令和截图才会离开本地这在处理敏感信息时是一个巨大的优势。这个工具非常适合以下几类人AI应用开发者正在构建需要与GUI交互的智能体效率追求者或RPA机器人流程自动化工程师希望用更现代、可编程的方式替代传统的自动化工具以及任何被云端自动化延迟所困扰的用户。它不是一个要取代所有现有方案的全能神器而是一把专门为解决“速度”和“隐私”痛点而打造的精密手术刀。2. 核心设计思路速度与可靠性的工程取舍eyehands的设计哲学非常明确在Windows平台上为AI自动化提供最快、最可靠的底层操作接口。为了实现“57毫秒截图”这个目标它在架构上做了几个关键抉择这些抉择也定义了它的能力边界和适用场景。2.1 分层捕获策略不把鸡蛋放在一个篮子里最体现工程思维的是其屏幕捕获策略。它没有死磕某一种截图技术而是实现了一个智能的后端选择器。启动时它会按顺序尝试三种捕获方案BetterCam (DXGI)首选方案。直接通过DirectX图形接口抓取这是Windows上最快的方式理想情况下帧率可达120fps以上。这需要较新的系统和显卡驱动支持。DXcam备选方案。同样基于DXGI但可能通过不同的封装库实现作为BetterCam不可用时的降级选择性能依然可观~39fps。mss (GDI)保底方案。使用传统的Windows GDI接口。这是最通用、兼容性最好的方式但速度最慢是确保在任何Windows机器上都能跑起来的最后保障。这种“性能优先兼容保底”的分层策略确保了工具在绝大多数机器上都能以最佳性能运行同时避免了因单一技术依赖而导致的启动失败。它在后台以一个独立的线程持续运行以大约20fps的速率将截图存入一个环形缓冲区。当AI代理请求截图时它无需临时启动捕获过程而是直接从缓冲区中取出最新的一帧这是实现低延迟的关键。2.2 输入模拟的“正道”SendInput API在鼠标键盘控制上eyehands选择了正确的底层API——SendInput。这一点至关重要很多Python自动化库如早期版本的某些工具为了简单使用的是已被微软标记为“废弃”的keybd_event和mouse_eventAPI。这些旧API在现代应用特别是那些使用“指针锁定”技术的应用如全屏游戏、Parsec远程桌面、某些全屏浏览器中会完全失效——你的点击指令会被系统静默忽略。eyehands通过Python的ctypes直接调用SendInput将输入事件注入到Windows的原始输入管道中。这模拟了真实硬件输入的行为因此能被几乎所有应用程序识别包括那些对输入源非常挑剔的游戏和全屏应用。这是其宣称支持“Games / pointer-lock”的底气所在。2.3 功能模块化核心轻量按需加载为了保持核心可执行文件那个单独的eyehands.exe小巧且启动迅速项目采用了模块化设计核心引擎包含高速截图、输入控制和HTTP服务器打包成一个约10MB的独立exe开箱即用。OCR功能基于EasyOCR和PyTorch这是一个强大的开源OCR引擎但模型文件较大。因此OCR被设计为可选功能。首次调用/find端点时需要加载约2GB的模型耗时约8秒。之后OCR结果会与截图帧进行哈希关联并缓存。只要屏幕内容没变对同一文本的重复查找就是瞬间完成的。UI自动化集成了Windows原生的UI Automation框架。这允许AI代理通过控件的名称、类型等属性来定位元素例如“点击那个叫‘保存’的按钮”而不是去猜测像素坐标大大提升了自动化的健壮性和可读性。这种设计让你可以根据需要权衡。如果你只需要快速的点击和截图直接使用exe即可。如果需要文本识别或更智能的元素查找再额外安装Python依赖。3. 从零开始部署与基础使用详解让我们抛开理论直接上手。使用eyehands的入门过程简单得令人惊讶。3.1 获取与运行首先从项目官网fireal.dev/eyehands/或 GitHub Releases 页面下载适用于Windows的.zip压缩包。解压后你会看到一个名为eyehands.exe的文件。不需要安装不需要管理员权限除非你要操作某些需要提权的应用直接双击运行它。一个命令行窗口将会弹出这是eyehands服务器。你会看到类似下面的输出eyehands v1.2.0 HTTP server listening on http://localhost:7331 License: Trial (6 days remaining) Auth token: abc123def456... (saved to .eyehands-token)这表示服务已经启动并在本地的7331端口上监听。同时它生成了一个用于API认证的令牌Token。这个令牌会自动保存到当前目录下的.eyehands-token文件中后续的SDK调用会自动读取它。注意首次运行会有7天的免费试用期。试用期结束后需要购买49美元的一次性许可证每台机器一个才能继续使用。这是一个非常开发者友好的定价策略没有订阅制。3.2 使用HTTP API进行最原始的交互服务器启动后你就可以用任何能发送HTTP请求的工具来测试它。最直接的就是使用curl命令。获取屏幕截图curl http://localhost:7331/screenshot --output screen.jpg执行后当前目录下就会生成一个screen.jpg文件这就是你整个桌面的实时截图。整个过程通常在100毫秒内完成。模拟鼠标点击curl -X POST http://localhost:7331/click_at \ -H Content-Type: application/json \ -H Authorization: Bearer YOUR_TOKEN_HERE \ -d {\x\:500, \y\:300}这条命令会让鼠标移动到屏幕坐标(500, 300)的位置以左上角为原点并执行一次左键点击。记得将YOUR_TOKEN_HERE替换为启动时控制台显示的那个令牌。3.3 使用Python SDK进行高效开发对于大多数开发者来说使用Python SDK是更优雅的方式。首先安装SDKpip install eyehands-sdk然后你可以编写如下脚本from eyehands import EyehandsClient import time # 初始化客户端它会自动从 .eyehands-token 文件读取令牌 client EyehandsClient() # 1. 截图并保存 start time.time() client.screenshot(current_screen.jpg) print(f截图耗时: {(time.time() - start)*1000:.1f}ms) # 通常会打印出 ~57ms # 2. 点击记事本窗口的某个位置假设你知道坐标 client.click_at(100, 150) # 3. 输入文字 - 注意这是模拟真实键盘输入而非粘贴 client.type_text(Hello from eyehands! This is typed, not pasted.) # 4. 执行一批操作原子化更快 actions [ {type: move_absolute, x: 500, y: 500}, {type: click, button: left}, {type: type_text, text: Batch operation}, {type: key, vk: enter} # 模拟按下回车键 ] client.batch(actions)Python SDK封装了所有HTTP端点提供了更符合Python习惯的同步/异步接口并且自动处理了认证和错误重试极大地提升了开发效率。4. 高级功能与集成赋能AI智能体基础操作只是开始eyehands真正强大的地方在于它与现代AI开发栈的无缝集成以及提供的高级感知能力。4.1 与AI框架集成让LLM拥有“手和眼”eyehands的HTTP API设计使其能与任何AI框架集成。项目官方提供了针对流行框架的集成工具。OpenAI Function Calling / Tools 这是目前最流行的AI智能体构建模式之一。eyehands提供了开箱即用的工具定义。from openai import OpenAI from eyehands.openai_tools import tools, dispatch client EyehandsClient() openai_client OpenAI(api_keyyour-key) # 将eyehands的工具描述添加到OpenAI的请求中 response openai_client.chat.completions.create( modelgpt-4, messages[{role: user, content: 帮我打开记事本并输入今天的日期。}], toolstools, # 注入eyehands的工具集 tool_choiceauto ) # 解析AI的响应并自动执行对应的eyehands操作 if response.choices[0].message.tool_calls: for tool_call in response.choices[0].message.tool_calls: # dispatch函数会自动将AI的调用映射到client的具体方法 result dispatch(client, tool_call) print(f执行 {tool_call.function.name} 结果: {result})通过这种方式你可以直接告诉GPT“点击保存按钮”或“在搜索框里输入XXX”AI会理解这些工具并生成正确的调用参数你的代码则负责执行。MCP (Model Context Protocol) 集成 对于使用Claude Code、Cursor或支持MCP的编辑器你可以安装MCP服务器让AI在编写代码时就能直接控制你的电脑进行测试或演示。pip install eyehands-sdk[mcp] # 然后在你的MCP配置文件中添加eyehands服务器安装后你的AI编程助手就能在编辑器内直接调用截图、点击等操作实现“所见即所得”的交互式编程。4.2 超越像素OCR与UI自动化依赖固定坐标的自动化是脆弱的。窗口位置一变脚本就失效了。eyehands提供了两种更鲁棒的定位方式。OCR文本搜索 当你需要点击一个按钮但只知道按钮上的文字时OCR功能就派上用场了。# 首先确保已安装EasyOCR: pip install easyocr torch torchvision from eyehands import EyehandsClient client EyehandsClient() # 在屏幕上寻找“保存”两个字 result client.find(保存) if result: print(f找到文本在坐标: ({result[x]}, {result[y]})) # 直接点击找到的文字中心 client.click_at(result[x], result[y]) else: print(未找到文本)首次调用find会较慢因为要加载OCR模型。之后对同一帧画面的搜索是即时的。UI Automation元素查找 这是Windows提供的原生无障碍接口能获取到窗口控件的深层信息是最稳定的定位方式。# 查找所有名为“确定”的按钮 elements client.ui_find(name确定, control_typeButton) for elem in elements: print(f按钮: {elem[name]}, 坐标: {elem[rect]}) # 可以直接通过元素ID点击不依赖坐标 client.ui_click_element(elem[id]) # 获取当前光标下的元素 element_at_cursor client.ui_at(*client.cursor_pos()) print(f光标下元素: {element_at_cursor[name]} ({element_at_cursor[control_type]}))UI Automation可以让你像前端操作DOM一样操作桌面应用彻底告别“像素狩猎”。4.3 浏览器扩展获取与Claude同品质的截图你可能注意到Claude Computer Use在浏览器里截图的清晰度非常高。这是因为浏览器扩展可以绕过操作系统层面的限制直接捕获浏览器渲染的内容。eyehands也提供了一个浏览器扩展让你能获得同等质量的截图。确保eyehands服务器正在运行。在浏览器中打开http://localhost:7331/ext/setup。页面会提供详细的指引教你如何加载这个开发者扩展Chrome/Edge或安装临时扩展。安装完成后当你使用/ext/screenshot端点时eyehands会优先通过浏览器扩展获取截图。如果扩展未启用则自动回退到原生的屏幕捕获方式。这个功能对于自动化Web应用特别有用能确保截取到的是完整的、高分辨率的网页内容即使网页有滚动或复杂布局。5. 实战场景与避坑指南理论说再多不如看实战。下面通过几个典型场景展示eyehands如何解决问题并分享一些我踩过坑后总结的经验。5.1 场景一自动化每日数据报表下载与整理需求每天上午10点登录内部数据平台筛选昨日数据导出Excel报表并保存到指定文件夹。传统脚本痛点使用pyautogui依赖固定坐标平台UI一更新就失效使用selenium只能操作浏览器无法处理后续的文件保存、重命名等系统对话框。eyehands解决方案import schedule import time from eyehands import EyehandsClient from datetime import datetime, timedelta client EyehandsClient() def daily_report(): # 1. 打开浏览器并导航这里假设浏览器已在固定位置打开或使用系统命令打开 client.click_at(100, 50) # 点击浏览器地址栏 client.type_text(https://internal-data-platform.com) client.key(enter) time.sleep(3) # 等待页面加载 # 2. 使用OCR登录避免硬编码密码输入框坐标 # 查找用户名输入框旁的“Username:”标签然后偏移点击 user_label client.find(Username:) if user_label: client.click_at(user_label[x] 100, user_label[y]) # 点击标签右侧区域 client.type_text(my_username) # 同理处理密码和登录按钮 client.find_and_click(Password:) client.type_text(my_password) client.find_and_click(Login) time.sleep(2) # 3. 使用UI Automation更可靠地操作日期选择器 # 假设日期控件是一个ComboBox date_elements client.ui_find(control_typeComboBox, name_containsDate) if date_elements: client.ui_click_element(date_elements[0][id]) # 输入昨日日期 yesterday (datetime.now() - timedelta(days1)).strftime(%Y-%m-%d) client.type_text(yesterday) client.key(enter) # 4. 点击导出按钮 client.find_and_click(Export Report) # 5. 处理系统“文件保存”对话框 - 这是pyautogui等工具的难点 time.sleep(1) # 等待对话框弹出 # 使用UI Automation找到对话框的保存按钮 save_dialog_buttons client.ui_find(control_typeWindow, name另存为) # 或 Save As if save_dialog_buttons: # 在对话框内查找“文件名”输入框和“保存”按钮 # 这里需要更精细的UI树遍历但原理相通 client.type_text(fC:\\Reports\\report_{yesterday}.xlsx) client.find_and_click_in_window(save_dialog_buttons[0][id], 保存) print(f[{datetime.now()}] 报表下载完成。) # 每天10点执行 schedule.every().day.at(10:00).do(daily_report) while True: schedule.run_pending() time.sleep(60)避坑心得混合定位策略不要只依赖一种定位方式。结合使用坐标用于固定位置的元素如开始菜单、OCR用于已知文本的按钮和UI Automation用于复杂的标准控件。UI Automation是最稳定的。等待的艺术在关键操作如点击后页面跳转、对话框弹出后一定要加time.sleep或更智能的等待如等待某个元素出现。eyehands提供了/click_and_wait端点它会在点击后持续截图直到屏幕画面发生变化基于图像哈希才返回这比固定等待时间更可靠。处理系统对话框这是桌面自动化的一个难点。eyehands的UI Automation能力在这里是王牌因为它能识别系统标准对话框的控件。多花时间研究目标对话框的UI树结构。5.2 场景二为本地LLM构建图形界面自动化测试工具需求你开发了一个本地运行的LLM聊天应用想测试其在不同用户操作下的响应。eyehands解决方案 你可以编写一个测试脚本利用eyehands模拟用户操作同时用/latest_b64端点实时获取屏幕的base64编码图像送入你的视觉LLM如GPT-4V、LLaVA进行分析形成闭环。import base64 import json from eyehands import EyehandsClient import your_llm_vision_client # 假设这是你的视觉LLM客户端 client EyehandsClient() llm_client your_llm_vision_client.LLMClient() def test_chat_flow(): # 启动被测应用 # client.click_at(...) 或使用系统命令 # ... test_steps [ 找到输入框并输入‘你好’, 点击发送按钮, 等待回复出现后截图并分析回复内容是否正确, 再输入‘你是谁’并发送 ] for step in test_steps: print(f执行步骤: {step}) # 1. 将当前步骤和屏幕截图送给LLM让它决定操作 screenshot_data client.screenshot_b64() # 获取base64格式截图 llm_response llm_client.analyze( imagescreenshot_data, promptf当前桌面状态如上。下一步需要{step}。请返回一个JSON包含action和参数例如 {{\action\: \click_at\, \args\: {{\x\: 100, \y\: 200}}}} 或 {{\action\: \type_text\, \args\: {{\text\: \Hello\}}}} ) # 2. 解析并执行LLM返回的操作 action_cmd json.loads(llm_response) func getattr(client, action_cmd[action]) func(**action_cmd[args]) # 3. 短暂等待操作生效 time.sleep(0.5) print(测试流程执行完毕。) # 可以集成到pytest等单元测试框架中避坑心得给LLM清晰的上下文在提示词中明确屏幕的坐标体系原点在左上角单位是像素并限制LLM的输出格式为固定的JSON schema便于解析。降低频率提高成功率不要试图让AI连续执行太快。每个操作后留出足够的时间让界面响应。eyehands的/click_and_wait端点在这里非常有用。备用方案对于关键断言如“检查回复是否包含某关键词”除了让视觉LLM判断最好结合/findOCR功能进行双重验证更可靠。5.3 性能调优与常见问题排查即使工具强大使用不当也会遇到问题。以下是一些常见情况的排查清单问题现象可能原因解决方案截图速度远慢于57ms1. 使用了mss (GDI)后备方案。2. 屏幕分辨率过高。1. 检查启动日志确认是否使用了BetterCam/DXcam。更新显卡驱动可能有助于启用DXGI。2. 考虑在代码中请求缩放后的截图如/screenshot?scale0.5。点击/输入在某些应用如游戏中无效应用使用了指针锁定或直接输入模式。确保eyehands使用的是SendInput默认就是。以管理员身份运行eyehands.exe有时能解决权限问题。对于全屏独占应用可能需要在窗口化模式下运行。OCR (/find) 首次调用极慢正在加载EasyOCR模型。这是正常现象首次加载约需8秒和2GB内存。可以考虑在程序初始化时预先调用一次简单的find来“预热”模型。ui_find找不到元素1. 目标应用不是标准Win32/WPF/UWP应用如Qt自定义绘制。2. 元素在非活跃窗口或最小化。1. 对于非标准应用回退到OCR或图像识别方案。2. 确保目标窗口在前台。UI Automation只能遍历当前活动的窗口树。浏览器扩展截图失败扩展未安装、未启用或连接断开。访问http://localhost:7331/ext/status查看状态。按照/ext/setup页面重新安装或加载扩展。确保浏览器允许该扩展访问“所有网站”或“本地主机”。许可证错误试用期已过或许可证无效。购买许可证后使用POST /activate端点或运行eyehands.exe --activate YOUR_KEY激活。性能调优建议批量操作尽可能使用/batch端点。将一系列鼠标移动、点击、输入组合成一个请求发送比逐个发送HTTP请求快一个数量级因为减少了网络往返开销。合理使用缓存如果你的AI代理需要反复分析同一帧画面例如在等待某个元素出现时轮询使用/latest或/latest_b64端点。它们返回的是后台缓冲区的最新帧几乎无延迟且不会触发新的截图操作。分辨率权衡传递给AI模型的截图不需要是原生4K分辨率。你可以在请求截图时添加scale参数如/screenshot?scale0.5来获取缩小后的图片这能大幅减少传输给云端AI的数据量降低成本并提升速度。6. 生态对比与选型思考eyehands并非唯一选择。理解它与其他工具的差异能帮助你在正确的地方使用它。vs. Claude Computer Use 这是最直接的对比。Claude Computer Use的最大优势是开箱即用、跨平台、安全功能完善如应用掩码。它适合快速原型、教学或一次性任务。而eyehands的核心优势是速度和本地控制。如果你的智能体需要高频、低延迟地与桌面交互或者你对数据隐私有严格要求eyehands是更优选择。事实上你可以两者结合用Computer Use进行“教学录制”生成初始脚本然后用eyehands来高速、本地化地执行。vs. PyAutoGUI / PyGetWindow / pynput 这些是Python生态中流行的本地自动化库。它们免费、开源、跨平台部分功能。eyehands相比它们的优势在于架构eyehands是独立的HTTP服务可与任何编程语言Go, Rust, Node.js的AI智能体交互而PyAutoGUI等必须和Python脚本绑在一起。性能eyehands的多后端截图策略和后台缓冲通常能提供更稳定、更快的截图速度。输入可靠性如前所述eyehands坚持使用SendInput对游戏和全屏应用兼容性更好。高级功能内置了OCR和UI Automation无需自己再组合pytesseract、pywinauto等库。vs. 专业RPA工具如UiPath, Automation Anywhere 这些是企业级、图形化、功能全面的RPA平台。eyehands则是一个轻量级、代码优先、开发者友好的工具。它更适合被集成到自定义的AI应用或脚本中而不是用于构建庞大的、由非技术人员维护的自动化流程。eyehands更像是一个给AI用的“低级驱动”而专业RPA工具是完整的“操作系统”。选型总结选eyehands当你构建需要与桌面高频、低延迟交互的AI智能体追求极致速度和本地隐私且主要环境是Windows。选 Claude Computer Use当你需要零配置、跨平台的解决方案或者主要进行教学、演示和一次性任务。选 PyAutoGUI 等开源库当你的项目预算有限且自动化逻辑相对简单或者需要跨平台支持Linux/Mac。选专业RPA工具当你在企业环境中需要图形化开发、大规模部署、流程管理和审计等功能。我个人在实际项目中的体会是eyehands填补了一个非常具体的空白为AI原生应用提供工业级、低延迟的“手眼”协调能力。它不是一个面向最终用户的工具而是一个面向开发者的强大组件。49美元的一次性费用对于需要将AI智能体能力从“纯聊天”扩展到“可操作现实数字界面”的开发者来说是一笔非常划算的投资它能省去你大量组合、调试不同底层库的时间并直接带来体验上的质变。最后一个小技巧在开发调试时一定要打开http://localhost:7331/view这个页面它会提供一个实时刷新的屏幕叠加视图让你清晰地看到AI智能体“眼中”的屏幕是什么样子以及它点击的位置这对于调试自动化逻辑至关重要。