
1. 项目缘起当AI助手成为“黑盒”我们需要一个状态指示器最近几个月Claude Code 这款AI编程助手彻底改变了我的开发工作流。它就像一位不知疲倦的结对编程伙伴能理解自然语言指令生成代码片段、修复bug甚至重构整个函数。效率的提升是肉眼可见的但随之而来的是一个新问题不确定性。当我发出一个指令后Claude Code 会进入“思考”状态光标闪烁后台的AI模型正在全力运转。但这个“黑盒”过程到底在干什么是卡住了还是在稳步推进是遇到了复杂逻辑正在深度推理还是单纯因为网络延迟在“摸鱼”等待的焦灼感尤其是在处理复杂任务时尤为明显。这让我想起了交通系统中的红绿灯。红灯停绿灯行黄灯提醒你做好准备。这套简单直观的视觉反馈系统让复杂的交通流变得有序且可预测。那么能不能给Claude Code 也装上一个“红绿灯”将AI内部不可见的工作状态转化为一目了然的视觉信号呢这个想法促使我动手将AI助手的抽象状态通过一个实体的硬件红绿灯装置具象化出来。这不仅仅是一个极客玩具更是提升人机协作透明度、优化工作节奏的实用工具。无论你是频繁使用AI编程的开发者还是对AI Agent工作流感兴趣的技术爱好者这个项目都能让你更直观地“感受”AI的思考过程。2. 核心设计用状态机模型解构AI工作流要给Claude Code 装红绿灯第一步不是去焊接LED而是需要建立一个清晰的状态模型。我们不能简单地将AI响应等同于“亮灯”必须深入其工作流定义出有意义的、可观测的状态。经过对Claude Code API和典型使用模式的分析我将其工作流抽象为一个经典的三段式状态机。这种状态机模型结构清晰状态转换明确非常适合用来描述具有阶段性特征的过程。2.1 定义AI工作的三个核心状态我的状态机包含以下三个核心状态分别对应红绿灯的三个灯色红灯 -IDLE/ERROR(空闲/错误)这是AI的“停止”状态。它可能发生在两种场景一是我没有发出任何指令Claude Code 处于待命状态二是AI在处理过程中遇到了无法解决的问题比如代码逻辑存在致命矛盾、请求超时或API返回了错误。红灯亮起意味着我需要介入——要么发起新任务要么去排查错误原因。黄灯 -THINKING/PROCESSING(思考/处理中)这是AI的“准备”或“进行中”状态。当我向Claude Code 发出一个指令例如“为这个函数添加错误处理”黄灯会立即亮起。这表示指令已被接收AI模型正在理解我的需求、检索相关知识、进行逻辑推理和代码生成。这个状态是AI核心的“黑盒”运算期。绿灯 -READY/SUCCESS(就绪/成功)这是AI的“通行”状态。当Claude Code 完成思考并生成了最终的代码块或文本回复时绿灯亮起。这告诉我“任务已完成结果已就绪请审阅。” 我可以放心地去查看它生成的代码并进行测试或整合。这个“红-黄-绿”的映射关系非常符合直觉几乎不需要学习成本。状态机的引入使得对AI工作流的监控从被动等待变成了主动观察。2.2 状态转换的逻辑与触发条件定义了状态接下来就要明确它们之间如何转换。这依赖于对Claude Code 工作流的钩子Hook或事件监听。初始状态系统启动后默认处于IDLE红灯。IDLE-THINKING(红变黄)触发条件是我通过IDE插件或快捷键向Claude Code 提交了一个查询或指令。我的监控程序需要捕获到这个“请求开始”的事件。THINKING-READY(黄变绿)触发条件是成功接收到Claude Code API返回的完整响应流。这里需要注意大型语言模型的响应可能是流式的streaming我们需要监听“流结束”或“收到最终令牌”的事件才能确认任务真正完成。READY-IDLE(绿变红)这是一个自动或手动的重置。可以设定一个超时例如结果展示10秒后也可以在我手动清除AI回复区域时触发表示一个交互周期结束准备接收下一个指令。任何状态 -ERROR(变红)这是一个异常路径。当网络请求失败、API返回错误码、或客户端解析响应出现异常时无论当前处于黄灯还是绿灯状态都应立即切换到红灯常亮或闪烁以明确告警。注意在实际实现中THINKING状态可能非常短暂对于简单问题或相当漫长对于复杂重构。黄灯的持续时间直接反映了AI的计算负载和任务复杂度这是最有价值的观测指标之一。3. 硬件选型与搭建从信号到实体的桥梁软件状态机已经就绪接下来需要将电信号转化为真实的灯光。硬件部分的核心是选择一个微控制器作为大脑并连接红绿灯模块。3.1 微控制器与红绿灯模块出于易用性和社区支持度的考虑我选择了Raspberry Pi Pico W。这款微控制器板价格低廉性能足够同时集成了Wi-Fi功能这对于后续与运行Claude Code的电脑通信至关重要。当然Arduino Uno、ESP32等也都是不错的选择。红绿灯模块可以直接购买现成的USB接口或GPIO接口的模拟红绿灯也可以自己动手用3个LED红、黄、绿和220欧姆的限流电阻在面包板上搭建。我选择了DIY方案更有趣也更灵活。将三个LED的阳极长脚通过电阻分别连接到Pico的GPIO引脚例如GP13-红 GP14-黄 GP15-绿阴极短脚统一连接到GND。3.2 通信方案本地网络通信硬件和软件我的电脑需要对话。我放弃了复杂的串口通信选择了基于本地网络的WebSocket协议。理由如下跨平台WebSocket是标准Web协议无论我的主机是Windows、macOS还是Linux都可以轻松创建客户端连接。实时性WebSocket提供全双工通信非常适合这种需要实时推送状态变化的场景。状态一旦改变可以立即推送给Pico。易于集成我可以在监控Claude Code状态的Python脚本中很容易地集成一个WebSocket服务器库如websockets。整个数据流是这样的运行在电脑上的Claude Code状态监控脚本作为WebSocket服务器在检测到状态变化时通过Wi-Fi向Pico W作为WebSocket客户端发送一条简单的消息例如{light: red}。Pico W收到后解析JSON并控制对应的GPIO引脚输出高电平点亮相应的LED。3.3 供电与外壳Pico W可以通过USB供电非常方便。我用一个闲置的手机充电头和一个USB线就能让它持续工作。为了美观和安全我使用激光切割亚克力板制作了一个迷你红绿灯外壳将LED和Pico板固定其中最终效果看起来就像一个精致的桌面摆件。4. 软件实现捕获状态与驱动硬件这是项目的核心编码部分分为两大部分运行在开发机上的状态监控客户端和运行在Pico W上的灯光控制固件。4.1 开发机端状态监控与WebSocket服务器首先需要在运行Claude Code的电脑上编写一个后台服务。以Python为例关键步骤如下监听Claude Code活动具体方法取决于Claude Code的集成方式。如果是通过VSCode插件可能需要研究插件的API或通过监听特定文件/日志的变化来推断状态。一个更通用的方法是模拟用户操作并结合API响应监听。这里我采用了一个混合方案全局快捷键监听使用pynput库监听我设定的“触发AI”快捷键如CtrlShiftC按下即视为任务开始触发THINKING状态黄灯。网络请求拦截使用mitmproxy或修改系统代理设置定向拦截发送到Claude API域名的请求和响应。当检测到完整的HTTP响应返回时触发READY状态绿灯。如果请求失败或超时则触发ERROR状态红灯闪烁。启动WebSocket服务器使用asyncio和websockets库创建一个简单的WebSocket服务器。# 示例代码片段状态监控与WebSocket服务器 import asyncio import websockets import json from pynput import keyboard current_state red # 初始状态 def on_activate(): global current_state current_state yellow print(状态思考中 (黄灯)) # 这里可以广播状态给所有连接的客户端 def on_response_received(): global current_state current_state green print(状态就绪 (绿灯)) # 广播状态 def on_error(): global current_state current_state red_blink print(状态错误 (红灯闪烁)) # 广播状态 # 设置快捷键监听 listener keyboard.GlobalHotKeys({ ctrlshiftc: on_activate, # ... 其他快捷键绑定到 on_response_received 和 on_error }) listener.start() # WebSocket服务器逻辑 async def state_server(websocket, path): print(硬件客户端已连接) try: # 首先发送当前状态 await websocket.send(json.dumps({light: current_state})) async for message in websocket: # 处理来自硬件的消息如心跳 pass except websockets.exceptions.ConnectionClosed: print(硬件客户端断开连接) async def main(): async with websockets.serve(state_server, 0.0.0.0, 8765): await asyncio.Future() # 永久运行 if __name__ __main__: asyncio.run(main())4.2 微控制器端Pico W固件开发在Pico W上我使用MicroPython进行编程因为它对网络支持友好。连接Wi-Fi首先编写代码让Pico W连接到本地Wi-Fi网络。WebSocket客户端实现一个WebSocket客户端连接到上一步电脑服务器指定的IP和端口如ws://192.168.1.100:8765。消息处理与GPIO控制持续监听服务器发来的消息。根据消息中的light字段值控制对应的GPIO引脚。# 示例代码片段Pico W MicroPython 客户端 import network import usocket as socket import ujson as json import time from machine import Pin # 配置Wi-Fi ssid 你的Wi-Fi名称 password 你的Wi-Fi密码 # 初始化LED引脚 red_led Pin(13, Pin.OUT) yellow_led Pin(14, Pin.OUT) green_led Pin(15, Pin.OUT) def set_light(state): red_led.off(); yellow_led.off(); green_led.off() if state red: red_led.on() elif state yellow: yellow_led.on() elif state green: green_led.on() elif state red_blink: # 实现闪烁逻辑 pass # 连接Wi-Fi此处省略详细代码 # ... # 简化的WebSocket客户端连接与消息处理循环伪代码 server_addr 192.168.1.100 server_port 8765 # 这里需要使用MicroPython的websocket客户端库或使用原始socket实现WebSocket握手 # 持续接收消息解析json调用set_light函数实操心得在Pico W上实现稳定的WebSocket重连机制是关键。网络可能波动电脑可能休眠因此客户端代码必须包含异常捕获和循环重试逻辑确保连接断开后能自动恢复保证红绿灯装置的可靠性。5. 高级功能与优化让红绿灯更智能基础的红绿灯已经能工作但我们可以让它变得更聪明提供更丰富的信息。5.1 状态精细化与黄灯呼吸效果最初的THINKING状态是简单的黄灯常亮。但AI的“思考”过程其实有子阶段。我们可以进一步细分THINKING_PARSING解析中黄灯慢速闪烁。表示AI正在理解我的自然语言指令。THINKING_GENERATING生成中黄灯快速闪烁或呈现“呼吸”效果亮度平滑变化。表示AI正在生成代码令牌。在Pico端可以通过PWM脉冲宽度调制控制LED的亮度轻松实现呼吸灯效果让状态反馈更加生动和细腻。5.2 历史状态记录与可视化状态数据是宝贵的。我修改了电脑端的服务器将每次状态切换的时间戳和类型记录到一个本地SQLite数据库或简单的日志文件中。2024-05-20 10:15:23 | IDLE - THINKING | 触发指令修复空指针异常 2024-05-20 10:15:31 | THINKING - READY | 耗时8.2秒 2024-05-20 10:16:05 | READY - IDLE基于这些数据我可以进行简单的分析平均响应时间统计不同类型指令代码生成、代码解释、bug修复的THINKING时长了解AI在不同任务上的“效率”。“摸鱼”识别如果THINKING状态异常漫长比如超过30秒而最终结果却很简单或错误那这次交互可能效率很低相当于AI“卡住了”或“摸鱼”了。日志可以帮助我回溯是哪个复杂指令导致了这个问题。5.3 集成到系统状态栏或IDE除了实体红绿灯也可以将状态同步到电脑的软件界面。例如开发一个简单的系统托盘应用使用Tkinter或PyQt显示红绿灯图标或者为VSCode开发一个状态栏插件直接在编辑器底部显示当前AI状态。这样即使实体红绿灯不在视线内也能通过屏幕一角获知状态。6. 常见问题与排查实录在项目实施过程中我遇到了不少坑这里把典型问题和解决方案记录下来供大家参考。6.1 硬件连接与通信问题问题现象可能原因排查步骤与解决方案LED不亮或亮度异常1. GPIO引脚配置错误输入/输出2. 电阻值过大或LED正负极接反3. 供电不足1. 确认代码中已将引脚设置为Pin.OUT。2. 用万用表检查电路确保LED方向正确电阻约为220欧姆。3. 尝试单独用3.3V电源直接点亮LED串联电阻检查硬件本身。Pico W无法连接Wi-Fi1. SSID/密码错误2. Wi-Fi加密方式不支持如WPA33. 路由器设置了MAC过滤1. 再三检查密码注意大小写和特殊字符。2. 将路由器加密暂时改为WPA2-PSK测试。3. 查看路由器后台将Pico W的MAC地址加入允许列表。WebSocket连接失败1. 电脑防火墙阻止了端口2. 服务器IP地址不正确3. 代码中服务器未启动1. 在电脑防火墙设置中开放8765端口或你自定义的端口。2. 在电脑上使用ipconfig(Win) 或ifconfig(Mac/Linux) 查看本地IP确保Pico连接的是这个IP。3. 在电脑上使用netstat -an6.2 状态监控不准确问题快捷键能触发黄灯但绿灯永远不会亮。排查这说明状态机从THINKING到READY的转换没有被触发。根本原因是“AI响应完成”这个事件没有被正确捕获。解决检查网络请求拦截的逻辑。确保你的拦截器能准确捕获到Claude API返回的完整HTTP响应而不是中途的chunked数据。一个更稳健的方法是结合使用快捷键触发黄灯同时启动一个超时计时器比如30秒如果计时器内收到了API响应则转绿灯如果超时则转红灯错误。这能防止因拦截逻辑漏报导致的“常亮黄灯”。6.3 实体灯与软件状态不同步问题有时电脑上任务已经完成但实体红灯还亮着或者相反。排查这是典型的状态同步问题。根源在于WebSocket消息可能丢失或Pico端处理消息的代码有bug。解决增加心跳机制在WebSocket连接上让Pico定期如每10秒向服务器发送一个ping服务器回复pong。这能保持连接活跃也能及时发现连接断开。状态查询与同步Pico在连接建立时主动向服务器请求当前状态get_state。此外Pico可以在每次收到任何消息后都回复一个确认。如果服务器短时间内没收到确认可以尝试重发上一次的状态消息。在Pico端加入本地超时复位例如如果黄灯亮起超过60秒仍未收到绿灯或红灯指令则Pico自动复位为红灯空闲/超时错误。这是一个重要的降级策略确保硬件不会卡死在某个异常状态。7. 项目总结与延伸思考完成这个项目后桌面上那个默默闪烁的红绿灯成了我开发过程中一个不可或缺的“伙伴”。它的价值远不止于一个酷炫的装饰。最直接的感受是它极大地缓解了等待AI响应时的焦虑。看着黄灯稳定地亮着我知道工作正在后台稳步推进绿灯亮起则带来一种确定的成就感。更重要的是通过观察黄灯持续的时长我潜移默化地加深了对不同编程任务复杂度的认知也能更合理地规划任务和打断时机。从技术层面看这个项目是一个经典的物理计算和状态机应用范例。它将虚拟的、后台的软件进程状态通过传感器软件监听和效应器LED映射到了物理世界实现了数字世界与物理世界的闭环。所使用的WebSocket通信、GPIO控制、事件监听等技术都是物联网和智能硬件项目中非常基础且核心的技能。这个想法完全可以延伸出去。你可以为任何异步的、状态不透明的软件进程添加物理状态指示器比如为漫长的编译过程装个进度条灯带为自动化测试套件装个“通过/失败”指示灯甚至为你的日历装个灯红色表示会议中绿色表示可打扰。关键在于找到那个对你有意义的“状态”然后动手把它变得可见、可感。技术最终要服务于体验而这个小小的红绿灯项目正是改善人机交互体验的一次有趣尝试。