SOP Fan-In:概览
fan-in 是一种外部事件源,用于启动 SOP 运行。每个源通过 dispatch_sop_event 将事件传递给 SOP 引擎,后者会将每个事件与所有已加载 SOP 的触发器逐一匹配,并为匹配的 SOP 启动运行。
一个 ZeroClaw 实例可以一次绑定多个 fan-in:一个 MQTT 主题、一个文件系统路径以及一个 AMQP 路由键都可以在无需单独进程的情况下输入同一个引擎。下面为每个来源提供了专门的指南。
调度是如何工作的
- 单一匹配器路径: 单个匹配器会评估每种触发器类型,因此无论来源如何,匹配行为都相同。
- 运行开始审计: 已启动的运行通过
SopAuditLogger进行持久化。 - 无头安全性: 在非智能体循环上下文中,
process_headless_results会将ExecuteStep操作记录为待处理状态,而不是静默执行它们。 - **不受信任的输入:**在到达模型上下文之前,topic 和 payload 文本会被截断、标准化、经过 prompt-guard 筛查并加上边界框架。
源代码
直接从 SopTrigger 注册表投影的每种 SOP 触发器类型、其字段以及其派发状态:
| 类型 | 字段 | 备注 |
|---|---|---|
mqtt | topic,可选的 condition | MQTT 消息到达。Live:由 MQTT 监听器传递。 |
webhook | path | 传入的 HTTP 请求。已上线:网关 /sop/* 和 SOP 优先的 /webhook 路由。 |
cron | expression | 基于时间的触发。实时:由 SOP 维护定时器(daemon / channel-start 路径)分发。 |
peripheral | board、signal,可选的 condition | 硬件信号。已定义并匹配,但没有外围监听器为其提供输入。 |
filesystem | path、可选的 condition、可选的 events | Filesystem 变更。实时:由文件系统监视器传递。 |
calendar | calendar_source,可选 calendar_ids,可选 condition | 日历事件状态。已定义并匹配,但没有轮询器实时提供它。 |
channel | channel、可选 alias、可选 condition | 配置的通道上的入站消息或 forge/platform 事件(telegram、discord、slack、Git 等)。实时:当启用该通道的 SOP dispatch 时,由通道协调器投递。Git forge 生产者会设置形如 <channel>.<alias>:<event_type> 的事件主题,并将 event_type 放入载荷中,因此编写的 condition 可以按类型过滤 forge 事件,而无需第二种触发器形状。 |
manual | 无 | 通过 sop_execute 工具发起的代理运行。不是外部 fan-in。 |
amqp | routing_key,可选 condition | AMQP 投递。Live:由 AMQP 消费者以 SOP 派发模式投递。 |
每个源在侧边栏中都有专属指南。实时源(由正在运行的监听器或经过身份验证的网关请求提供)会在事件到达时启动运行;cron 触发器由守护进程的定期 SOP 维护周期调度;代理发起的运行会在代理轮次内通过 sop_execute 启动;其余已定义但尚未接入的源(外围设备和日历)可以验证并匹配,但目前还没有实时事件源路由到调度器。
安全默认值
| 担忧 | 机制 |
|---|---|
| Webhook 身份验证 | Gateway 配对 Bearer 身份验证,以及可选的 gateway.webhook_secret/X-Webhook-Secret;/sop/* 和 /webhook 共享同一个速率限制器。必须至少配置一个控制项用于 SOP 分发,并且所有已配置的控制项都必须通过验证。单独的 [channels.webhook] 别名密钥永远不会授权这些路由 |
| Webhook 重放保护 | 可选的 X-Idempotency-Key,按 SOP 路径设置命名空间,并在 /sop/* 与 /webhook 之间分别设置命名空间。键会在分派前预留,表示至多尝试一次,而不能证明之前的运行已开始 |
| MQTT 传输 | mqtts:// 搭配 use_tls = true 用于 TLS 传输 |
| Filesystem 根目录 | 宽泛根路径(/、/home、/etc、/var、/proc、/sys、/dev、/tmp)在配置校验时会被拒绝,除非启用 allow_broad_roots;include/exclude glob 的作用范围是事件 |
| Filesystem symlinks | 默认情况下,符号链接事件路径会在读取任何元数据、哈希或内容之前被拒绝;follow_symlinks = true 可选择启用,但仍要求规范化后的目标解析到受监视的根目录内 |
| 不受信任的触发输入 | 主题和载荷文本在进入模型上下文之前会被设定上限、规范化、经过提示词防护筛查并加上边框。 |
| 不安全触发块 | untrusted_input_guard = "block" 会使用 BlockedUnsafe 拒绝不安全的未受信任事件;默认的 warn 会审计并允许。 |
| Cron 验证 | 无效的 cron 表达式在解析和缓存构建期间会以失败关闭方式处理 |
| 无头调度 | 无头调用方会记录运行进度,而不是自动执行 ExecuteStep |
故障排除
| 症状 | 可能的原因 | 修复 |
|---|---|---|
| SOP 从不从实时源开始 | 触发器模式不匹配或 condition 失败 | 验证触发器模式与已送达事件匹配;检查 condition 是否符合负载 |
| SOP 已启动,但某个步骤未执行 | 无活动 agent 循环的无头触发 | 为 ExecuteStep 运行一个代理循环,或者将运行设计为在审批时暂停 |
| Webhook 触发器从未触发 | 精确触发路径不匹配、SOP 子系统不可用或身份验证被拒绝 | 配置 sop.sops_dir 后运行 zeroclaw daemon,准确匹配完整请求路径,并提供已配置的 bearer/secret 标头 |
| 外设或日历触发器从不触发 | 事件源未连接到调度器 | 使用实时源(Webhook、MQTT、Filesystem、AMQP)或使用 sop_execute 启动运行 |
| Cron 触发器从未触发 | 维护 tick 未运行(未运行 zeroclaw daemon 或 zeroclaw channel start;独立的 gateway start 不会运行该任务),sops_dir 未设置/为空,或 maintenance_interval_secs = 0 | 将 sop.sops_dir 设置为非空值(默认未设置;文档中的值为 shared/sops),并将 sop.maintenance_interval_secs 设置为非零值(默认为 60),然后运行 zeroclaw daemon(或 zeroclaw channel start) |
另见
- 语法:完整的
SOP.toml和SOP.md格式 - SOP 如何运行
- Channels: 概览:MQTT、文件系统和 AMQP 的传输端