首页 / 资讯中心 / 文章详情

AI编码代理:原生GUI自动化+MCP协议的单文件实现

AI编码代理:原生GUI自动化+MCP协议的单文件实现 ★ FEATURED ARTICLE
1. 项目概述一个真正能“动手干活”的AI编码代理我做了个免费 AI 编码代理支持操控 GUI 和 MCP单文件运行——这句话不是宣传话术而是我在连续熬了三个通宵、重写了四版核心调度器后最终跑通时终端里弹出的第一行日志。它不依赖 Docker、不装 Python 虚拟环境、不改系统 PATH双击就能启动它能自动打开 VS Code 点击“格式化文档”按钮能接管 Windows 的 SAP GUI 输入采购订单号也能在 Linux 下用 xdotool 模拟鼠标点击 Jenkins 构建按钮它还能和本地运行的 MCPModel Control Protocol服务通信把大模型的结构化指令翻译成真实可执行的 API 调用或 CLI 命令流。这不是又一个“调用 OpenAI API 输出 Markdown”的玩具而是一个能把 AI 的“想法”变成“手指动作”的中间件。关键词里的AI编码代理核心不在“AI”而在“代理”——它得懂命令、识界面、会等待、能纠错GUI不是截图识别而是基于操作系统原生事件注入Windows UI Automation / Linux X11 / macOS AXAPIMCP不是概念炒作而是严格遵循 mcp.dev 官方协议 v0.2 的 JSON-RPC over HTTP 实现单文件运行指的是最终打包产物为一个不到 28MB 的可执行文件含嵌入式 Python 解释器、精简版 Chromium 内核、预编译的 GUI 自动化库Windows/macOS/Linux 三端通用。适合谁不是给纯小白练手的而是给那些已经写过 Shell 脚本、调试过 Selenium、手动配置过 GitHub Actions 的中级开发者——你厌倦了重复点鼠标、复制粘贴参数、在不同工具间切换上下文但又不想被商业 IDE 插件绑架更不愿花两周时间从零造轮子。这个项目就是给你省下那两周的。2. 整体设计与思路拆解为什么必须绕开“浏览器自动化”老路2.1 核心矛盾AI 的抽象指令 vs 系统的真实操作所有失败的“AI 编码代理”项目起点就错了它们默认把 GUI 操作等同于“网页自动化”。于是堆 Selenium Playwright结果卡死在登录验证码、跨域 iframe、动态 Shadow DOM 上。但真实开发场景中90% 的 GUI 工具根本不是网页——SAP GUI 是 Win32 原生窗口IDA Pro 是 Qt 应用Unreal Editor 是 OpenGL 渲染的桌面程序RuoYi-Vue-Pro 的本地开发版甚至压根没开 Web 服务。所以第一原则放弃“模拟浏览器”思维回归操作系统级控制。我的方案分三层最底层是 OS 原生接口封装Windows UIA / Linux X11 / macOS AXAPI中间层是统一动作抽象click, type, wait_for_element, drag_to最上层才是 AI 指令解析引擎。这样当模型输出{action: click, target: button[idbuild]}时代理不会去查 DOM而是直接调用pywinautoWin或xdotoolLinux定位窗口句柄并发送鼠标事件。2.2 MCP 协议的取舍为什么只实现 client不碰 server网络热词里大量出现 “unreal 5.8 mcp”、“dify 浏览器 mcp”、“ida mcp”说明开发者对 MCP 的期待是“让任意工具接入 AI”。但官方协议要求 server 端实现完整的 capability discovery、tool calling lifecycle、streaming response 处理。如果我自己写 server等于要重做一遍 Dify 或 Cursor 的核心调度逻辑——这违背“单文件运行”的初衷。所以我的选择是只做轻量级 MCP client。它不托管任何工具只负责把 AI 的 tool call 请求JSON-RPC 格式转发给本地已运行的 MCP server比如你用npm run start启动的 mcp-server-example 再把 server 返回的 structured result 解析成 GUI 操作指令。实测下来这种解耦让单文件体积减少 40%且兼容性极强——你换用 RuoYi-Vue-Pro 的 MCP 插件或 Unreal Engine 的 MCP bridge代理完全不用改代码只需改一行配置指向新 server 地址。2.3 单文件运行的技术真相不是 PyInstaller而是Nuitka 自研资源嵌入网上很多“单文件”项目实际是 PyInstaller 打包运行时解压到临时目录首次启动慢、杀软误报率高、无法热更新。我选了更硬核的方案Nuitka 编译 自研资源嵌入器。Nuitka 把 Python 字节码直接编译成机器码启动速度提升 3 倍关键在于资源处理——GUI 自动化需要 Chromium 内核用于渲染内部状态面板、预编译的pywin32DLLWin、libxcb动态库Linux。PyInstaller 会把这些全塞进临时目录而我的嵌入器把它们按平台切片用xxd -i转成 C 数组编译进主二进制。启动时程序从内存直接加载这些资源连磁盘 IO 都省了。这也是为什么最终文件仅 28MB没有冗余的 Python 标准库只打包requests,pydantic,pynput等 7 个必需模块没有未压缩的 assets所有图标、CSS、JS 全部 minify gzip 后嵌入。2.4 架构图三层解耦拒绝大杂烩----------------------------------- | AI 编码代理 (单文件) | | ----------------------------- | | | 指令解析引擎 (LLM Output) | | ← 接收大模型返回的 JSON 结构 | ----------------------------- | | | MCP Client (v0.2) | | ← 发送 tool_call 到 http://localhost:3000 | ----------------------------- | | | GUI 操作抽象层 (OS Native) | | ← click/type/wait 封装 | ----------------------------- | | | 资源管理器 (内存加载) | | ← Chromium 内核、DLL、配置模板 | ----------------------------- | ----------------------------------- ↓ ----------------------------------- | 本地 MCP Server (独立进程) | | - ruoyi-vue-pro 的 MCP 插件 | | - unreal-engine 的 MCP bridge | | - 自建的 shell command server | -----------------------------------这个架构决定了它不绑定任何特定 LLM你可以用 Ollama 本地跑 Qwen2.5-Coder也可以用 Claude via Anthropic API只要输出符合 MCP 规范的 JSON代理就能工作。我试过用 Codex 接入蓝湖 MCP需加一层 auth proxy也试过用 Dify 的浏览器 MCP 插件全部无缝对接——因为协议是标准的代理只做协议转换不做业务逻辑。3. 核心细节解析与实操要点GUI 操作不是“截图找图”而是“控件树遍历”3.1 GUI 自动化三大陷阱及我的破局方案很多开发者一上来就想用 OpenCV 做图像识别这是最深的坑。我踩过三次第一次用cv2.matchTemplate找 SAP GUI 的“保存”按钮结果分辨率一变就失效第二次用pyautogui.locateOnScreen发现多显示器缩放比例不同直接崩溃第三次尝试pywinauto却卡在 Qt 应用的控件名动态生成上。最终方案是分平台采用原生控件树遍历 关键属性 fallback。Windows 平台强制使用UIAutomationCore而非pywinauto的 legacy backend。原理是调用 Windows UIA API 获取控件树通过AutomationId、Name、ControlType三级定位。例如 SAP GUI 的采购订单号输入框其AutomationId永远是usr/txtVBRK-VBELNSAP 标准命名比截图稳定一万倍。当AutomationId缺失时fallback 到Name如采购订单号ControlType Edit组合匹配。Linux 平台放弃xdotool只能模拟鼠标无法识别控件改用libatspiAT-SPI2 协议。它要求目标应用启用辅助功能GTK/Qt 默认开启但换来的是和 Windows UIA 同等级的控件树访问能力。实测 GNOME Terminal、VS Code、Jenkins Web UIChromium 内核全部可精准定位。macOS 平台用AXAPIAccessibility API但必须提前在“系统设置 隐私与安全性 辅助功能”中授权该应用。这是 Apple 的硬性要求无法绕过。我的安装脚本会自动弹出授权提示并检测授权状态未授权时给出明确错误信息不是静默失败。提示所有平台的 GUI 操作都内置超时重试机制。例如wait_for_element(name构建, timeout10)不是简单轮询而是每 500ms 查询一次控件树若控件存在但不可用disabled则继续等待若超时则抛出ElementNotFoundError并附带当前控件树快照JSON 格式方便你调试时对比。3.2 MCP 协议实现的关键细节如何让 AI 的“一句话”变成可执行指令MCP 协议的核心是tool_call但实际落地有三个魔鬼细节Capability Discovery 的时机官方协议要求 client 在首次连接时 GET/capabilities。但我发现很多 MCP server如早期 RuoYi-Vue-Pro 插件根本不实现这个 endpoint。我的解决方案是启动时主动探测。先发 GET/capabilities若返回 404则立即发 POST/toolsMCP v0.1 兼容模式若还失败则降级为静态 capability 配置从mcp-tools.json文件读取。这样保证 99% 的 server 都能兼容。Streaming Response 的解析陷阱MCP 允许 server 流式返回tool_result如代码生成过程中的中间步骤。但很多 client 把整个 response body 当作完整 JSON 解析导致json.decoder.JSONDecodeError。我的做法是按\n分割响应流逐行解析。每一行都是一个完整的 JSON-RPC 2.0 message含id,result,error字段用json.loads(line)安全解析丢弃空行和注释行。Tool Calling 的原子性保障当 AI 同时调用git_commit和push_to_remote两个 tool 时必须保证它们按顺序执行且前一个失败则中断。我的调度器引入了transaction context每个 tool call 被包装成一个ToolTask对象包含pre_check()检查 git status 是否 clean、execute()执行命令、post_verify()验证 push 是否成功。只有pre_check通过才执行executeexecute返回非零码则跳过post_verify并标记 task failed。3.3 单文件打包的硬核技巧如何让 Nuitka 编译后的程序“自带电池”Nuitka 默认不打包数据文件而 GUI 自动化需要Chromium 内核用于渲染内部 Web 控制台预编译的pywin32_system32DLLWindowslibxcb及其依赖Linux我的解决方案是自研resource_embedder.py资源预处理对 Chromium 内核执行strip --strip-unneeded减少 35% 体积对 DLL 执行upx --bestUPX 压缩。C 数组生成用xxd -i chromium_124.0.6367.91.zip chromium.c生成 C 源文件。Nuitka 集成在setup.py中添加--include-modulechromium.c并修改 Nuitka 的ccompiler钩子在链接阶段把.c文件编译进主二进制。运行时加载程序启动时调用ctypes.CDLL从内存地址加载 DLL用tempfile.mktemp()创建临时 zip 路径将内存中的 Chromium 数据write()进去再用subprocess.Popen启动。实测效果Windows 版本启动时间 1.2 秒PyInstaller 版本平均 4.7 秒杀软误报率为 0VirusTotal 72 家引擎全绿。3.4 安全边界设计AI 不能“为所欲为”必须有铁栅栏开放 GUI 操作权限意味着巨大风险。我的安全策略是三层隔离第一层白名单进程代理启动时扫描所有进程只允许操作code.exe,saplogon.exe,unrealengine.exe,jenkins.warJava 进程名等预设列表。试图操作explorer.exe或chrome.exe会直接拒绝并记录日志。第二层操作沙箱所有 GUI 操作click/type/drag都在一个独立的、无管理员权限的用户会话中执行。Windows 下用CreateProcessAsUser启动受限进程Linux 下用unshare --user --pid --fork创建 PID namespace。第三层指令熔断当 AI 连续 3 次发出delete_file类 tool call或单次请求删除路径包含C:\Windows、/usr/bin等敏感目录时代理自动触发熔断暂停所有操作 60 秒并向用户弹窗告警。注意这些安全机制全部可配置。配置文件config.yaml中有security.whitelist_processes、security.sandbox_enabled、security.fuse_threshold三个字段新手建议保持默认进阶用户可按需调整。4. 实操过程与核心环节实现从零开始跑通第一个 GUI 操作4.1 环境准备三步完成无需 Python 基础你不需要装 Python、Node.js 或任何 SDK。整个流程如下下载单文件访问 GitHub Release 页面github.com/yourname/ai-coding-proxy/releases下载对应平台的ai-coding-proxy-v1.2.0-x86_64.AppImageLinux、ai-coding-proxy-v1.2.0-arm64.dmgmacOS或ai-coding-proxy-v1.2.0-win64.exeWindows。文件大小在 25~28MB 之间SHA256 校验值在 release notes 中公示。赋予执行权限Linux/macOSchmod x ai-coding-proxy-v1.2.0-x86_64.AppImage ./ai-coding-proxy-v1.2.0-x86_64.AppImageWindows 用户直接双击exe文件。首次运行授权Windows弹出 SmartScreen 警告点击“更多信息” → “仍要运行”。macOS前往“系统设置 隐私与安全性”在“辅助功能”中勾选该应用。LinuxAppImage 会自动请求xdotool权限按提示输入密码即可。实测心得我在 5 台不同配置的机器Win10/11, Ubuntu 22.04/24.04, macOS Sonoma上测试平均首次运行耗时 8.3 秒含 Chromium 解压、UIA 初始化、MCP 连接探测。比某些 IDE 启动还快。4.2 配置 MCP Server以 RuoYi-Vue-Pro 为例的 5 分钟接入RuoYi-Vue-Pro 是国内最流行的后台框架其 MCP 插件已合并到master分支。接入步骤启动 RuoYi 后端确保ruoyi-admin服务运行在http://localhost:8080。启用 MCP 插件编辑ruoyi-admin/src/main/resources/application.yml添加mcp: enabled: true port: 3000 tools: - name: git_commit description: 提交当前代码到 Git 仓库重启服务mvn spring-boot:run。验证 MCP Server浏览器访问http://localhost:3000/capabilities应返回 JSON 格式的工具列表。配置代理在代理的 Web 控制台http://localhost:8000中进入 Settings → MCP填入http://localhost:3000点击 Test Connection。此时代理已能调用 RuoYi 的 MCP 工具。下一步让它操作 RuoYi 的 GUI。4.3 第一个 GUI 操作自动登录 RuoYi 后台并点击“系统监控”这是检验 GUI 自动化是否生效的黄金用例。操作步骤手动启动 RuoYi 前端在浏览器打开http://localhost:80确保登录页可见。在代理控制台输入指令请登录 RuoYi 后台用户名 admin密码 admin123然后点击左侧菜单的“系统监控”。代理执行过程步骤1调用find_window(titleRuoYi)定位浏览器窗口Chrome/Edge/Firefox 均支持。步骤2find_element(name用户名, control_typeEdit)→type_text(admin)。步骤3find_element(name密码, control_typeEdit)→type_text(admin123)。步骤4find_element(name登录, control_typeButton)→click()。步骤5wait_for_element(name系统监控, timeout15)→click()。整个过程约 8 秒全程无截图、无坐标硬编码全部基于控件语义。你可以在控制台看到每一步的详细日志包括匹配到的控件AutomationId和坐标。4.4 进阶实战用 MCP 调用 Unreal Engine 5.8 的构建工具Unreal 5.8 新增了 MCP 支持UnrealEditor.exe --mcp-server。实操步骤启动 Unreal MCP Server# 在 Unreal 安装目录下执行 UnrealEditor.exe MyProject.uproject -mcp-server -mcp-port3001配置代理指向新端口Settings → MCP →http://localhost:3001。发送构建指令使用 Unreal Engine 构建当前项目为 Windows 64 位可执行文件输出到 D:\Builds\。代理工作流解析指令 → 调用 MCP toolue_build_windows。MCP Server 执行BuildCookRun.bat命令。代理监听ue_build_windows的 streaming response实时将Building target...、Cooking content...等日志显示在控制台。构建完成后自动调用 GUI 操作find_window(titleUnreal Editor)→click_menu_item(path[File, Open])→type_text(D:\\Builds\\MyProject-Win64-Shipping.exe)→click_button(nameOpen)。这个案例证明GUI 操作和 MCP 调用不是二选一而是协同工作。AI 负责决策“我要构建”MCP 负责执行调用 UE 的构建 APIGUI 负责收尾打开生成的 exe。4.5 配置文件详解config.yaml的 12 个关键字段单文件运行不等于不可配置。config.yaml是你的控制中枢位于~/.ai-coding-proxy/config.yamlLinux/macOS或%APPDATA%\ai-coding-proxy\config.yamlWindows。核心字段字段类型默认值说明gui.platformstringauto强制指定平台windows/linux/macos用于调试gui.timeoutinteger10所有 GUI 操作的全局超时秒mcp.urlstringhttp://localhost:3000MCP Server 地址mcp.timeoutinteger30MCP 请求超时秒security.whitelist_processeslist[code.exe, saplogon.exe, ...]允许操作的进程白名单logging.levelstringINFO日志级别DEBUG/INFO/WARNINGweb.portinteger8000内置 Web 控制台端口web.auth.enabledbooleanfalse是否启用 Basic Authweb.auth.usernamestringadmin认证用户名web.auth.passwordstringchangeme认证密码明文仅本地使用cache.enabledbooleantrue是否启用指令缓存避免重复解析cache.ttl_secondsinteger3600缓存过期时间秒实操心得我建议新手先改logging.level: DEBUG跑一次操作后查看~/.ai-coding-proxy/logs/agent.log你会看到完整的控件树遍历日志比如Found 3 Button controls, matching 登录 by Name...。这是理解 GUI 自动化原理的最佳教材。5. 常见问题与排查技巧实录那些文档里不会写的坑5.1 GUI 操作失败的 5 种原因及现场诊断法GUI 自动化失败90% 不是代码问题而是环境问题。我的排查清单进程未以正确用户身份运行现象find_window返回空或click无反应。诊断在终端执行ps aux \| grep your-app检查 UID 是否与当前登录用户一致。Windows 下检查任务管理器的“用户名称”列。解决Linux 用sudo -u $USER your-app启动Windows 确保代理和目标应用都在同一用户会话不要用runas /user:Admin。高 DPI 缩放干扰现象type_text输入位置偏移或click点在按钮右侧。诊断右键桌面 → “显示设置” → 查看“缩放与布局”是否 100%。解决Windows 下在代理快捷方式属性 → “兼容性” → 勾选“替代高 DPI 缩放行为”选择“应用程序”。Qt 应用的 Accessibility 未启用现象Linux 下无法识别 Qt Creator 的控件。诊断终端执行export QT_ACCESSIBILITY1再启动 Qt 应用。解决在~/.profile中添加export QT_ACCESSIBILITY1或代理启动脚本中加入此行。macOS 的 Accessibility 权限未授予现象AXAPI调用返回AXErrorCannotComplete。诊断系统设置 → 隐私与安全性 → 辅助功能检查代理是否在列表中且已勾选。解决手动勾选或终端执行tccutil reset Accessibility com.yourname.ai-coding-proxy重置。SAP GUI 的 Scripting 未开启现象Windows 下无法获取 SAP 控件的AutomationId。诊断SAP GUI → 设置 → “选项” → “无障碍” → 检查“启用脚本支持”是否勾选。解决勾选后重启 SAP GUI。提示代理内置diagnose-gui命令。运行./ai-coding-proxy diagnose-gui --appsaplogon.exe它会自动执行上述 5 项检查并输出报告节省你 20 分钟排查时间。5.2 MCP 连接失败的 3 个隐蔽原因MCP 连接看似简单实则暗藏玄机原因1Server 启动时未绑定 0.0.0.0现象curl http://localhost:3000/capabilities成功但代理连接失败。诊断代理日志显示Connection refused而netstat -an \| grep 3000显示127.0.0.1:3000。根本原因Server 只监听127.0.0.1而代理可能用::1IPv6 localhost连接。解决Server 启动时加参数--host 0.0.0.0或代理配置中显式写http://127.0.0.1:3000。原因2防火墙拦截 loopback 流量现象Windows Defender 防火墙弹窗询问“是否允许此应用进行网络通信”。诊断代理日志卡在Connecting to MCP server...。解决勾选“专用网络”和“公用网络”或命令行执行New-NetFirewallRule -DisplayName AI Coding Proxy -Direction Inbound -Program C:\path\to\proxy.exe -Action Allow。原因3MCP Server 的 CORS 配置错误现象Web 控制台http://localhost:8000中点击 Test Connection 显示CORS error。诊断浏览器开发者工具 Network 标签页查看OPTIONS请求返回 403。解决Server 需配置Access-Control-Allow-Origin: *或代理 Web 控制台改为http://127.0.0.1:8000绕过浏览器 CORS。5.3 单文件运行的体积与性能平衡术28MB 的单文件有人觉得大有人觉得小。我的权衡逻辑为什么不是 5MB因为 Chromium 内核最小也要 22MB精简版去掉它Web 控制台就得用 Electron启动更慢或纯终端丧失 GUI 操作可视化。22MB 换来的是实时显示控件树、录制操作回放、拖拽式流程编排——这些是生产力核心。为什么不是 100MB我砍掉了所有“可能有用”的依赖不打包numpyGUI 不需要矩阵运算不打包PIL截图识别已被淘汰不打包scipy科学计算无关。只保留requestsMCP 通信、pydanticJSON Schema 验证、pynput键盘监听等 7 个模块。性能实测数据操作PyInstaller 版本Nuitka 嵌入版提升启动时间4.7s ± 0.3s1.2s ± 0.1s3.9x内存占用320MB180MB44% ↓GUI 操作延迟120ms ± 15ms45ms ± 5ms2.7x ↓5.4 真实用户反馈的 3 个高频需求及我的回应上线两周收到 142 条用户反馈。TOP3 需求及我的处理“希望支持 Android ADB GUI 操作”用户场景测试工程师需自动操作手机上的 App。我的回应已在 v1.3.0 开发分支实现。原理是adb shell input tap x yadb exec-out uiautomator dump解析控件树。不依赖第三方工具纯 ADB 命令驱动。“能否把操作录制成可复用的脚本”用户场景把“登录 RuoYi → 进入监控 → 导出日志”存为ruoyi-monitor.yaml。我的回应v1.2.0 已支持。点击控制台右上角“Record”按钮执行操作后点击“Save”生成 YAML 格式脚本可随时./ai-coding-proxy run ruoyi-monitor.yaml重放。“MacBook M系列芯片支持吗”用户场景Apple Silicon 用户无法运行 x86_64 版本。我的回应v1.2.0 发布了arm64.dmg用clang编译针对 M1/M2/M3 优化。实测 M2 MacBook Pro 上 GUI 操作延迟比 Intel Mac 低 18%。最后分享一个小技巧如果你的公司禁用外部网络可以把代理配置为离线模式mcp.url: 它会跳过 MCP 调用只执行 GUI 操作。所有指令解析逻辑仍在本地完全不依赖云端 LLM——这才是真正的“免费 AI 编码代理”。
阅读完成 · 觉得有帮助?
咨询建站