ARTICLE · INTELLIGENCE

战地情报 · 详情页

来自尧图项目组的一线实战观察与深度解析

Python实现按键精灵(一)录制脚本:用TaoToken统一Key打通AI辅助生成录制配置

Python实现按键精灵(一)录制脚本:用TaoToken统一Key打通AI辅助生成录制配置 1. 从一次重复点击说起Python 按键精灵录制脚本要解决什么如果你每天要在某个客户端里重复点几十次同样的按钮、拖几次同样的窗口、按几遍同样的快捷键那“按键精灵”这个词大概率已经在你脑子里转过好几圈了。用 Python 做按键精灵核心就两件事先把人的操作录下来再让程序按录下来的轨迹回放。这一篇聚焦第一步——录制脚本。录制脚本听起来玄乎拆开看其实很朴素监听鼠标的移动、点击、滚轮监听键盘的按下与释放把每个事件带上时间戳写进文件。回放时按时间戳依次重放就还原了操作。Python 里做这件事pynput负责监听pywin32负责精确控制光标和窗口toml负责存配置组合起来就是一个最小可用的录制器。这篇适合谁会一点 Python 基础、想给自己或团队做自动化重复键鼠操作的开发者也适合刚接触pynput、被“监听器一开就卡死主线程”劝退过的朋友。我会先给一份能直接跑的录制脚本骨架再给config.toml配置示例然后演示怎么用 TaoToken 的统一 Key 把 AI 工具接进来辅助生成和补全录制逻辑最后给出运行验证和录制回放测试的具体动作。全程可复制踩过的坑我也会标出来。2. 前置准备TaoToken 统一 Key 与录制环境2.1 为什么录制脚本阶段就要接 AI 工具录制脚本本身不复杂但写起来琐碎事件回调要处理时间戳格式、要过滤高频移动事件、要决定存 JSON 还是 TOML、回放时坐标要不要做屏幕缩放适配。这些细节每次都要查文档。我的做法是把 AI 工具接进编码流程让它帮我补全回调函数、生成配置模板、解释报错。问题是不同 AI 工具的 Key 和接口地址各不相同切来切去很烦。TaoToken 在这里的作用是统一 Key 与 API 通道一个 Key 走一个兼容接口模型对话、编码辅助、Agent 类工具都能接。对录制脚本这种“边写边问”的场景省掉的是反复配置环境的时间。官网入口在 https://taotoken.net/?utm_sourcetaotoken_aicg_blog_endutm_mediumcsdnutm_campaignrewriteutm_content API 基址是 https://taotoken.net/api 这个地址不加 UTM 参数。2.2 环境与依赖Python 建议 3.9 以上。依赖装这几个pip install pynput pywin32 tomlpynput跨平台监听键鼠pywin32只在 Windows 上用负责SetCursorPos这类精确控制toml读写配置。如果你在 macOS 或 Linux 上跑pywin32那段换成对应平台的库即可录制监听部分pynput是通用的。注意监听全局键鼠在部分系统上需要辅助功能权限第一次运行如果没反应先去系统设置里给终端或 IDE 授权。2.3 拿 Key 与接入文档到控制台创建 API Key入口是 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。创建后复制保存后面配置里会用到。接入方式、请求格式、可用模型看文档 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。如果你主要用命令行里的编码助手Coding Plan 页面有对应说明 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。3. 可复制配置config.toml 与录制脚本骨架3.1 config.toml 配置示例先建一个config.toml把录制参数和 AI 通道都放进去脚本读它就行[record] output_file record.json log_file record.log # 鼠标移动事件采样间隔秒太小会录出海量点 move_sample_interval 0.05 # 是否录制键盘 record_keyboard true # 是否录制滚轮 record_scroll true [replay] # 回放速度倍率1.0 为原速 speed 1.0 # 坐标缩放适配不同分辨率 scale_x 1.0 scale_y 1.0 [ai] base_url https://taotoken.net/api api_key 你的_TaoToken_Key model claude-3-5-sonnetmove_sample_interval是关键参数。鼠标移动事件触发极频繁全录下来文件会爆炸回放也卡。按时间间隔采样既保留轨迹又控制体积。3.2 录制脚本骨架下面这份骨架可以直接跑录鼠标移动、点击、滚轮和键盘import json import time import toml from datetime import datetime from pynput import mouse, keyboard cfg toml.load(config.toml) events [] last_move_ts 0.0 start_ts time.time() def now_str(): return datetime.now().strftime(%Y-%m-%d %H:%M:%S.%f)[:-3] def on_move(x, y): global last_move_ts t time.time() - start_ts if t - last_move_ts cfg[record][move_sample_interval]: return last_move_ts t events.append({type: move, t: round(t, 4), x: x, y: y}) def on_click(x, y, button, pressed): t time.time() - start_ts events.append({ type: click, t: round(t, 4), x: x, y: y, button: button.name, pressed: pressed }) def on_scroll(x, y, dx, dy): t time.time() - start_ts events.append({ type: scroll, t: round(t, 4), x: x, y: y, dx: dx, dy: dy }) def on_press(key): if not cfg[record][record_keyboard]: return t time.time() - start_ts try: k key.char except AttributeError: k str(key) events.append({type: key_press, t: round(t, 4), key: k}) def on_release(key): if not cfg[record][record_keyboard]: return t time.time() - start_ts try: k key.char except AttributeError: k str(key) events.append({type: key_release, t: round(t, 4), key: k}) if key keyboard.Key.esc: return False def save(): with open(cfg[record][output_file], w, encodingutf-8) as f: json.dump(events, f, ensure_asciiFalse, indent2) print(f已保存 {len(events)} 个事件到 {cfg[record][output_file]}) if __name__ __main__: print(开始录制按 Esc 结束...) m_listener mouse.Listener( on_moveon_move, on_clickon_click, on_scrollon_scroll) k_listener keyboard.Listener(on_presson_press, on_releaseon_release) m_listener.start() k_listener.start() k_listener.join() m_listener.stop() save()几个设计点说明。start_ts记录录制起点所有事件时间都是相对时间回放时不用关心绝对时钟。on_move里做采样过滤避免高频事件淹没文件。按Esc结束录制on_release返回False让键盘监听器退出主线程join返回后停掉鼠标监听并落盘。3.3 用 TaoToken 辅助生成与补全写这类脚本时我常让 AI 帮我做三件事补全回放函数、把 JSON 转成更易读的格式、解释pynput的报错。接入方式就是上面config.toml里的[ai]段。下面是一个调用示例把当前录制的事件摘要发给模型让它生成回放骨架import requests import toml cfg toml.load(config.toml)[ai] def ask_ai(prompt): resp requests.post( f{cfg[base_url]}/v1/messages, headers{ x-api-key: cfg[api_key], anthropic-version: 2023-06-01, content-type: application/json, }, json{ model: cfg[model], max_tokens: 1024, messages: [{role: user, content: prompt}], }, timeout60, ) resp.raise_for_status() return resp.json()[content][0][text] if __name__ __main__: prompt 我有一个鼠标键盘事件列表字段为 type/t/x/y/button/pressed/key请生成一个按时间戳回放的 Python 函数骨架使用 pywin32 控制鼠标。 print(ask_ai(prompt))这段代码把base_url指向 TaoToken 的 API 通道Key 用统一的那一个。模型对话也可以直接在网页端试 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你更习惯在编辑器里用编码助手Coding Plan 那条通道更适合长期用 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。4. 验证请求与成功结果4.1 先验证 AI 通道通不通在跑录制脚本前先确认 Key 和通道没问题。用上面的ask_ai发一句简单请求print(ask_ai(回复通道正常))预期返回一段文本说明 Key、地址、模型都对。如果返回 401检查 Key 是否复制完整返回 404检查base_url是否写成了https://taotoken.net/api而不是带/v1的完整路径具体路径以文档为准。4.2 运行录制脚本python recorder.py终端打印“开始录制按 Esc 结束...”。这时做几个动作把鼠标从屏幕左上移到中间点一下滚一下滚轮按几个键最后按Esc。脚本退出后会打印类似已保存 47 个事件到 record.json打开record.json应该看到结构化的数组每条带type、t和坐标或按键信息。t是递增的move事件数量明显少于你实际移动的次数——说明采样过滤生效了。4.3 录制回放测试动作光录不够得验证能回放。写一个最小回放函数import json import time import win32api def replay(path, speed1.0): with open(path, encodingutf-8) as f: events json.load(f) t0 time.time() for e in events: target e[t] / speed wait target - (time.time() - t0) if wait 0: time.sleep(wait) if e[type] move: win32api.SetCursorPos([e[x], e[y]]) elif e[type] click and e[pressed]: win32api.SetCursorPos([e[x], e[y]]) # 这里按 button 调 mouse_event略 print(回放完成) replay(record.json)测试动作录一段“移动→点击→移动→点击”的简单操作回放时观察光标是否按原轨迹走、点击位置是否一致。如果轨迹对但点击没触发检查button字段的映射如果整体偏慢调speed倍率。5. 本篇常见错排查监听器一开主线程就卡住。这是最常见的。pynput的Listener如果直接with ... as listener: listener.join()会阻塞主线程。正确做法是start()后让主线程做别的事或者像骨架里那样用键盘监听join作为退出条件。别在监听回调里做耗时操作回调要轻。鼠标移动事件太多文件几百 MB。没做采样过滤。move_sample_interval设成 0.03 到 0.08 秒之间比较合适太小没意义太大轨迹会失真。也可以只在坐标变化超过阈值时才记录。pywin32导入报错或SetCursorPos无效。确认是 Windows 环境且装了pywin32。多显示器或高 DPI 缩放下GetCursorPos拿到的坐标和SetCursorPos设置的坐标可能不在同一坐标系需要在脚本开头调用SetProcessDpiAwareness声明 DPI 感知。键盘监听拿不到字符key.char抛AttributeError。特殊键Shift、Ctrl、方向键没有char属性用str(key)兜底骨架里已经处理。如果连普通字母都拿不到检查系统辅助功能权限。AI 请求返回 401 或超时。401 多半是 Key 没带对检查请求头字段名是否和文档一致超时把timeout调大或换模型试。别把 Key 硬编码进提交到仓库的脚本里用环境变量或本地config.toml并加进.gitignore。回放时坐标全偏。录制和回放的屏幕分辨率或缩放不同。在config.toml里用scale_x、scale_y做换算或者录制时同时存下屏幕尺寸回放时按比例映射。6. 下一步把录制和 AI 辅助串成工作流录制脚本跑通后你手里就有了一份带时间戳的事件流。接下来可以做的事很多把record.json转成可编辑的步骤列表、给关键步骤加注释、用 AI 把重复片段抽成函数、甚至让模型根据事件流反推“用户意图”生成更语义化的脚本。这些都需要一个稳定的 AI 通道TaoToken 的统一 Key 在这里的价值就是不用为每个工具单独配环境。如果你主要做模型对话式的辅助生成从模型对话入口进 https://taotoken.net/models?utm_sourcetaotoken_aicg_blog_endutm_contentmodelsutm_campaignrewrite 。如果你要把录制、回放、AI 补全做成长期跑的编码/Agent 流程Coding Plan 更合适 https://taotoken.net/coding-plan?utm_sourcetaotoken_aicg_blog_endutm_contentcoding_planutm_campaignrewrite 。Key 管理和新建在控制台 https://taotoken.net/console/api-keys?utm_sourcetaotoken_aicg_blog_endutm_contentapi_keysutm_campaignrewrite 。接口细节和参数以文档为准 https://taotoken.net/doc?utm_sourcetaotoken_aicg_blog_endutm_contentdocutm_campaignrewrite 。下一篇会讲回放阶段的坐标适配和异常处理把这份录制骨架补成一个能稳定跑重复任务的完整按键精灵。
RELATED READING

延伸阅读

更多一线实战笔记与深度复盘,助您持续精进