安卓设备驱动大模型智能体:控制无人机与物联网硬件的架构实战
近期我把手头跑了大半年的一个项目收尾了一套让大模型智能体AI agents通过安卓设备去驱动无人机和物联网硬件的系统我给这套系统起了个内部代号叫 “Mobile Tunnel”。名字灵感和功能其实挺直白的——安卓设备在整条链路里就是一条移动的“隧道”一头是理解和决策的大模型另一头是各种能飞、能转、能亮、能返回数据的物理硬件。这篇文章想把这套东西的架构思路、实现细节以及我实际跑通的场景和踩过的坑一次性讲清楚。写这篇文章之前我先交代一下它适合谁看。如果你正在做类似“用自然语言控制硬件”的项目或者你被卡在“大模型只能聊出文字、动不了真机”这个环节又或者你想把自家安卓手机变成智能家居/无人机的中枢控制器那这篇文章对你会有直接参考价值。我会尽量不写废话纯粹把从零到一的路线和关键代码段放出来。先抛出我开工前最困惑的问题大模型既然能写代码、能分析图片为什么让它“控制一个安卓手机”这件事仍然要比想象中麻烦得多答案是绝大多数现成方案都把 AI 智能体限制在“API 对话层”而 Mobile Tunnel 的做法是把安卓本身变成一个可执行的操作终端。下面从项目设计的原点开始拆。1. 为什么需要一根“隧道”AI智能体与安卓设备的控制鸿沟1.1 大多数AI连接方案停在“对话层”现在的智能助手、聊天机器人和硬件之间的协作几乎都建立在“文本进出”上。你想要得到天气信息它去调用天气接口你想要控制智能灯它去调用灯的云平台 API。问题在于当硬件没有开放云 API或者场景不在联网状态下大模型就彻底失去了“手”。我做 Mobile Tunnel 之前就试过让大模型直接通过云平台去控制一个只有本地 BLE 服务的土壤湿度传感器。结果很尴尬它既不知道设备的 UUID也无法发起蓝牙扫描。原因很简单AI 智能体的能力边界被锁死了——它只能用别人封装好的 HTTP 接口不能像人一样“拿起手机、打开 App、点一下按钮”。1.2 安卓作为“通用执行终端”的合理性所以我在想能不能反过来大模型不直接控制硬件而是控制一台安卓设备安卓设备再去通过各种协议控制硬件。安卓本身就是一台小电脑它有蓝牙、WiFi、USB、摄像头、屏幕能装 App也能运行很多硬件厂商的移动端 SDK。更重要的是安卓可以同时对接多套协议——BLE 接传感器、WiFi 接智能家居、USB 接无人机遥控器——这正好补足了大模型“没有手”的短板。Mobile Tunnel 的核心理念就是把安卓当作大模型的“通用双手”。我不再为每个硬件都写一个云 API 适配层而是只做一件事让大模型能控制安卓屏幕能调用安卓上的底层协议工具。只要这层隧道打通理论上任何能在安卓上运行或以安卓为控制中心的设备全部都能成为智能体的执行对象。1.3 从架构角度看隧道要解决的三个问题我做需求拆解时把任务收敛成三个具体问题第一怎么让大模型“看”到安卓屏幕上的状态并准确点击、滑动、输入。第二怎么把无人机这类需要通过厂商 SDK 才能控制的硬件封装成大模型可以调用的标准工具函数。第三怎么把 IoT 设备的发现、连接、读写、控制也封装成一套统一接口让大模型不用区分背后是 BLE 还是 MQTT。这三个问题分别对应三条链路屏幕控制链路、无人机控制链路、IoT 控制链路。Mobile Tunnel 的整体结构就是围绕这三条链路展开的。2. 整体架构从大模型到执行器的三层命令链路2.1 架构分层编排层、工具适配层、执行层我最终没有做一个把所有逻辑都塞进一个 App 的“巨无霸”而是拆成了三层。这样做的最大好处是调试方便——模型编排逻辑出问题不需要碰硬件驱动代码硬件协议升级也不会污染 AI 侧的决策逻辑。第一层是编排层负责跑大模型接收用户的任务指令维护多轮对话上下文并决定下一步调用哪个工具。我在实际项目中编排层跑在本地 Python 服务里因为大模型推理需要较高性能安卓设备本身扛不起来。这一层只靠 JSON 收发消息和下层完全解耦。第二层是工具适配层这是 Mobile Tunnel 的核心。它维护了一张“工具清单”例如click(x, y)、swipe(x1, y1, x2, y2, duration)、read_sensor(soil_moisture)、drone_takeoff()等。每个工具都有清晰的名称、参数、描述以及一个“实际执行函数”。当编排层的模型决定调用drone_takeoff()时工具适配层会真的去执行这个函数。第三层是设备执行层也就是运行在安卓设备上的实际执行者。它负责完成屏幕点击、蓝牙 GATT 读写、USB 控制指令下发等工作并把执行结果包装成结构化状态返回给工具适配层。2.2 一次任务指令的完整数据流我用一个真实例子说明用户说“看看阳台花盆的土壤是不是干了如果干了就打开补光灯。”这条指令从进入系统到执行完成会经过这样一条路径用户输入的文本进到编排层。大模型理解意图后发现需要先查看土壤湿度于是输出一个“调用工具”的决策例如{ tool: read_sensor, params: { sensor: soil_moisture } }。工具适配层收到这个 JSON调用设备执行层中的 BLE 读取函数。安卓上的 BLE 读取代码通过 GATT 服务读取传感器的特征值把湿度数值返回。适配层把“土壤湿度12%”回传给大模型。大模型判断湿度偏低再次输出{ tool: set_device, params: { device: grow_light, state: on } }。工具适配层执行此工具通过 WiFi 或红外打开补光灯并把执行成功信息返回给大模型。大模型整合所有信息输出最终自然语言回应“土壤偏干已开灯。”整条链路的数据全部是标准 JSON不涉及任何私有通信协议。这个设计也为后续接入更多设备打下了很好的基础因为工具清单是可用注册方式动态扩展的。2.3 为什么编排层不跑在安卓端有一个问题很容易被问既然让 AI 控制安卓为什么不把大模型直接放进安卓 App省掉服务端我实际测过两类方案。端侧模型的问题是手机性能捉襟见肘一次工具调用的意图解析要 3-4 秒而且可用的模型能力偏弱对复杂工具参数的理解容易出错。纯云端 API 的问题则是延迟相对高但模型能力强。我的选择是本地 Python 服务 云端 API 的折中方案编排层只做上下文管理和调度不存大量历史图像流量和成本都可控。这个权衡不一定适合所有人。如果只是演示 Demo端侧模型完全够用但如果要达到“连续操作不崩”、“长任务拆解不出错”的程度还是推荐把编排层放到算力更充足的地方。3. 屏幕控制链路让大模型既“看得见”也“点得动”3.1 屏幕信息采集XML层级树 vs 多模态截图的取舍屏幕控制要解决的第一个问题是怎么把“屏幕长什么样”变成大模型能理解的信息。我试过两条技术路线各自有很明显的使用边界。第一条路线是用安卓的无障碍服务AccessibilityService抓取当前界面的视图层级导出成 XML 结构。这种方案在原生控件界面下非常精准能直接拿到每个按钮的文本和坐标模型只需要读一小段文本就能知道界面有哪些可操作项。缺点是很多 App 的界面是自绘的控件不会暴露到无障碍树里抓出来是一大块空白区域完全没法定位。第二条路线是截屏 多模态大模型视觉识别。这种方案对界面形态没有要求只要像素还在模型就能理解内容。缺点是视觉模型的输出未必稳定偶尔会把“关闭”按钮的坐标估算偏移几十像素而且每一轮都要传一张图token 消耗明显更高。我的最终策略是两条路线共存用了一个简单的判断条件无障碍树里如果可操作节点数量大于 3就走 XML 方案如果解析出来是空白或异常内容就自动切换成截屏方案。这样既保证了大多数场景下的速度和准确性又不会在自绘界面上傻掉。3.2 操作工具箱为LLM设计的最小原子动作搞定了“看见”接下来是“操作”。我最初犯过一个错误把工具设计得特别“高级”比如直接做一个open_app(智能家居)这种语义级函数。后来我发现模型在缺少准确 App 内部状态知识的情况下越抽象的工具越容易调错。最终我收敛成六个原子动作click(x, y)点击屏幕坐标。long_click(x, y, duration)长按用于图标拖动或唤起右键菜单。swipe(x1, y1, x2, y2, duration)滑动用于翻页、滚动列表。input_text(text)向当前焦点输入框填充文字。back()返回上一页。screenshot()返回当前屏幕截图用于确认操作后的状态。原子动作的好处是模型只需要按屏幕上看到的内容决定坐标而不需要理解“打开、关闭、切换”这些业务含义。那些偏语义的控制比如“打开智能家居 App”我会在工具适配层用状态机去拆解成多个原子动作而不是把这些语义直接暴露给模型。3.3 工具函数的JSON Schema描述让模型知道怎么用有了原子动作还要解决“模型怎么知道该调用哪个函数”的问题。我从函数调用Function Calling模式里借鉴了做法给每个工具写一份 JSON Schema包含工具名称、描述、参数类型、参数说明和必需字段。以点击为例Schema 大概长这样{ name: click, description: 点击屏幕指定坐标坐标取自screenshot返回的像素位置, parameters: { type: object, properties: { x: { type: integer, description: 目标点x坐标像素 }, y: { type: integer, description: 目标点y坐标像素 } }, required: [x, y] } }描述里面那句“坐标取自 screenshot 返回的像素位置”不是废话它是在引导模型使用正确来源的数据而不是凭记忆编造坐标。实际跑出来的效果错误率会下降很多。经验是描述写得越具体、越贴近“上一轮工具返回了什么”模型就越不容易乱调工具。3.4 实操心得坐标偏移、像素密度与手势时长屏幕控制看似简单实际跑起来坑很多我挑几个典型的。第一个是像素密度问题。安卓设备存在多种分辨率模式我最初的实现直接把display.getRealMetrics()拿到的宽高当成点击坐标基准。结果某台测试机启用了显示缩放后截屏分辨率没问题但触摸事件的坐标映射错位点击位置全部偏到左上角。解决办法是在执行点击前先换算一次event.getX() * (screenWidth / viewWidth)确保触摸坐标和截图坐标在同一条坐标系内。第二个是手势时长的把握。快速滑动和慢速拖动的行为差别很大有些 App 的列表项在慢速滑动时会被判定为“拖动”触发编辑操作。我在工具参数里留了一个duration_ms字段默认给 300 毫秒模型可以根据情况调整。实测下来翻页用 200 到 300 毫秒即可拖拽图标则要 800 毫秒以上。第三个是点击后的等待。模型发出点击命令后如果立刻读取屏幕 XML可能界面还没来得及刷新导致误判“点击无效”。优化方式是在点击后固定等待 400 毫秒再刷新截图复杂页面可以再加一点。这个等待时间不要写死在代码里建议做成可配置项不同设备的渲染速度差得很远。4. 无人机控制链路让安卓成为无人机的飞行终端4.1 通信链路选型USB OTG连接与地面端App无人机是 Mobile Tunnel 里最有意思、也最容易出安全问题的一环。市面上主流的消费级无人机大多要求通过厂商自带的地面站 App 连接遥控器再通过遥控器与飞行器建立通信。厂商通常会提供移动端 SDK允许第三方 App 接入但前提是必须有安卓设备通过 USB OTG 线连接到遥控器。我最初以为可以通过蓝牙直连遥控器试了几次都不稳定。后来查文档才发现很多遥控器只有 USB 接口能同时承担数据传输和视频回传蓝牙通道只用于部分参数设置。最终选型是安卓手机 USB OTG 线 遥控器安卓端集成厂商提供的移动端 SDK。这一环的代码量不小但结构非常简单。核心是初始化一个“控制上下文”对象注册飞行状态回调然后调用起飞、降落、航线飞行等接口。Mobile Tunnel 的工具适配层把这些接口再包了一层变成大模型能调用的工具函数。4.2 把飞行动作封装成“工具”起飞、航线、拍照、返航无人机控制工具的设计我严格遵循“安全优先、动作单一”的原则。每个工具只做一件事绝不把多个动作揉在一起。目前暴露给大模型的工具包括drone_takeoff(altitude_meters)垂直起飞到指定高度。drone_fly_to(latitude, longitude, altitude_meters)飞往指定坐标点。drone_gimbal_rotate(pitch, yaw)调整云台角度。drone_capture_photo()拍摄一张照片并返回保存路径。drone_land()原地降落。drone_return_home()返回起飞点。为什么这么设计因为飞行动作是不可逆的一次drone_fly_to的失误可能造成设备受损。工具粒度越粗模型越容易在参数上出错。我在参数描述里明确写了“经纬度必须是 float 类型纬度范围 -90 到 90经度范围 -180 到 180”并让适配层在真正执行前做一次数值校验。超出范围直接拒绝绝不让错误数据传到 SDK 层。4.3 安全兜底遥测回传、限飞区检查与强制降落无人机控制最大的挑战不在功能而在容错。大模型在飞行途中如果出现幻觉输出一个偏离航线很远的坐标后果不堪设想。所以我在工具适配层做了三层安全兜底第一层是起飞前的强制检查。任何“起飞”和“航线飞行”指令执行前都会先调用一个drone_get_telemetry()工具获取当前位置、电量、卫星信号强度。如果数据异常直接终止。第二层是地理围栏。我在配置文件中定义了允许飞行的最大半径任何目标点超过这个半径工具直接返回错误信息并把“超出安全范围”的原因透传给大模型。这样模型能在反馈中知道自己为什么失败下一步决策也更合理。第三层是异常自动降落。飞行过程中如果连续两次遥测都没有心跳或者电量低于阈值执行层不等待大模型指示自动触发降落返航逻辑。这一步是硬编码的绕开了模型的决策链路。原因是机器控制的安全预案不应该依赖一个充满不确定性的 AI 模型来决策。还有一个很有用的细节所有的无人机执行结果都返回结构化遥测而不是一句话。例如 “{ status: in_air, altitude_m: 2.5, battery: 78 }”。模型拿到这种数据可以自己判断“电量是否足够继续任务”而不是被动等我给它翻译。5. IoT设备联动BLE、WiFi、MQTT与红外的统一出口5.1 设备发现与配对BLE扫描、广播过滤和连接管理IoT 部分最头疼的不是控制而是设备发现。不同设备有不同协议有的走 BLE有的走 WiFi还有老设备只支持红外。Mobile Tunnel 的 IoT 模块是从“发现”就把协议差异抹平的。关于 BLE 设备我在安卓端写了一个扫描管理器定期扫描周边广播包按照厂商定义的服务 UUID 或者设备名称前缀过滤。扫描结果会转换成统一格式{ protocol: ble, device_id: a4:c1:38:xx:xx:xx, name: soil_sensor_01, services: [0000180f-0000-1000-8000-00805f9b34fb] }WiFi 设备则通过局域网探测方式发现MQTT 设备直接根据配置中心的订阅列表枚举。设备注册表统一存在一个 JSON 文件里每次发现新设备就追加一条记录。这样大模型面对的设备列表全部是结构一致的 JSON 条目它不需要关心这台设备是蓝牙还是 WiFi 的。配对环节同样被隐藏了。BLE 配对由适配层在后台完成成功后直接把设备标记为connected: true只有连接失败才会把错误信息返回给大模型。5.2 传感器读取BLE GATT特征值的解析封装传感器数据读取是 IoT 模块里最常见的“读”操作。BLE 传感器一般通过 GATT 服务向客户端暴露特征值数据格式五花八门有的是 16 位整数有的是 IEEE 754 浮点数有的前面还带着一个状态字节。我在适配层做了一个“解析器注册表”每个设备类型对应一个解析函数。例如温湿度传感器原始字节是 4 个字节解析函数负责取出湿度值和温度值并换算成百分比和摄氏度。def parse_temp_humidity(raw_bytes: bytes) - dict: temp_raw int.from_bytes(raw_bytes[0:2], little, signedTrue) / 10.0 hum_raw int.from_bytes(raw_bytes[2:4], little, signedTrue) / 10.0 return {temperature_c: temp_raw, humidity: hum_raw}解析函数统一返回 dict结构为{ metric: value, unit: ..., time: 123456789 }。这样传感器读出来的结果模型可以直接阅读和决策。一个很容易漏掉的点是读一次传感器不代表数据可取很多传感器休眠后需要几十毫秒才能返回稳定读数。我后来在读取前加了一次主动唤醒指令并做两次采样取平均数值才稳定下来。5.3 执行器控制插座、风扇、补光灯的统一 Power 接口执行器控制比传感器简单但同样需要统一协议。我把所有执行器收敛成一个set_device(device_id, state)接口state 可以是 “on”、“off”也可以是一个 JSON 数值比如风扇的转速、灯的亮度。这个接口在适配层内部按协议分发WiFi 智能插座通过本地局域网发送 HTTP 请求。MQTT 设备把控制指令发布到对应主题。红外遥控设备调用安卓手机的红外发射器按配置的编码发送红外信号。统一接口的最大收益是模型的决策流程变得非常简洁。它不需要知道“补光灯是 WiFi 还是红外”只需要决定“开灯”这个目标。至于怎么开那是适配层的事。5.4 联动场景agent 如何决定先查后控设备一旦多起来就涉及“怎么编排”的问题。我常用的做法是给模型提供一个“设备说明文档”把每个设备的能力、单位和可操作字段写清楚。大模型拿到这份文档后相当于在一张地图上找路径。比如用户说“阳台光线暗把补光灯打开”模型看到设备表里有“光照传感器”和“补光灯”两个设备会先调用光照传感器确认当前数值再决定是否开灯。这个“先查再控”的习惯不是靠提示词硬塞给模型的而是靠我给传感器类工具的描述里明确加了“读取数据并判断是否需要控制其他设备”的提示。实测下来这种“带说明的决策”方式比纯让模型凭记忆瞎猜靠谱得多。还有一个小细节所有 IoT 控制工具的执行结果都带一个reported_state字段表示设备实际返回的状态。模型如果不放心可以再次读取核验形成“控制-确认”闭环。6. 一次完整任务串联检查植物状态并启动补光灯6.1 任务拆解计划生成与实际执行前面讲的都是模块这一节把这些模块串成一个完整任务。我用最多的测试场景是“检查植物状态并自动补光”因为流程短、包含传感器读取、逻辑判断、执行器控制三个关键环节非常适合验证系统。当用户发出指令后编排层的模型先输出一份任务计划大致是“第一步读取土壤湿度第二步读取光照强度第三步根据湿度数值决定是否浇水第四步根据光照值决定是否开灯。”这份计划不会直接执行只是让模型自己想清楚路径。实际执行时仍是一步一步通过工具调用来推进。这样设计有个额外好处模型一旦在中间某步失败它能根据已完成的步骤自动修正后续计划而不是机械地按原计划往下走。6.2 执行回放每一步的状态变化我截取了最近一次测试的执行记录做了脱敏第 1 步模型调用read_sensor(soil_moisture)返回{ value: 12, unit: % }。模型判断土壤偏干。第 2 步模型调用read_sensor(light_lux)返回{ value: 320, unit: lux }。模型判断光照偏低。第 3 步模型调用set_device(grow_light, on)执行成功返回{ reported_state: on }。第 4 步为保险起见模型又调用了一次get_device_state(grow_light)确认状态确实为 on。第 5 步模型输出最终回答“土壤湿度 12%光照 320 lux已开启补光灯。”整个过程 11 秒完成其中大部分时间花在 BLE 读取和模型推理上。第一次跑的时候模型在“是否浇水”这件事上犹豫了因为它没有浇水执行器。后来我在设备文档里明确写了“本场景不包含浇水执行器如湿度低仅提示用户”模型就不会再做无谓的尝试。6.3 失败与恢复蓝牙断连的自动重试链路完整测试不可能一帆风顺。某次演示中土壤传感器在第一次读取后断开了蓝牙连接第二次读取直接报错。如果不做处理任务会卡死在“读取失败”然后模型大概率会道歉并终止。我针对这种情况设计了自动恢复策略所有 BLE 读取函数在执行前会先检查连接状态如果发现已断开自动发起重连最多重试 3 次每次间隔 2 秒。重连成功后再执行读取如果重试完仍失败才把错误抛给大模型。那次演示中实际是第二次重试就连接成功了任务完整走完观众根本不知道中间断过一次。这个经验很朴素硬件链路的稳定性不能指望 AI 来处理应该在工具层就把故障屏蔽掉。越往底层越要“强健”越往模型层越要“灵活”。7. 稳定性与安全生产环境里踩过的问题清单这里直接给一份我在开发中遇到过的、比较有代表性的问题汇总。每一条都是实际触发过的不是理论推导。问题描述触发场景根因解决对策无障碍服务被系统自动关闭长时间无人操作后部分系统会回收常驻无障碍服务前台服务 定时自检 系统设置引导截屏权限失效部分应用内禁止截屏应用层安全策略拦截改用无障碍节点绘制视图或明确提示失败原因蓝牙扫描间歇性失败设备密集区域扫描回调竞争串行扫描队列 失败自动重试无人机遥控器连接掉线USB 线松动或协议传输异常物理链路不稳增加心跳检测断开后自动重建连接模型工具调用参数幻觉长对话积累后上下文过长导致遗忘截断历史 重新生成工具说明传感器返回异常大值设备信号波动原始数据未校验增加数值范围校验与二次采样红外控制不生效距离过远或编码错误红外编码老化引入“重发一次”机制日志文件无限增长长时间压测未做日志轮转定时压缩和清理7.1 无障碍服务被系统回收与后台保活这个问题在我开发早期几乎每周都遇到。手机锁定屏幕一段时间后系统会为了省电杀掉后台无障碍服务导致点击操作全部失效。排查时发现单纯在代码里标记“前台服务”还不够某些定制系统的省电策略更激进。我的处理思路是用两个保底机制一是维护一个定期心跳每 30 秒检查一次无障碍服务是否活着如果发现没有响应就通过辅助手段重新拉起二是把手机设置里的“耗电保护”引导开关写进了配置文档使用者需要手动把 App 设为不限制后台电量。这俩机制配合长跑任务基本不再掉线。7.2 LLM工具幻觉与危险操作的确认沙盒工具幻觉是这类系统的通病。大模型有时会凭空编造一个不存在的工具名或者给已有工具填一个不存在的参数。我的对策是编排层在真正执行工具前先做一次“工具名白名单校验”和“参数类型校验”不通过直接拒绝。更严格的场景比如无人机起飞、返回我会加一道“确认沙盒”。模型如果想执行危险操作编排层不会直接下发而是先把指令暂存向用户发一次确认请求只有用户同意后才放行。这个机制牺牲了一点全自动体验但考虑到设备安全我认为完全值得。7.3 长时间运行的资源管理Mobile Tunnel 在一次连续 8 小时的压测里暴露出内存和日志问题。截图采集会产生大量 Bitmap 对象如果不及时回收内存会持续上涨BLE 连接如果反复断开重连连接对象也会泄漏。现在的做法是保持一个截图复用池每次都只保留最近三张截图用于模型上下文BLE 管理则统一走连接池设备断开后立即释放 GATT 回调资源。日志方面我加了按大小自动轮转超过 5MB 就切片。这些问题不解决系统短时间演示没问题但没法当作可靠工具使用。8. 写在最后Mobile Tunnel 的边界与后续方向8.1 当前还不能解决的问题我虽然把这套系统跑通了但必须承认它有很多边界。首先是视觉识别类操作仍然不够稳尤其是遇到自绘动画界面截屏识别的坐标误差会比较明显。其次多设备并发控制还比较初级目前主要靠任务队列串行处理一旦同时控制两台无人机和三组传感器调度逻辑会变得复杂。还有一个不可忽视的问题是模型推理成本。每次截图和工具调用都会消耗 token一个完整场景跑下来成本比单纯聊天高出几十倍。对个人项目来说还好如果要规模化成本优化必须提上日程比如采用更小尺寸的模型做工具调用或者增加本地缓存。8.2 下一步想做的改进与一段个人体会接下来我计划做三件事。第一是把屏幕控制的坐标推测改成“语义化操作优先”也就是尽量让模型基于无障碍树里的控件 ID 操作减少像素坐标依赖。第二是给 IoT 模块增加更多设备协议比如 Thread/Matter 设备让这套隧道真正覆盖下一代智能家居标准。第三是把无人机和 IoT 的联动打通实现“无人机侦察环境数据自动调整家里的环境参数”这种跨硬件场景。最后说一点个人体会。做 Mobile Tunnel 的过程中我最大的收获不是某个功能跑通了而是体会到了“抽象层级”的重要性。大模型和硬件之间必须有清晰的分层和稳定的接口否则任何一端的不确定都会放大成整个系统的不可控。把模型当作“大脑”、安卓当作“手”、硬件当作“执行器”让每一层都尽量稳定、标准、可替换这套系统的可靠性才会真正落地。如果你也在做类似的 AI 控制硬件项目我建议先从最简单的屏幕控制开始跑通一个“大模型帮你点开 App 并执行一个操作”的小闭环再去碰无人机和复杂 IoT。底层的坑越早踩完后面接入新硬件时就越轻松。