嵌入式AI工程化 · 综合实战 👉 关于作者

回归现实:单Agent实践框架

将嵌入式AI工程化法则完整落地的实战指南 —— 一套基于现有工具、可立即上手的完整实践框架

itg · 嵌入式AI工程化系列 · 综合实战 · 法则先行,执行随后

核心理念:多Agent架构是愿景,是交给大团队和时间去实现的未来。但在那一天到来之前,你依然可以在单Agent环境下,用这套轻量级的法则体系,让AI在物理世界中安全、高效、可追溯地运行。法则先行,执行随后。言出法随,即刻收敛。

一、单Agent的现实:不等待未来,从现在开始

多Agent协作是我们的愿景——审慎者审查代码,探索者提出新方案,仲裁者在关键时刻做出切换判断,教师记录每一次决策的上下文。但实现这套体系需要复杂的调度系统、多模型管理、状态同步机制。这需要大团队,需要时间,需要技术的进一步发展。

但法则本身,不需要等待。

在单Agent环境下,我们依然可以完整地实施这套体系。Agent只有一个,但法则可以通过文件、通过流程、通过约定,被Agent理解和执行。Agent不需要"性格",它只需要在被要求时,按照我们预设的规则切换行为模式。Agent不需要"协作",它只需要在每一步都遵循我们定义的收敛标准。

本文的核心:在单Agent环境下,用最务实的、最轻量的方式,让法则完整落地。所有方法均可独立运行,互不依赖。你可以从任何一章开始,先实践最迫切需要的那一项。

二、基础设施:法则文件夹

在项目根目录下创建一个法则文件夹,它是整个体系的物理载体:

project/
├── laws/                    # 法则文件夹(Agent自动加载)
│   ├── project-rules.md     # 项目规约(技术栈、架构约束、编码规范)
│   ├── decision-ledger.md   # 决策账本(每次重要决策的记录)
│   ├── knowledge-vitals.md  # 知识体征(文档热度和健康度追踪)
│   ├── skills/              # Skills定义(高频需求的意图模板)
│   │   ├── i2c-driver.yaml
│   │   ├── gpio-config.yaml
│   │   └── alarm-threshold.yaml
│   └── templates/           # 工程模板(新模块的骨架)
│       ├── driver-template.c
│       ├── test-template.c
│       └── readme-template.md
├── src/                     # 源代码
├── tests/                   # 测试代码
└── docs/                    # 项目文档

单Agent接入方式:在每次AI对话开始时,将project-rules.md的内容作为系统提示词注入,或在对话中明确要求Agent"先读取laws/目录下的所有文件,再开始执行任务"。

三、决策账本:让每一次选择都有据可查

3.1 账本格式

不需要复杂的数据库,一个Markdown文件即可:

# 决策账本

## DECISION-2026-001
- 日期:2026-05-15
- 决策:选用STM32F407作为主控芯片
- 背景:需要支持多路I2C和CAN总线,F407有3路I2C和2路CAN
- 替代方案:STM32F103(I2C和CAN不足),ESP32(功耗偏高)
- 裁决人:itg
- 状态:已确认

## DECISION-2026-002
- 日期:2026-05-15
- 决策:SPI Flash驱动采用DMA模式
- 背景:轮询模式占用CPU过高,影响传感器采样周期
- 替代方案:中断模式(代码复杂度高),轮询+缓存(延迟不可控)
- 裁决人:itg
- 状态:已确认

3.2 单Agent操作方式

记录决策:每次做出重要技术选型、架构调整、方案切换时,手动在decision-ledger.md中追加一条记录。这不需要Agent自动执行,你只需要养成习惯——花一分钟,把决策背景和替代方案写下来。

查询决策:当AI提出一个方案时,要求它先读取decision-ledger.md,确认是否有历史决策禁止了这个方向。例如:

"在给出建议之前,请先读取laws/decision-ledger.md,确认你的建议不会违反已记录的技术决策。"

3.3 实战价值

三个月后,当你忘记为什么选了这颗芯片而不是另一颗时,打开决策账本,一分钟就能找回上下文。当新同事入职时,他不需要你口头解释历史决策,他只需要读这份文件。

四、闭环收敛:每次修复都同步增强测试

4.1 核心操作

当AI帮你修复了一个Bug后,不要只让它生成修复代码。同时要求它:

"请完成以下两项任务:
1. 生成修复代码(git diff格式)
2. 生成一个新的测试用例,确保同样的Bug不会再次出现"

4.2 最小化测试文件

不需要复杂的测试框架。在你的tests/目录下,为每个模块维护一个简单的测试脚本:

// tests/test_rs485.c
#include "unity.h"
#include "../src/rs485.h"

void test_rs485_timeout_handling(void) {
    // 模拟超时场景
    rs485_set_timeout_ms(10);
    uint8_t result = rs485_send_and_wait(test_data, 4);
    TEST_ASSERT_EQUAL(RS485_ERR_TIMEOUT, result);
}

void test_rs485_retry_counter_reset(void) {
    // 验证上次修复的Bug:重试计数器是否正确重置
    rs485_reset();
    TEST_ASSERT_EQUAL(0, rs485_get_retry_count());
}

4.3 单Agent操作方式

每次修复Bug后,要求Agent同步更新对应的测试文件。如果测试文件还不存在,要求Agent创建一个。你可以这样说:

"请修复rs485.c中的超时处理Bug,并同步更新tests/test_rs485.c,增加一个验证超时后重试计数器正确重置的测试用例。"

4.4 实战价值

一个没有测试的修复,只是把Bug从"已知"变成了"未知"。一个带测试的修复,是把Bug从"存在"变成了"免疫"。这个习惯一旦养成,你的代码质量会持续上升,而不是反复震荡。

五、知识生命体征:让文档"活着"

5.1 文档元数据

在每个重要文档的头部,加入一段简单的元数据:

<!--
doc_id: SPEC-001
title: RS485驱动设计规约
created: 2026-03-15
last_modified: 2026-05-10
reference_count: 8
last_referenced: 2026-05-14
health_score: 0.85
status: healthy
wake_keywords: [RS485, 超时, MAX485, 总线挂死]
-->

5.2 手动更新规则

不需要自动化脚本。只需要养成两个习惯:

  • 修改文档时:更新last_modifiedhealth_score(如果内容有重大变更,手动调高健康度)
  • 引用文档时:更新reference_countlast_referenced

5.3 唤醒关键词的使用

当你在AI对话中遇到特定问题时,主动告诉AI:

"我遇到了RS485总线挂死的问题。请先读取所有wake_keywords中包含'RS485'或'总线挂死'的文档,然后再给出诊断建议。"

5.4 知识体征看板

knowledge-vitals.md中维护一份全局视图:

# 知识体征看板
最后更新:2026-05-15

## 当前风险警示
- 🔴 高危:SPEC-003(SPI Flash规约,健康度0.4,已半年未验证)
- 🟡 注意:SPEC-001(RS485规约,健康度0.7,建议近期复审)

## 热力分布
- 热区文档(本月被引用3次以上):SPEC-001, SPEC-005
- 冷区文档(半年未引用):SPEC-002, HISTORY-2023-001

5.5 实战价值

你不用再担心"这份文档还能不能信"。打开knowledge-vitals.md,一眼就能看到哪些文档需要复审,哪些文档已经过时。当AI引用一份健康度只有0.4的文档时,你会立刻知道需要谨慎对待它的建议。

六、Skills:高频需求的"快速通道"

6.1 Skill定义

每个Skill是一个YAML文件,放在laws/skills/目录下。它定义了该Skill的意图模板、所需上下文和验证标准。

# laws/skills/i2c-driver.yaml
skill_name: i2c-driver
description: 生成一个新的I2C外设驱动
intent_template: |
  请为传感器 {sensor_name} 生成I2C驱动。
  总线:{bus}
  I2C地址:{address}
  采样率:{sample_rate}Hz

required_context:
  - laws/project-rules.md        # 项目规约
  - laws/decision-ledger.md      # 决策账本
  - docs/schematic.md            # 电路描述

output_requirements:
  - 生成 {sensor_name}.c 和 {sensor_name}.h
  - 代码必须遵循project-rules.md中的编码规范
  - 必须包含负日志(EXPECT_WITHIN检查)

verification:
  - 编译通过
  - I2C扫描测试通过
  - 连续读取100次无超时

6.2 单Agent操作方式

当你需要生成一个I2C驱动时,不需要每次都解释上下文。只需要告诉AI:

"按照laws/skills/i2c-driver.yaml中定义的模板,为TMP117传感器生成驱动。总线I2C1,地址0x48,采样率1Hz。"

6.3 实战价值

一个Skill定义只需创建一次,之后每次使用都能节省大量解释上下文的时间。随着Skill库的积累,你的AI协作效率会持续提升。

七、工程模板:让每个新模块从第一天就遵守法则

7.1 驱动模板

laws/templates/下维护一套带法则标记的代码模板:

// laws/templates/driver-template.c
// 模板使用说明:
// 1. 替换 [MODULE_NAME] 为实际模块名
// 2. 替换 [PERIPHERAL] 为实际外设类型(I2C/SPI/UART)
// 3. 保留所有负日志宏

#include "[MODULE_NAME].h"
#include "negative_logger.h"

// 初始化函数
int [MODULE_NAME]_init(void) {
    LOG("INFO", "[MODULE_NAME] initializing...");

    // 期望外设在50ms内就绪
    EXPECT_WITHIN(50, "[MODULE_NAME]_READY", check_ready());

    if (!check_ready()) {
        LOG("ERROR", "[MODULE_NAME] initialization failed");
        return -1;
    }

    EVENT_OCCURRED("[MODULE_NAME]_READY");
    LOG("INFO", "[MODULE_NAME] initialized successfully");
    return 0;
}

// 数据读取函数
int [MODULE_NAME]_read(uint8_t *buffer, uint16_t len) {
    EXPECT_WITHIN(100, "[MODULE_NAME]_DATA_READY", data_available());
    return 0;
}

7.2 测试模板

// laws/templates/test-template.c
#include "unity.h"
#include "../src/[MODULE_NAME].h"

void test_[MODULE_NAME]_init(void) {
    TEST_ASSERT_EQUAL(0, [MODULE_NAME]_init());
}

void test_[MODULE_NAME]_read_timeout(void) {
    TEST_ASSERT_EQUAL(-1, [MODULE_NAME]_read(NULL, 0));
}

7.3 单Agent操作方式

当需要新增一个驱动时:

"请按照laws/templates/driver-template.c和laws/templates/test-template.c的模板,为BME680传感器生成驱动和测试代码。模块名bme680,外设类型I2C。"

7.4 实战价值

模板确保每个新模块从创建第一天就嵌入了负日志、可观测性和测试框架。你不会再遇到"这个驱动没有日志,调试完全靠猜"的困境。

八、Agent的Token上限与方案切换

8.1 设定Token消耗上限

在每次AI对话开始时,明确告诉Agent:

"本次对话的Token消耗上限为20000。如果超过此上限仍未解决问题,请停止当前路径的优化,并执行方案切换评估。"

8.2 方案切换评估

当Agent接近Token上限时,要求它生成一份决策报告:

"你已经消耗了18000 Token,但问题尚未解决。请停止当前修复路径,生成一份方案切换报告,包含:
1. 当前路径的已投入成本(时间/Token)
2. 当前路径的成功率评估
3. 2-3个替代方案及其预估成本
4. 推荐切换方案及理由"

8.3 实战价值

你不会再陷入"AI在一个错误方向上越走越深,消耗了大量Token却毫无进展"的困境。Token上限是你的硬约束,方案切换是你的安全阀。

九、全部组件的协同工作流

一个完整的新功能开发流程如下:

1

创建Skill定义(如需要)

如果是高频需求(如生成I2C驱动),先在laws/skills/下创建Skill定义,后续复用。

2

按照模板生成代码

告诉AI使用laws/templates/下的模板,生成驱动代码和测试代码。

3

决策记录

如果涉及技术选型,在decision-ledger.md中追加记录。

4

闭环收敛

生成代码后立即运行测试。如果发现Bug,要求AI同步修复代码和增强测试用例。

5

知识体征更新

修改文档后,更新文档头部的元数据。定期查看knowledge-vitals.md,复审健康度低的文档。

6

Token监控

如果某个Bug调试超过Token上限,要求AI生成方案切换报告,重新评估技术路线。

十、总结:法则先行,执行随后

这套单Agent实践框架,是你整套体系在"当下"的落地形态。它不依赖任何新工具的开发,不需要任何IDE插件的支持,不需要多Agent调度系统。它只需要你:

  • 创建laws/文件夹
  • 养成记录决策的习惯
  • 每次修复Bug时同步要求AI增强测试
  • 每次修改文档时更新元数据
  • 每次开始AI对话时设定Token上限

这五项习惯,每一项都对应你体系中的一条核心法则。它们不需要同时养成,你可以从最迫切需要的那一项开始。

多Agent架构是愿景,是交给大团队和时间去实现的未来。但在那一天到来之前,你依然可以在单Agent环境下,用这套轻量级的法则体系,让AI在物理世界中安全、高效、可追溯地运行。

法则先行,执行随后。言出法随,即刻收敛。

本文定位

本文是整个嵌入式AI工程化系列的综合实战篇。它将前10篇文章中定义的核心法则——闭环收敛、决策账本、知识生命体征、Skills、工程模板——整合为一套可立即上手的单Agent实践框架。所有方法基于现有工具(VSCode、Git、AI编程助手),不需要开发IDE插件,不需要多Agent调度系统。建议在理解③闭环收敛、⑦Skills和⑤知识生命体征后阅读,但各节可独立使用。

系列导航: ① 五层进化 · ② 实践项目模板 · ③ 自主修复闭环 · ④ 从收敛到进化 · ⑤ 知识的生命体征 · ⑥ 电路图分析器 · ⑦ Skills · ⑧ 历史的包袱 · ⑨ 固件铭牌与设备画像 · ⑩ 合规验证与AI编程 · ⑪ 回归现实:单Agent实践框架

关于作者