☰
免费AI编码代理实战:GUI操控与MCP协议驱动的单文件自动化工具
2026/10/6 6:06:09 网站建设 项目流程

这阵子把手头几个自动化脚本项目收尾之后,我做了一件惦记了很久的事:给自己写一个免费的 AI 编码代理工具。和市面上一堆编码代理不太一样,它除了能读代码、改代码、跑终端命令之外,还能直接操控 GUI——打开窗口、点击按钮、填写表单,并且原生支持 MCP 协议,能接入各种外部工具服务。最关键的是,整个程序只打包成一个单文件,扔到哪台机器都能直接跑,不需要配 Python 环境,也不需要装一堆依赖。

这个项目我从零开始写了大概十天,走了不少弯路,也踩了不少坑。之所以想把整个过程整理出来,是因为我发现很多人对 AI 编码代理的理解还停留在“对话式补全代码”的层面,根本没意识到它其实可以变成真正替你操作电脑的“自动化助手”。尤其是 GUI 操控加 MCP 这套组合,做完之后的实用价值超出我预期。如果你也在考虑自己做一个类似的工具,或者想给现有 Agent 加上 GUI 能力,这篇文章可以帮你少走很多弯路。

1. 项目起源与核心设计思路

1.1 从痛点出发:AI编码代理为何普遍“看不见”界面

目前主流的 AI 编码代理,基本都停留在“代码文件 + 终端命令”这两个维度。它们能帮你读取仓库内容、生成补丁、运行测试,但一旦遇到必须通过图形界面完成的任务就无能为力。我手头有个实际场景:帮客户维护一个老旧桌面应用,它的配置界面没有命令行替代方案,每次打包发布前都要手动点十几个按钮。代理商沟通的时候,对方问我能不能让 AI 帮我点这些按钮。

当时市面上没有合适的轮子。通用 RPA 工具太重,UI 自动化框架需要单独维护脚本,而我已经有了一个基于 LLM 的 Agent 框架,缺的只是“看得见屏幕、动得了鼠标键盘”的能力。于是这个项目的核心需求变得非常明确:做一个轻量的 AI 编码代理,在原有代码能力基础上,叠加 GUI 操控和 MCP 协议支持,让 AI 能真正操作外部软件、调用外部工具链。免费开源是我的一个自我要求,因为这本来就是为了解决个人效率问题做的东西,没必要商业化。

1.2 技术选型:GUI操控能力如何与MCP协议配合

项目命名叫“FreeCodingAgent”,本质上是一个多模态 Agent 壳子。GUI 操控我采用了“截图 + 视觉模型识别 + 坐标点击”的技术路线,而不是走 Windows UI Automation 或 macOS Accessibility 那套原生 API。主要原因有三个:跨平台一致性好,不管 Windows、macOS 还是 Linux,截图接口都是现成的;不依赖目标软件是否暴露 UI 元素树信息,老程序、非原生界面、远程桌面里的界面都能处理;视觉模型天然理解界面语义,不需要为每个软件单独写选择器。

MCP 协议这块,我参考官方 Python SDK 实现了一个轻量客户端,支持 stdio 和 SSE 两种传输方式。这样既能连接本地 MCP 服务器(比如文件系统、数据库工具),也能接入远程 MCP 服务。GUI 操控和 MCP 的配合逻辑是:GUI 负责“手动操作”,MCP 负责“读数据和写数据”。比如让 Agent 在 GUI 里填表格时,它可以通过 MCP 查询数据库拿到真实数据,再驱动鼠标键盘填进去。这个组合让 Agent 不再是个盲操作者。

1.3 为什么必须坚持“单文件运行”

项目立项时我就定了一个硬性指标:编译产物必须是一个独立可执行文件。用户拿压缩包解压后,得到一个文件,双击或者命令行一行启动,不依赖系统里预装 Python、Node.js 或 .NET 运行时。技术选型上,最终用了 Go 作为 Agent 主框架语言,GUI 操控层通过调用系统原生接口实现。Go 编译出的静态二进制天然满足单文件分发需求,交叉编译也很方便。

这个决策牺牲了一些开发效率。Go 生态里直接可用的 GUI 自动化库不如 Python 丰富,很多功能需要自己封装系统 API。但收益明显:实测在 2008 年的老笔记本上能直接跑,在 Windows Server 无桌面环境的最小化安装里也能运行(只要有图形会话),完全不用装任何依赖。对于需要分发到客户机器上的工具来说,单文件的运维成本几乎为零。

2. GUI操控与MCP接入的核心实现

2.1 GUI操控落地细节:从视觉识别到动作执行

GUI 操控链路拆开看就是四个环节:截屏、识别、定位、执行。

截屏我用了 Go 的kbinani/screenshot库,支持多显示器,返回原始 RGBA 数据。识别环节没有直接接云端多模态大模型,而是优先用本地的 OCR 加模板匹配做初筛,只有初筛置信度低于阈值时,才调用大模型接口做二次判断。这样做的原因是成本:日常自动化场景里,大部分按钮和输入框都可以靠 OCR + 图标模板匹配搞定,完全不需要大模型介入。实测下来,只有识别复杂表格、图表区域时才需要大模型出马。

定位环节有个关键细节——高 DPI 缩放。Windows 系统显示缩放设置为 125%、150% 时,截图坐标和真实鼠标坐标并不一致,两者的映射关系是屏幕物理分辨率与逻辑分辨率之比。如果忽略这一点,坐标偏移非常严重。我最终的方案是:截屏时获取逻辑分辨率W/H,执行鼠标点击时除以缩放因子映射到物理坐标。

坐标计算的伪代码大致是这样:

# 截图坐标到屏幕物理坐标的转换 scale_x = physical_width / logical_width scale_y = physical_height / logical_height # 假设视觉模型识别到图形界面元素中心点位于截图中的 (xs, ys) real_x = int(xs * scale_x) real_y = int(ys * scale_y) # 执行点击 mouse.move(real_x, real_y) mouse.click()

实际测试中,在 150% 缩放下,如果不做映射直接点击,偏差能达到几十像素,按钮多点不中。这个坑几乎每个做屏幕自动化的人都会遇到,建议读者直接抄这个映射公式。

2.2 MCP客户端实现的关键逻辑

MCP 协议本身是 JSON-RPC 2.0,基础交互就是客户端向服务器发送initialize请求,握手成功后通过tools/list拿到工具列表,再通过tools/call调用具体工具。我在 Go 里实现了一个最小客户端,核心结构体就几个:客户端会话、传输通道、工具注册表。

一个值得分享的细节是工具调用的流式输出处理。MCP 服务器返回结果时,可能一次性返回大 JSON 对象,也可能分多次返回小片段。为了让用户看到实时输出,我没有等整个响应体攒完,而是逐块解码并边写边显示。这个体验细节在终端里感知很明显——大模型生成代码时,如果一直黑屏等最终结果,用户会觉得卡死了。

MCP 客户端的核心调用流程简化如下:

func (c *Client) CallTool(ctx context.Context, name string, args map[string]interface{}) ([]byte, error) { // 构造 JSON-RPC 请求 req := JSONRPCRequest{ JSONRPC: "2.0", ID: atomic.AddInt64(&c.seq, 1), Method: "tools/call", Params: map[string]interface{}{ "name": name, "arguments": args, }, } // 发送请求 resp, err := c.transport.Send(ctx, req) if err != nil { return nil, err } // 返回结构化输出 return parseResponse(resp) }

2.3 单文件打包的技术路径与踩坑

单文件运行用 Go 是天然支持的,但真正落地时有几个容易翻车的地方。第一个是嵌入外部资源,比如内置的提示词模板、OCR 模型文件,这些我全部用 Go 的embed.FS编译进二进制,运行时不读取外部文件。

第二个坑是 Windows 下静态二进制的图标和版本信息。Go 默认生成的 exe 没有图标,点击右键看属性也没有版本详情,看起来像病毒文件。这个问题需要借助goversioninfo工具,在构建时生成.syso文件嵌入资源,这一步在自动化构建脚本里是必须的。

第三个坑是交叉编译。开发机是 macOS,但主要运行环境是 Windows。交叉编译 Windows 版时,凡是涉及 CGO 的库都要注意,GUI 操控层如果用了 Windows API,必须通过 syscall 方式调用,不能依赖 CGO。我最终把所有 Windows 专属调用封装在一个独立包中,通过 build tag 隔离平台代码。这样保证了GOOS=windows go build一步到位。

3. 实操全过程:从零构建一个可用的AI编码代理

3.1 环境准备与依赖清单

整个项目核心代码约 3500 行,依赖如下:

  • Go 1.22,用于 Agent 主框架和 MCP 客户端
  • gopkg.in/telebot.v4,用于 Telegram 机器人接口(没错,我做了一个 Telegram 远程控制入口)
  • kbinani/screenshot,用于跨平台截屏
  • moutend/go-windows和mousetrap,用于 Windows 鼠标键盘操控
  • joho/godotenv,用于读取环境变量配置

开发时用 Windows 11 真机做 GUI 测试,macOS 做交叉编译。建议读者如果是开发类似工具,一定准备两台机器或者虚拟机,因为 GUI 自动化非常依赖真实系统环境,纯容器里跑不起来的。

3.2 核心代码结构与实现思路

项目结构分为三层:Agent 调度层、工具执行层、硬件访问层。

Agent 调度层负责与大模型对话,把用户指令拆解为一系列工具调用;工具执行层实现了read_file、run_shell、click_ui、input_text、fetch_url等工具;硬件访问层封装鼠标、键盘和截屏操作。

其中最有意思的工具是click_ui,它接收两个参数:目标界面的文字描述和置信度阈值。内部流程是先截屏,再 OCR 定位候选区域,然后返回坐标并执行点击。这个工具可以让用户用自然语言指挥 Agent,比如“点击右上角的发布按钮”,Agent 自己判断按钮位置。

// 视觉定位工具的简化实现 func (a *Agent) ClickUI(target string, threshold float64) (bool, error) { // 1. 截取当前屏幕 img, err := screen.Capture() if err != nil { return false, err } // 2. OCR目标文字 regions := ocr.FindText(img, target) if len(regions) == 0 { return false, fmt.Errorf("目标元素未找到: %s", target) } // 3. 取置信度最高的中心点 best := regions[0] for _, r := range regions { if r.Score > best.Score { best = r } } if best.Score < threshold { return false, fmt.Errorf("置信度低于阈值: %.2f < %.2f", best.Score, threshold) } // 4. 坐标缩放并点击 realX, realY := scaleCoordinates(best.CenterX, best.CenterY) mouse.Click(realX, realY) return true, nil }

3.3 联调运行与效果验证

第一次完整跑通一个任务是让它打开记事本并输入一段文字。这条指令被拆解成三步:通过系统命令启动 notepad,等待窗口出现,然后输入文字。

这里等待窗口出现非常关键。新启动的 GUI 程序需要几百毫秒到几秒的加载时间,如果 Agent 马上去 OCR 截图,大概率找不到目标。我的方案是轮询检测:每 300 毫秒截一次屏,一旦 OCR 找到窗口标题栏文字就立刻执行下一步,最多超时 10 秒。这个简单策略避免了大量“窗口还没打开就点击”的竞态问题。

实测中,这个任务从输入指令到完成,耗时大约 5 秒,其中大部分时间花在 OCR 识别上。从用户体验来看,完全在可接受范围。

4. 常见问题与排查技巧实录

4.1 GUI坐标识别不准的四类典型场景

场景一:高 DPI 缩放导致偏移。这个问题前面提过,解决方法是用逻辑分辨率和物理分辨率的比例换算坐标。Windows 下可以通过系统 API 直接获取缩放因子,代码里做一个乘除法映射即可。

场景二:多显示器布局产生负坐标。副屏在主屏左边时,副屏控件坐标是负数。screenshot 库捕获多屏后返回的图片是全屏拼接,但 OCR 得到的是相对图片的坐标,必须再加上主屏偏移量才能得到真实屏幕坐标。这里最容易犯错,建议调试时先打印原始截图尺寸和坐标值,人工对比一次屏幕布局。

场景三:窗口被遮挡导致识别失败。目标窗口虽然在前台,但如果有弹窗、悬浮窗遮挡,OCR 识别文字的区域可能被破坏。我的处理是先尝试将目标窗口强制置前,用SetForegroundWindowAPI 把窗口带起来,再重新截图识别。

场景四:输入法状态干扰文本输入。在中文系统上直接通过事件注入输入英文字母时,如果当前输入法处于中文模式,字母会被替换成拼音候选。这个问题坑了很多做 RPA 的人。我的方案是统一使用SendInputAPI 并附加扫描码,绕过输入法直接发送原始按键。

4.2 MCP连接失败的排查顺序

接入 MCP 服务器时,最常见的问题按出现频率排,基本是这四类:服务器进程启动失败、JSON-RPC 握手失败、工具列表为空、调用超时。

我的排查经验是从底层往上查。比如本地 stdio 服务器启动失败,先用命令行手动启动一次,看有没有报错输出,很多 MCP 服务器需要指定环境变量。握手失败通常是协议版本不匹配,MCP 从 2024-12-31 到 2025-03-26 的版本有过不兼容更新,客户端必须用自己的版本号换取服务器协商。工具列表为空的常见原因是服务器配置了声明的工具但实际注册失败,超过一半是这个原因,要去服务器日志里找线索。

我把排查过程整理成了一张速查表:

错误现象可能原因排查动作
连接被拒绝stdio路径错误或端口不通手动启动服务器验证进程是否能正常运行
initialize失败协议版本不匹配检查客户端和服务端的支持版本
工具列表为空服务器内部工具注册异常查看服务器日志,确认工具初始化没有报错
调用超时工具执行时间长或网络延迟调大客户端超时时间到 30 秒以上
响应格式解析失败服务器返回了非JSON-RPC格式数据开启协议日志,比对原始字节流

这个表我打印出来贴在显示器边上,排查问题效率高很多,建议做同类项目的人直接照抄。

4.3 单文件跨机器运行的兼容性问题

单文件发布虽然省心,但跨机器跑的时候还是有几个问题值得警惕。

最典型的是目标机器缺少 Microsoft Visual C++ 运行库。如果 Go 代码用到需要 CGO 的库,编译出来的二进制会动态链接msvcp140.dll等文件,换一台新机器就报 0xc000007b 错误。解决办法是编译时强制CGO_ENABLED=0,确保静态链接。

另一个问题是杀毒软件误报。单文件 Go 程序频繁截图、模拟鼠标点击,行为特征确实接近远控木马,第一次编译完就收到 360 和 Defender 的报警。我是通过申请代码签名证书解决的,虽然有免费的自签名方案,但信任链依然不如商业签名靠谱。这个问题的用户体验影响很大,读者如果打算分发工具,建议预留签名证书的成本。

还有一个用户环境特有的问题:Windows 的锁屏状态。如果用户离开前按了Win+L,屏幕被锁定,截图全是黑的,鼠标点击也无效。我会在启动时检查会话状态,若锁屏则提醒用户先解锁,避免白白等待。

5. 实战效果回顾与后续演进方向

5.1 用真实任务刁难它:一组测试结果

为了检验项目可用性,我设计了三组测试任务,覆盖不同复杂度的场景:

第一组是“打开 Git 客户端,克隆一个仓库”。Agent 需要启动 GitKraken,等待界面加载,点击左上角“Clone”按钮,输入仓库地址,再点 Clone。整个过程消耗 20 秒,一次通过。这个任务验证了基础 GUI 操控链路。

第二组是“登录内部系统,从指定页面抓取表格数据,汇总成 Markdown 文件”。这个场景结合了 GUI 和 MCP。Agent 通过 MCP 读取数据库,拿到筛选条件,再通过 GUI 在网页上点击查询,最后截图识别表格内容生成 Markdown。总共耗了 90 秒,中间出现了两次识别不准,调用大模型重新判断后成功。

第三组是“扫描项目代码里的 TODO,按文件树导出报告”。这个任务纯代码,主要验证原有编码代理能力没有被 GUI 改造带崩,输出完全正常。

整体测试下来,最有价值的感受是:自由度和可靠性是矛盾的。纯 GUI 视觉识别解决不了复杂组件(如下拉菜单嵌套或右键菜单),这类操作必须手动写规则辅助;而 MCP 正好填补了“确定性获取数据”的缝隙。真正好用的 Agent 是让视觉当眼睛、键盘鼠标当手、MCP 当大脑的信息通道,三者协同而不是互相替代。

5.2 使用心得与后续规划

这里分享三个我个人的使用心得。

第一,别追求界面识别百分之百准确。日常自动化任务中,90% 以上的 GUI 操作其实都很固定,组合好 OCR、窗口置前、等待超时这老三样,已经能覆盖绝大多数场景。为了剩下 10% 增加复杂规则,性价比太低。

第二,MCP 工具要按“最小可用”原则设计。我最初写了 20 多个 MCP 工具,后来删减到 12 个,因为 tool 越多,大模型在意图识别时越容易选错。做 Agent 工具的人应该把工具边界做清晰,减少歧义。

第三,单文件发布的推广价值被低估了。产品咕咕一段时间没发,这次体验完成之后,我把编译产物发到几个工作群,结果因为“一个文件就能跑”这个特性,不少人主动问怎么获取源码。降低分发成本,有时候比功能本身更能带来用户。

后续的演进方向我主要有三个:一是增加语音输入入口,在操控 GUI 时直接说“点击确定”,Agent 就能执行,交互会更自然;二是给 MCP 客户端增加动态发现和权限管理功能,避免工具滥用;三是支持更细粒度的 GUI 操作,比如拖拽、方向键、组合快捷键,这些场景在自动化测试里很常见。

最后分享一个调试 GUI Agent 时的小技巧:环境变量里加一个DEBUG=1,让 Agent 每次点击前先在终端输出“即将点击坐标 (x,y) 对应的元素是XXX”,连续跑几次,就能轻松定位到底是识别错了,还是坐标映射错了。这个调试开关我大概加了两行代码,省下来的排查时间远超预期。如果你也在做类似工具,建议一上来就把这个钩子埋好。

需要专业的网站建设服务?

联系我们获取免费的网站建设咨询和方案报价,让我们帮助您实现业务目标

立即咨询