基于 MCU 的 Agent(三)

前两篇文章里,我分别梳理了 ESPAgent 的单板工具调用链路,以及它如何从一块 ESP32-S3 演化成四块 ESP32-S3 的 Agent Mesh。到现在,这个项目又往前走了一大步:它已经不再只是“飞书能控制几个 GPIO、点亮一个灯”的演示,而是开始具备一个更完整的边缘 Agent 系统该有的几个关键结构:角色分工、跨节点 ReAct 闭环、权限裁决、安全边界、结构化结果消息、显示终端,以及面向二次开发的动态硬件扩展底座。

如果说第一篇的重点是“LLM 怎么选工具”,第二篇的重点是“多个 ESP32 怎么协作”,那这第三篇更想回答的是:当一个 MCU Agent 项目真的开始走向系统化,它会长成什么样;哪些已经做到了,哪些只是规划,哪些又必须认真承认还没完成。

这篇文章就按当前项目的最新真实进度来写,不再回避工程边界。主要讲六部分:四角色 Agent Mesh 现在到底是什么状态;为什么 OutputMessage 对 MCU Agent 很关键;Guardian 这块安全节点到底做了什么;P4 显示终端现在展示到了哪一步;Lua runtime 与 manifest 动态扩展是怎么接进来的;以及最后我对这个项目当前阶段的判断。

第一章:现在的 ESPAgent 已经不是单板 Agent 了

当前项目的核心硬件形态已经比较明确:

1
2
3
4
5
/dev/ttyUSB0  esp32s3-coordinator-01  coordinator_agent
/dev/ttyUSB1 esp32s3-sensor-01 sensor_agent
/dev/ttyUSB2 esp32s3-control-01 control_agent
/dev/ttyUSB3 esp32s3-guardian-01 guardian_agent
/dev/ttyACM0 ESP32-P4 display terminal

这五块板不是五个重复的聊天机器人,而是五个不同层次的节点。

前四块 ESP32-S3 是真正参与协作的 Agent Mesh:

  • Coordinator 负责 Feishu / WebSocket / LLM / ReAct / 调度 / timeline。
  • Sensor 负责温湿度、空气质量、光照、presence 等环境感知,以及 telemetry 发布。
  • Control 负责 WS2812、GPIO、舵机、继电器、virtual device 等执行路径。
  • Guardian 负责 policy_checkpolicy_decision、审计、StateBoard、watchdog 和隐私治理。

而 ESP32-P4 则不再是“第四角色”,它现在更像一个第五节点:不是决策者,而是 Display Terminal,是一个专门观察 Agent Mesh 推理与通信过程的可视化终端。

这背后的架构思想其实很简单:

1
2
S3 负责真实 Agent 行为与真实硬件
P4 / Android 负责复杂显示、调试和交互

这比把一块 S3 专门浪费在“显示角色”上更合理。S3 的资源更适合承担边缘感知、控制和安全逻辑,P4 则更适合承接更复杂的 UI 与多过程展示。

第二章:多节点协作现在不是“发个 MQTT 就结束”

前期很多 MCU AI 项目都会卡在一个很典型的问题上:

1
2
3
4
Agent 发出命令
-> MQTT 发布出去
-> 另一块板去执行
-> 本地 Agent 只能说“我已经发送了”

这其实不算真正的闭环。因为对于用户来说,“我已经发送了”并不等于“灯真的变蓝了”“温湿度真的读取到了”“继电器真的打开了”。

所以项目里现在补上的最关键结构之一,就是结构化 OutputMessage

当前四板主链路已经变成:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
Feishu / WebSocket / Serial / Cron / Proactive

message_bus inbound queue

agent_loop

LLM tool calling / ReAct / spawn_subagent

mesh_send_command

Guardian policy_check / policy_decision

Sensor / Control 执行命令

espagent.output.v1 OutputMessage

Coordinator 后台等待并回注 message_bus

LLM 再总结成最终回复

Feishu / WebSocket / P4 / Android

这条链路真正解决的是“跨节点 ReAct 的结果如何回到推理回路里”。

当前 OutputMessage 的 schema 叫 espagent.output.v1,它不是大模型厂商原生的 message,而是 ESPAgent 在节点之间约定的结构化结果消息。它会携带:

  • node_id
  • role
  • command_id
  • trace_id
  • action
  • status
  • summary
  • result
  • error
  • ts_ms

这样 Coordinator 在下发一个远程动作时,不再只是拿到一个“命令已发送”的本地 tool result,而是可以真正等待远端同一 command_id 的结果回来。

这就让跨节点 ReAct 从:

1
推理 -> 下发

变成了:

1
推理 -> 下发 -> 等待远端结果 -> 再推理 -> 面向用户回复

现在这个闭环已经在真实板端验证过。比如从飞书让远程控制板把状态灯调成蓝色,Coordinator 的返回不再是“我已尝试发送”,而是等到 control_agentOutputMessage 回来,再回复用户“远程控制板的状态灯已设置为蓝色”。

这件事看起来只是多了一层结果等待,但本质上它让 MCU Agent 脱离了“只会发指令的聊天壳”,开始具备“知道自己行为结果”的基本能力。

第三章:第四角色为什么变成了 Guardian

早期最容易想到的四角色划分,是把第四块板拿去做显示。但项目推进下来后,第四角色更有价值的定位变成了 guardian_agent

原因也很现实:

第一,显示并不是强约束的边缘职责,P4/Android 更适合做这件事。

第二,当项目真的开始让 AI 参与硬件控制,安全问题比显示问题更早变成主问题。尤其是多节点场景里,控制请求跨过了 MQTT、跨过了不同 ESP32、还可能面向高风险硬件,这时“是否允许执行、谁来裁决、如何审计”会比“怎么显示更好看”更关键。

所以现在第四角色是这样定义的:

1
2
3
4
5
6
7
Guardian:
policy_check
policy_decision
audit
privacy
watchdog
StateBoard

当前 Guardian 已经做了几件实事。

1. policy gate

Coordinator 在执行 mesh_send_command 时,不会直接把命令打给 Sensor 或 Control,而是先发布 espagent.policy_check.v1。Guardian 收到后会根据目标角色、动作、安全等级、部分参数边界和白名单规则,返回 espagent.policy_decision.v1

只有 decision=allow,Coordinator 才会继续发真正的 Mesh command。

2. Control 本地二次校验

Guardian 的意义不只是“中央审核”。当前 control_agent 本机也会缓存最近的 allow decision,并在执行前本地再检查一次。也就是说,即使有人想伪造 MQTT control topic,也不能轻易绕过 Guardian 边界。

3. 审计与 StateBoard

Guardian 还会订阅 agent/timelinenodes/+/statenodes/+/telemetry,对关键事件生成 espagent.guardian.audit.v1。同时它还维护了一个轻量 StateBoard,用来记录最近的 policy_decisionmesh_command_resultfinal_reply、watchdog 状态摘要等。

4. 风险分数与隐私模式

现在 policy_decision 里已经不是单纯的 allow / deny,还会给出 risk_scoreprivacy_mode=metadata_only。这说明 Guardian 已经不只是布尔判断节点,而开始承担“动作风险表达”和“隐私边界表达”的角色。

当然,当前 Guardian 还不是最终态。私有 broker ACL/TLS、真实硬件互锁接线、生产级密钥轮换、参数级更细粒度策略、完整脱敏策略,这些都还没有完成。但项目已经从“靠 prompt 告诉模型不要乱来”走到了“固件路径上强制经过安全节点”的阶段,这个层级已经不一样了。

第四章:ESP32-P4 现在能做什么

P4 这部分是项目最近一个很重要的进度点。

当前 P4 的代码已经不只是个 LVGL 智能家居面板,而是明确增加了一个 AgentMesh tab,并接入了 MQTT 观察链路。它的定位也越来越清楚:

1
2
3
Display Terminal
AgentMesh Observer
Debug / Demo Console

这块屏不是新的 Coordinator,也不直接绕过 Guardian 去控制硬件。它的任务是订阅 Mesh 数据流,然后把多个 Agent 之间的推理、通信和结果展示出来。

当前 P4 已经接入或补齐的内容有:

  • 订阅 agent/timeline
  • 订阅 agent/dispatch
  • 订阅 nodes/+/state
  • 订阅 nodes/+/telemetry
  • 订阅 nodes/+/events
  • 订阅 alerts
  • 订阅 security/policy_check
  • 订阅 security/policy_decision
  • 订阅 security/audit
  • 订阅 guardian/stateboard
  • 订阅 guardian/watchdog

在 UI 上,它现在已经有几层显示:

1. 四角色状态卡

P4 的 AgentMesh 页会为 Coordinator / Sensor / Control / Guardian 分别显示:

  • 当前状态
  • 最近活动
  • 最近 RX
  • 最近 TX

这意味着你不再只看到“某条 timeline 过去了”,而是可以看到每个角色最近在干什么。

2. timeline

P4 已经能解析并显示这些事件:

  • tool_use
  • tool_result
  • policy_check
  • policy_decision
  • mesh_command_queued
  • mesh_command_result
  • guardian_audit
  • stateboard_update
  • watchdog_node_state
  • watchdog_node_telemetry
  • final_reply

这让“用户从飞书说了一句话,系统内部到底发生了哪些步骤”开始具备可视化基础。

3. 遥测卡片绑定

P4 现在不只是显示 timeline,也开始把 sensor_agent telemetry 真正绑定到 UI 卡片上。最近这轮改动里,我把这些补上了:

  • 温度通过 MQTT 实时刷新
  • 湿度通过 MQTT 实时刷新
  • 光照通过 MQTT 实时刷新
  • CO2 通过 MQTT 实时刷新
  • TVOC 会作为 CO2 卡片的 note 显示
  • sample_count 会作为 telemetry 的附加上下文显示
  • risk_score 会在 policy decision 结果区显示

也就是说,P4 不再只是“看通信过程”,开始同时看“数据”和“推理过程”。

当前这版 P4 工程已经重新编译并烧录到 /dev/ttyACM0。屏幕侧的核心链路已经具备,下一步主要是继续用真实四板流量和飞书命令验证“每种事件是否都稳定显示到了 UI”。

第五章:Lua runtime 和 manifest 动态扩展

如果一个 MCU Agent 项目只能操作固件里预先写死的设备,那它最终还是会卡在“每接一个新硬件都要重新写 C、重新编译、重新烧录”。

所以项目这段时间补的另一个很重要的方向,就是受控的动态扩展。

不过这里我没有直接走“让 AI 自由裸控 GPIO/I2C/UART/SPI”的方向,因为那条路很危险。真正落地的路径有两层。

第一层:manifest primitive

项目现在已经有 runtime hardware manifest 体系。开发者可以用结构化 JSON 描述一个硬件设备的通信方式、参数和权限边界,固件会校验:

  • manifest_version
  • permissions
  • role / risk 边界
  • SHA-256 sidecar

目前已经补上的 manifest 类型主要是 read-only 路径,例如:

  • I2C
  • UART
  • Modbus
  • SPI
  • ADC
  • GPIO input

控制类 manifest 也已经开始支持,但不是完全开放的自由控制,而是必须继续经过 Guardian、风险级别、duration、safe-state restore 等限制。

这意味着项目已经开始具备一种更接近“二次开发产品”的底座:不是所有新设备都必须重新写固件,而是可以通过 manifest 描述能力边界,然后由固件按规则去调用既有 primitive。

第二层:Lua runtime

除了 manifest,项目还把 Lua runtime 真正接进了固件。

当前已经支持:

  • lua_runtime_info
  • lua_list_modules
  • lua_list_scripts
  • lua_run_source
  • lua_run_script
  • lua_run_script_async
  • lua_list_jobs
  • lua_get_job
  • lua_stop_job

但这套 Lua 不是裸脚本执行器。它被严格限制在 ESPAgent 现有能力边界内。当前 Lua 访问硬件的路径是:

1
2
3
4
5
Lua
-> espagent.call_capability(name, args_json)
-> capability registry / tool registry
-> sandbox / role profile / Guardian / Mesh / interlock
-> 真正硬件

这意味着 Lua 的价值不是绕过系统,而是在系统允许的边界内提供更灵活的组合能力。

换句话说,项目在吸收 esp-claw 这类单板 Agent runtime 思想时,保留的是它的工程化优势,而不是照搬它的“直接脚本化硬件访问方式”。

这条边界我认为非常重要。因为如果脚本层可以绕过 capability_registrytool_registryGuardianControl interlock,那整个多节点安全架构就失去意义了。

第六章:关于 skills、benchmark 和“这个项目现在算到哪一步了”

现在这个项目已经不仅仅有工具,还有一套运行时 skills 和 benchmark 体系。

当前 SPIFFS / prompt 里已经补充了几类更偏系统层的 skills:

  • Agent Mesh 协调
  • MQTT Mesh 运维边界
  • MCU edge AI 能力边界
  • sandbox / permissions
  • privacy / data minimization
  • tool integrity / prompt injection 防护

这些 skills 的意义不是“给模型多讲一点背景故事”,而是把系统边界固化到运行时提示里,让模型在工具选择、权限判断和上下文使用上更稳定。

另一方面,项目现在也不再只是“凭感觉说 skills 有效”,而是增加了自己的 benchmark。通过 tools/benchmark_skills_usb0_3.py,可以在四板串口上对 skills loading、Mesh routing、sandbox、privacy、prompt injection、workflow 等行为做回归验证。

这件事本身也很重要。因为如果一个 Agent 系统没有验证手段,那很多时候我们说“这个 skill 已经支持”“这个边界已经生效”其实只是主观判断。

到目前为止,我对这个项目的判断是:

已经跨过去的阶段

  • 已经不是单板玩具,而是四角色多节点 Agent Mesh。
  • 已经不是只会本地 tool calling,而是跨节点 ReAct + OutputMessage 闭环。
  • 已经不是只有硬件控制,而是加上了 Guardian 安全裁决。
  • 已经不是只有串口/飞书结果,而是开始有 P4 终端展示推理与通信过程。
  • 已经不是完全写死硬件,而是开始有 manifest 和 Lua 两层动态扩展底座。

还没跨过去的阶段

  • 还不是完全异步、可恢复、可查询的任务调度系统。
  • 还没有完整的长期 trace 索引与远程查询 API。
  • 还没有生产级的 TLS、ACL、密钥轮换和真实硬件互锁部署流程。
  • 还没有把 Android / P4 做成成熟的工程化上位机。
  • 还没有把复杂协议全部做成真实可执行 primitive。

也就是说,这个项目现在已经有了非常清晰的系统骨架,但还没有到“产品完成态”。

最后一章:为什么我仍然觉得这条路值得继续做

如果只从“点灯、读温湿度”这些局部现象来看,做四块 ESP32、再加 P4 和 Android,似乎有点重。但真正值得做的从来不是这些单个现象,而是它背后的系统能力迁移。

这个项目现在最有意思的地方,其实是把很多原本只在 PC Agent、云端 Agent、代码 Agent 上才常见的概念,开始一点点迁移到了 MCU 边缘系统里:

  • ReAct
  • tool calling
  • subagent
  • OutputMessage
  • sandbox
  • policy gate
  • audit
  • dynamic extension
  • benchmark
  • timeline visualization

这些能力一旦能在 MCU 边缘端建立起稳定边界,它的意义就不再只是“做一个会聊天的控制板”,而是为一种新的边缘智能设备形态打基础:设备自己能够理解任务、调用工具、请求权限、把结果结构化返回、和其他节点协作,并且把全过程可视化给人看。

当前 ESPAgent 距离这种终局当然还有距离,但方向已经开始变清楚了。

从单板 Agent 到四角色 Agent Mesh,从工具调用到跨节点闭环,从硬件控制到权限治理,从串口日志到 P4 可视化终端,我觉得这条路已经不是“能不能做”的问题,而是“后面把哪些能力做扎实”的问题了。