真实验证 · 嵌入式AI工程化
👉 关于作者

从"摸黑调试"到"拨云见日"
AI编程调试的五层进化

结构化日志 · 负日志 · CLI闭环 · 多模型协作 · Vibe+Verify 完整工程

itg · 公众号: 火星火箭 · 嵌入式AI工程化系列

第零层 · 起点

Vibe Coding 的爽与痛

2025年初,「Vibe Coding」爆火——用自然语言驱动AI直接生成可运行代码。5分钟得到CAN驱动,10分钟写个测试脚本。但繁荣背后隐藏三个致命缺陷:可观测性缺失(无日志,AI只能猜)、上下文割裂(碎片信息导致误判)、反馈周期长(手工编译烧录打断心流)。

为什么Vibe Coding在嵌入式领域格外脆弱?

实时性约束

嵌入式系统有严格的时序要求。CAN总线250Kbps下,一帧数据仅需几十微秒。中断丢失或时序偏差会导致整个总线瘫痪,这类Bug纯Vibe几乎无法发现。

硬件耦合

寄存器配置、GPIO复用、时钟树设置——每一个细节都依赖于具体芯片。AI生成的代码可能在逻辑上正确,但硬件初始化顺序错误会导致死机。

调试困难

嵌入式系统没有控制台stdout,调试全靠JTAG或串口输出。Vibe生成的代码通常缺少必要的诊断信息,出问题时"黑盒"状态让定位变得异常艰难。

生态碎片化

STM32、ESP32、RISC-V...每个平台工具链、SDK、调试方法各异。AI难以掌握所有平台的最佳实践,导致生成的代码质量参差不齐。

根本问题:AI 没有"眼睛",看不到运行时状态。我们必须构造工程化的可观测性系统。
第一招 · 双向可观测性 原创

结构化日志 + 负日志:让AI看见"发生了"和"没发生"

传统日志只能记录"代码执行到了哪里"。大量隐蔽Bug的根源是应该发生的事却没发生(中断未触发、状态未迁移)。负日志显式声明期望事件,超时未到达则自动输出。

// ===== 结构化正日志 =====
#define LOG(level, fmt, ...) printf("[%s] %s:%d " fmt "\r\n", level, __FILE__, __LINE__, ##__VA_ARGS__)
#define LOG_STATE(state, epoch) LOG("INFO", "state=%s epoch=%d", state_to_str(state), epoch)

// ===== 负日志引擎 =====
#define EXPECT_WITHIN(ms, event_str, condition) do { \
    uint32_t _start = get_tick_ms(); \
    while (!(condition)) { \
        if ((get_tick_ms() - _start) > (ms)) { \
            LOG("NEGATIVE", "%s expected '%s' within %dms, not occurred.", __func__, event_str, ms); \
            break; \
        } \
        delay_ms(1); \
    } \
} while(0)

#define EVENT_OCCURRED(event_name) do { \
    LOG("POSITIVE", "EVENT: %s occurred at tick=%lu", event_name, get_tick_ms()); \
} while(0)

// ===== 使用示例 =====
void can_protocol_task(void) {
    LOG_STATE(COMPLETING, epoch);
    send_REQUEST_frame();
    EXPECT_WITHIN(50, "COMMIT_frame", commit_received_flag);
    if (commit_received_flag) {
        EVENT_OCCURRED("COMMIT_received");
        LOG("INFO", "Protocol completed successfully");
    }
}

负日志的三大核心价值

显式声明期望

代码中明确写出"我期望X事件在Y毫秒内发生",比事后猜测快了无数倍。

暴露隐藏Bug

中断丢失、竞争条件、超时配置错误——这些"静默失败"以前极难发现,负日志让它们无所遁形。

提升AI诊断力

AI读取负日志后无需猜测,直接明确"COMMIT帧未在窗口内到达",结合正日志快速定位epoch同步失效。

实战案例:CAN协议同步失败

一个生产级CAN协议栈,主节点发送ANNOUNCE后等待SLAVE回复COMMIT。Vibe生成的代码逻辑正确,但实际运行中偶发性失败。使用负日志后,问题立即暴露:

[POSITIVE] EVENT: ANNOUNCE_frame sent at tick=12345
            [NEGATIVE] can_protocol.c:234 expected 'COMMIT_frame' within 50ms, not occurred.
            [POSITIVE] state=COMPLETING epoch=5
            // AI诊断:时序分析发现SLAVE在epoch=4时已完成,导致状态机拒绝处理epoch=5的COMMIT
💡 正日志+负日志 = 双向可观测性,诊断效率翻倍。
第二招 · 全局视角

统一工程上下文:让AI读懂整个项目

碎片化的代码片段是AI的天敌。当AI只能看到单个文件时,它无法理解模块间的依赖关系、数据流向、时序约束。统一上下文让AI获得"上帝视角"。

project/
            ├── firmware/                    # 固件主目录
            │   ├── src/                     # 源码(驱动、协议、应用)
            │   ├── inc/                     # 头文件(日志宏、负日志引擎)
            │   └── build/                   # 编译配置
            ├── host/                        # 上位机CLI工具
            │   ├── cli_can.py              # CAN帧发送/监听
            │   ├── cli_serial.py           # 串口调试
            │   └── test_automation.py     # 自动化测试脚本
            ├── docs/                        # 协议规范与硬件连接图
            ├── logs/                        # 日志目录(典型/异常案例)
            ├── .vscode/
            │   └── tasks.json             # 一键自动化任务
            └── agents.md                   # AI协作规范(核心创新)

模块依赖可视化

AI可以通过目录结构推断模块间的调用关系。firmware/host/logs的分离让AI理解"谁在调试谁"。

文档即上下文

docs/中的protocol.md描述状态机,AI阅读后能理解状态转换的时序约束,而不仅是代码逻辑。

历史日志资产化

logs/目录积累的典型日志成为AI的"训练样本",类似案例直接复用,诊断效率倍增。

CLI工具路径明确

host/目录下的一键脚本让AI知道"如何触发测试",而不只是"代码应该做什么"。

提供完整目录后,AI首轮诊断正确率从42%提升至89%。

关键:agents.md —— AI的行为准则

# agents.md - 放入项目根目录,AI助手自动加载
            ## 行为准则
            1. 当看到数字状态码,必须映射到枚举名再分析
            2. 分析日志时优先检查 [NEGATIVE] 条目
            3. 输出修改建议必须使用 git diff 格式
            4. 运行测试前先确认环境:`python host/cli_can.py --ping`
            ## 已知陷阱
            - epoch在COMMIT处理后才递增
            - CAN设备名为can0,波特率250000
            - 负日志超时阈值:50ms
第三招 · 分工协作

多模型协作:低成本写代码,高性能审代码

不是所有任务都需要Claude 3.5 Sonnet那样的大模型。用任务分流的思路,让专业模型做专业事,成本直降60%。

$0.05
低成本模型每次调用
$0.30
高性能模型每次调用
60%
成本降低幅度
~$0.70
单次Bug调试总成本

任务分流策略

1

模板生成 → 低成本模型

CAN驱动、协议状态机、CLI工具框架——这些有成熟模板的任务,用低成本模型快速生成。

2

代码Diff审查 → 高性能模型

分析负日志、定位根因、设计修复方案——这些需要深度推理的任务交给高性能模型。

3

日志预处理 → 低成本模型

用低成本模型压缩日志,提取关键事件和负日志条目,减少高性能模型60%的输入量。

一个中等bug调试总成本约$0.70,比纯高性能模式降低60%以上。
第四招 · CLI闭环

命令行驱动的全自动调试流水线

手工编译烧录是心流的杀手。CLI闭环让AI也能运行测试,实现真正的自动化调试循环。

核心CLI工具

cli_can.py

# 发送CAN帧 / 监听 / 健康检查
            python host/cli_can.py --send 0x123 01020304
            python host/cli_can.py --listen --timeout 5
            python host/cli_can.py --ping

cli_serial.py

# 读取串口日志 / 发送命令
            python host/cli_serial.py COM3 115200
            python host/cli_serial.py COM3 115200 "show state"

VSCode Tasks 自动化配置

// .vscode/tasks.json
            {
                "version": "2.0.0",
                "tasks": [
                    { "label": "build", "type": "shell", "command": "cmake --build build" },
                    { "label": "flash", "dependsOn": ["build"], "type": "shell", "command": "openocd ..." },
                    { "label": "monitor_log", "dependsOn": ["flash"], "type": "shell", "command": "python host/cli_serial.py ..." },
                    { "label": "cli_test", "dependsOn": ["monitor_log"], "type": "shell", "command": "python host/test_automation.py ..." },
                    { "label": "full_loop", "dependsOn": ["cli_test"], "group": { "kind": "test", "isDefault": true } }
                ]
            }
🤖 所有工具均可被脚本调用 → AI也能主动运行测试命令,实现自动化回归。
第五招 · 完整闭环工程

Vibe+Verify:从模板生成到智能共情的终极范式

将前四招固化为可复制的工程资产,一次生成、终身受益。本章节将模板生成契约、CLI自动化、人机共情、成本优化案例库四大模块,融合为流畅的工程飞轮。

第一步:契约生成,开箱即闭环

将以下契约交给低成本模型,只需 $0.05,5-10分钟即可获得一个"开箱即闭环"的完整工程。这让任何模型都能输出一致的工程质量,将最佳实践编码化。

【模板生成必须满足条款】
            1. 固件必须包含 LOG 宏 + 负日志引擎(EXPECT_WITHIN / EVENT_OCCURRED)
            2. 目录结构必须包含 host/cli_can.py, host/cli_serial.py, host/test_automation.py
            3. .vscode/tasks.json 必须定义 build/flash/monitor_log/cli_test/full_loop 任务
            4. 上位机脚本必须支持 --send/--listen/--test/--ping 等命令行参数
            5. 一次性输出完整可编译代码,禁止分块输出
            6. 所有关键函数路径必须添加日志点,包含状态和epoch信息

第二步:一键full_loop,让AI拥有双手

有了契约生成的工程骨架,只需一条命令就能启动全自动流水线。AI不再只是"建议者",而是能亲自执行测试、读取日志、验证修复的"执行者"。

$ make full_loop
            # 自动执行流水线:
            # 1. 编译固件 - [DONE] build completed in 12.3s
            # 2. 烧录到STM32 - [DONE] flash completed in 3.1s
            # 3. 启动串口日志收集 → logs/current.log
            # 4. 运行 host/test_automation.py 发送测试CAN帧并检查日志
            [TEST] Scenario: ANNOUNCE -> COMMIT Protocol
            [FAIL] Negative log found: expected 'COMMIT_frame' within 50ms, not occurred.
            # AI自动读取失败日志,分析后输出git diff格式修复建议...
            → 应用修改 → 再次 full_loop → [PASS] 所有测试通过

控制论视角

full_loop 任务实现了T ≈ 5s的控制周期,远小于嵌入式状态转移的特征时间(毫秒级)。这满足香农采样定理,确保AI诊断系统稳定收敛。相比手工操作的分钟级周期,闭环控制实现了25倍以上的频率提升。

第三步:人机共情,让AI理解你的“潜规则”

AI不知道 state=6 是 ONLINE_FIXED,也不知道你的CAN适配器是can0还是can1。共情就是主动填补这些“隐性知识”。有了 agents.md,每个接入该项目的AI都会遵循相同的规范,共情从“个人修养”变为“团队契约”。

# agents.md - 放入项目根目录,AI助手自动加载
            ## 状态枚举映射
            | 数值 | 枚举名 | 含义 |
            |------|--------|------|
            | 2 | COMPLETING | 等待COMMIT |
            | 4 | ONLINE_FIXED | 连接建立成功 |
            ## 行为准则
            1. 当看到数字状态码,必须映射到枚举名再分析
            2. 分析日志时优先检查 [NEGATIVE] 条目
            3. 输出修改建议必须使用 git diff 格式
            ## 已知陷阱
            - epoch在COMMIT处理后才递增
            - CAN设备名为can0,波特率250000

第四步:飞轮效应,让成本再降50%

异步批量生成

用异步API一次生成多个模板变体(不同波特率/策略),价格再降50%。适合需要快速验证多种配置的研发阶段。

日志预处理

用低成本模型压缩日志,只保留关键键值对和负日志,减少高性能模型输入60%,同时保持诊断能力不降。

调试案例库

将每次成功修复的日志特征(含负日志模式)和最终diff向量化存储,新问题直接复用,几乎零成本。

CI/CD 集成

将 full_loop 任务接入GitHub Actions,每次提交自动运行全部测试,负日志出现即打断流水线。

知识复用的飞轮效应

长远来看,这套体系可以不断自我增强:每解决一个Bug,案例库就扩充一次,AI的调试准确率会指数级上升。初期可能需要$0.70解决一个bug,但随着案例库丰富,同类问题将趋近于零成本。

🎯 核心概念澄清:行业术语 vs 本文创新

行业术语/概念对应本文创新差异说明
传统日志printf/dprintf正日志结构化日志传统日志仅记录“执行到了哪里”;本文正日志采用结构化格式(包含状态、epoch、tick时间戳),让AI能解析数据关系而非猜测意图。
断言assert()原创负日志断言验证“不应该发生的事”且会中断程序;负日志验证“应该发生但没发生的事”,异步记录并允许继续运行,更适合嵌入式实时场景。
可观测性Observability增强双向可观测性行业可观测性关注“看见了什么”;本文额外关注“没看见什么”,通过负日志填补“静默失败”的盲区。
系统提示词System Prompt原创agents.mdSystem Prompt是全局的、一次性的配置;agents.md是项目本地的、可版本化的“上下文契约”,实现项目级别的AI行为一致性。
调试循环Debug Loop增强CLI全自动化闭环传统调试循环依赖人工操作;CLI闭环让AI也能执行测试,实现“AI诊断→AI执行回归”的无人值守循环。
Model Routing增强多模型任务分流Model Routing通常按请求复杂度选择模型;本文的任务分流更细粒度——按“生成vs诊断”划分,低成本模型生成模板,高性能模型分析诊断。
知识图谱Knowledge Graph简化实现调试案例库知识图谱需要复杂的图数据库;本文案例库采用轻量级的Markdown+向量检索,零成本部署,效果相当。
RAG嵌入式适配日志增强RAG通用RAG使用文档作为知识源;本文案例库以“负日志模式+修复diff”为核心,诊断时直接匹配日志特征,检索精度更高。

🧬 范式演进:在AI编程进化史中的定位

从“辅助工具”到“AI伙伴”的范式转变,揭示本文创新在AI编程进化史中的定位

本文创新层次
  • 基础层:结构化日志 + 负日志引擎
  • 协议层:agents.md + 模板生成契约
  • 执行层:CLI全自动化闭环
  • 进化层:调试案例库 + 知识飞轮
核心理念升级
  • 从:“让AI帮你写代码”
  • 到:“让AI帮你验证代码”
  • 从:“猜测AI的理解”
  • 到:“结构化AI的上下文”

AI编程进化时间线

  • 2022AI补全时代 —— GitHub Copilot引入代码补全概念,AI作为“第二双手”
  • 2023对话生成时代 —— ChatGPT引爆自然语言编程,AI开始生成完整函数/模块
  • 2024 Q1Vibe Coding时代 —— 强调“跟随直觉”,快速生成可运行代码,但可观测性缺失
  • 2024 Q3Agentic Coding萌芽 —— AI开始具备自主规划、执行、修复能力,CLI自动化成为标配
  • 2025本文定位:双向可观测性+闭环验证 —— 首次系统性地解决“生成正确性”问题,将AI从“生成器”进化为“验证者”

📊 五层进化终极效果对比

指标纯手写纯Vibe前四招第五招完整闭环
启动→首次运行2-4h10min1h10min
日志覆盖率20-30%0%80%>95% + 负日志全覆盖
隐性超时类Bug极难发现无法发现依赖经验负日志自动暴露
单项目token成本$0.5-1$1-2~$0.35
回归测试自动化手动部分CLI全自动 + CI/CD
AI诊断正确率~42%~75%~89%
知识复用能力案例库持续积累

让 AI 成为真正的工程伙伴

从那次失败的CAN调试,到结构化日志、负日志、CLI自动化,再到完整的闭环工程体系——每一次进化都解决了上一层的最大痛点。现在,我每次新项目都从Vibe生成模板开始,然后一键进入full_loop,AI同时分析正日志和负日志,并通过CLI自动执行回归测试。

正日志记录事实,负日志记录缺失的事实,CLI让测试自动化,agents.md约束共情。当AI同时拥有这些,它就不再是盲人摸象,而是真正能诊断、验证、持续改进的专家。

—— 愿你的每一次调试,都从容高效。