Skip to main content

Documentation Index

Fetch the complete documentation index at: https://openclaw.zhcndoc.com/llms.txt

Use this file to discover all available pages before exploring further.

私有 QA 堆栈旨在以比单个单元测试更贴近真实、具有渠道形态的方式来验证 OpenClaw。 当前组件:
  • extensions/qa-channel: 带有 DM、频道、线程、 反应、编辑和删除表面的合成消息通道。
  • extensions/qa-lab: 用于观察转录、注入传入消息以及导出 Markdown 报告的调试器 UI 和 QA 总线。
  • extensions/qa-matrix、未来的 runner 插件:驱动子 QA gateway 中真实频道的实时传输适配器。
  • qa/: 用于启动任务和基线 QA 场景的仓库后备种子资源。
  • Mantis:针对需要真实传输、浏览器截图、VM 状态和 PR 证据的 bug,在 live verification 之前和之后进行验证。

命令入口

所有 QA 流程都通过 pnpm openclaw qa <subcommand> 运行。许多命令都有 pnpm qa:* 脚本别名;这两种形式都受支持。
命令作用
qa run打包后的 QA 自检;写入一份 Markdown 报告。
qa suite在 QA gateway 车道上运行仓库后备场景。别名:pnpm openclaw qa suite --runner multipass,用于一次性 Linux VM。
qa coverage打印 markdown 场景覆盖清单(--json 用于机器输出)。
qa parity-report比较两个 qa-suite-summary.json 文件并写入 agentic parity 报告。
qa character-eval在多个实时模型上运行 character QA 场景,并输出经评审的报告。见报告
qa manual针对所选 provider/model 车道运行一次性 prompt。
qa ui启动 QA 调试器 UI 和本地 QA 总线(别名:pnpm qa:lab:ui)。
qa docker-build-image构建预烘焙的 QA Docker 镜像。
qa docker-scaffold为 QA 仪表盘 + gateway 车道写入 docker-compose 脚手架。
qa up构建 QA 站点,启动 Docker 支持的堆栈,打印 URL(别名:pnpm qa:lab:up:fast 变体会添加 --use-prebuilt-image --bind-ui-dist --skip-ui-build)。
qa aimock仅启动 AIMock provider 服务器。
qa mock-openai仅启动支持场景感知的 mock-openai provider 服务器。
qa credentials doctor / add / list / remove管理共享的 Convex 凭证池。
qa matrix面向一次性 Tuwunel homeserver 的实时传输车道。见Matrix QA
qa telegram面向真实私有 Telegram 群组的实时传输车道。
qa discord面向真实私有 Discord guild 频道的实时传输车道。
qa slack面向真实私有 Slack 频道的实时传输车道。
qa mantis用于实时传输 bug 的前后验证 runner,包含第一个 Discord 状态反应场景。见Mantis

操作流程

当前的 QA 操作流程是一个双栏 QA 站点:
  • 左侧:Gateway 仪表盘(Control UI)与 agent。
  • 右侧:QA Lab,显示类似 Slack 的转录和场景计划。
使用以下命令运行:
pnpm qa:lab:up
这会构建 QA 站点,启动 Docker 支持的 gateway 通道,并暴露 QA Lab 页面,供操作员或自动化循环向 agent 下达 QA 任务、观察真实频道行为,以及记录哪些有效、哪些失败、哪些仍然受阻。 若想在不每次都重建 Docker 镜像的情况下更快地迭代 QA Lab UI, 可使用挂载式 QA Lab bundle 启动堆栈:
pnpm openclaw qa docker-build-image
pnpm qa:lab:build
pnpm qa:lab:up:fast
pnpm qa:lab:watch
qa:lab:up:fast 会让 Docker 服务继续使用预构建镜像,并将 extensions/qa-lab/web/dist 挂载到 qa-lab 容器中。qa:lab:watch 会在变更时重建该 bundle,而当 QA Lab 资源哈希变化时,浏览器会自动重新加载。 若要进行本地 OpenTelemetry 追踪冒烟测试,运行:
pnpm qa:otel:smoke
该脚本会启动一个本地 OTLP/HTTP 追踪接收器,使用启用 diagnostics-otel 插件的 otel-trace-smoke QA 场景,然后 解码导出的 protobuf spans,并断言发布关键形态: 必须存在 openclaw.runopenclaw.harness.runopenclaw.model.callopenclaw.context.assembledopenclaw.message.delivery;成功回合中的模型调用不得导出 StreamAbandoned;原始诊断 ID 和 openclaw.content.* 属性必须不出现在 trace 中。它会将 otel-smoke-summary.json 写在 QA suite 产物旁边。 可观测性 QA 仅限源代码检出环境。npm tarball 会刻意省略 QA Lab,因此包级 Docker 发布通道不会运行 qa 命令。变更诊断 埋点时,请在已构建的源代码检出环境中使用 pnpm qa:otel:smoke 若要运行一个真实传输的 Matrix 冒烟通道,运行:
pnpm openclaw qa matrix --profile fast --fail-fast
该通道的完整 CLI 参考、profile/场景目录、环境变量和产物布局 见 Matrix QA。简而言之:它会在 Docker 中预置一个一次性 Tuwunel homeserver, 注册临时的 driver/SUT/observer 用户,在一个仅限该传输的子 QA gateway 中运行真实的 Matrix 插件(不使用 qa-channel),然后在 .artifacts/qa-e2e/matrix-<timestamp>/ 下写入 Markdown 报告、JSON 摘要、observed-events 产物以及合并输出日志。 For transport-real Telegram, Discord, and Slack smoke lanes:
pnpm openclaw qa telegram
pnpm openclaw qa discord
pnpm openclaw qa slack
They target a pre-existing real channel with two bots (driver + SUT). Required env vars, scenario lists, output artifacts, and the Convex credential pool are documented in Telegram, Discord, and Slack QA reference below. 在使用共享的实时凭据之前,运行:
pnpm openclaw qa credentials doctor
doctor 会检查 Convex broker 环境变量,验证端点设置,并在存在维护者密钥时确认 admin/list 可达性。它只会报告密钥是已设置还是缺失。

实时传输覆盖

实时传输通道共享同一个契约,而不是每个通道都自行发明各自的场景列表结构。qa-channel 是更广泛的合成产品行为套件,不属于实时传输覆盖矩阵的一部分。
通道CanaryMention gatingBot-to-botAllowlist block顶层回复Restart resumeThread follow-upThread isolationReaction observationHelp commandNative command registration
Matrixxxxxxxxxx
Telegramxxxx
Discordxxxx
Slackxxx
这让 qa-channel 保持为更广泛的产品行为套件,而 Matrix、 Telegram 以及未来的实时传输共享一份明确的传输契约 检查清单。 若要在不把 Docker 带入 QA 路径的情况下使用一次性 Linux VM 通道,运行:
pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline
这会启动一个全新的 Multipass guest,安装依赖,在 guest 内部构建 OpenClaw, 运行 qa suite,然后将正常的 QA 报告和 摘要复制回宿主机上的 .artifacts/qa-e2e/...。 它沿用与宿主机上的 qa suite 相同的场景选择行为。 默认情况下,宿主机和 Multipass 的 suite 运行会并行执行多个所选场景,并使用隔离的 gateway worker。qa-channel 默认并发度为 4,并受所选场景数量上限约束。使用 --concurrency <count> 可调整 worker 数量,或使用 --concurrency 1 进行串行执行。 当任一场景失败时,该命令以非零状态退出。若你希望保留产物但不希望失败导致退出码为失败,请使用 --allow-failures。 实时运行会转发对 guest 实用的受支持 QA 身份验证输入:基于环境变量的 provider 密钥、QA 实时 provider 配置路径,以及 存在时的 CODEX_HOME。请将 --output-dir 保持在仓库根目录下,这样 guest 才能通过挂载的工作区写回。

Telegram, Discord, and Slack QA reference

Matrix has a dedicated page because of its scenario count and Docker-backed homeserver provisioning. Telegram, Discord, and Slack are smaller — a handful of scenarios each, no profile system, against pre-existing real channels — so their reference lives here.

共享 CLI 标志

These lanes register through extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts and accept the same flags:
标志默认值说明
--scenario <id>仅运行此场景。可重复。
--output-dir <path><repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp>报告/摘要/观测消息以及输出日志的写入位置。相对路径会相对于 --repo-root 解析。
--repo-root <path>process.cwd()从中性 cwd 调用时的仓库根目录。
--sut-account <id>sutQA gateway 配置中的临时账户 id。
--provider-mode <mode>live-frontiermock-openailive-frontier(旧的 live-openai 仍然可用)。
--model <ref> / --alt-model <ref>provider 默认值主/备用模型引用。
--fastoff在支持的情况下使用 provider 快速模式。
--credential-source <env|convex>envConvex 凭证池
--credential-role <maintainer|ci>CI 中为 ci,否则为 maintainer--credential-source convex 时使用的角色。
每个通道在任一场景失败时都会以非零状态退出。--allow-failures 会在不设置失败退出码的情况下写入产物。

Telegram QA

pnpm openclaw qa telegram
目标是一个真实的私有 Telegram 群组,使用两个不同的机器人(driver + SUT)。SUT 机器人必须有 Telegram 用户名;当两个机器人都在 @BotFather 中启用 Bot-to-Bot Communication Mode 时,bot-to-bot 观测效果最佳。 当使用 --credential-source env 时所需的环境变量:
  • OPENCLAW_QA_TELEGRAM_GROUP_ID — 数字聊天 id(字符串)。
  • OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_TELEGRAM_SUT_BOT_TOKEN
可选:
  • OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1 会在观测消息产物中保留消息正文(默认会脱敏)。
场景(extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44):
  • telegram-canary
  • telegram-mention-gating
  • telegram-mentioned-message-reply
  • telegram-help-command
  • telegram-commands-command
  • telegram-tools-compact-command
  • telegram-whoami-command
  • telegram-context-command
输出产物:
  • telegram-qa-report.md
  • telegram-qa-summary.json — 从 canary 开始包含每条回复的 RTT(driver 发送 → 观测到的 SUT 回复)。
  • telegram-qa-observed-messages.json — 除非设置 OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1,否则正文会被脱敏。

Discord QA

pnpm openclaw qa discord
目标是一个真实的私有 Discord guild 频道,使用两个不同的机器人:一个由 harness 控制的 driver bot,以及一个由子 OpenClaw gateway 通过捆绑的 Discord 插件启动的 SUT bot。验证频道 mention 处理、SUT bot 是否已在 Discord 中注册原生 /help 命令,以及可选的 Mantis 证据场景。 当使用 --credential-source env 时所需的环境变量:
  • OPENCLAW_QA_DISCORD_GUILD_ID
  • OPENCLAW_QA_DISCORD_CHANNEL_ID
  • OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN
  • OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID — 必须与 Discord 返回的 SUT bot 用户 id 一致(否则该通道会快速失败)。
可选:
  • OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1 会在观测消息产物中保留消息正文。
场景(extensions/qa-lab/src/live-transports/discord/discord-live.runtime.ts:36):
  • discord-canary
  • discord-mention-gating
  • discord-native-help-command-registration
  • discord-status-reactions-tool-only — 可选的 Mantis 场景。它会单独运行,因为它会将 SUT 切换为始终开启、仅工具的 guild 回复,并将 messages.statusReactions.enabled=true,然后捕获一条 REST reaction 时间线以及一个 HTML/PNG 视觉产物。
显式运行 Mantis 状态反应场景:
pnpm openclaw qa discord \
  --scenario discord-status-reactions-tool-only \
  --provider-mode live-frontier \
  --model openai/gpt-5.4 \
  --alt-model openai/gpt-5.4 \
  --fast
输出产物:
  • discord-qa-report.md
  • discord-qa-summary.json
  • discord-qa-observed-messages.json — 除非 OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1,否则正文会被脱敏。
  • discord-qa-reaction-timelines.jsondiscord-status-reactions-tool-only-timeline.png,在状态反应场景运行时生成。

Slack QA

pnpm openclaw qa slack
目标是一个真实的私有 Slack 频道,使用两个不同的机器人:一个由 harness 控制的 driver bot,以及一个由子 OpenClaw gateway 通过捆绑的 Slack 插件启动的 SUT bot。 使用 --credential-source env 时所需环境变量:
  • OPENCLAW_QA_SLACK_CHANNEL_ID
  • OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_BOT_TOKEN
  • OPENCLAW_QA_SLACK_SUT_APP_TOKEN
可选:
  • OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1 会在观测消息产物中保留消息正文。
场景(extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts:39):
  • slack-canary
  • slack-mention-gating
输出产物:
  • slack-qa-report.md
  • slack-qa-summary.json
  • slack-qa-observed-messages.json — 除非设置 OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1,否则正文会被脱敏。

Convex 凭证池

Telegram、Discord 和 Slack 通道可以从共享的 Convex 池租用凭证,而不是读取上面的环境变量。传入 --credential-source convex(或设置 OPENCLAW_QA_CREDENTIAL_SOURCE=convex);QA Lab 会获取一个独占租约,在运行期间持续发送心跳,并在关闭时释放它。池类型为 "telegram""discord""slack" broker 在 admin/add 上验证的负载形状:
  • Telegram(kind: "telegram"):{ groupId: string, driverToken: string, sutToken: string }groupId 必须是数字 chat-id 字符串。
  • Discord(kind: "discord"):{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }
运行环境变量以及 Convex broker 端点契约见 Testing → 通过 Convex 共享 Telegram 凭证(该节名称早于 Discord 支持;broker 语义对两种类型完全相同)。

仓库内种子

种子资产位于 qa/
  • qa/scenarios/index.md
  • qa/scenarios/<theme>/*.md
它们故意保留在 git 中,以便 QA 计划对人和 agent 都可见。 qa-lab 应保持为一个通用的 markdown 运行器。每个场景 markdown 文件都是一次测试运行的唯一真实来源,并且应定义:
  • 场景元数据
  • 可选的类别、能力、通道和风险元数据
  • 文档和代码引用
  • 可选的插件要求
  • 可选的 gateway 配置补丁
  • 可执行的 qa-flow
支撑 qa-flow 的可复用运行时表面可以保持通用和跨切面。例如,markdown 场景可以将传输侧助手与浏览器侧助手结合起来,通过 Gateway 的 browser.request 连接驱动嵌入式 Control UI,而无需添加特例运行器。 场景文件应按产品能力分组,而不是按源代码树目录分组。文件移动时应保持场景 ID 稳定;使用 docsRefscodeRefs 进行实现可追溯性。 基线列表应保持足够广泛,以覆盖:
  • DM 和频道聊天
  • 线程行为
  • 消息动作生命周期
  • cron 回调
  • 记忆回忆
  • 模型切换
  • 子代理交接
  • 仓库读取和文档读取
  • 一个小型构建任务,例如 Lobster Invaders

提供方 mock 通道

qa suite 有两个本地 provider mock 通道:
  • mock-openai 是具备场景感知的 OpenClaw mock。它仍然是仓库内 QA 和 parity gate 的默认确定性 mock 通道。
  • aimock 启动一个基于 AIMock 的 provider server,用于实验性的协议、fixture、record/replay 和 chaos 覆盖。它是附加性的,不会替换 mock-openai 的场景分发器。
provider 通道的实现位于 extensions/qa-lab/src/providers/ 下。每个 provider 都拥有自己的默认值、本地 server 启动、gateway 模型配置、auth-profile 分阶段需求,以及 live/mock 能力标志。共享 suite 和 gateway 代码应通过 provider 注册表路由,而不是按 provider 名称分支。

传输适配器

qa-lab 为 markdown QA 场景拥有一个通用的传输连接点。qa-channel 是该连接点上的第一个适配器,但设计目标更广:未来真实或合成的频道都应接入同一个 suite runner,而不是新增一个特定于传输的 QA 运行器。 在架构层面,分工如下:
  • qa-lab 负责通用的场景执行、worker 并发、产物写入和报告。
  • 传输适配器负责 gateway 配置、就绪检查、入站和出站观测、传输动作,以及标准化的传输状态。
  • qa/scenarios/ 下的 markdown 场景文件定义测试运行;qa-lab 提供执行它们的可复用运行时表面。

添加一个频道

向 markdown QA 系统添加频道需要恰好两件事:
  1. 该频道的传输适配器。
  2. 一组覆盖该频道契约的场景包。
当共享的 qa-lab 主机可以承载整个流程时,不要新增一个顶层 QA 命令根。 qa-lab 负责共享的主机机制:
  • openclaw qa 命令根
  • suite 启动与关闭
  • worker 并发
  • 产物写入
  • 报告生成
  • 场景执行
  • qa-channel 场景的兼容别名
Runner 插件负责传输契约:
  • openclaw qa <runner> 如何挂载到共享 qa 根下面
  • 如何为该传输配置 gateway
  • 如何检查就绪
  • 如何注入入站事件
  • 如何观测出站消息
  • 如何暴露转写记录和标准化的传输状态
  • 如何执行传输支持的动作
  • 如何处理传输特定的重置或清理
新频道的最低接入标准:
  1. 保持 qa-lab 作为共享 qa 根的所有者。
  2. 在共享 qa-lab 主机连接点上实现传输 runner。
  3. 将传输特定机制保留在 runner 插件或频道 harness 内部。
  4. openclaw qa <runner> 的形式挂载 runner,而不是注册一个竞争性的根命令。Runner 插件应在 openclaw.plugin.json 中声明 qaRunners,并从 runtime-api.ts 导出匹配的 qaRunnerCliRegistrations 数组。保持 runtime-api.ts 轻量;懒加载 CLI 和 runner 执行应保留在独立入口之后。
  5. 在主题化的 qa/scenarios/ 目录下编写或改造 markdown 场景。
  6. 对新场景使用通用场景助手。
  7. 除非仓库正在进行有意的迁移,否则保持现有兼容别名可用。
决策规则很严格:
  • 如果行为可以在 qa-lab 中只实现一次,就把它放在 qa-lab
  • 如果行为依赖于某个频道传输,就把它保留在那个 runner 插件或插件 harness 中。
  • 如果某个场景需要一个多个频道都能使用的新能力,添加一个通用助手,而不是在 suite.ts 中写特定频道分支。
  • 如果某个行为只对一种传输有意义,就让该场景保持传输特定,并在场景契约中明确说明。

场景助手名称

新场景推荐使用的通用助手名称:
  • waitForTransportReady
  • waitForChannelReady
  • injectInboundMessage
  • injectOutboundMessage
  • waitForTransportOutboundMessage
  • waitForChannelOutboundMessage
  • waitForNoTransportOutbound
  • getTransportSnapshot
  • readTransportMessage
  • readTransportTranscript
  • formatTransportTranscript
  • resetTransport
现有场景仍可使用兼容别名 — waitForQaChannelReadywaitForOutboundMessagewaitForNoOutboundformatConversationTranscriptresetBus — 但新的场景编写应使用通用名称。这些别名是为了避免一次性迁移,而不是未来的模型。

报告

qa-lab 会从观测到的总线时间线导出一份 Markdown 协议报告。 报告应回答:
  • 哪些工作正常
  • 哪些失败了
  • 哪些仍然被阻塞
  • 值得补充哪些后续场景
关于可用场景的清单——在评估后续工作量或接入新的传输方式时很有用——请运行 pnpm openclaw qa coverage(加上 --json 可输出机器可读格式)。 如需进行角色和风格检查,请在多个在线模型 引用上运行同一个场景,并写出一份经过评判的 Markdown 报告:
pnpm openclaw qa character-eval \
  --model openai/gpt-5.5,thinking=medium,fast \
  --model openai/gpt-5.2,thinking=xhigh \
  --model openai/gpt-5,thinking=xhigh \
  --model anthropic/claude-opus-4-6,thinking=high \
  --model anthropic/claude-sonnet-4-6,thinking=high \
  --model zai/glm-5.1,thinking=high \
  --model moonshot/kimi-k2.5,thinking=high \
  --model google/gemini-3.1-pro-preview,thinking=high \
  --judge-model openai/gpt-5.5,thinking=xhigh,fast \
  --judge-model anthropic/claude-opus-4-6,thinking=high \
  --blind-judge-models \
  --concurrency 16 \
  --judge-concurrency 16
该命令运行本地 QA 网关子进程,而不是 Docker。角色评估 场景应通过 SOUL.md 设定 persona,然后运行普通用户回合, 例如聊天、工作区帮助和小文件任务。候选模型不应被告知自己正在接受评估。 该命令会保留每份完整对话记录,记录基本运行统计,然后在支持的情况下, 以 fast 模式并使用 xhigh 推理要求裁判模型按自然度、氛围和幽默感对运行结果进行排序。 在比较不同提供方时使用 --blind-judge-models:裁判提示仍然会获得每份对话和运行状态, 但候选引用会被替换为中性标签,例如 candidate-01;报告会在解析后将排序映射回真实引用。 候选运行默认使用 high thinking,而 GPT-5.5 使用 medium,支持该能力的较旧 OpenAI 评估引用使用 xhigh。 可通过 --model provider/model,thinking=<level> 为单个候选项内联覆盖。--thinking <level> 仍然会设置全局回退值, 而较旧的 --model-thinking <provider/model=level> 形式保留用于兼容性。 OpenAI 候选引用默认使用 fast 模式,因此在提供方支持时会启用优先处理。 当单个候选或裁判需要覆盖时,可在内联中添加 ,fast,no-fast,fast=false。 只有在想要对所有候选模型强制开启 fast 模式时才使用 --fast。 报告中会记录候选和裁判的耗时以便进行基准分析,但裁判提示会明确说明不要按速度排序。 候选和裁判模型运行默认并发度都为 16。当提供方限制或本地网关压力使运行过于嘈杂时, 可降低 --concurrency--judge-concurrency。 当未传入候选 --model 时,角色评估默认使用 openai/gpt-5.5openai/gpt-5.2openai/gpt-5anthropic/claude-opus-4-6anthropic/claude-sonnet-4-6zai/glm-5.1moonshot/kimi-k2.5google/gemini-3.1-pro-preview。 当未传入 --judge-model 时,裁判默认使用 openai/gpt-5.5,thinking=xhigh,fastanthropic/claude-opus-4-6,thinking=high

相关文档