很多做嵌入式的朋友问我,这两年AI编程工具冒出来这么多,到底能不能用在单片机、RTOS、Linux驱动这种工程上?我的回答一直是:能用,但前提是你得换一套开发范式。不是让你把代码丢给AI然后坐等结果,而是把AI当成团队里一个水平飘忽但反应极快的同事,你得给它画边界、写验收单、做代码审查,甚至替它兜底。这篇文章想聊的,就是这个“面向AI协同的嵌入式软件开发范式”——它不只是Prompt技巧,而是从任务拆解、状态建模、代码生成、静态检查再到硬件验证的整套流程改造。我尽量把这一路踩过的坑和沉淀下来的方法都写清楚,适合正在折腾嵌入式+AI编程的同行参考。
1. 面向AI协同的嵌入式开发,到底在解决什么问题
嵌入式软件和纯后端软件有一个本质区别:你不能让代码先跑起来再说。它跑在真实硬件上,连着传感器、电机、通信总线,出了Bug轻则重启,重则烧板子、撞机器、丢数据。所以传统嵌入式开发的节奏是“小步慢走”,每个功能都要过设计、编码、编译、烧录、示波器/逻辑分析仪验证。这个节奏一旦遇到AI编程工具,就容易出问题——AI生成代码的速度太快了,快到你根本没时间验证,结果就是陷入“修了A坏B,改了B崩C”的恶性循环。
我见过不少团队接入AI编程工具后效率反而下降,原因就在这里。他们直接把AI当成一个“代码生成器”,需求描述两句话丢进去,代码出来就贴进工程,编译过了就算完事。这在做网页脚本或业务系统时可能能扛住,但嵌入式不行。MCU引脚有没有被你复用?中断优先级有没有冲突?看门狗有没有因为长阻塞被饿死?DMA缓冲区和普通数组有没有重叠?这些AI一概不知道,它只是在你给的上下文里做概率生成。
所以真正的问题是:我们要不要用AI,而是怎么让AI在一个约束极强的系统里工作。答案就是开发范式要变。从“人写代码、机器编译”变成“人定义意图、AI生成实现、工具链自动验证、人做关键审查”。这个范式里,人的精力不再耗在敲每一行寄存器操作上,而是放在状态建模、接口设计、验收条件定义上——这恰恰是嵌入式最值钱的部分。AI则负责把状态机翻译成C语言,把协议解析代码从文档批量生成,把重复性的寄存器初始化、错误处理、日志埋点干完。
这套范式还有一个更大的价值:它逼你把需求边界说清楚。很多时候你自己都说不清“长按三秒进入配置模式”和“双击在配置模式和运行模式之间切换”在时序上到底怎么处理,AI更不可能替你决定。当你开始写提示词,把输入、输出、时序、异常分支一项项列清楚,你其实是在做一次正式的需求评审。我自己的体会是,这个“被迫说清楚”的过程,对项目质量的影响比AI生成的那几百行代码还要大。
面向AI协同的嵌入式开发,本质上是一次分工重组。AI做它擅长的:大范围搜索已知模式、快速生成样板代码、批量改写接口。人做自己擅长的:定义系统约束、评审关键逻辑、在硬件上验证行为。后面的章节我会具体拆解这套流程每一步怎么做。
2. 构建AI可参与的嵌入式软件开发流程
2.1 为什么状态机是AI协同的第一道关口
先说一个我反复给团队强调的观点:状态机不是一种代码风格,而是一种需求描述语言。AI最怕的不是代码生成,而是需求说一半。你告诉它“做一个按键控制LED的功能”,它能给你生成五个不同版本的代码,有的用轮询、有的用外部中断、有的带消抖、有的不带,每个看起来都对,但放到你的工程里没一个能直接跑。问题不是AI笨,而是这个需求本身缺少约束。
状态机会把约束补上。当你把“按键控制LED”拆成“空闲态、短按确认态、长按激活态、激活态”四个状态,并且明确定义每个状态的进入条件、退出条件、执行动作,AI生成的代码就只有一个正确方向了。这不是什么新思想,嵌入式架构里用状态机收敛复杂度是很成熟的做法,只是在AI协同的场景下,状态机从“可选的架构方案”变成了“必选的协作接口”。原因很简单:状态机是人类和AI之间信息损失最小的需求描述方式。
我在项目里特别推荐用一个表格来描述状态机:
| 状态 | 触发事件 | 条件 | 动作 | 下一状态 |
|---|---|---|---|---|
| IDLE | BUTTON_PRESSED | 按下时间 > 3s | 启动LED呼吸灯,置标志位 | ACTIVE_LONG |
| IDLE | BUTTON_PRESSED | 按下时间 <= 3s | 只亮LED 200ms | SHORT_CONFIRM |
| SHORT_CONFIRM | TIMEOUT_200MS | 无 | 关LED | IDLE |
| ACTIVE_LONG | BUTTON_RELEASED | 无 | 保持呼吸灯 | ACTIVE |
| ACTIVE | BUTTON_PRESSED | 无 | 关闭LED,清标志位 | IDLE |
这个表格直接丢给AI,再配上你的引脚定义、定时器句柄、函数命名规范,生成的代码基本一次就能过编译。别嫌这事麻烦,写这个表花十五分钟,能省下后面至少两个小时的来回改Prompt和Debug时间。状态建模做到位,AI就从“猜你要什么”变成了“翻译你给的表”。
2.2 AI协同下的五个工程步骤
有了状态机这个基础,我再把完整的AI协同流程拆成五个步骤。这套流程我实践了将近两年,团队新人也按这个路径上手,效果远比以前“人写代码、AI查错”的用法稳定。
第一步是任务拆解。千万别让AI一次生成整个固件,一次会话只做一个模块。比如“完成按键消抖状态机模块”是一个任务,“实现Modbus RTU从站协议解析”是另一个任务。每个任务要包含三部分内容:功能描述、接口约束、验收标准。验收标准一定要明确,比如“连续100ms电平稳定才判定按键状态变化”,这就是可检验的标准。没有验收标准的任务AI没法自测,输出质量就完全靠运气。
第二步是上下文组装。把相关头文件的函数声明、结构体定义、当前工程使用的MCU型号和寄存器映射、编码规范说明贴给AI。很多嵌入式工程师嫌弃AI生成代码风格和工程不一致,百分之八十是因为没给上下文让它仿写。我会在工程里维护一个CONVENTIONS.md,写清楚命名规则(函数用模块前缀、变量用匈牙利命名、宏全大写)、错误处理方式(统一返回错误码)、注释格式(doxygen风格),每次起新会话先把这个文件丢进去,生成风格立刻统一了。
第三步是AI生成代码。我不追求一次生成完整成品,而是让AI先生成骨架函数,我再逐段补充。提示词里通常会有制式要求:“请先列出本模块需要实现的函数清单,每个函数给出输入输出说明,然后逐个实现。”这样AI会先暴露它理解的分解方式,如果函数拆错了,我改提示词比改代码快得多。
第四步是自动检查。生成代码之后先不急着烧板子,先用静态检查工具过一遍。PC-Lint、Clang-Tidy、Cppcheck这三件套我用得最多,配合编译器的-Wall -Wextra -Wshadow参数。AI生成的代码最常栽在阴影变量、隐式类型转换、未处理返回值这几类问题上,静态检查一扫一个准。这一步其实就是把“代码审查的第一遍”交给工具,人只处理工具报出来的真问题。
第五步是硬件验证。这一步没有任何捷径,逻辑分析仪、示波器、串口打印全得上。我习惯让AI在生成代码时顺便生成自测函数,比如一个返回当前状态机状态的GetState函数,跑起来之后轮询打印。状态机这种东西,单看代码很难确认逻辑是否正确,但把状态跳转打印出来,一眼就能看出有没有“想当然”的路径。
这套流程把AI嵌入到每个环节,但没有把判断力交出去。AI负责从“表”到“码”的翻译,人负责从“需求”到“表”的抽象和从“码”到“行为”的验证。岗位职责变了,但没有空缺。
3. 提示词与上下文工程:驱动嵌入式AI编程的核心技术
3.1 嵌入式场景提示词的三层结构
网上聊AI编程提示词的文章很多,但大多是针对Web开发的,拿到嵌入式场景经常水土不服。嵌入式提示词要解决的核心问题是“约束表达”——你得让AI在芯片资源、实时性、可靠性这些硬约束下做选择。我的做法是把每条提示词拆成三层结构。
第一层是身份与背景约束。不需要写什么“你是一个经验丰富的嵌入式工程师”这种虚话,而是写清楚实际约束:“MCU为STM32F407,主频168MHz,Flash 1MB,RAM 192KB,使用HAL库,编译环境为arm-none-eabi-gcc,C标准为C11。”这段信息决定了AI对寄存器操作、内存占用、库函数可用性的判断。同一个功能,跑在顺控芯片上和跑在Cortex-M4上,代码策略完全不同。
第二层是接口与实现约束。给出函数签名、调用方代码、数据结构定义,明确告诉AI“只能修改函数内部实现,不允许改动接口”。这样生成的代码才能直接嵌进现有工程。我还会加上“禁止使用动态内存分配”“所有函数需返回错误码”“可重入函数不能使用全局变量”这类嵌入式专属约束。这些约束不写,AI倾向于用malloc、用静态局部变量保存状态、甚至用stdbool之外的自定义类型,新老代码风格冲突严重。
第三层是任务与验收描述。将已经建模好的状态机表格、输入输出时序要求、边界条件处理要求整体贴入提示词。验收条件写得越具体越好,比如“当接收缓冲区剩余空间不足时返回ERR_BUFFER_FULL并保留已接收数据,不得丢弃半包”。AI根据提示词无法真正执行代码,但它能根据验收条件做自洽性检查,生成代码时会更小心处理边界情况。
我顺手整理一个提示词模板,基本覆盖常见模块生成场景:
背景:MCU为XX,使用XX库,C11。 接口:已有uint8_t按键扫描值,已提供BSP_Key_GetState函数,返回KEY_UP/KEY_DOWN。 任务:实现按键消抖状态机。状态定义参照表(粘贴表格)。 约束:不使用动态内存,函数内最多使用两个static变量,消抖时限100ms±10ms。 验收:初始化后默认IDLE态;连续100ms检测到相同电平才跳状态;在任何状态按下均可响应;提供GetButtonState函数供外部查询。 输出:请先给出状态跳转表确认理解无误,再生成完整C文件,包含头文件。
这套模板我在多个项目里验证过,生成一次通过的几率从三成提升到七成,剩下的三成主要是不熟悉新库API造成的错误,人工修一下就行。
3.2 上下文选型与知识库管理
嵌入式软件工程的信息密度极高,一个工程里可能有几十个模块头文件、芯片用户手册、库函数参考。直接把所有资料塞给AI,轻则超出上下文窗口限制,重则让AI注意力被无关信息干扰,反而生成错误代码。AI协同效果好不好,七成取决于你选了哪些上下文喂进去。
我的上下文选取优先级是这样排列的:第一优先,本次任务直接相关的模块接口头文件和调用方代码,比如实现UART发送模块,就要贴UART寄存器结构体、发送函数调用示例;第二优先,工程编码规范文件和现有的代码风格样例,让AI有样可依;第三优先,芯片和库的参考信息,但只贴你需要的章节,不要贴整本手册;第四优先才是一般性的公共知识,比如C标准文档,这在模型预训练里已经有了,不需要额外占用窗口。
还有一个很多人忽略的点:上下文不是越多越好,要讲究“局部性”。AI生成某个具体函数时,给它看整个应用层代码反而会让它学会“跨模块调用方便”这种坏习惯,生成一堆紧耦合代码。我通常只给四类内容——函数骨架、被调用的下层接口声明、被本模块使用的数据结构、编码规范摘要。局部信息越聚焦,生成代码的内聚性越好。
知识库管理是上下文工程的前置工作。我会在工程仓库里单独开一个docs/ai/目录,维护三个文件:CONVENTIONS.md(编码规范)、ARCHITECTURE.md(模块调用关系)、API_SUMMARY.md(关键接口速览)。这三个文件不是为了给人看的,是为AI定制的“高密度上下文包”。以前维护技术文档总觉得工程量太大,现在把这些文件维护好,AI生成质量的提升立竿见影,值。
4. 实操:从需求到代码的AI协同完整流程示例
4.1 任务定义与状态建模
光讲方法论容易飘,我完整走一个例子。假设现在有一个需求:设计一个温控风扇的控制器,功能包括:按键开关机、两个按键调挡(1-3挡)、温度超过阈值自动升挡、LCD显示当前挡位和温度。硬件上用的是最常见的STM32G031 + 一颗NTC温度传感器 + 两个按键 + 4线风扇,通信接口是I2C的LCD屏。
按传统做法,这个功能大概要写两三百行C代码,涉及按键消抖、温度采样滤波、挡位控制逻辑、LCD刷新、任务调度。面对这个任务,直接跟AI说“写一个温控风扇程序”,它能给你生成一个能编译但完全不可控的东西。所以第一步是把状态机建出来。
我列了一个简单的状态机表:
| 当前状态 | 事件 | 条件 | 动作 | 下一状态 |
|---|---|---|---|---|
| OFF | POWER_BTN | 无 | 上电风扇,启动1挡 | ON_1 |
| ON_1 | POWER_BTN | 无 | 断开风扇 | OFF |
| ON_1 | SPEED_BTN | 无 | 升到2挡 | ON_2 |
| ON_1 | TEMP_HIGH | 温度 > 45℃ | 升到2挡,置自动标志 | ON_2 |
| ON_2 | SPEED_BTN | 无 | 升到3挡 | ON_3 |
| ON_2 | TEMP_LOW | 温度 <= 40℃,自动标志清零 | 降到1挡 | ON_1 |
| ON_2 | TEMP_HIGH | 温度 > 50℃ | 升到3挡,置自动标志 | ON_3 |
| ON_3 | SPEED_BTN | 无 | 降到1挡,自动标志清零 | ON_1 |
| ON_3 | TEMP_LOW | 温度 <= 45℃ | 降到2挡 | ON_2 |
光有表还不够,还要定义好三个接口:uint8_t Fan_GetTemp(void)返回0-100摄氏度;void Fan_SetSpeed(uint8_t speed)设置挡位;uint8_t Fan_GetKeyEvent(void)返回按键事件。我把这张表和接口说明作为提示词主体,附加MCU型号、HAL库版本和代码规范,让AI生成状态机实现。
4.2 代码生成与人工审查
提示词发出后,AI生成的代码大体结构是这样(模拟输出):
typedef enum { FAN_STATE_OFF = 0, FAN_STATE_ON_1, FAN_STATE_ON_2, FAN_STATE_ON_3 } FanState_t; static FanState_t fanState = FAN_STATE_OFF; static uint8_t autoFlag = 0; void Fan_Process(void) { uint8_t keyEvent = Fan_GetKeyEvent(); uint8_t temp = Fan_GetTemp(); FanState_t nextState = fanState; switch (fanState) { case FAN_STATE_OFF: if (keyEvent == KEY_POWER) { Fan_SetSpeed(1); nextState = FAN_STATE_ON_1; } break; case FAN_STATE_ON_1: if (keyEvent == KEY_POWER) { Fan_SetSpeed(0); nextState = FAN_STATE_OFF; } else if (keyEvent == KEY_SPEED) { Fan_SetSpeed(2); nextState = FAN_STATE_ON_2; } else if (temp > 45) { autoFlag = 1; Fan_SetSpeed(2); nextState = FAN_STATE_ON_2; } break; // ...其他状态类似 default: break; } fanState = nextState; }这段代码逻辑上是对的,但我知道AI会忽略几个嵌入式专属问题。第一个是按键消抖,Fan_GetKeyEvent由谁负责?如果它没有做消抖,状态机会被抖动信号反复触发。第二是自动调挡的阈值回差,上表中ON_2到ON_1的阈值是40℃,而ON_1到ON_2的阈值是45℃,中间5℃回差是防止抖动的关键,但AI生成的代码可能不会自动带上这个逻辑依赖。第三是初始化,如果Fan_Process在启动时被调用一次,它的状态是OFF,温度数据还没初始化,会不会误动作。
所以人工审查的重点不是读逻辑,而是查“边界耦合”。我会检查三个点:外部依赖是否按约束接入、全局变量是否被多处修改、异常输入(温度读数为0、按键事件永远为无)时状态机是否卡死。这套审查通常花不了十分钟,比从零写省太多时间了。
4.3 编译烧录与验证
代码通过人工审查后进入编译验证。我在命令行执行编译命令,参考如下:
arm-none-eabi-gcc -mcpu=cortex-m0plus -mthumb \ -Wall -Wextra -Wshadow -Werror \ -I./inc -I./HAL/inc \ -c src/fan_control.c -o build/fan_control.o编译报错是常事,AI生成的代码很容易在类型不匹配和隐式转换上踩坑。比如Fan_GetTemp返回uint8_t,但AI可能直接用int temp来接收,然后跟45比较时产生符号性问题。这类错误静态检查能拦下一大半。我建议编译时直接把-Werror打开,宁可编译多花几分钟,也别让一堆warning混过去。
烧录验证阶段我用了两块工具:一块逻辑分析仪抓状态机的输出中断时序,确认按键事件不抖动;另一块串口输出调试日志,把状态跳转打印出来。这次实测第一次烧录就发现了一个问题:开机瞬间LCD还没初始化完成,但状态机已经执行到ON_1,然后Fan_SetSpeed被调用,LCD还没准备好导致死等。这个问题藏在模块之间的启动时序里,AI不可能知道应用层初始化顺序,只能靠硬件验证暴露出来。处理办法是在主循环先初始化外设再调用Fan_Process,或者给状态机加一个INIT状态。
实测定下来,这个模块从建模到验证大概花了两个小时,其中状态建模半小时、AI生成半小时、人工审查半小时、烧录排查半小时。换成纯手写,写代码加单步调试至少得一天,还容易漏掉状态跳转的边界场景。这套方案在中等复杂度的模块上,效率提升是实打实的。
5. 嵌入式AI编程的常见问题与排查技巧实录
5.1 AI生成嵌入式代码的典型八坑
跟AI协同开发一年多,我基本把AI在嵌入式代码上的常见问题摸了个遍。这些问题高度集中,了解它们能帮你快速定位AI代码的Bug。
第一个坑是死等轮询与阻塞。AI默认会写while(flag==0);这种阻塞式等待,这在很多RTOS裸机混编环境里是致命的。它会饿死看门狗、拖垮其他任务。我给的提示词里现在固定加一句话“禁止自旋等待,如需等待必须使用超时计数器”。第二个坑是无条件启用中断但没配优先级。AI生成的代码经常外设初始化时直接HAL_NVIC_EnableIRQ,却忽略了分组配置和优先级数值是否设置了,这在Cortex-M上可能引发不可预期行为。第三个坑是缓冲区越界,AI处理不定长数据时喜欢用定长数组但没校验长度,解析协议时一个max_len检查不到位,就是内存踩踏的隐患。
第四个坑是静态变量滥用。AI分不清“可重入函数”和“模块内部使用静态变量”的边界,经常在需要可重入的地方用了静态数据。解决方法是提示词里明确说明数据保存机制,比如“带上下文指针的接口设计”。第五个坑是错误处理缺失。AI生成的文件操作、通信发送、内存拷贝代码经常漏掉返回值检查,嵌入式里一个返回错误被忽略,后面调试能让你怀疑人生。第六个坑是类型宽度随意。int在Cortex-M0上谁知道是16位还是32位?AI经常会用int做位运算或保存寄存器值,导致高字节被截断。
第七个坑是数学运算溢出。AI计算定时器重载值、ADC转换结果、温度补偿时,会直接写出temp*100/1024这类表达式,完全不顾uint8_t溢出。这个问题我在PID控制类代码里碰到过好几次,所有牵涉乘法运算的地方都要单独做类型审查。第八个坑是注释与实现不符。AI能生成非常漂亮的注释,但代码逻辑可能跟注释描述的是两码事,甚至注释抄袭了网上的另一段逻辑。这时候你不能信注释,只能信行为。
5.2 问题排查思路速查表
遇到AI代码出问题,我的排查顺序一般是这样:
| 症状 | 优先怀疑 | 排查方法 |
|---|---|---|
| 编译告警 | 隐式类型转换、未使用变量 | 打开-Wall -Wextra -Wshadow,逐条处理 |
| 运行时卡死 | 自旋等待、死循环 | 打断点看PC指针,查看门狗复位标志 |
| 中断不触发 | 优先级未配置、中断标志未清除 | 检查NVIC配置代码,用逻辑分析仪抓引脚 |
| 数据错乱 | 缓冲区越界、共用体字段顺序 | 开启内存保护单元或加Canary值 |
| 功能时好时坏 | 时序竞争、未初始化变量 | 加日志轮询状态,检查所有声明是否赋初值 |
| 静态变量冲突 | 可重入函数误用静态变量 | 代码审查,追踪所有static修饰的变量 |
这套表格我贴在工位旁边,每次AI代码出问题就过一遍。说个具体的例子,有次AI生成的一个Modbus解析函数,回环测试跑一百次对九十九次,就那一次数据错乱。查了两天,最后用二分注释法定位到AI在解析多字节写入指令时,把数据长度的校验表达式写反了——length > buffer_size被写成了length < buffer_size,单个字节溢出刚好偶尔踩到边界。这类Bug靠人眼审查很难一眼看出来,但结合正常代码的比对、边界值测试就能快速锁定。
排查AI代码问题的时候我还有一个习惯:保留每次生成代码的对话记录和Prompt版本。同一个模块改了两版后,AI可能引入第一版没有的Bug。把新旧代码diff一遍,往往能直接看出问题是什么时候埋进去的。AI生成的代码不像人手写的,有时候改动一行会导致其他完全不想关的函数风格突变,这种混乱也是Bug温床,不如直接重新生成一块干净模块。
5.3 复杂安全场景的AI协同策略
最后聊一个进阶话题,就是安全要求极高的场景,比如汽车电子里的OTA升级加签验签、Bootloader固件校验这类功能。这种模块的特点是对正确性要求极高,出一次错就会致命。我的经验是AI在此类场景中不是用来直接生成核心算法的,而是用来生成胶水代码和测试桩,核心密码学流程和校验逻辑必须由有安全背景的工程师手写并评审。
具体做法是这样:把复杂功能拆成“安全核心”和“外围辅助”两块。外围辅助包括命令解析、状态机、存储驱动、日志打印,这些可以交给AI生成,因为它们逻辑清楚、边界明确,AI出错率低。安全核心包括签名算法、密钥管理、哈希校验、固件加密,这些用传统方式手写,靠人工走读加形式化验证。外围代码做好接口隔离,必要时加一层编译期隔离,比如用宏控制只能在Debug模式编译AI生成的模块,Release阶段强制使用经过评审的实现。
AI也可以在安全场景里做反向辅助——让它写威胁模型和攻击树。你把固件升级协议描述给它,让它列出潜在的攻击面,虽然结论需要人来甄别,但它的发散性能提供不少思路。有一次我让AI分析一个引导加载程序的风险点,它列了九条,其中有两条确实是我没考虑到的——一个是升级过程中掉电导致的A/B分区切换不一致,另一个是回滚保护机制缺失。这两点后来都成了产品需求的一部分。
这种“AI做外围、人做核心、AI做验证、人做决策”的组合,是目前我看到的在复杂嵌入式安全场景里相对靠谱的协同方式。技术工具永远在变,但“关键判断不能外包”这条原则,在嵌入式这个行当短时间内不会变。
6. 从范式到落地:给同行的一点实操建议
写到最后,我再唠叨几点经验之谈。第一个建议是先拿你手头最无聊、最重复的模块试水AI协同,比如设备信息存储、串口命令解析、状态上报这一类,别一上来就让AI碰复杂的控制算法或安全关键逻辑。找几个历史任务回放,把之前的代码删了用AI重写一遍,对比代码体积和可读性,你就能摸清这个工具在你项目里的脾气。第二个建议是建好团队级别的提示词模板库和上下文包,别让每个人各写各的。几个月后你会发现,大家喂给AI的工程规范都是一致的,生成代码风格就统一,审查成本直线下降。第三个建议是不要迷信单次生成效果,迭代才是常态。第一次生成不满意很正常,不要反复编辑你原来的需求,而是应该修改变量定义和约束条件重新生成。AI编程在嵌入式领域最大的价值不是帮你少打字,而是逼你在动手前把系统想明白。
抛开那些热闹的工具和参数不谈,面向AI协同的嵌入式软件开发范式,本质上是把AI放进了工程师原有的开发闭环里,让它加速而不是接管。状态机约束意图,上下文工程约束信息,静态检查约束质量,硬件验证约束行为——这些环节一个都不能少,少了任何一个,AI生成代码的优势都会被返工成本吃掉。我在实际项目中感受到的最大变化不是代码写得快了,而是代码审查和硬件调试的时间显著缩短了,因为大部分低级错误在生成阶段就已经被规则挡回去了。这种变化带来的轻松感,做过嵌入式的人都懂。希望这篇总结对正在探索AI协同的同行有用,也欢迎你在自己的项目里试试这套流程,回头来交流碰到了什么新问题。