Keyboard shortcuts

Press or to navigate between chapters

Press ? to show this help

Press Esc to hide this help

Matrix

在 Matrix 房间中运行 ZeroClaw,包括端到端加密(E2EE)房间。

谁可以与代理通信

入站发送方会根据为绑定代理解析出的对等集合进行限制,该集合来自代理所属的 peer_groups 配置。匹配时会去除开头的 @,并对通道的原生发送方标识符执行不区分大小写的比对。集合会拒绝所有人;包含 "*" 的集合会接受所有人;否则仅接受列出的外部对等方(以及对等代理)。这与网关配对(gateway.require_pairing)不同,后者验证的是 HTTP/WebSocket 客户端,而非聊天通道的发送方。

matrix 的对等组将 channel 设置为 matrix,在 external_peers 中列出允许的发送者(对于 matrix,使用完整的 Matrix 用户 ID,@user:server.tld["*"] 接受任何人),可选地命名对等 agents 以实现跨代理分发、一个 ignore 屏蔽列表,以及一个 output_modalitymirrorvoicetext)。字段参考请参见 Peer Groups

在何处设置:

网关仪表板

在 Web 仪表板中打开 /config/peer_groups

zerocode

Config 窗格中的 Peer groups 下。

本指南针对的常见故障模式:

“Matrix 配置正确,检查通过,但机器人未响应。”

快速常见问题解答

如果 Matrix 显示已连接但没有回复,请先验证以下内容:

  1. 发送方在代理的对等集合中(用于测试:external_peers = ["*"])。
  2. 机器人账号已加入目标房间。
  3. 凭据归属于机器人账户(在令牌路径上执行 whoami 检查,参见 §5C)。
  4. 已加密房间可解密:已设置 recovery_key(推荐)或密钥已共享至机器人设备。
  5. 守护进程已在配置更改后重启。

1. 需求

在测试消息流之前:

  1. 机器人账号已加入目标房间。
  2. 凭据用于对机器人账户进行身份验证:可使用 user_id + password(推荐,参见 §2),或使用 access_token(令牌方式,§3)。
  3. allowed_rooms 包含目标房间(或留空以允许机器人已加入的所有房间)。条目会与每条传入消息的规范房间 ID(!room:server)进行字面匹配,因此请在此列出规范房间 ID:ZeroClaw 不会为此允许列表解析 #alias:server 条目。(仅会为出站投递目标解析别名,例如 cron 的 delivery.to。)可在客户端中查找房间的规范 ID(在 Element 中:房间设置 → 高级 → 内部房间 ID)。
  4. 对等组授权发送方(external_peers = ["*"] 用于开放测试,参见 §6)。
  5. 对于 E2EE 房间,机器人可以解密:recovery_key(推荐)会自动恢复密钥,或者手动将密钥共享到机器人设备。

2. 配置

access_token 🔑 secret · default null

机器人账户的 Matrix 访问令牌。未设置时,该通道将回退为使用 user_id + password 进行密码登录。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.access_token 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.access_token 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.access_token    # 掩码输入,加密存储

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__access_token=
ack_reactions bool? · default null

顶层 [channels].ack_reactions 的覆盖项。当为 None 时,回退到全频道范围的默认值。当显式设置(true/false)时,仅对此 Matrix 实例优先生效。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.ack_reactions 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.ack_reactions 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.ack_reactions <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__ack_reactions=
allowed_rooms string[] · default []

允许的 Matrix 房间 ID。留空 = 允许机器人已加入的所有房间。每个条目会与每条传入消息的规范房间 ID(!abc:server)进行精确匹配;#room:server 别名不会被解析用于此允许列表(它们仅在用于出站投递目标时才会被解析,例如 cron delivery.to)。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.allowed_rooms 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.allowed_rooms 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.allowed_rooms <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__allowed_rooms=
approval_timeout_secs integer · default 300

always_ask 工具等待操作员批准的秒数,超时后自动拒绝。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.approval_timeout_secs 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.approval_timeout_secs 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.approval_timeout_secs <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__approval_timeout_secs=
device_id string? · default null

可选的 Matrix 设备 ID。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.device_id 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.device_id 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.device_id <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__device_id=
draft_update_interval_ms integer · default 1500

Partial 模式下 Matrix 草稿编辑与 SingleMessage 模式下思考/推理进度编辑之间的最小间隔(毫秒)。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.draft_update_interval_ms 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.draft_update_interval_ms 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.draft_update_interval_ms <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__draft_update_interval_ms=
excluded_tools string[] · default []

从此通道的工具规范中排除的工具。设置后,通过此通道响应时不会向模型公开这些工具。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.excluded_tools 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.excluded_tools 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.excluded_tools <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__excluded_tools=
homeserver* string · default

Matrix 服务器名称或 homeserver URL(例如 "matrix.org""https://matrix.example.org")。服务器名称使用标准的 /.well-known/matrix/client 发现机制。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.homeserver 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.homeserver 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.homeserver <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__homeserver=
interrupt_on_new_message bool · default false

在新消息到达时是否中断正在进行的代理响应。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.interrupt_on_new_message 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.interrupt_on_new_message 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.interrupt_on_new_message <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__interrupt_on_new_message=
mention_only bool · default false

为 true 时,在群组中仅响应 @ 提及该机器人的消息。私信始终会被处理。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.mention_only 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.mention_only 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.mention_only <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__mention_only=
message_max_bytes integer · default 48000

单条消息流式草稿编辑和单独最终响应的序列化 Matrix 事件内容字节预算。渲染后的 Markdown 正文、生成的 HTML 以及回复/编辑关系都会计入此限制。超出大小的进度记录会丢弃完整的最旧条目;单独的最终响应会保留 UTF-8 安全的前缀。低于 512 的值将使用该最小值,从而为非空的序列化事件留出空间。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.message_max_bytes 字段。

zerocode

Config 面板中,设置 channels.matrix.<alias>.message_max_bytes 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.message_max_bytes <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__message_max_bytes=
multi_message_delay_ms integer · default 800

在 MultiMessage 模式下,发送每个段落之间的延迟(毫秒)。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.multi_message_delay_ms 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.multi_message_delay_ms 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.multi_message_delay_ms <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__multi_message_delay_ms=
password 🔑 secret · default null

Matrix 账户的可选登录密码(用于初始登录流程)。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.password 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.password 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.password    # 掩码输入,加密存储

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__password=
recovery_key 🔑 secret · default null

可选的 Matrix 恢复密钥,用于自动还原 E2EE 密钥备份。设置后,ZeroClaw 会在启动时恢复房间密钥和交叉签名密钥。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.recovery_key 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.recovery_key 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.recovery_key    # 掩码输入,加密存储

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__recovery_key=
reply_in_thread bool · default true

为 true(默认值)时,回复将以话题回复的形式发送。如果尚不存在话题,则从传入消息开始新的话题。为 false 时,仅继续现有话题。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.reply_in_thread 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.reply_in_thread 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.reply_in_thread <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__reply_in_thread=
reply_min_interval_secs integer · default 0

每个(通道,接收方)出站节流下限(秒)。范围:0..=REPLY_MIN_INTERVAL_MAX_SECS(0 表示禁用)。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.reply_min_interval_secs 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.reply_min_interval_secs 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.reply_min_interval_secs <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__reply_min_interval_secs=
reply_queue_depth_max integer · default 0

每个(channel, recipient)出站节流队列的深度。取值范围:0..=REPLY_QUEUE_DEPTH_CEILING。当 reply_min_interval_secs > 0 且此值为 0 时,节流封装器会使用 DEFAULT_REPLY_QUEUE_DEPTH(16)作为替代值。当队列已满时,最新的发送会被丢弃,并记录一条 WARN 日志。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.reply_queue_depth_max 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.reply_queue_depth_max 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.reply_queue_depth_max <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__reply_queue_depth_max=
stream_draft_delete bool · default true

在发送最终响应之前,删除 Matrix 单消息进度草稿。为 false 时,持久化进度会作为可见记录保留;仅包含占位符的草稿仍会在最终响应之前被删除。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.stream_draft_delete 字段。

zerocode

Config 面板中,设置 channels.matrix.<alias>.stream_draft_delete 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_draft_delete <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__stream_draft_delete=
stream_draft_lines integer · default 10

Matrix 单消息流式草稿中保留的进度行最大数量。设置为 0 可移除行数限制;所有行仍共同受限于单个有字节数上限的 Matrix 草稿事件。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.stream_draft_lines 字段。

zerocode

Config 面板中,设置 channels.matrix.<alias>.stream_draft_lines 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_draft_lines <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__stream_draft_lines=
stream_mode MatrixStreamMode · default "off"

用于渐进式响应传递的流式模式。"off"(默认):单条最终消息。"partial":就地编辑草稿。"single_message":进度草稿加单独的最终消息。"multi_message":按段落拆分传递。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.stream_mode 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.stream_mode 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_mode <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__stream_mode=
stream_reasoning StreamReasoningMode · default "status"

Matrix 单消息推理可见性。"off" 抑制由推理生成的草稿更新,"status" 发出保活信号但不包含原始推理文本,"full" 将提供商的原始推理文本发出到进度草稿中。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix,然后设置 channels.matrix.<alias>.stream_reasoning 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.stream_reasoning 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_reasoning <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__stream_reasoning=
stream_tool_arguments StreamToolArgumentEntry[] · default []

Matrix 单消息进度行中显示的工具参数。缺失或为空表示采用保守的 safe 默认值。使用一个 { default_base = "none" | "safe" | "all" } 条目设置继承设置,然后使用带有可选 baseincludeexcludeargument_chars 调整项的工具精确名称条目。argument_chars 限制每个显示值的字符数,默认值为 60;0 表示禁用此限制。在 safe 下,未知工具解析为不包含任何参数;显示前会对每个选中的值进行泄露信息清理。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.stream_tool_arguments 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.stream_tool_arguments 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_tool_arguments <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__stream_tool_arguments=
user_id string? · default null

可选的 Matrix 用户 ID(例如 "@bot:matrix.org")。

将它放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.user_id 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.user_id 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.user_id <value>

环境变量

导出此覆盖配置(POSIX shell;可放入 ~/.bashrc~/.zshrc.env 或 Dockerfile 中)。将 <alias> 替换为实际的别名:

export ZEROCLAW_channels__matrix__<alias>__user_id=

Matrix 配置为 [channels.matrix.<alias>] 块。可通过以下任一方式进行设置:

网关仪表板

在 Web 仪表板中打开 /config/channels/matrix

zerocode

Config 窗格中,Channels 下。

推荐设置:密码 + 恢复密钥

运行 Matrix 的官方、最省事方式是让 ZeroClaw 重新登录并管理其自己的设备身份:

  • 省略 device_id 在登录时让 homeserver 分配一个。ZeroClaw 会将分配到的 id 保存到 session.json,并在每次重启时重用它,因此你无需查找、复制或同步任何值。手动固定 device_id 是导致密钥共享失败的最常见原因。
  • 省略 access_token 当其未设置时,ZeroClaw 会回退到密码登录。自动恢复流程(§8)同样使用全新登录,因此机器人无需操作员介入即可从损坏的本地状态中自我修复。
  • 设置 password 在没有 access_token 的情况下,使用 user_id + password 进行登录。
  • 设置 recovery_key 这会从服务器端备份恢复房间密钥,并在每次启动时自动对新注册的设备进行交叉签名:无需 emoji 验证,无需手动共享密钥,无需引导。请参阅 §5I 了解如何从 Element 获取它。

因此,一个完整的推荐配置块会设置 homeserveruser_idpasswordrecovery_key,而不设置 access_tokendevice_id

access_token + device_id 路径(§3)仍然可用,并为必须复用已有令牌的运维人员提供了完整文档,但它要求你自行维护一个稳定的 device_id,因此除非有特殊原因,否则建议优先使用密码 + 恢复密钥。

channels.matrix.<alias>.password 是机密信息。 以加密形式存储,绝不以明文保存在 config.toml 中。请通过以下方式之一进行设置,这些方式会在写入时加密:

网关仪表板

打开 /config/channels/matrix,并在其中设置 channels.matrix.<alias>.password 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.password 字段(输入内容会被掩码处理)。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.password    # 提示输入掩码内容,以加密形式存储

**channels.matrix.<alias>.access_token 是机密信息。**以加密方式存储,绝不以明文形式保存在 config.toml 中。请通过以下任一方式进行设置,这些方式会在写入时加密:

网关仪表板

打开 /config/channels/matrix 并在其中设置 channels.matrix.<alias>.access_token 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.access_token 字段(输入内容已掩码)。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.access_token    # 提示输入掩码内容,以加密形式存储

homeserver 为必填项。对于推荐的设置,还需设置 user_idpasswordrecovery_keyaccess_tokendevice_id 仅在 §3 中基于令牌的路径中需要;allowed_rooms 可选地限制 bot 在哪些房间中响应。通过对等组授权发送者。完整字段索引:配置参考

还没有 recovery_key 请参阅 §5I:其中详细说明了如何在 Element 中生成一个。想改用令牌方式?请参阅 §3,了解通过密码登录 API 调用一次性生成 access_token 和稳定 device_id 的方法。要查找你已有令牌对应的 device_id,请参阅 §5H

关于 user_iddevice_id

  • 对于推荐的密码 + 恢复密钥设置,请设置 user_id 并将 device_id 留空:homeserver 会分配该值,ZeroClaw 会将其持久化保存。
  • ZeroClaw 从 Matrix /_matrix/client/v3/account/whoami 读取身份信息。
  • 只有在使用 access_token 登录时,才需要手动设置 device_id:令牌登录所携带的设备是服务器已经创建的,而 ZeroClaw 需要这个确切的 id 来恢复 E2EE 会话(参见 §5H 了解如何查找它)。

线程与上下文

当 Matrix 会话发生在某个话题(thread)中时,该话题就是其独立的会话。ZeroClaw 会为每个话题派生一个独立的会话密钥,因此每个话题都拥有独立的上下文窗口和历史记录:某个话题中的消息绝不会渗入另一个话题,并且代理也无法看到同级话题中较早的对话轮次。对于 Matrix,这一行为由 reply_in_thread 控制:当其开启时,顶层消息会开启一个话题,且每个话题都是一个独立的会话;当其关闭时,回复将发布在频道根级别,并且历史记录将改为按发送者和目标来索引,而非按话题。

  • 隔离正是关键所在。 每个线程的上下文都是自包含的:它不会泄漏到线程之外,线程之外的任何内容也不会泄漏进来。并行线程持有各自独立的对话状态,因此互不相关的任务永远不会相互干扰。
  • 长线程会增大上下文。 线程在保持活动状态期间会累积历史记录,因此与其他长对话一样,过长的线程最终会填满模型的上下文窗口。开始新线程即可重置。
  • 进行中的工作以线程为单位进行隔离。 在某个线程中发送新消息不会取消另一个线程中进行中的响应;每个线程的任务都是独立的。

为任意 surface 设置线程行为:

网关仪表板

打开 /config/channels/matrix 并切换 channels.matrix.<alias>.reply_in_thread 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.reply_in_thread 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.reply_in_thread true     线程回复开启
zeroclaw config set channels.matrix.<alias>.reply_in_thread false    # 频道根目录的回复

3. 令牌路径(备选方案):获取 access_tokendevice_id

[!IMPORTANT] 本节仅适用于 access_token 路径。如果你按照 §2 中推荐的密码 + 恢复密钥设置进行操作,则可以跳过本节:你不需要访问令牌或手动管理的 device_id

当你必须复用已有令牌(例如从另一部署中复制的令牌)时,请使用此路径。Element 不会直接公开令牌,因此生成令牌的规范方式是进行一次性的密码登录 API 调用,该调用会同时返回访问令牌和稳定的设备 ID。令牌登录会携带设备,因此在此路径下 device_id 是必需的,并且必须保持稳定。

如果你的操作员账户已经拥有令牌,请跳至§4。如果你只需要查找现有令牌的 device_id,请参阅§5H 选项 1(whoami)或选项 2(Element)。

步骤 1:通过密码登录获取令牌

运行一次此操作。替换 your.homeserver、机器人用户名、密码,并选择任意短字符串作为 device_id(字母数字,不含空格;这是 ZeroClaw 在每次重启时都会复用的_服务器端_设备标签):

sh

curl -sS -X POST https://your.homeserver/_matrix/client/v3/login \
  -H "Content-Type: application/json" \
  -d '{"type":"m.login.password","identifier":{"type":"m.id.user","user":"YOUR_BOT_USERNAME"},"password":"YOUR_PASSWORD","device_id":"NEW_DEVICE_ID"}'

响应:

{"user_id": "@bot:example.com", "access_token": "syt_...", "device_id": "NEWDEVICE"}

步骤 2:将两个值都应用到 ZeroClaw

将响应中的 access_tokendevice_iduser_id 填入你的 [channels.matrix.<alias>] 配置块(参见 §2 了解设置位置),然后重启:zeroclaw service restart

备注

  • 首次粘贴时请保留令牌的副本。机密信息在静态存储时会被加密,zeroclaw config get 在令牌字段会显示 [masked];你之后将无法再获取它。如果你在 §5C 中需要用它来执行 curl 验证代码片段,请将其暂存到草稿笔记中。
  • 每次重启时复用相同的 device_id:更改它会强制进行新的服务器端设备注册,从而破坏加密房间中的密钥共享和验证。§8 中的自动恢复路径可处理那些清除确实是正确做法的罕见情况。
  • 稍后轮换访问令牌而无需重新运行向导:更新配置中的 access_token 字段(参见 §2),然后执行 zeroclaw service restart
  • Token 显示为已过期或无效:启动时,使用相同的 curl 生成一个新的,重复步骤 2。

4. 快速验证

如果尚未应用,请先应用 §2 中设置的字段集,然后使用 zeroclaw service restart(后台)或 zeroclaw daemon(前台)重新启动。在已配置的 Matrix 房间中发送一条纯文本消息。确认:

  • ZeroClaw 日志显示,Matrix 监听器启动时没有重复的同步/认证错误。
  • 在加密房间中,机器人可以读取并回复来自允许用户的加密消息。

5. 排查“无响应“问题

按顺序处理。

A. 房间与成员

  • 确认机器人账号已加入房间。
  • 如果你要将某个房间放入 allowed_rooms,必须使用规范的房间 ID(!room:server),而不是 #alias:server。别名不会被解析用于允许列表,因此别名条目会静默地匹配不到任何内容。可在 Element 中通过房间设置 → 高级 → 内部房间 ID 找到规范 ID。

B. 发送方允许列表(对等组)

发送方必须在 agent 的 peer 集合中,参见本页顶部的谁可以与 agent 通信。为便于诊断,可临时设置 external_peers = ["*"] 并重启守护进程。

C. 令牌和身份

密钥在静态存储时已加密且不可检索:对于任何密钥字段,zeroclaw config get 都会打印 [masked]。要运行下面的检查,请使用你在 §3 中生成的访问令牌(或重新生成一个)以及你自己的 homeserver URL。

在服务端验证令牌:

sh

curl -sS -H Authorization: Bearer <access_token> \
  "https://your.homeserver/_matrix/client/v3/account/whoami"
  • 返回的 user_id 必须与机器人账号匹配。
  • 如果响应中缺少 device_id,请手动设置(参见 §5H)。
  • 轮换访问令牌:更新配置中的 access_token 字段(参见 §2),然后执行 zeroclaw service restart

D. E2EE 特定检查

  • 机器人设备必须已从受信任的设备接收房间密钥。
  • 如果尚未向此设备共享密钥,则无法解密加密事件。
  • 从受信任的 Matrix 会话验证设备信任关系和密钥共享。
  • matrix_sdk_crypto::backups: Trying to backup room keys but no backup key was found:此设备尚未启用密钥备份恢复功能。这对消息流不会造成致命影响;但仍建议完成设置(参见 §5I)。
  • 如果收件人看到机器人消息显示为“未验证”,请从受信任的 Matrix 会话验证/签名机器人设备,并在重启过程中保持 device_id 稳定不变。

E. 日志级别

ZeroClaw 默认将 matrix_sdkmatrix_sdk_basematrix_sdk_crypto 抑制为 warn 级别;它们在 info 级别下会产生大量日志。如需恢复 SDK 输出以进行调试:

sh

RUST_LOG=info,matrix_sdk=info,matrix_sdk_base=info,matrix_sdk_crypto=info zeroclaw daemon

F. 消息格式(Markdown)

  • ZeroClaw 将 Matrix 回复作为支持 Markdown 的 m.room.message 文本内容发送。
  • 支持 formatted_body 的 Matrix 客户端会渲染强调、列表和代码块。
  • 如果格式显示为纯文本:首先检查客户端功能,然后确认 ZeroClaw 正在运行支持 Markdown 输出的 Matrix 构建版本。

G. 全新启动测试

配置更改后,请重启守护进程并发送新消息。旧的时间线历史将不会重新播放。

H. 查找现有令牌的 device_id

只有在使用 access_token 方式时才需要这一步(§3)。推荐的密码 + 恢复密钥配置完全省略了 device_id:由家庭服务器分配一个,并由 ZeroClaw 持久化保存,因此无需查找。如果你已切换到推荐的配置,请跳过本节。

如果你确实需要固定一个 device_id(因为你正在复用现有的访问令牌,而非通过密码登录),可以用它来查找绑定到该令牌的 device_id。对于走令牌路径的全新机器人,请参阅 §3:那里的密码登录流程会同时返回这两个值。

ZeroClaw 在令牌路径上进行 E2EE 会话恢复时需要一个稳定的 device_id。如果缺少它,每次重启都会注册一个新设备,从而破坏密钥共享和设备验证。

选项 1:whoami(最简单)

sh

curl -sS -H Authorization: Bearer <access_token> \
  "https://your.homeserver/_matrix/client/v3/account/whoami"

如果令牌绑定到设备会话,响应中将包含 device_id

{"user_id": "@bot:example.com", "device_id": "ABCDEF1234"}

如果缺少 device_id,则该令牌是在没有设备登录的情况下创建的(例如通过 admin API 创建)。请通过 §3 同时铸造新的令牌和 device_id。

选项 2:从 Element 或其他 Matrix 客户端

  1. 以机器人账户身份登录 Element。
  2. 设置 → 会话。
  3. 复制当前会话的设备 ID。
  4. 在配置中设置 device_id(参见 §2),然后执行 zeroclaw service restart。请保持 device_id 稳定:更改它会强制进行新的设备注册,从而破坏现有的密钥共享和验证。

H(续)。加密存储删除恢复

症状: 检测到 Matrix 一次性密钥上传冲突;停止同步以避免无限重试循环,通道变得不可用。

原因: 本地加密存储已被删除,而旧设备仍在主服务器上注册了一次性密钥。由于旧密钥仍存在于服务器端,SDK 无法上传新密钥,导致无限的一次性密钥(OTK)冲突循环。

修复:重新登录

全新登录会创建一个带有新 device_id 的新设备,从而完全绕过 OTK 冲突(无需通过 UIA 进行设备删除)。

  1. 停止 ZeroClaw。

    sh

    zeroclaw service stop
    
  2. 获取一个新的访问令牌和 device_id

    sh

    curl -sS -X POST "https://matrix.org/_matrix/client/v3/login" \
      -H "Content-Type: application/json" \
      -d {"type":"m.login.password","identifier":{"type":"m.id.user","user":"YOUR_BOT_USERNAME"},"password":"YOUR_PASSWORD","device_id":"NEW_DEVICE_ID"}
    

    保存返回的 access_tokendevice_id

  3. 删除本地加密存储:

    sh

    rm -rf ~/.zeroclaw/state/matrix/
    
  4. 应用新凭据:在配置中设置 access_token(密钥,参见 §2)和 device_id

  5. 重启:

    sh

    zeroclaw service start
    

首次重启时会出现的情况

  • Our own device might have been deleted:无害;旧设备已不存在。
  • Failed to decrypt a room event:来自重置之前的旧消息;无法恢复。
  • Matrix E2EE recovery successful:已从服务器备份恢复房间密钥(仅当设置了 recovery_key 时;参见 §5I)。
  • 新消息解密并正常工作。

预防措施: 在计划重新登录之前,不要删除本地状态目录。如果需要从头开始,请先获取新的凭据,然后删除存储,再更新配置。

I. 恢复密钥(推荐用于端到端加密)

恢复密钥让 ZeroClaw 能够自动从服务器端备份中恢复房间密钥和交叉签名密钥。设备重置、加密存储删除以及全新安装都会自动恢复:无需 emoji 验证,也无需手动共享密钥。

第 1 步:从 Element 获取你的恢复密钥

  1. 在 Element(网页版或桌面版)中登录机器人账号。
  2. 设置 → 安全与隐私 → 加密 → 安全备份
  3. 如果已设置备份,则在首次启用备份时会显示您的恢复密钥。如果已保存该密钥,请使用它。
  4. 如果尚未设置备份,请点击 “Set up Secure Backup” → “Generate a Security Key”。Element 会显示该密钥(形如 EsTj 3yST y93F SLpB ...);请将其复制到安全的地方保存。
  5. 越过密钥显示界面继续:Element 接着会要求你在确认框中重新输入密钥,以证明你已保存它。粘贴密钥并继续以完成设置。这与你填入 recovery_key 的值相同。
  6. (可选)密钥保存后,可退出该机器人的 Element 会话:点击账户菜单 → 所有设置 → Account,然后点击 Remove this device。保持登录状态也没问题,移除设备只是为了让设备列表更整洁。

步骤 2:将恢复密钥添加到 ZeroClaw

将恢复密钥应用到 ZeroClaw:

channels.matrix.<alias>.recovery_key 是一项机密信息。 它以加密形式存储,绝不会以明文保存在 config.toml 中。请通过以下方式之一进行设置,这些方式会在写入时进行加密:

网关仪表板

打开 /config/channels/matrix,并在其中设置 channels.matrix.<alias>.recovery_key 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.recovery_key 字段(输入内容会被遮蔽)。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.recovery_key    # 提示输入掩码内容,以加密形式存储

然后运行 zeroclaw service restart。恢复密钥会立即在静态状态下加密。

第 3 步:重启

sh

zeroclaw service restart

启动时你应该看到:

Matrix E2EE recovery successful — room keys and cross-signing secrets restored from server backup.

从现在开始,即使本地加密存储被删除,ZeroClaw 也会在下次启动时自动恢复。

6. 调试日志

Matrix 通道特定的诊断:

sh

RUST_LOG=zeroclaw::channels::matrix=debug zeroclaw daemon

表面:

  • 会话恢复确认
  • 每个同步周期完成
  • OTK 冲突标志状态
  • 健康检查结果
  • 瞬态与致命同步错误分类

对于 SDK 级别的详细信息:

sh

RUST_LOG=zeroclaw::channels::matrix=debug,matrix_sdk_crypto=debug zeroclaw daemon

7. 运维说明

  • 将 Matrix 令牌从日志和屏幕截图中排除。
  • 先使用宽松的 external_peers = ["*"],验证后再收紧为明确的用户 ID。
  • allowed_rooms 中始终使用规范的房间 ID:入站允许列表不解析别名(仅在出站 delivery.to 中解析别名)。
  • 线程:channels.matrix.reply_in_threadtrue(默认值)时,每条机器人回复都会位于以用户消息为根的线程中。顶层用户消息会开启一个新线程;已有的线程则会继续。主房间时间线仅承载用户发起的消息。
  • 线程根上下文: ZeroClaw 在任意线程中看到的第一条入站消息会以 [Thread root from @sender]: <root body> 作为前缀,以便智能体获得触发该回复的对话内容。由机器人自身发起的线程会跳过此前导内容。跟踪仅在内存中进行;守护进程重启后,每个活跃线程中的下一条消息会重新注入该前导内容,且仅注入一次。
  • 内联回复媒体: channels.matrix.mention_only = true 会让 bot 忽略纯媒体上传(没有可供提及的文本正文)。当用户对这样一个被丢弃的事件进行内联回复并提出问题时(@bot can you see this?),ZeroClaw 会遍历该回复的 m.relates_to.m.in_reply_to.event_id,获取父事件,并将其媒体拉取到当前消息中:尽管原始上传已被过滤掉,agent 的视觉处理管线仍能看到该图像。
  • 附件随文本一起进入线程: 当存在线程锚点时,room.send_attachment 调用会携带带有 EnforceThread::ThreadedAttachmentConfig::reply(...),因此 PDF / 图片 / 语音留言会落入机器人的线程内,而非主时间线。
  • 出站媒体标记: 智能体会在其回复文本中输出 [image:url|path][file:url|path][voice:url|path][video:...][audio:...](以及大写形式 / [document:...] 别名);ZeroClaw 获取相应字节(http(s):// 使用 HTTP 获取,否则进行本地读取)并将其作为相应的 Matrix 消息事件上传。目标缺失或不可读不会导致致命错误: 通道会记录一条警告,仅丢弃该标记,并追加一行 (note: I couldn't deliver the file at <path>.),以便操作员看到所尝试的操作,而不是回复被无声丢弃。
  • 语音消息(MSC3245):携带 org.matrix.msc3245.voice 字段的入站 m.audio 事件会被保存到 {workspace_dir}/matrix_files/,并通过该代理配置的转录服务商进行处理,以便代理同时获得转录文本和源文件路径。出站语音便笺使用 [voice:<url|path>] 标记;ZeroClaw 会将其作为带有语音标志和零波形设置的 m.audio 上传,使 Element 将该气泡渲染为语音便笺。有关转录服务商的设置,请参阅 Model Providers
  • 确认反应:channels.matrix.ack_reactions 控制(默认为 true)。开启时,机器人在处理过程中会以 👀 作出反应,完成时则以 ✅ 作出反应。设为 false 可让房间保持无反应。
  • 持久会话: 首次成功登录时,ZeroClaw 会写入 ~/.zeroclaw/state/matrix/session.json(user_id + device_id + access_token + 可选的 refresh_token)。后续重启会从该数据块调用 restore_session():无需重新登录。matrix-rust-sdk 的 SQLite 加密存储与之并列存放于 ~/.zeroclaw/state/matrix/store/一旦 session.json 存在,在配置中轮换 access_token 将不起作用,直到该文件被删除:已保存的令牌优先生效。删除 session.json 可强制根据配置值重新登录。
  • 交叉签名:recovery_key 与你账户服务器端密钥存储中封存的密钥匹配时,ZeroClaw 会在每次启动时运行 recovery().recover(key),SDK 会导入你现有的 master / self-signing / user-signing 密钥,并自动为新注册的设备签名。无需引导,无需 UIA,无需密钥轮换。 如果你的账户尚未设置交叉签名,请先在 Element 中生成恢复密钥(Settings → Security & Privacy → Secure Backup),然后再配置 recovery_key
  • Cron 投递: delivery.to 应当是一个纯房间 id(!abc:server)或别名(#room:server)。对于旧版配置中写作 <sender>||<room> 的情况也予以兼容:ZeroClaw 会提取最后一个以 !/# 开头的片段,并就该格式错误的值发出警告。

流式传输

Matrix 通过 stream_mode 设置来流式传输回复:

  • off(默认):整条回复在 agent 完成后作为一条消息发送。最简单,且永远不会显示写到一半的答案。
  • partial:机器人会立即发布一条草稿,并在答案以流式方式生成时就地编辑该草稿。draft_update_interval_ms 用于控制编辑的节奏;如果 Matrix 对编辑进行限流,请调高该值。
  • multi_message:每个段落作为独立消息发送,以 multi_message_delay_ms 间隔分隔。适用于较长的回答,避免内容堆积成一大段文字。

将其放置在任何表面上:

网关仪表板

打开 /config/channels/matrix 并设置 channels.matrix.<alias>.stream_mode 字段。

zerocode

Config 窗格中,设置 channels.matrix.<alias>.stream_mode 字段。

zeroclaw config

zeroclaw config set channels.matrix.<alias>.stream_mode <value>

Matrix 具体说明:在 partial 模式下,工具执行状态通过与答案文本相同的编辑流水线显示。在 single_message 模式下,工具/进度状态更新会被编辑到一个滚动草稿中,而最终答案会作为单独的 Matrix 消息发送。stream_draft_lines 控制可见进度行数:0 仅移除行数限制;它不会创建第二条进度消息。message_max_bytes 同时限制草稿和最终事件内容的大小,计算的是渲染后的 Markdown(包括生成的 HTML)以及 Matrix 回复/编辑关系元数据,而不只是 Markdown 源文本。超出大小的进度内容会丢弃完整的最旧行或条目,使窗口保留最新活动;超大的单个项目会替换为可见警告。单独的最终响应会保留 UTF-8 安全的前缀。进度内容会在 Markdown 渲染前进行转义,因此推理内容可以跨行保持可读,同时用户/模型/工具内容无法引入 Markdown 或 HTML 格式。小于 512 的值会使用该有效最小值,以便容纳非空的序列化 Matrix 事件。该预算不适用于审批提示、系统通知、计划投递或其他普通发送。请选择低于 Matrix 事件限制的预算。stream_reasoning 控制该进度草稿中提供商推理的可见性:off 会抑制由推理生成的草稿更新,status 会发送不包含原始推理文本的存活信号,而 full 会将提供商的原始推理文本写入进度草稿。stream_draft_delete 控制是否在发布最终答案前删除持久化的进度记录;删除失败会记录日志,但最终答案仍会继续发送。即使启用了记录保留,只有占位符的草稿也会在最终答案之前移除。在 multi_message 模式下,每个段落都会作为独立的线程消息发布,并且拆分会识别代码围栏,因此围栏代码块中的空行不会导致代码块跨消息断开。

stream_tool_arguments 控制哪些工具参数会出现在 single_message 进度行中。缺少配置或配置为空时,将使用按工具设置的保守默认值;技能包装器、插件、MCP 工具和无法解析的名称仅显示其名称。单个 default_base 条目可选择 nonesafeall,而精确名称工具规则可以替换该基础设置,或添加和移除字段:

stream_tool_arguments = [
    { default_base = "safe", argument_chars = 60 },
    { tool = "delegate", base = "none", include = ["agent", "background", "prompt"], argument_chars = 0 },
    { tool = "mock_tool", base = "all", exclude = ["token"] },
]

规则顺序无关紧要,重复的工具或默认条目会被拒绝,规则中省略 base 时会继承 default_base。选定 base 后,include 会添加字段;exclude 会移除字段。仅用于运行时的字段始终不会显示,以凭据命名的字段会在每个选定值内递归脱敏,并且每个渲染值在传递到 Matrix 前都会经过凭据泄漏检测和单行规范化。包含复合值仍然是操作员明确作出的披露决定,但不会绕过凭据脱敏。在 safe 模式下,仅渲染建议的顶层标量参数;null、数组和对象会被省略。选择 all 或在 include 中指定参数,即表示操作员明确选择对复合值进行紧凑 JSON 渲染。默认条目中的 argument_chars 会更改继承的每值上限(原为 60);工具规则中的同一字段会覆盖该工具的上限。0 会保留完整值,但 message_max_bytes 仍会限制渲染后草稿的大小。显式指定 all 会应用于未知工具;如果只为一个扩展工具启用参数,请使用精确名称规则。

8. 从损坏的本地状态自动恢复

matrix-rust-sdk 默认的 SQLite 存储是单设备的,并假定本地视图与主服务器保持同步。有两种故障模式会不可恢复地破坏该假定;ZeroClaw 会在启动时检测每一种故障,并(当同时配置了 passworduser_id 时)自动清除 ~/.zeroclaw/state/matrix/ 并重新认证,从而在服务器端创建一个全新的设备。

  • 孤立的加密状态。 存在 store/ 目录但缺少 session.json(手动清理、之前的安装被中断等原因)。在孤立的加密状态之上重新登录会重现无法自行恢复的 Duplicate one-time keys / SigningKeyChanged 冲突。
  • StateStoreDataKey::OneTimeKeyAlreadyUploaded 标志已设置。 SDK 在首次检测到重复 OTK 上传时会将此键持久化到状态存储中(参见 SDK 自己的注释:“we forgot about some of our one-time keys. This will lead to UTDs.”)。该标志在重启后依然存在;唯一的修复方法是清除数据并重新注册。

检测到 device_id 偏移时予以容忍,而非清除。 如果 channels.matrix.device_idsession.json 中存储的 device id 不一致,通道会记录一条警告并采用已保存的 id(即登录时 homeserver 实际分配的值)。在偏移时清除会造成恢复循环,因为自动恢复本身会生成新的 id,导致配置与会话永久失去同步。

recover() 本身失败时(通常为 MAC check for the secret storage key failed),该通道会记录 homeserver 的默认 secret-storage key id、密钥事件是否包含 passphrase 信息、去除空白字符后的输入长度,以及完整的错误链:这些信息可指明 哪一 层拒绝了恢复密钥,同时不会泄露其值。恢复失败属于非致命错误(不会触发自动擦除);bot 会继续运行,只是新设备不会被交叉签名。

如果未配置 password + user_id,则无法运行自动恢复:通道会中止并返回一个可操作的错误,指明两种选择:配置它们,或手动执行 rm -rf ~/.zeroclaw/state/matrix/

另见