跳到主内容
快讯直播
AI智模界
教程

小米蓝牙遥控器 2 Pro 做 vibe coding 快捷键手柄

用命令行智能体写代码时,真正消耗注意力的往往不是思考,而是反复出现的几个动作:接受改动、退回上一版、清空上下文重开、换个模型再试。这些动作每次都要把手从思路里抽出来,去找 Enter、Esc、Ctrl+C,或者敲一串斜杠命令。

这篇教程要做的东西很具体:把一只几十元的小米蓝牙遥控器 2 Pro 配对到电脑上,当成一个只有十来个按键的实体快捷键手柄。手边一按,动作就送到正在跑的智能体会话里。价格以购买渠道当前标价为准,不同时间会浮动。

做出来的效果长这样:左边终端里 Claude Code、Codex CLI 或 aider 正在跑,右边是编辑器。方案看着不错,拇指按下遥控器中间的 OK,等于回车,改动被接受;方案跑偏了,按返回键,等于连按两次 Esc 打开回滚;上下文已经脏了,按主页键,等于 Ctrl+C 之后输入 /new 再回车;想换个模型重问,按菜单键,等于输入 /model 再回车。中间不需要把视线移到键盘上。

整个过程不需要写驱动程序。遥控器在电脑眼里就是一只蓝牙键盘,你要做的只是把一个按键翻译成一个动作。

前置条件清单

  • 小米蓝牙遥控器 2 Pro 一只,装上电池,按键时指示灯有反应。
  • 一台带蓝牙的电脑。macOS、Windows、Linux 都可以走通;台式机没有蓝牙,插一个 USB 蓝牙适配器即可。
  • 一个已经能正常跑起来的命令行智能体,并且你知道它这几个动作对应什么:接受改动、回滚、开新会话、切换模型。不同工具的按键和斜杠命令不一样,以该工具官方文档的当前版本为准。
  • 平台对应的按键重映射工具:
  • macOS:Karabiner-Elements
  • Windows:AutoHotkey v2,也可以用 PowerToys 的 Keyboard Manager,但它按设备区分按键的能力有限
  • Linux:python-evdev 配合 wtype(Wayland)或 xdotool(X11)
  • 十来分钟不被打断的时间,以及一个可以随便按、按错了也无所谓的空白终端窗口。

步骤一:先弄清它在系统里是什么设备

遥控器出厂时一般已经绑在电视或盒子上。配对前先在原设备上解绑,或者把电视关机、把遥控器拿远,否则它会优先连回老设备。

进入配对模式通常靠长按某两个键,常见组合是同时长按主页键和返回键若干秒,直到指示灯快闪。不同批次可能不一样,以说明书或官方页面为准。然后打开系统蓝牙设置,找名字类似 Xiaomi Bluetooth Remote 2 Pro 的设备。

Linux 下用命令行更直观:

```bash

bluetoothctl

[bluetooth]# power on

[bluetooth]# agent on

[bluetooth]# scan on

此时让遥控器进入配对模式,等它出现在扫描列表里

[bluetooth]# pair XX:XX:XX:XX:XX:XX

[bluetooth]# trust XX:XX:XX:XX:XX:XX

[bluetooth]# connect XX:XX:XX:XX:XX:XX

```

trust 这一步别省,否则系统会在闲置后主动断开,下次按键没反应。

配对完确认它被识别成输入设备:

```bash

ls /dev/input/by-id/ | grep -i -E 'xiaomi|remote'

sudo libinput debug-events --show-keycodes

```

这时按几下遥控器。如果终端里刷出 KEY_ENTER、KEY_BACK、KEY_HOMEPAGE、KEY_VOLUMEUP 这类事件,说明它就是个标准输入设备,后面的思路全部成立。如果什么都不刷,先看是不是配对没连上,而不是急着写脚本。

步骤二:把每个键的真实键码抓出来

同一个型号、不同固件,按键上报的键码可能不一样。所以先做一次“学习”,别照抄别人的表。

Linux 下用一段最小的监听脚本:

```python

#!/usr/bin/env python3

依赖: pip install evdev

import evdev

from evdev import ecodes

HINT = "remote" # 换成 /dev/input/by-id 里看到的设备名片段

def find_device():

for path in evdev.list_devices():

dev = evdev.InputDevice(path)

if HINT.lower() in dev.name.lower():

return dev

raise SystemExit("没找到遥控器,先确认已配对并连接")

dev = find_device()

print("正在监听:", dev.name, dev.path)

for ev in dev.read_loop():

if ev.type == ecodes.EV_KEY and ev.value == 1: # 只打印按下

print(evdev.categorize(ev).keycode)

```

Windows 上打开 AutoHotkey 托盘菜单里的 Key history,逐个按键看扫描码和键名。macOS 上打开 Karabiner-Elements 的 Event Viewer,按一下看 key_code。

把结果记成一张表,左边是物理按键,右边是系统看到的键码。这张表是后面所有配置的依据。

步骤三:设计键位映射表

设计原则只有一条:优先用遥控器独有的键去触发“危险动作”,Enter 和 Esc 这类与键盘共用的键尽量少改,否则会连带影响正常打字。

遥控器按键动作发送到终端的内容备注
OK(方向键中间)接受当前改动 / 确认Enter与键盘回车同码,通常不用重映射
返回回滚上一轮Esc,Esc有的工具是 /rewind,按你的工具改
主页开新会话Ctrl+C,然后 /new 回车先中断再清空
菜单切换模型/model 回车换成你工具的模型命令
上 / 下翻历史、选候选Up / Down保持原样,不拦截
左 / 右切标签页Ctrl+Tab / Ctrl+Shift+Tab视终端而定
音量加对提示回答 yesy 回车适合一路确认的批处理场景
音量减中断当前生成Esc兼作“停一下”
语音键聚焦终端窗口无按键,只激活窗口语音本身多半用不了,见排错
电源键建议不映射—部分系统会当作休眠或关机

表里的斜杠命令只是占位。你的智能体用 /clear 还是 /new、用 /model 还是别的写法,以官方文档为准。如果工具支持自定义快捷键,更好的做法是在工具配置里把“接受”绑到一个冷门组合(比如 Ctrl+Y),映射层只负责发这个组合,语义更稳。

步骤四:写映射脚本

所有平台都要处理同一个坑:按键发生时,焦点不一定在终端上。所以每个“动作”都应该先激活终端窗口,再发按键。

macOS 用 Karabiner-Elements 做按键识别,用脚本做动作。先写一个动作脚本:

```bash

#!/usr/bin/env bash

保存为 ~/bin/agent-action,然后 chmod +x ~/bin/agent-action

set -euo pipefail

activate() {

osascript -e 'tell application "System Events" to set frontmost of (first process whose name is "Terminal") to true' || true

}

key() { osascript -e "tell application \"System Events\" to key code $1"; }

type_text() { osascript -e "tell application \"System Events\" to keystroke \"$1\""; }

case "${1:-}" in

accept) activate; key 36 ;; # Return

rollback) activate; key 53; key 53 ;; # Esc Esc

newsession) activate

osascript -e 'tell application "System Events" to key code 8 using control down'

sleep 0.3

type_text "/new"; key 36 ;;

model) activate; type_text "/model"; key 36 ;;

interrupt) activate; key 53 ;;

*) echo "用法: agent-action {accept|rollback|newsession|model|interrupt}"; exit 1 ;;

esac

```

然后在 Karabiner-Elements 的 Complex Modifications 里加规则,用 device_if 把规则限定在这只遥控器上,动作写成 shell_command:

```json

{

"description": "小米遥控器:返回键 -> 回滚",

"manipulators": [

{

"type": "basic",

"from": { "key_code": "escape", "modifiers": { "optional": ["any"] } },

"to": [ { "shell_command": "$HOME/bin/agent-action rollback" } ],

"conditions": [

{ "type": "device_if", "identifiers": [ { "vendor_id": 0, "product_id": 0 } ] }

]

}

]

}

```

vendor_id 和 product_id 不要照抄,从 Karabiner-Elements 的 Devices 面板里抄下遥控器那一行的实际数值。脚本要发按键,需要在系统设置里给终端和 osascript 开辅助功能权限。

Windows 用 AutoHotkey v2。先按步骤二查 Key history,确认遥控器各键在 AHK 里的键名,再写成这样:

```ahk

#Requires AutoHotkey v2.0

SendMode "Input"

SetKeyDelay 30, 30

ActivateTerm() {

if WinExist("ahk_exe WindowsTerminal.exe")

WinActivate

else if WinExist("ahk_exe powershell.exe")

WinActivate

}

Accept() {

ActivateTerm()

Send "{Enter}"

}

Rollback() {

ActivateTerm()

Send "{Esc}{Esc}"

}

NewSession() {

ActivateTerm()

Send "^c"

Sleep 300

SendText "/new"

Send "{Enter}"

}

SwitchModel() {

ActivateTerm()

SendText "/model"

Send "{Enter}"

}

; 下面的键名要换成你 Key history 里实际看到的名字

Browser_Home::NewSession()

AppsKey::SwitchModel()

Volume_Up::Accept()

Volume_Down::Rollback()

```

如果 Key history 显示某个键是扫描码形式,就改用 SC0xx:: 的写法,把 xx 换成实际值。注意 Enter 和 Esc 不要全局拦截,否则正常键盘也会被改写。

Linux 用 python-evdev 直接读事件,配合 grab() 独占设备,按键就不会再漏进终端:

```python

#!/usr/bin/env python3

依赖: pip install evdev;发按键需要 wtype(Wayland) 或 xdotool(X11)

import shutil, subprocess, time

import evdev

from evdev import ecodes

HINT = "remote"

DEBOUNCE = 0.25

def run(cmd):

subprocess.run(cmd, check=False)

def send_key(name):

if shutil.which("wtype"):

run(["wtype", "-k", name])

else:

run(["xdotool", "key", name])

def send_text(text):

if shutil.which("wtype"):

run(["wtype", "--", text])

else:

run(["xdotool", "type", "--", text])

def focus_terminal():

if shutil.which("wmctrl"):

run(["wmctrl", "-a", "Terminal"]) # 换成你终端窗口标题的一部分

ACTIONS = {

ecodes.KEY_ENTER: lambda: (focus_terminal(), send_key("Return")),

ecodes.KEY_BACK: lambda: (focus_terminal(), send_key("Escape"), send_key("Escape")),

ecodes.KEY_HOMEPAGE: lambda: (focus_terminal(), send_key("ctrl+c"), send_text("/new"), send_key("Return")),

ecodes.KEY_MENU: lambda: (focus_terminal(), send_text("/model"), send_key("Return")),

ecodes.KEY_VOLUMEUP: lambda: (focus_terminal(), send_key("Return")),

ecodes.KEY_VOLUMEDOWN: lambda: (focus_terminal(), send_key("Escape")),

}

def main():

dev = None

for path in evdev.list_devices():

d = evdev.InputDevice(path)

if HINT.lower() in d.name.lower():

dev = d

break

if dev is None:

raise SystemExit("没找到遥控器")

dev.grab() # 独占设备

last = {}

for ev in dev.read_loop():

if ev.type != ecodes.EV_KEY or ev.value != 1:

continue

action = ACTIONS.get(ev.code)

if action is None:

continue

now = time.monotonic()

if now - last.get(ev.code, 0) < DEBOUNCE:

continue

last[ev.code] = now

action()

if __name__ == "__main__":

main()

```

普通用户读 /dev/input/event* 需要权限,把账号加进 input 组,重新登录后生效:

```bash

sudo usermod -aG input "$USER"

```

步骤五:加三道保险

第一道是去抖。方向键长按会自动连发,脚本里必须做时间窗过滤,否则一次“返回”可能发出六次 Esc,直接翻过回滚菜单。

第二道是独占。Linux 的 grab()、Karabiner 的设备条件、AHK 里不拦截共用键,都是同一个意思:别让遥控器按键和键盘互相污染。

第三道是能随时退出。映射脚本在后台跑的时候,得有一个不依赖键盘的退出方式,比如关掉终端窗口、用系统托盘菜单退出,或者在脚本里加一条“长按音量减两秒就 exit”。遥控器的电源键不建议拿来当急停,部分系统会把它当成休眠键。

常见坑与排错

配对成功但按键没反应,或者过一会儿就断。 多数是没 trust,或者系统的蓝牙省电策略把设备关了。Windows 在设备管理器里找到这个蓝牙设备,取消“允许计算机关闭此设备以节约电源”;Linux 重新 trust 再 connect;必要时重启蓝牙服务。

遥控器死活连不上电脑,一直连回电视。 先把电视关机或把遥控器拿到另一个房间再配对。有些型号会记住最后一次连接的设备并主动回连。

系统弹出“键盘设置助理”或要求识别键盘布局。 直接关掉,不影响使用。系统把它当成了一把没有物理布局信息的小键盘。

同一个键按一次触发好几次。 去抖窗口没设,或者 D-pad 的自动连发被当成了多次独立按键。

改了 Enter 之后正常打字也乱了。 说明映射没有按设备区分。退回“只映射遥控器独有的键”这个策略,把 Enter、Esc 留给键盘。

按键发出去了,但打到了浏览器或者编辑器里。 动作里少了“先激活终端”这一步。窗口标题也要对得上,wmctrl -a "Terminal" 里的字符串要和实际标题匹配。

Linux 报权限不足。 没加 input 组,或者加完没重新登录。macOS 需要在隐私设置里给辅助功能权限。Windows 上如果目标终端是以管理员身份启动的,AHK 脚本也要用管理员权限运行。

语音键没反应,或者只发出一个普通按键。 语音走的是厂商私有链路,配对到电脑后一般不会传音频,最多上报一个普通键码。把它当“聚焦终端”这类辅助键用就行,别指望语音输入。

蓝牙延迟高、偶尔卡。 USB 3.0 接口对 2.4G 有干扰,把蓝牙适配器插到前面板,或者用一根延长线把它挪远。遥控器和电脑之间尽量别有金属遮挡。

重启后脚本找不到设备。 别把 /dev/input/eventN 写死,那个编号会变。按设备名匹配,或者用 /dev/input/by-id/ 下的稳定路径。

下一步建议

脚本跑通之后,值得补的几件事:

把脚本做成开机自启。Linux 写一个 systemd user service,macOS 用 launchd 或者登录项,Windows 把 AHK 脚本放进启动目录。这样插上电池就能用,不用每次手动起。

把键位从硬编码挪到配置文件。写一个 JSON,左边是键码,右边是动作名,改键位不用动代码。用得越久越会发现某些键位不合手,改配置比改脚本省事。

用“长按”扩展第二层动作。单按是高频动作,长按进低频动作,比如长按菜单键打开 git diff、长按主页键打开测试命令。这样十几个键能覆盖二十来个动作。

加一点声音反馈。遥控器本身没有屏幕,动作发出去有没有生效全靠终端画面。用 paplay 或 afplay 播一个极短的提示音,确认感会强很多。

最后,先用一周再决定要不要调。刚开始的键位设计往往和实际手感有差距,记录一下哪些键你从来没按过、哪些键老是按错,再按真实频率重排一次,比一开始就设计得很复杂更有效。

AI 生成本文由 AI 基于公开信息自动生成,仅供参考。