ZeroClaw MQTT 通道接入指南:从 Broker 订阅到 SOP 事件驱动的完整实战
【免费下载链接】zeroclawFast, small, and fully autonomous AI personal assistant infrastructure, any OS, any platform — deploy anywhere, swap anything 🦀项目地址: https://gitcode.com/gh_mirrors/ze/zeroclaw
ZeroClaw 的mqtt通道(channel)负责连接 MQTT Broker、订阅主题,并把每条到达的消息送入 Agent 循环或 SOP 引擎,是典型的外部事件扇入(fan-in)源。本文以 MQTT 通道文档 为主体,结合仓库中的配置 Schema 与监听器实现,带你掌握[channels.mqtt]全部字段的含义与校验规则、TLS 配置的正确姿势、底层订阅-分发调用链,以及「收到消息 → 触发 SOP 运行」的完整实战路径。
MQTT 通道在 ZeroClaw 中的定位
mqtt通道的本质是一个SOP 事件源(SOP event source):它订阅 Broker 上配置的主题,将每一条 publish 消息打包成 SOP 事件,交由 SOP 引擎按触发器匹配并启动运行,而不是进入常规聊天循环。在配置层面,它是[channels.mqtt.<alias>]下的多实例通道(见 schema.rs 中的注册)。
这一点决定了它的两个关键属性:
- 纯输入通道:从配置 Schema 看,
mqtt与amqp被归类为 input-only 传输,其Channel::send是空操作(no-op),没有出站消息面。它只负责把事件送进引擎,不负责对外回复。 - 触发语法与主题匹配在 SOP 侧:通道文档只覆盖 Broker 连接层;触发器(trigger)的语法、主题通配与
condition判定,统一由 SOP Fan-In: MQTT 说明,两页配合使用。
同时,它由channel-mqtt构建特性门控:在 crates/zeroclaw-channels/Cargo.toml 中channel-mqtt = ["dep:rumqttc"],即启用该特性才会引入rumqttc客户端依赖;channels-full特性集合中也包含它。需要说明:channel-mqtt不在default-channels之内,启用它需要显式开启对应 feature。
配置文件字段详解
通道的全部字段由MqttConfig结构体定义(schema.rs#L17416-L17465),前缀为channels.mqtt。下面按「行为 / 连接 / 高级」分组整理,附默认值与取值约束:
| 字段 | 分组 | 类型 | 默认值 | 说明 |
|---|---|---|---|---|
enabled | 行为 | bool | false | 是否激活。运行时只加载enabled = true的通道。默认false是有意设计:防止粘贴了半截[channels.<type>.<alias>]配置块就把通道意外带活 |
broker_url | 连接 | string | 无(必填) | Broker 地址,如mqtt://localhost:1883或mqtts://broker.example.com:8883。必须使用mqtt://(明文)或mqtts://(TLS)前缀,校验会拒绝其他 scheme |
username/password | 连接 | string | 无 | 可选认证凭据。password标记为 secret 字段,配置导出与 Schema 中带x-secret标注,注意保密 |
client_id | 高级 | string | 无(必填) | MQTT 客户端 ID,同一 Broker 下必须唯一,且不能为空 |
topics | 高级 | string 数组 | 空 | 要订阅的主题列表,至少一个,支持通配符,如sensors/#、alerts/+/critical |
qos | 高级 | u8 | 1 | 服务质量:0= 至多一次(at-most-once),1= 至少一次(at-least-once),2= 恰好一次(exactly-once)。默认 1;大于 2 会被校验拒绝 |
use_tls | 高级 | bool | false | 是否启用 TLS 加密。必须与broker_url的 scheme 配对:mqtt://→false,mqtts://→true |
keep_alive_secs | 高级 | u64 | 30 | 心跳保活间隔(秒),防止 Broker 因空闲而断开连接 |
excluded_tools | 行为 | string 数组 | 空 | 从该通道工具规格中排除的工具列表。设置后这些工具不会在经由该通道响应时暴露给模型 |
一个最小可用配置(基本订阅者)只需要broker_url和topics,但按校验规则还必须提供非空client_id并显式置enabled = true:
[channels.mqtt.default] enabled = true broker_url = "mqtt://localhost:1883" client_id = "zeroclaw-sop" topics = ["sensors/#", "alerts/+/critical"]完整字段参考见 config reference。
配置校验规则:启动前的一道保险
MqttConfig::validate()(schema.rs#L17476-L17519)在监听器启动时最先执行,逐项检查:
- QoS 合法:
qos必须为 0、1 或 2,否则报qos must be 0, 1, or 2; - URL scheme 合法:
broker_url必须以mqtt://或mqtts://开头,否则报错; - TLS 与 scheme 配对:
mqtt://+use_tls = true报错;mqtts://+use_tls = false报错(这是最常见的连接失败原因之一); - 至少一个主题:
topics为空直接拒绝启动; - client_id 非空:空
client_id触发RequiredFieldEmpty校验错误。
这些规则在 crates/zeroclaw-channels/src/orchestrator/mqtt.rs 的单元测试中均有对应断言:mqtt_config_validation_rejects_bad_qos、mqtt_config_validation_rejects_bad_url、mqtt_config_validation_rejects_empty_topics、mqtt_tls_flag_rejects_mqtt_scheme_with_use_tls等,把「错误配置在启动前被拦截」固化成了可回归的测试行为。
TLS 配置:让 scheme 与 use_tls 保持一致
启用加密的唯一正确姿势是:use_tls与broker_url的 scheme 严格配对——
mqtts://搭配use_tls = true(TLS 加密传输);mqtt://搭配use_tls = false(明文传输)。
[channels.mqtt.secure] enabled = true broker_url = "mqtts://broker.example.com:8883" client_id = "zeroclaw-sop-secure" topics = ["iot/#"] use_tls = true两者不一致是启动期最常见的连接失败原因,且会被validate()在连接前直接拒绝,属于「快速失败」设计。在实现层,use_tls = true时监听器调用Transport::tls_with_default_config()配置 TLS 传输并输出日志MQTT SOP listener: TLS transport enabled(mqtt.rs#L38-L45)。安全基线层面,SOP 扇入的安全默认值表格也把「MQTT 传输」列在册:mqtts://配use_tls = true(见 SOP Fan-In 概览)。
底层实现:run_mqtt_sop_listener 的分发链路
从源码结构看,mqtt通道在 crates/zeroclaw-channels/src/orchestrator/mqtt.rs 中实现为run_mqtt_sop_listener,它不实现Channeltrait,而是通过dispatch_untrusted_fan_in把 MQTT 消息路由给 SOP 引擎——这再次印证了它作为扇入监听器而非聊天通道的定位。其执行流程如下:
- 校验并构造客户端:先
config.validate(),再以client_id、broker_host、broker_port构造MqttOptions,设置keep_alive,若配置了用户名/密码则调用set_credentials; - 按 QoS 映射:
0 → QoS::AtMostOnce、1 → QoS::AtLeastOnce、其余→ QoS::ExactlyOnce; - 逐主题订阅:遍历
config.topics调用client.subscribe(topic, qos),每个主题订阅成功都会写日志; - 健康标记:连接建立(
ConnAck)后调用zeroclaw_runtime::health::mark_component_ok("mqtt"),出错时mark_component_error("mqtt", ...),供健康检查面板观测; - 消息分发:收到
Packet::Publish时,把 payload 以 UTF-8 lossy 方式转成文本,通过SopIngress以SopTriggerSource::Mqtt连同msg.topic一起 dispatch 给 SOP 引擎; - 断线自愈:轮询出错时记录 WARN 日志并继续循环,由
rumqttc自身处理自动重连(auto-reconnect)。
值得注意的细节:broker_host/broker_port两个辅助函数负责从 URL 中拆解主机与端口,端口缺省时按 scheme 推断——mqtt://默认1883、mqtts://默认8883(mqtt.rs#L108-L134),并配有broker_port_defaults_1883_for_mqtt、broker_port_defaults_8883_for_mqtts等测试验证。
SOP 触发器:主题匹配与 condition 判定
通道建立订阅后,消息如何触发运行由 SOP Fan-In: MQTT 决定:
- 主题通配:支持
+(单层)与#(多层)通配符。例如订阅sensors/#能匹配sensors/temp、sensors/humidity/outdoor;alerts/+/critical匹配alerts/room1/critical。 - payload 进入事件:MQTT payload 会被转发进 SOP 事件的 payload,供可选的触发器
condition判定;步骤上下文接收的是被截断(capped)、净化(sanitized)、加框(framed)后的形态,且整个 topic/payload 文本在进入模型上下文前会经过长度上限、归一化与 prompt-guard 筛查(见 SOP Fan-In 概览的安全默认值)。 - JSON-path 条件:像
$.value > 85这样的 condition 要求发布者发送 JSON 主体,否则判定无从谈起。
「收到消息 → 事件被构造 → 派发」这条链路由监听器与SopIngress::dispatch共同完成,属于「一个匹配路径」设计:无论事件来自 MQTT、文件系统还是 AMQP,都走同一个触发器匹配器,行为一致(见 SOP Fan-In 概览)。
触发一次运行
加载好 SOP 并让 MQTT 通道完成订阅后,向命中触发器模式的主题发布一条消息即可,例如用mosquitto_pub或任意 Broker 客户端:
mosquitto_pub -h localhost -p 1883 -t "sensors/temp" -m '{"value": 92}'监听器会从 topic 与 payload 构造事件并派发:每一个已加载 SOP,只要其topic模式命中、且condition(若有)对 payload 成立,就会启动一次运行。如果什么都没发生,依次核对:主题是否真的命中触发器模式、Broker 订阅是否存活、condition是否与 payload 相符,具体可对照 扇入概览的故障排查表。
审批与观察
命中检查点(checkpoint)的运行会暂停为WaitingApproval状态,可以用 CLI 或网关 API 处置:
- CLI:
zeroclaw sop list、zeroclaw sop approve; - 网关 API(out-of-band):
GET /admin/sop/pending、POST /admin/sop/approve、POST /admin/sop/deny(详见 gateway API)。
故障排查速查表
| 症状 | 可能原因 | 解决办法 |
|---|---|---|
| 启动期连接错误 | Broker URL 与 TLS 标志不一致 | 让 scheme 与use_tls配对:mqtt://配false,mqtts://配true |
| 已订阅但收不到消息 | 主题过滤器与发布者实际发布的主题不匹配 | 对照发布方实际 emit 的主题,核对topics与+/#通配符写法 |
| SOP 不启动 | 主题不匹配或condition判定失败 | 对照 触发器文档 检查触发器主题与condition是否与 payload 相符 |
延伸阅读
- SOP Fan-In: MQTT:触发器语法与主题匹配规则
- SOP Fan-In 概览:扇入分发原理与安全默认值
- AMQP 通道:同为消息队列扇入源的另一通道
- Channels 概览:全部通道的横向视图
- SOP 语法:
SOP.toml/SOP.md文件格式 - 实现与测试:监听器实现、配置 Schema、特性定义
【免费下载链接】zeroclawFast, small, and fully autonomous AI personal assistant infrastructure, any OS, any platform — deploy anywhere, swap anything 🦀项目地址: https://gitcode.com/gh_mirrors/ze/zeroclaw
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考