chore(i18n): refresh zh-CN translations
This commit is contained in:
parent
ce9f899872
commit
99d232a83c
@ -4,62 +4,62 @@ read_when:
|
||||
- 为拉取请求添加前后验证
|
||||
- 添加 Discord、Slack、WhatsApp 或其他实时传输场景
|
||||
- 调试需要截图、浏览器自动化或 VNC 访问的 QA 运行
|
||||
summary: Mantis 是用于在实时传输协议上复现 OpenClaw 缺陷、捕获前后对比证据,并将产物附加到 PR 的视觉端到端验证系统。
|
||||
summary: Mantis 是用于在实时传输协议上复现 OpenClaw 缺陷、捕获修复前后证据,并将构件附加到拉取请求的可视化端到端验证系统。
|
||||
title: Mantis
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T20:39:41Z"
|
||||
generated_at: "2026-05-04T00:35:07Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 3463882b01a7941f6d758c509d6cd70e099aa8352053347fa9c37a80e5b256ce
|
||||
source_hash: 7d1fe1e6cb57406fab351892b43c7057a0d08e26455d76a50157f958474e363e
|
||||
source_path: concepts/mantis.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
Mantis 是 OpenClaw 端到端验证系统,用于需要真实运行时、真实传输协议和可见证明的错误。它会针对已知有问题的 ref 运行场景,捕获证据,再针对候选 ref 运行相同场景,并将比较结果发布为制品,维护者可以从 PR 或本地命令中检查这些制品。
|
||||
Mantis 是 OpenClaw 的端到端验证系统,适用于需要真实运行时、真实传输协议和可见证据的 bug。它会针对已知有问题的 ref 运行一个场景、捕获证据,然后针对候选 ref 运行同一场景,并将对比结果发布为制品,维护者可以从 PR 或本地命令中检查这些制品。
|
||||
|
||||
Mantis 从 Discord 开始,因为 Discord 提供了一个高价值的首条通道:真实机器人认证、真实公会渠道、回应、帖子、原生命令,以及人类可视化确认传输协议显示内容的浏览器 UI。
|
||||
Mantis 从 Discord 开始,因为 Discord 为我们提供了一条高价值的首条验证线:真实 bot 凭证、真实公会频道、回应、话题串、原生命令,以及一个浏览器 UI,人类可以在其中直观确认传输协议展示了什么。
|
||||
|
||||
## 目标
|
||||
|
||||
- 使用用户看到的相同传输协议形态,从 GitHub issue 或 PR 复现错误。
|
||||
- 在应用修复之前,在基线 ref 上捕获 **before** 制品。
|
||||
- 在应用修复之后,在候选 ref 上捕获 **after** 制品。
|
||||
- 尽可能使用确定性 oracle,例如 Discord REST 回应读取或渠道转录检查。
|
||||
- 当错误有可见 UI 表面时捕获截图。
|
||||
- 从智能体控制的 CLI 本地运行,也可从 GitHub 远程运行。
|
||||
- 当登录、浏览器自动化或提供商认证卡住时,保留足够的机器状态以便 VNC 救援。
|
||||
- 当运行被阻塞、需要手动 VNC 帮助或完成时,向操作员 Discord 渠道发布简明 Status。
|
||||
- 使用用户看到的相同传输协议形态,从 GitHub issue 或 PR 复现 bug。
|
||||
- 在应用修复前,在基线 ref 上捕获一个**之前**制品。
|
||||
- 在应用修复后,在候选 ref 上捕获一个**之后**制品。
|
||||
- 尽可能使用确定性的判定器,例如 Discord REST 回应读取或频道转录检查。
|
||||
- 当 bug 有可见 UI 表面时捕获截图。
|
||||
- 从智能体控制的 CLI 在本地运行,并从 GitHub 远程运行。
|
||||
- 保留足够的机器状态,以便在登录、浏览器自动化或提供商凭证卡住时进行 VNC 救援。
|
||||
- 当运行被阻塞、需要手动 VNC 帮助或完成时,向操作员 Discord 频道发布简洁状态。
|
||||
|
||||
## 非目标
|
||||
|
||||
- Mantis 不是单元测试的替代品。Mantis 运行通常应在理解修复后转化为更小的回归测试。
|
||||
- Mantis 不是常规快速 CI 门禁。它更慢,使用实时凭证,并且仅用于实时环境很重要的错误。
|
||||
- Mantis 不应要求人类参与常规操作。手动 VNC 是救援路径,不是理想路径。
|
||||
- Mantis 不是单元测试的替代品。理解修复后,Mantis 运行通常应该转化为更小的回归测试。
|
||||
- Mantis 不是常规的快速 CI 门禁。它更慢,会使用实时凭证,并且只保留给实时环境很重要的 bug。
|
||||
- Mantis 正常运行不应需要人工参与。手动 VNC 是救援路径,不是理想路径。
|
||||
- Mantis 不会在制品、日志、截图、Markdown 报告或 PR 评论中存储原始密钥。
|
||||
|
||||
## 所有权
|
||||
|
||||
Mantis 位于 OpenClaw QA 栈中。
|
||||
Mantis 位于 OpenClaw 质量保障栈中。
|
||||
|
||||
- OpenClaw 拥有场景运行时、传输协议适配器、证据 schema,以及 `pnpm openclaw qa mantis` 下的本地 CLI。
|
||||
- QA Lab 拥有实时传输协议 harness 组件、浏览器捕获辅助工具和制品写入器。
|
||||
- 当需要远程 VM 时,Crabbox 拥有已预热的 Linux 机器。
|
||||
- QA Lab 拥有实时传输协议 harness 组件、浏览器捕获帮助器和制品写入器。
|
||||
- 当需要远程 VM 时,Crabbox 拥有预热的 Linux 机器。
|
||||
- GitHub Actions 拥有远程 workflow 入口点和制品保留。
|
||||
- ClawSweeper 拥有 GitHub 评论路由:解析维护者命令、分发 workflow,以及发布最终 PR 评论。
|
||||
- ClawSweeper 拥有 GitHub 评论路由:解析维护者命令、派发 workflow,并发布最终 PR 评论。
|
||||
- 当场景需要智能体式设置、调试或卡住状态报告时,OpenClaw 智能体通过 Codex 驱动 Mantis。
|
||||
|
||||
此边界将传输协议知识保留在 OpenClaw 中,将机器调度保留在 Crabbox 中,将维护者 workflow 粘合逻辑保留在 ClawSweeper 中。
|
||||
这个边界将传输协议知识保留在 OpenClaw 中,将机器调度保留在 Crabbox 中,并将维护者 workflow 胶水保留在 ClawSweeper 中。
|
||||
|
||||
## 命令形态
|
||||
## 命令形式
|
||||
|
||||
第一个本地命令会验证 Discord 机器人、公会、渠道、消息发送、回应发送和制品路径:
|
||||
第一个本地命令会验证 Discord bot、公会、频道、消息发送、回应发送和制品路径:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa mantis discord-smoke \
|
||||
--output-dir .artifacts/qa-e2e/mantis/discord-smoke
|
||||
```
|
||||
|
||||
本地 before 和 after 运行器接受以下形态:
|
||||
本地之前和之后运行器接受这种形式:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa mantis run \
|
||||
@ -70,22 +70,38 @@ pnpm openclaw qa mantis run \
|
||||
--output-dir .artifacts/qa-e2e/mantis/local-discord-status-reactions
|
||||
```
|
||||
|
||||
运行器会在输出目录下创建分离的基线和候选 worktree,安装依赖,构建每个 ref,使用 `--allow-failures` 运行场景,然后写入 `baseline/`、`candidate/`、`comparison.json` 和 `mantis-report.md`。对于第一个 Discord 场景,成功验证意味着基线 Status 为 `fail`,候选 Status 为 `pass`。
|
||||
运行器会在输出目录下创建分离的基线和候选 worktree,安装依赖,构建每个 ref,使用 `--allow-failures` 运行场景,然后写入 `baseline/`、`candidate/`、`comparison.json` 和 `mantis-report.md`。对于第一个 Discord 场景,成功验证意味着基线状态为 `fail`,候选状态为 `pass`。
|
||||
|
||||
GitHub smoke workflow 是 `Mantis Discord Smoke`。第一个真实场景的 before 和 after GitHub workflow 是 `Mantis Discord Status Reactions`。它接受:
|
||||
第一个 VM/浏览器原语是桌面冒烟测试:
|
||||
|
||||
- `baseline_ref`:预期会复现仅 queued 行为的 ref。
|
||||
```bash
|
||||
pnpm openclaw qa mantis desktop-browser-smoke \
|
||||
--output-dir .artifacts/qa-e2e/mantis/desktop-browser
|
||||
```
|
||||
|
||||
它会租用或复用一台 Crabbox 桌面机器,在 VNC 会话内启动可见浏览器,捕获桌面,将制品拉回本地输出目录,并把重新连接命令写入报告。该命令默认使用 Hetzner 提供商,因为它是 Mantis 验证线中第一个具备可用桌面/VNC 覆盖的提供商。针对另一个 Crabbox 机器池运行时,可以用 `--provider`、`--crabbox-bin` 或 `OPENCLAW_MANTIS_CRABBOX_PROVIDER` 覆盖它。
|
||||
|
||||
有用的桌面冒烟测试标志:
|
||||
|
||||
- `--lease-id <cbx_...>` 或 `OPENCLAW_MANTIS_CRABBOX_LEASE_ID` 会复用预热的桌面。
|
||||
- `--browser-url <url>` 会更改可见浏览器中打开的页面。
|
||||
- `--keep-lease` 或 `OPENCLAW_MANTIS_KEEP_VM=1` 会让新创建且通过的租约保持打开,以便 VNC 检查。失败的运行默认会在创建了租约时保留租约,以便操作员重新连接。
|
||||
- `--class`、`--idle-timeout` 和 `--ttl` 会调整机器大小和租约生命周期。
|
||||
|
||||
GitHub 冒烟测试 workflow 是 `Mantis Discord Smoke`。第一个真实场景的之前和之后 GitHub workflow 是 `Mantis Discord Status Reactions`。它接受:
|
||||
|
||||
- `baseline_ref`:预期会复现仅排队行为的 ref。
|
||||
- `candidate_ref`:预期会显示 `queued -> thinking -> done` 的 ref。
|
||||
|
||||
它会签出 workflow harness ref,构建独立的基线和候选 worktree,针对每个 worktree 运行 `discord-status-reactions-tool-only`,并将 `baseline/`、`candidate/`、`comparison.json` 和 `mantis-report.md` 作为 Actions 制品上传。
|
||||
它会检出 workflow harness ref,构建单独的基线和候选 worktree,针对每个 worktree 运行 `discord-status-reactions-tool-only`,并将 `baseline/`、`candidate/`、`comparison.json` 和 `mantis-report.md` 作为 Actions 制品上传。
|
||||
|
||||
你也可以直接从 PR 评论触发 status-reactions 运行:
|
||||
你也可以直接从 PR 评论触发状态回应运行:
|
||||
|
||||
```text
|
||||
@Mantis discord status reactions
|
||||
```
|
||||
|
||||
评论触发器有意保持狭窄。它仅在具有 write、maintain 或 admin 访问权限的用户发出的 pull request 评论上运行,并且只识别 Discord 状态回应请求。默认情况下,它使用已知有问题的基线 ref 和当前 PR head SHA 作为候选。维护者可以覆盖任一 ref:
|
||||
评论触发器有意保持狭窄。它只会在来自拥有写入、维护或管理员访问权限的用户的拉取请求评论上运行,并且只识别 Discord 状态回应请求。默认情况下,它使用已知有问题的基线 ref,并使用当前 PR head SHA 作为候选。维护者可以覆盖任一 ref:
|
||||
|
||||
```text
|
||||
@Mantis discord status reactions baseline=origin/main candidate=HEAD
|
||||
@ -98,44 +114,45 @@ ClawSweeper 命令示例:
|
||||
@clawsweeper verify e2e discord
|
||||
```
|
||||
|
||||
第一个命令是显式且聚焦场景的。第二个命令以后可以根据标签、变更文件和 ClawSweeper 审查发现,将 PR 或 issue 映射到推荐的 Mantis 场景。
|
||||
第一个命令是显式且聚焦场景的。第二个命令稍后可以根据标签、变更文件和 ClawSweeper 审查发现,将 PR 或 issue 映射到推荐的 Mantis 场景。
|
||||
|
||||
## 运行生命周期
|
||||
|
||||
1. 获取凭证。
|
||||
2. 分配或复用 VM。
|
||||
3. 为基线 ref 准备干净的 checkout。
|
||||
4. 安装依赖,并且只构建场景需要的内容。
|
||||
5. 使用隔离的状态目录启动子 OpenClaw Gateway 网关。
|
||||
6. 配置实时传输协议、提供商、模型和浏览器配置文件。
|
||||
7. 运行场景并捕获基线证据。
|
||||
8. 停止 Gateway 网关并保留日志。
|
||||
9. 在同一 VM 中准备候选 ref。
|
||||
10. 运行相同场景并捕获候选证据。
|
||||
11. 比较 oracle 结果和视觉证据。
|
||||
12. 写入 Markdown、JSON、日志、截图和可选 trace 制品。
|
||||
13. 上传 GitHub Actions 制品。
|
||||
14. 发布简明 PR 或 Discord Status 消息。
|
||||
3. 当场景需要 UI 证据时,准备桌面/浏览器配置文件。
|
||||
4. 为基线 ref 准备干净检出。
|
||||
5. 安装依赖,并只构建场景需要的内容。
|
||||
6. 使用隔离的状态目录启动子 OpenClaw Gateway 网关。
|
||||
7. 配置实时传输协议、提供商、模型和浏览器配置文件。
|
||||
8. 运行场景并捕获基线证据。
|
||||
9. 停止 Gateway 网关并保留日志。
|
||||
10. 在同一 VM 中准备候选 ref。
|
||||
11. 运行同一场景并捕获候选证据。
|
||||
12. 对比判定器结果和视觉证据。
|
||||
13. 写入 Markdown、JSON、日志、截图和可选 trace 制品。
|
||||
14. 上传 GitHub Actions 制品。
|
||||
15. 发布简洁的 PR 或 Discord 状态消息。
|
||||
|
||||
场景应能够以两种不同方式失败:
|
||||
场景应该能够以两种不同方式失败:
|
||||
|
||||
- **错误已复现**:基线以预期方式失败。
|
||||
- **Harness 失败**:环境设置、凭证、Discord API、浏览器或提供商在错误 oracle 具有意义之前失败。
|
||||
- **Bug 已复现**:基线以预期方式失败。
|
||||
- **Harness 失败**:在 bug 判定器有意义之前,环境设置、凭证、Discord API、浏览器或提供商失败。
|
||||
|
||||
最终报告必须区分这些情况,以便维护者不会将不稳定环境误认为产品行为。
|
||||
最终报告必须区分这些情况,避免维护者把不稳定环境与产品行为混淆。
|
||||
|
||||
## Discord MVP
|
||||
## Discord 最小可行版本
|
||||
|
||||
第一个场景应针对公会渠道中的 Discord 状态回应,其中源回复投递模式为 `message_tool_only`。
|
||||
第一个场景应该针对公会频道中的 Discord 状态回应,其中源回复投递模式为 `message_tool_only`。
|
||||
|
||||
它是很好的 Mantis 种子,原因如下:
|
||||
它是一个很好的 Mantis 起点,原因如下:
|
||||
|
||||
- 它在 Discord 中表现为触发消息上的回应,可见。
|
||||
- 它通过 Discord 消息回应状态提供强 REST oracle。
|
||||
- 它会演练真实的 OpenClaw Gateway 网关、Discord 机器人认证、消息分发、源回复投递模式、状态回应状态和模型轮次生命周期。
|
||||
- 它足够狭窄,可以让第一个实现保持明确。
|
||||
- 它在 Discord 中以触发消息上的回应形式可见。
|
||||
- 它通过 Discord 消息回应状态提供强 REST 判定器。
|
||||
- 它会执行真实的 OpenClaw Gateway 网关、Discord bot 凭证、消息分发、源回复投递模式、状态回应状态和模型轮次生命周期。
|
||||
- 它足够狭窄,可以让第一个实现保持诚实。
|
||||
|
||||
预期场景形态:
|
||||
预期场景形式:
|
||||
|
||||
```yaml
|
||||
id: discord-status-reactions-tool-only
|
||||
@ -166,9 +183,9 @@ evidence:
|
||||
screenshotMessageRow: true
|
||||
```
|
||||
|
||||
基线证据应显示 queued 确认回应,但在 tool-only 模式下没有生命周期转换。候选证据应显示在 `messages.statusReactions.enabled` 显式为 true 时,生命周期状态回应正在运行。
|
||||
基线证据应显示已排队的确认回应,但在仅工具模式下没有生命周期转换。候选证据应显示当 `messages.statusReactions.enabled` 被显式设置为 true 时,生命周期状态回应会运行。
|
||||
|
||||
第一个可执行切片是选择加入的 Discord 实时 QA 场景:
|
||||
第一个可执行切片是选择启用的 Discord 实时 QA 场景:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa discord \
|
||||
@ -180,23 +197,24 @@ pnpm openclaw qa discord \
|
||||
--output-dir .artifacts/qa-e2e/mantis/discord-status-reactions-candidate
|
||||
```
|
||||
|
||||
它会使用始终开启的公会处理、`visibleReplies: "message_tool"`、`ackReaction: "👀"` 和显式状态回应配置 SUT。oracle 会轮询真实的 Discord 触发消息,并期望观察到序列 `👀 -> 🤔 -> 👍`。制品包括 `discord-qa-reaction-timelines.json`、`discord-status-reactions-tool-only-timeline.html` 和 `discord-status-reactions-tool-only-timeline.png`。
|
||||
它会为被测系统配置始终开启的公会处理、`visibleReplies:
|
||||
"message_tool"`、`ackReaction: "👀"` 和显式状态回应。判定器会轮询真实的 Discord 触发消息,并期望观察到序列 `👀 -> 🤔 -> 👍`。制品包括 `discord-qa-reaction-timelines.json`、`discord-status-reactions-tool-only-timeline.html` 和 `discord-status-reactions-tool-only-timeline.png`。
|
||||
|
||||
## 现有 QA 组件
|
||||
## 现有质量保障组件
|
||||
|
||||
Mantis 应基于现有私有 QA 栈构建,而不是从零开始:
|
||||
Mantis 应该基于现有私有质量保障栈构建,而不是从零开始:
|
||||
|
||||
- `pnpm openclaw qa discord` 已经使用 driver 和 SUT 机器人运行实时 Discord 通道。
|
||||
- 实时传输协议运行器已经在 `.artifacts/qa-e2e/` 下写入报告和 observed-message 制品。
|
||||
- `pnpm openclaw qa discord` 已经运行带有 driver 和 SUT bot 的实时 Discord 验证线。
|
||||
- 实时传输协议运行器已经会在 `.artifacts/qa-e2e/` 下写入报告和已观察消息制品。
|
||||
- Convex 凭证租约已经为共享实时传输协议凭证提供独占访问。
|
||||
- 浏览器控制服务已经支持截图、快照、headless 托管配置文件和远程 CDP 配置文件。
|
||||
- QA Lab 已经拥有用于传输协议形态测试的调试器 UI 和总线。
|
||||
- 浏览器控制服务已经支持截图、快照、无头托管配置文件和远程 CDP 配置文件。
|
||||
- QA Lab 已经有用于传输协议形态测试的调试器 UI 和总线。
|
||||
|
||||
第一个 Mantis 实现可以是在这些组件之上的一层很薄的 before/after 运行器,再加一个视觉证据层。
|
||||
第一个 Mantis 实现可以是在这些组件之上的薄层之前/之后运行器,再加上一层视觉证据。
|
||||
|
||||
## 证据模型
|
||||
|
||||
每次运行都会写入稳定的制品目录:
|
||||
每次运行都会写入一个稳定的制品目录:
|
||||
|
||||
```text
|
||||
.artifacts/qa-e2e/mantis/<run-id>/
|
||||
@ -216,63 +234,63 @@ Mantis 应基于现有私有 QA 栈构建,而不是从零开始:
|
||||
run.log
|
||||
```
|
||||
|
||||
`mantis-summary.json` 应是机器可读的事实来源。Markdown 报告用于 PR 评论和人工审查。
|
||||
`mantis-summary.json` 应该是机器可读的事实来源。Markdown 报告用于 PR 评论和人工审查。
|
||||
|
||||
摘要必须包括:
|
||||
摘要必须包含:
|
||||
|
||||
- 测试的 refs 和 SHA
|
||||
- 测试过的 ref 和 SHA
|
||||
- 传输协议和场景 id
|
||||
- 机器提供商以及机器 id 或租约 id
|
||||
- 不包含密钥值的凭证来源
|
||||
- 机器提供商和机器 id 或租约 id
|
||||
- 不含密钥值的凭证来源
|
||||
- 基线结果
|
||||
- 候选结果
|
||||
- 错误是否在基线上复现
|
||||
- bug 是否在基线上复现
|
||||
- 候选是否修复了它
|
||||
- 制品路径
|
||||
- 经过清理的设置或清理问题
|
||||
- 已清理的设置或清理问题
|
||||
|
||||
截图是证据,不是密钥。它们仍然需要遵守脱敏纪律:私有渠道名称、用户名或消息内容可能会出现。对于公开 PR,在脱敏方案更成熟之前,优先使用 GitHub Actions 制品链接,而不是内联图片。
|
||||
截图是证据,不是密钥。它们仍然需要遵守遮盖纪律:私有频道名称、用户名或消息内容可能会出现。对于公共 PR,在遮盖方案更成熟之前,优先使用 GitHub Actions 制品链接,而不是内联图片。
|
||||
|
||||
## 浏览器和 VNC
|
||||
|
||||
浏览器通道有两种模式:
|
||||
浏览器验证线有两种模式:
|
||||
|
||||
- **Headless 自动化**:CI 默认模式。Chrome 启用 CDP 运行,Playwright 或 OpenClaw 浏览器控制会捕获截图。
|
||||
- **VNC 救援**:当登录、MFA、Discord 反自动化或视觉调试需要人类参与时,在同一 VM 上启用。
|
||||
- **无头自动化**:CI 的默认模式。Chrome 启用 CDP 运行,Playwright 或 OpenClaw 浏览器控制会捕获截图。
|
||||
- **VNC 救援**:当登录、MFA、Discord 反自动化或视觉调试需要人工时,在同一 VM 上启用。
|
||||
|
||||
Discord 观察者浏览器配置文件应足够持久,以避免每次运行都登录,但应与个人浏览器状态隔离。配置文件属于 Mantis 机器池,而不是开发者笔记本电脑。
|
||||
|
||||
当 Mantis 卡住时,它会发布一条 Discord Status 消息,其中包含:
|
||||
当 Mantis 卡住时,它会发布一条 Discord 状态消息,包含:
|
||||
|
||||
- 运行 id
|
||||
- 场景 id
|
||||
- 机器提供商
|
||||
- 制品目录
|
||||
- 可用时的 VNC 或 noVNC 连接说明
|
||||
- 简短阻塞文本
|
||||
- VNC 或 noVNC 连接说明(如果可用)
|
||||
- 简短阻塞原因文本
|
||||
|
||||
第一个私有部署可以将这些消息发布到现有操作员渠道,之后再迁移到专用 Mantis 渠道。
|
||||
首个私有部署可以先将这些消息发布到现有的操作员渠道,之后再迁移到专用的 Mantis 渠道。
|
||||
|
||||
## 机器
|
||||
|
||||
第一个远程实现中,Mantis 应优先通过 Crabbox 使用 AWS。Crabbox 为我们提供已预热机器、租约跟踪、水合、日志、结果和清理。如果 AWS 容量太慢或不可用,则在同一机器接口后添加 Hetzner 提供商。
|
||||
Mantis 的首个远程实现应优先通过 Crabbox 使用 AWS。Crabbox 为我们提供预热机器、租约跟踪、水合、日志、结果和清理。如果 AWS 容量太慢或不可用,请在同一个机器接口后添加 Hetzner 提供商。
|
||||
|
||||
最低 VM 要求:
|
||||
|
||||
- 安装了支持桌面的 Chrome 或 Chromium 的 Linux
|
||||
- Linux,并安装可运行桌面的 Chrome 或 Chromium
|
||||
- 用于浏览器自动化的 CDP 访问
|
||||
- 用于救援的 VNC 或 noVNC
|
||||
- Node 22 和 pnpm
|
||||
- OpenClaw checkout 和依赖缓存
|
||||
- OpenClaw 检出和依赖缓存
|
||||
- 使用 Playwright 时的 Playwright Chromium 浏览器缓存
|
||||
- 足够的 CPU 和内存,可运行一个 OpenClaw Gateway 网关、一个浏览器和一次模型运行
|
||||
- 可出站访问 Discord、GitHub、模型提供商和凭证 broker
|
||||
- 可出站访问 Discord、GitHub、模型提供商和凭证代理
|
||||
|
||||
VM 不应在预期凭证或浏览器配置文件存储之外保留长期存在的原始密钥。
|
||||
VM 不应在预期的凭证或浏览器配置文件存储之外保留长期存在的原始密钥。
|
||||
|
||||
## 密钥
|
||||
|
||||
远程运行的密钥存放在 GitHub 组织或仓库密钥中,本地运行的密钥存放在本地操作员控制的密钥文件中。
|
||||
远程运行的密钥存放在 GitHub 组织或仓库密钥中,本地运行的密钥存放在由本地操作员控制的密钥文件中。
|
||||
|
||||
推荐的密钥名称:
|
||||
|
||||
@ -282,32 +300,32 @@ VM 不应在预期凭证或浏览器配置文件存储之外保留长期存在
|
||||
- `OPENCLAW_QA_DISCORD_GUILD_ID`
|
||||
- `OPENCLAW_QA_DISCORD_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_DISCORD_NOTIFY_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1` 用于公开 GitHub 工件上传
|
||||
- `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1` 用于公开 GitHub 构件上传
|
||||
- `OPENCLAW_QA_CONVEX_SITE_URL`
|
||||
- `OPENCLAW_QA_CONVEX_SECRET_CI`
|
||||
|
||||
从长期来看,Convex 凭证池应继续作为实时传输凭证的常规来源。GitHub 密钥用于引导代理和回退通道。
|
||||
长期来看,Convex 凭证池应继续作为实时传输凭证的常规来源。GitHub 密钥用于引导代理和备用通道。
|
||||
|
||||
Mantis 运行器绝不能打印:
|
||||
Mantis runner 绝不能打印:
|
||||
|
||||
- Discord 机器人令牌
|
||||
- 提供商 API 密钥
|
||||
- 浏览器 Cookie
|
||||
- 提供商 API key
|
||||
- 浏览器 cookie
|
||||
- 认证配置文件内容
|
||||
- VNC 密码
|
||||
- 原始凭证载荷
|
||||
|
||||
公开工件上传还应遮蔽 Discord 目标元数据,例如机器人、服务器、渠道和消息 ID。GitHub smoke 工作流因此会启用 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`。
|
||||
公开构件上传还应遮盖 Discord 目标元数据,例如机器人、服务器、频道和消息 ID。GitHub smoke workflow 因此启用了 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`。
|
||||
|
||||
如果令牌被意外粘贴到 issue、PR、聊天或日志中,请在新密钥存储完成后轮换它。
|
||||
如果令牌被意外粘贴到 issue、PR、聊天或日志中,请在新密钥存储后轮换该令牌。
|
||||
|
||||
## GitHub 工件和 PR 评论
|
||||
## GitHub 构件和 PR 评论
|
||||
|
||||
Mantis 工作流应将完整证据包上传为短期 Actions 工件。当工作流针对错误报告或修复 PR 运行时,还应将已遮蔽的 PNG 截图发布到 `qa-artifacts` 分支,并在该错误或修复 PR 上更新或插入一条评论,内联展示前后对比截图。不要只把主要证明发布在通用 QA 自动化 PR 上。原始日志、观测到的消息以及其他体量较大的证据保留在 Actions 工件中。
|
||||
Mantis workflow 应将完整证据包上传为短期 Actions 构件。当 workflow 针对 bug 报告或修复 PR 运行时,还应将已遮盖的 PNG 截图发布到 `qa-artifacts` 分支,并在该 bug 或修复 PR 上更新插入一条评论,内联展示修复前/后的截图。不要只把主要证明发布到通用 QA 自动化 PR 上。原始日志、观察到的消息和其他体积较大的证据保留在 Actions 构件中。
|
||||
|
||||
生产工作流应使用 Mantis GitHub App 发布这些评论,而不是使用 `github-actions[bot]`。将应用 ID 和私钥作为 `MANTIS_GITHUB_APP_ID` 与 `MANTIS_GITHUB_APP_PRIVATE_KEY` GitHub Actions 密钥存储。该工作流使用隐藏标记作为更新插入键,在令牌可以编辑时更新该评论,并在较旧的机器人所有标记无法编辑时创建一条新的 Mantis 所有评论。
|
||||
生产 workflow 应使用 Mantis GitHub App 发布这些评论,而不是使用 `github-actions[bot]`。将 app id 和私钥作为 `MANTIS_GITHUB_APP_ID` 与 `MANTIS_GITHUB_APP_PRIVATE_KEY` GitHub Actions 密钥存储。workflow 使用隐藏标记作为更新插入键;当令牌可以编辑该评论时就更新该评论;当较旧的 bot 所有标记无法编辑时,就创建新的 Mantis 所有评论。
|
||||
|
||||
PR 评论应简短且可视化:
|
||||
PR 评论应简短且以视觉为主:
|
||||
|
||||
```md
|
||||
Mantis Discord Status Reactions QA
|
||||
@ -327,15 +345,15 @@ candidate showed the expected queued -> thinking -> done sequence.
|
||||
| <inline screenshot> | <inline screenshot> |
|
||||
```
|
||||
|
||||
当运行失败是因为 harness 失败时,评论必须说明这一点,而不是暗示候选版本失败。
|
||||
当运行失败是因为 harness 失败时,评论必须说明这一点,而不是暗示候选修复失败。
|
||||
|
||||
## 私有部署说明
|
||||
|
||||
私有部署可能已经有一个 Mantis Discord 应用。当该应用拥有正确的机器人权限并且可以安全轮换时,请复用该应用,而不是创建另一个应用。
|
||||
私有部署可能已经有一个 Mantis Discord 应用。如果该应用具备正确的机器人权限并且可以安全轮换,请复用该应用,而不是创建另一个 app。
|
||||
|
||||
通过密钥或部署配置设置初始操作者通知渠道。它可以先指向现有维护者或运维渠道,然后在专用 Mantis 渠道存在后再迁移过去。
|
||||
通过密钥或部署配置设置初始操作员通知渠道。它可以先指向现有的维护者或运维渠道,等专用 Mantis 渠道存在后再迁移过去。
|
||||
|
||||
不要把服务器 ID、渠道 ID、机器人令牌、浏览器 Cookie 或 VNC 密码放入本文档。请将它们存储在 GitHub 密钥、凭证代理或操作者的本地密钥存储中。
|
||||
不要把服务器 ID、频道 ID、机器人令牌、浏览器 cookie 或 VNC 密码放进本文档。将它们存储在 GitHub 密钥、凭证代理或操作员的本地密钥存储中。
|
||||
|
||||
## 添加场景
|
||||
|
||||
@ -343,44 +361,44 @@ Mantis 场景应声明:
|
||||
|
||||
- ID 和标题
|
||||
- 传输协议
|
||||
- 必需凭证
|
||||
- 基线引用策略
|
||||
- 候选引用策略
|
||||
- 所需凭证
|
||||
- 基线 ref 策略
|
||||
- 候选 ref 策略
|
||||
- OpenClaw 配置补丁
|
||||
- 设置步骤
|
||||
- 激励
|
||||
- 预期基线判定器
|
||||
- 预期候选判定器
|
||||
- 可视化采集目标
|
||||
- 视觉捕获目标
|
||||
- 超时预算
|
||||
- 清理步骤
|
||||
|
||||
场景应优先使用小型、带类型的判定器:
|
||||
|
||||
- 用于 reaction 错误的 Discord reaction 状态
|
||||
- 用于线程错误的 Discord 消息引用
|
||||
- 用于 Slack 错误的 Slack 线程 ts 和 reaction API 状态
|
||||
- 用于电子邮件错误的电子邮件消息 ID 和标头
|
||||
- 当 UI 是唯一可靠可观测对象时使用浏览器截图
|
||||
- 用于 reaction bug 的 Discord reaction 状态
|
||||
- 用于 threading bug 的 Discord 消息引用
|
||||
- 用于 Slack bug 的 Slack thread ts 和 reaction API 状态
|
||||
- 用于 email bug 的 email 消息 ID 和标头
|
||||
- 当 UI 是唯一可靠可观测项时使用浏览器截图
|
||||
|
||||
视觉检查应作为补充。如果平台 API 可以证明错误,请使用该 API 作为通过/失败判定器,并保留截图用于增强人的信心。
|
||||
视觉检查应作为补充。如果平台 API 能证明 bug,请使用 API 作为通过/失败判定器,并保留截图用于增强人工信心。
|
||||
|
||||
## 提供商扩展
|
||||
|
||||
在 Discord 之后,同一个运行器可以添加:
|
||||
在 Discord 之后,同一个 runner 可以添加:
|
||||
|
||||
- Slack:reaction、线程、应用提及、模态框、文件上传。
|
||||
- 电子邮件:在连接器不足时,使用 `gog` 进行 Gmail 认证和消息线程处理。
|
||||
- WhatsApp:二维码登录、重新识别、消息投递、媒体、reaction。
|
||||
- Telegram:群组提及门控、命令、可用时的 reaction。
|
||||
- Matrix:加密房间、线程或回复关系、重启恢复。
|
||||
- Slack:reactions、threads、app mentions、modals、file uploads。
|
||||
- Email:Gmail 认证,以及在 connectors 不足时使用 `gog` 进行消息 threading。
|
||||
- WhatsApp:QR 登录、重新识别、消息投递、媒体、reactions。
|
||||
- Telegram:群组 mention gating、commands、可用时的 reactions。
|
||||
- Matrix:加密房间、thread 或 reply relations、重启恢复。
|
||||
|
||||
每种传输协议都应有一个低成本 smoke 场景,以及一个或多个错误类别场景。昂贵的可视化场景应保持为选择加入。
|
||||
每种传输协议都应有一个低成本 smoke 场景,以及一个或多个 bug 类别场景。昂贵的视觉场景应保持为选择启用。
|
||||
|
||||
## 未决问题
|
||||
## 待解决问题
|
||||
|
||||
- 复用现有 Mantis 机器人时,哪个 Discord 机器人应作为驱动,哪个应作为 SUT?
|
||||
- 第一阶段中,观察者浏览器登录应使用人类 Discord 账号、测试账号,还是只使用机器人可读的 REST 证据?
|
||||
- GitHub 应为 PR 保留 Mantis 工件多长时间?
|
||||
- 复用现有 Mantis bot 时,哪个 Discord bot 应作为 driver,哪个应作为 SUT?
|
||||
- 第一阶段的观察者浏览器登录应使用真人 Discord 账号、测试账号,还是只使用 bot 可读取的 REST 证据?
|
||||
- GitHub 应为 PR 保留 Mantis 构件多长时间?
|
||||
- ClawSweeper 应在什么时候自动推荐 Mantis,而不是等待维护者命令?
|
||||
- 对于公开 PR,截图在上传前是否应被遮蔽或裁剪?
|
||||
- 公开 PR 上传前是否应遮盖或裁剪截图?
|
||||
|
||||
@ -1,61 +1,61 @@
|
||||
---
|
||||
read_when:
|
||||
- 了解 QA 栈如何协同工作
|
||||
- 扩展 qa-lab、qa-channel 或传输适配器
|
||||
- 扩展 qa-lab、qa-channel 或传输协议适配器
|
||||
- 添加由仓库支持的 QA 场景
|
||||
- 围绕 Gateway 网关仪表板构建更高真实度的 QA 自动化
|
||||
summary: QA 栈概览:qa-lab、qa-channel、由仓库支撑的场景、实时传输通道、传输适配器和报告。
|
||||
title: QA overview
|
||||
x-i18n:
|
||||
generated_at: "2026-05-03T22:25:26Z"
|
||||
generated_at: "2026-05-04T00:35:07Z"
|
||||
model: gpt-5.5
|
||||
provider: openai
|
||||
source_hash: 7553094890e20eb760df149ac8bd598048c023dc072743ffe2a8dd60d17382de
|
||||
source_hash: 0b376767b967a51cc8a45ca5ce420f78067b52e6368d2abe921ffed533f6f9ba
|
||||
source_path: concepts/qa-e2e-automation.md
|
||||
workflow: 16
|
||||
---
|
||||
|
||||
私有 QA 栈用于以更真实、更贴近渠道形态的方式演练 OpenClaw,这是单个单元测试做不到的。
|
||||
私有 QA 栈旨在以比单个单元测试更接近真实、符合渠道形态的方式来演练 OpenClaw。
|
||||
|
||||
当前组成:
|
||||
当前组成部分:
|
||||
|
||||
- `extensions/qa-channel`:合成消息渠道,包含私信、渠道、线程、表情回应、编辑和删除表面。
|
||||
- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察会话记录、注入入站消息,以及导出 Markdown 报告。
|
||||
- `extensions/qa-matrix`、未来的 runner 插件:实时传输适配器,用于在子 QA Gateway 网关内驱动真实渠道。
|
||||
- `qa/`:由仓库支持的启动任务种子资产和基线 QA 场景。
|
||||
- [Mantis](/zh-CN/concepts/mantis):针对需要真实传输、浏览器截图、VM 状态和 PR 证据的 bug,进行修复前后的实时验证。
|
||||
- `extensions/qa-channel`:合成消息渠道,覆盖私信、渠道、线程、回应、编辑和删除表面。
|
||||
- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察对话记录、注入入站消息,并导出 Markdown 报告。
|
||||
- `extensions/qa-matrix`、未来的运行器插件:实时传输协议适配器,用于在子 QA Gateway 网关内驱动真实渠道。
|
||||
- `qa/`:由仓库支持的启动任务和基线 QA 场景种子资产。
|
||||
- [Mantis](/zh-CN/concepts/mantis):针对需要真实传输协议、浏览器截图、VM 状态和 PR 证据的 bug,进行修复前后实时验证。
|
||||
|
||||
## 命令表面
|
||||
## 命令界面
|
||||
|
||||
每个 QA 流都在 `pnpm openclaw qa <subcommand>` 下运行。许多命令都有 `pnpm qa:*` 脚本别名;两种形式都受支持。
|
||||
每个 QA 流程都在 `pnpm openclaw qa <subcommand>` 下运行。许多命令有 `pnpm qa:*` 脚本别名;两种形式都受支持。
|
||||
|
||||
| 命令 | 用途 |
|
||||
| --------------------------------------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `qa run` | 内置 QA 自检;写入 Markdown 报告。 |
|
||||
| `qa suite` | 针对 QA Gateway 网关 lane 运行由仓库支持的场景。别名:`pnpm openclaw qa suite --runner multipass`,用于一次性 Linux VM。 |
|
||||
| `qa coverage` | 打印 markdown 场景覆盖率清单(`--json` 用于机器输出)。 |
|
||||
| `qa parity-report` | 比较两个 `qa-suite-summary.json` 文件并写入智能体 parity 报告。 |
|
||||
| `qa character-eval` | 在多个实时模型上运行角色 QA 场景,并生成带评判的报告。参见[报告](#reporting)。 |
|
||||
| `qa manual` | 针对选定的提供商/模型 lane 运行一次性提示词。 |
|
||||
| `qa ui` | 启动 QA 调试器 UI 和本地 QA 总线(别名:`pnpm qa:lab:ui`)。 |
|
||||
| `qa docker-build-image` | 构建预制 QA Docker 镜像。 |
|
||||
| `qa docker-scaffold` | 为 QA 仪表板 + Gateway 网关 lane 写入 docker-compose 脚手架。 |
|
||||
| `qa up` | 构建 QA 站点,启动 Docker 支持的栈,并打印 URL(别名:`pnpm qa:lab:up`;`:fast` 变体会添加 `--use-prebuilt-image --bind-ui-dist --skip-ui-build`)。 |
|
||||
| `qa aimock` | 仅启动 AIMock 提供商服务器。 |
|
||||
| `qa mock-openai` | 仅启动感知场景的 `mock-openai` 提供商服务器。 |
|
||||
| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享 Convex 凭证池。 |
|
||||
| `qa matrix` | 针对一次性 Tuwunel homeserver 的实时传输 lane。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 |
|
||||
| `qa telegram` | 针对真实私有 Telegram 群组的实时传输 lane。 |
|
||||
| `qa discord` | 针对真实私有 Discord guild 渠道的实时传输 lane。 |
|
||||
| `qa slack` | 针对真实私有 Slack 渠道的实时传输 lane。 |
|
||||
| `qa mantis` | 用于实时传输 bug 的修复前后验证 runner,包含第一个 Discord 状态回应场景。参见 [Mantis](/zh-CN/concepts/mantis)。 |
|
||||
| 命令 | 用途 |
|
||||
| --------------------------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
|
||||
| `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` 文件,并写入智能体一致性报告。 |
|
||||
| `qa character-eval` | 跨多个实时模型运行角色 QA 场景,并生成评审报告。参见[报告](#reporting)。 |
|
||||
| `qa manual` | 针对所选提供商/模型通道运行一次性提示。 |
|
||||
| `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](/zh-CN/concepts/qa-matrix)。 |
|
||||
| `qa telegram` | 针对真实私有 Telegram 群组的实时传输协议通道。 |
|
||||
| `qa discord` | 针对真实私有 Discord guild 渠道的实时传输协议通道。 |
|
||||
| `qa slack` | 针对真实私有 Slack 渠道的实时传输协议通道。 |
|
||||
| `qa mantis` | 面向实时传输协议 bug 的修复前后验证运行器,包含 Discord 状态回应证据和 Crabbox 桌面/浏览器冒烟测试。参见 [Mantis](/zh-CN/concepts/mantis)。 |
|
||||
|
||||
## 操作者流程
|
||||
|
||||
当前 QA 操作者流程是一个双栏 QA 站点:
|
||||
|
||||
- 左侧:带有智能体的 Gateway 网关仪表板(Control UI)。
|
||||
- 右侧:QA Lab,显示类似 Slack 的会话记录和场景计划。
|
||||
- 右侧:QA Lab,显示类似 Slack 的对话记录和场景计划。
|
||||
|
||||
运行方式:
|
||||
|
||||
@ -63,9 +63,9 @@ x-i18n:
|
||||
pnpm qa:lab:up
|
||||
```
|
||||
|
||||
这会构建 QA 站点,启动 Docker 支持的 Gateway 网关 lane,并公开 QA Lab 页面,操作者或自动化循环可以在这里给智能体分配 QA 任务、观察真实渠道行为,并记录哪些成功、失败或仍然阻塞。
|
||||
这会构建 QA 站点,启动 Docker 支持的 Gateway 网关通道,并暴露 QA Lab 页面,操作者或自动化循环可以在此给智能体分配 QA 任务、观察真实渠道行为,并记录哪些内容有效、失败或仍被阻塞。
|
||||
|
||||
为了更快迭代 QA Lab UI,而不必每次都重建 Docker 镜像,可以使用 bind-mounted 的 QA Lab bundle 启动栈:
|
||||
若要在不每次都重建 Docker 镜像的情况下更快迭代 QA Lab UI,请使用绑定挂载的 QA Lab bundle 启动栈:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa docker-build-image
|
||||
@ -74,27 +74,27 @@ pnpm qa:lab:up:fast
|
||||
pnpm qa:lab:watch
|
||||
```
|
||||
|
||||
`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` bind-mount 到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该 bundle,当 QA Lab 资产哈希变化时浏览器会自动重新加载。
|
||||
`qa:lab:up:fast` 会让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` 绑定挂载到 `qa-lab` 容器。`qa:lab:watch` 会在变更时重建该 bundle,当 QA Lab 资产哈希变化时,浏览器会自动重新加载。
|
||||
|
||||
要进行本地 OpenTelemetry trace smoke,请运行:
|
||||
若要进行本地 OpenTelemetry 跟踪冒烟测试,请运行:
|
||||
|
||||
```bash
|
||||
pnpm qa:otel:smoke
|
||||
```
|
||||
|
||||
该脚本会启动本地 OTLP/HTTP trace receiver,启用 `diagnostics-otel` 插件运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans,并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功轮次中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须留在 trace 之外。它会在 QA suite artifacts 旁写入 `otel-smoke-summary.json`。
|
||||
该脚本会启动本地 OTLP/HTTP 跟踪接收器,在启用 `diagnostics-otel` 插件的情况下运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf spans,并断言发布关键形态:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功轮次中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须保留在跟踪之外。它会在 QA suite 产物旁边写入 `otel-smoke-summary.json`。
|
||||
|
||||
可观测性 QA 仅适用于源码 checkout。npm tarball 有意省略 QA Lab,因此 package Docker release lane 不会运行 `qa` 命令。修改诊断 instrumentation 时,请从已构建的源码 checkout 运行 `pnpm qa:otel:smoke`。
|
||||
可观测性 QA 仅限源码 checkout。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。变更诊断插桩时,请从已构建的源码 checkout 运行 `pnpm qa:otel:smoke`。
|
||||
|
||||
要运行真实传输的 Matrix smoke lane,请运行:
|
||||
若要运行真实传输协议 Matrix 冒烟通道,请运行:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa matrix --profile fast --fail-fast
|
||||
```
|
||||
|
||||
此 lane 的完整 CLI 参考、profile/场景目录、环境变量和 artifact 布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中配置一个一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输的子 QA Gateway 网关内运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-<timestamp>/` 下写入 Markdown 报告、JSON 摘要、observed-events artifact 和合并输出日志。
|
||||
该通道的完整 CLI 参考、profile/场景目录、环境变量和产物布局见 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中预配一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输协议的子 QA Gateway 网关中运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-<timestamp>/` 下写入 Markdown 报告、JSON 摘要、observed-events 产物和合并输出日志。
|
||||
|
||||
对于真实传输的 Telegram、Discord 和 Slack smoke lane:
|
||||
对于真实传输协议的 Telegram、Discord 和 Slack 冒烟通道:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa telegram
|
||||
@ -102,62 +102,62 @@ pnpm openclaw qa discord
|
||||
pnpm openclaw qa slack
|
||||
```
|
||||
|
||||
它们以一个预先存在的真实渠道为目标,并使用两个 bot(driver + SUT)。必需环境变量、场景列表、输出 artifacts 和 Convex 凭证池记录在下面的 [Telegram、Discord 和 Slack QA 参考](#telegram-discord-and-slack-qa-reference)中。
|
||||
它们面向已有的真实渠道,并使用两个 bot(driver + SUT)。所需环境变量、场景列表、输出产物和 Convex 凭证池记录在下方的 [Telegram、Discord 和 Slack QA 参考](#telegram-discord-and-slack-qa-reference)中。
|
||||
|
||||
使用池化实时凭证之前,运行:
|
||||
使用池化实时凭证前,请运行:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa credentials doctor
|
||||
```
|
||||
|
||||
Doctor 会检查 Convex broker 环境、验证 endpoint 设置,并在存在 maintainer secret 时验证 admin/list 可达性。它只报告 secret 的已设置/缺失状态。
|
||||
Doctor 会检查 Convex broker 环境、验证 endpoint 设置,并在存在维护者密钥时验证 admin/list 可达性。它只报告密钥的已设置/缺失状态。
|
||||
|
||||
## 实时传输覆盖范围
|
||||
## 实时传输协议覆盖范围
|
||||
|
||||
实时传输 lane 共享一份契约,而不是各自发明自己的场景列表形态。`qa-channel` 是宽泛的合成产品行为 suite,不属于实时传输覆盖矩阵。
|
||||
实时传输协议通道共享一个契约,而不是各自发明自己的场景列表形态。`qa-channel` 是广泛的合成产品行为 suite,不属于实时传输协议覆盖矩阵。
|
||||
|
||||
| Lane | Canary | 提及门控 | Bot-to-bot | allowlist 阻止 | 顶层回复 | 重启恢复 | 线程后续消息 | 线程隔离 | 表情回应观察 | Help 命令 | 原生命令注册 |
|
||||
| -------- | ------ | -------- | ---------- | -------------- | -------- | -------- | ------------ | -------- | ------------ | --------- | ------------ |
|
||||
| Matrix | x | x | x | x | x | x | x | x | x | | |
|
||||
| Telegram | x | x | x | | | | | | | x | |
|
||||
| Discord | x | x | x | | | | | | | | x |
|
||||
| Slack | x | x | x | | | | | | | | |
|
||||
| 通道 | Canary | 提及门控 | Bot 到 bot | Allowlist 阻断 | 顶层回复 | 重启恢复 | 线程跟进 | 线程隔离 | 回应观察 | 帮助命令 | 原生命令注册 |
|
||||
| -------- | ------ | -------- | ---------- | --------------- | -------- | -------- | -------- | -------- | -------- | -------- | ------------ |
|
||||
| Matrix | x | x | x | x | x | x | x | x | x | | |
|
||||
| Telegram | x | x | x | | | | | | | x | |
|
||||
| Discord | x | x | x | | | | | | | | x |
|
||||
| Slack | x | x | x | | | | | | | | |
|
||||
|
||||
这会保留 `qa-channel` 作为宽泛的产品行为 suite,同时让 Matrix、Telegram 和未来实时传输共享一份明确的传输契约 checklist。
|
||||
这会将 `qa-channel` 保持为广泛的产品行为 suite,同时让 Matrix、Telegram 和未来的实时传输协议共享一个明确的传输协议契约检查清单。
|
||||
|
||||
要在不把 Docker 带入 QA 路径的情况下运行一次性 Linux VM lane,请运行:
|
||||
若要运行一个不把 Docker 带入 QA 路径的一次性 Linux VM 通道,请运行:
|
||||
|
||||
```bash
|
||||
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` 串行执行。
|
||||
任何场景失败时,该命令都会以非零状态退出。当你想获取 artifacts 但不想要失败退出码时,请使用 `--allow-failures`。
|
||||
实时运行会转发对 guest 实用的受支持 QA auth 输入:基于环境的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,这样 guest 才能通过挂载的工作区写回。
|
||||
这会启动一个全新的 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 key、QA 实时 provider 配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,这样 guest 才能通过挂载的工作区写回。
|
||||
|
||||
## Telegram、Discord 和 Slack QA 参考
|
||||
|
||||
Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景数量更多,并且需要 Docker 支持的 homeserver 配置。Telegram、Discord 和 Slack 更小,每个只有少量场景、没有 profile 系统,并针对预先存在的真实渠道,因此它们的参考放在这里。
|
||||
Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它场景数量较多,并且需要 Docker 支持的 homeserver 预配。Telegram、Discord 和 Slack 更小,每个只有少量场景,没有 profile 系统,并且面向已有真实渠道,因此它们的参考放在这里。
|
||||
|
||||
### 共享 CLI 标志
|
||||
|
||||
这些 lane 通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同的标志:
|
||||
这些通道通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同的标志:
|
||||
|
||||
| 标志 | 默认值 | 描述 |
|
||||
| 标志 | 默认值 | 描述 |
|
||||
| ------------------------------------- | --------------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- |
|
||||
| `--scenario <id>` | — | 仅运行此场景。可重复。 |
|
||||
| `--output-dir <path>` | `<repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp>` | 写入报告、摘要、观察到的消息和输出日志的位置。相对路径基于 `--repo-root` 解析。 |
|
||||
| `--repo-root <path>` | `process.cwd()` | 从中立 cwd 调用时的仓库根目录。 |
|
||||
| `--sut-account <id>` | `sut` | QA Gateway 网关配置内的临时账号 id。 |
|
||||
| `--provider-mode <mode>` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可用)。 |
|
||||
| `--model <ref>` / `--alt-model <ref>` | provider default | 主/备用模型引用。 |
|
||||
| `--fast` | off | 支持时启用提供商快速模式。 |
|
||||
| `--credential-source <env\|convex>` | `env` | 参见 [Convex 凭证池](#convex-credential-pool)。 |
|
||||
| `--credential-role <maintainer\|ci>` | CI 中为 `ci`,否则为 `maintainer` | `--credential-source convex` 时使用的角色。 |
|
||||
| `--scenario <id>` | — | 仅运行此场景。可重复指定。 |
|
||||
| `--output-dir <path>` | `<repo>/.artifacts/qa-e2e/{telegram,discord,slack}-<timestamp>` | 写入报告、摘要、观测到的消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 |
|
||||
| `--repo-root <path>` | `process.cwd()` | 从中性 cwd 调用时的仓库根目录。 |
|
||||
| `--sut-account <id>` | `sut` | QA Gateway 网关配置中的临时账户 id。 |
|
||||
| `--provider-mode <mode>` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍然可用)。 |
|
||||
| `--model <ref>` / `--alt-model <ref>` | provider 默认值 | 主模型和备用模型引用。 |
|
||||
| `--fast` | 关闭 | provider 支持时使用快速模式。 |
|
||||
| `--credential-source <env\|convex>` | `env` | 参见 [Convex 凭证池](#convex-credential-pool)。 |
|
||||
| `--credential-role <maintainer\|ci>` | CI 中为 `ci`,否则为 `maintainer` | 使用 `--credential-source convex` 时采用的角色。 |
|
||||
|
||||
任何场景失败时,每条 lane 都会以非零状态退出。`--allow-failures` 会写入产物,但不会设置失败退出码。
|
||||
任何场景失败时,每个测试通道都会以非零状态退出。`--allow-failures` 会写入产物,但不会设置失败退出码。
|
||||
|
||||
### Telegram QA
|
||||
|
||||
@ -165,9 +165,9 @@ Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景
|
||||
pnpm openclaw qa telegram
|
||||
```
|
||||
|
||||
目标是一个真实的私有 Telegram 群组,其中有两个不同的 bot(driver + SUT)。SUT bot 必须有 Telegram 用户名;当两个 bot 都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,bot 到 bot 观察效果最好。
|
||||
目标是一个真实的私有 Telegram 群组,其中包含两个不同的机器人(驱动程序 + SUT)。SUT 机器人必须拥有 Telegram 用户名;当两个机器人都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,机器人到机器人的观测效果最佳。
|
||||
|
||||
使用 `--credential-source env` 时必需的环境变量:
|
||||
当 `--credential-source env` 时所需的环境变量:
|
||||
|
||||
- `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 数字聊天 id(字符串)。
|
||||
- `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN`
|
||||
@ -175,7 +175,7 @@ pnpm openclaw qa telegram
|
||||
|
||||
可选:
|
||||
|
||||
- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在观察到的消息产物中保留消息正文(默认会脱敏)。
|
||||
- `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1` 会在观测消息产物中保留消息正文(默认会脱敏)。
|
||||
|
||||
场景(`extensions/qa-lab/src/live-transports/telegram/telegram-live.runtime.ts:44`):
|
||||
|
||||
@ -191,8 +191,8 @@ pnpm openclaw qa telegram
|
||||
输出产物:
|
||||
|
||||
- `telegram-qa-report.md`
|
||||
- `telegram-qa-summary.json` — 包含从 canary 开始的每条回复 RTT(driver 发送 → 观察到 SUT 回复)。
|
||||
- `telegram-qa-observed-messages.json` — 正文会脱敏,除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`。
|
||||
- `telegram-qa-summary.json` — 包含从 canary 开始的每条回复 RTT(驱动程序发送 → 观测到 SUT 回复)。
|
||||
- `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被脱敏。
|
||||
|
||||
### Discord QA
|
||||
|
||||
@ -200,26 +200,26 @@ pnpm openclaw qa telegram
|
||||
pnpm openclaw qa discord
|
||||
```
|
||||
|
||||
目标是一个真实的私有 Discord guild 频道,其中有两个 bot:由 harness 控制的 driver bot,以及由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT bot。验证频道提及处理、SUT bot 是否已向 Discord 注册原生 `/help` 命令,以及选择加入的 Mantis 证据场景。
|
||||
目标是一个真实的私有 Discord guild 渠道,其中包含两个机器人:由 harness 控制的驱动机器人,以及由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT 机器人。它会验证渠道提及处理、SUT 机器人是否已向 Discord 注册原生 `/help` 命令,以及需要选择加入的 Mantis 证据场景。
|
||||
|
||||
使用 `--credential-source env` 时必需的环境变量:
|
||||
当 `--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(否则该 lane 会快速失败)。
|
||||
- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须匹配 Discord 返回的 SUT 机器人用户 id(否则该测试通道会快速失败)。
|
||||
|
||||
可选:
|
||||
|
||||
- `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1` 会在观察到的消息产物中保留消息正文。
|
||||
- `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 视觉产物。
|
||||
- `discord-status-reactions-tool-only` — 选择加入的 Mantis 场景。它会单独运行,因为它会将 SUT 切换为始终开启、仅工具驱动的 guild 回复,并设置 `messages.statusReactions.enabled=true`,然后捕获 REST 反应时间线以及 HTML/PNG 可视产物。
|
||||
|
||||
显式运行 Mantis status-reaction 场景:
|
||||
|
||||
@ -236,7 +236,7 @@ pnpm openclaw qa discord \
|
||||
|
||||
- `discord-qa-report.md`
|
||||
- `discord-qa-summary.json`
|
||||
- `discord-qa-observed-messages.json` — 正文会脱敏,除非设置 `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`。
|
||||
- `discord-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_DISCORD_CAPTURE_CONTENT=1`,否则正文会被脱敏。
|
||||
- 运行 status-reaction 场景时会生成 `discord-qa-reaction-timelines.json` 和 `discord-status-reactions-tool-only-timeline.png`。
|
||||
|
||||
### Slack QA
|
||||
@ -245,9 +245,9 @@ pnpm openclaw qa discord \
|
||||
pnpm openclaw qa slack
|
||||
```
|
||||
|
||||
目标是一个真实的私有 Slack 频道,其中有两个不同的 bot:由 harness 控制的 driver bot,以及由子 OpenClaw Gateway 网关通过内置 Slack 插件启动的 SUT bot。
|
||||
目标是一个真实的私有 Slack 渠道,其中包含两个不同的机器人:由 harness 控制的驱动机器人,以及由子 OpenClaw Gateway 网关通过内置 Slack 插件启动的 SUT 机器人。
|
||||
|
||||
使用 `--credential-source env` 时必需的环境变量:
|
||||
当 `--credential-source env` 时所需的环境变量:
|
||||
|
||||
- `OPENCLAW_QA_SLACK_CHANNEL_ID`
|
||||
- `OPENCLAW_QA_SLACK_DRIVER_BOT_TOKEN`
|
||||
@ -256,7 +256,7 @@ pnpm openclaw qa slack
|
||||
|
||||
可选:
|
||||
|
||||
- `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1` 会在观察到的消息产物中保留消息正文。
|
||||
- `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1` 会在观测消息产物中保留消息正文。
|
||||
|
||||
场景(`extensions/qa-lab/src/live-transports/slack/slack-live.runtime.ts:39`):
|
||||
|
||||
@ -267,70 +267,70 @@ pnpm openclaw qa slack
|
||||
|
||||
- `slack-qa-report.md`
|
||||
- `slack-qa-summary.json`
|
||||
- `slack-qa-observed-messages.json` — 正文会脱敏,除非设置 `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1`。
|
||||
- `slack-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_SLACK_CAPTURE_CONTENT=1`,否则正文会被脱敏。
|
||||
|
||||
### Convex 凭证池
|
||||
|
||||
Telegram、Discord 和 Slack lane 可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间发送 Heartbeat,并在关闭时释放。池类型为 `"telegram"`、`"discord"` 和 `"slack"`。
|
||||
Telegram、Discord 和 Slack 测试通道可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间发送 Heartbeat,并在关闭时释放它。池类型为 `"telegram"`、`"discord"` 和 `"slack"`。
|
||||
|
||||
broker 在 `admin/add` 上验证的 payload 形状:
|
||||
broker 在 `admin/add` 上验证的载荷形状:
|
||||
|
||||
- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }` — `groupId` 必须是数字 chat-id 字符串。
|
||||
- Telegram(`kind: "telegram"`):`{ groupId: string, driverToken: string, sutToken: string }` — `groupId` 必须是数字聊天 id 字符串。
|
||||
- Discord(`kind: "discord"`):`{ guildId: string, channelId: string, driverBotToken: string, sutBotToken: string, sutApplicationId: string }`。
|
||||
|
||||
操作用环境变量和 Convex broker 端点契约位于 [测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该小节名称早于 Discord 支持;两种类型的 broker 语义相同)。
|
||||
操作环境变量和 Convex broker 端点契约位于 [测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该小节名称早于 Discord 支持;两种类型的 broker 语义相同)。
|
||||
|
||||
## 仓库支持的 seeds
|
||||
## 仓库支持的种子
|
||||
|
||||
seed 资产位于 `qa/`:
|
||||
种子资产位于 `qa/`:
|
||||
|
||||
- `qa/scenarios/index.md`
|
||||
- `qa/scenarios/<theme>/*.md`
|
||||
|
||||
这些内容有意纳入 git,以便 QA 计划对人类和智能体都可见。
|
||||
这些内容有意放在 git 中,因此 QA 计划对人工和智能体都可见。
|
||||
|
||||
`qa-lab` 应保持为通用 Markdown runner。每个场景 Markdown 文件都是一次测试运行的事实来源,并应定义:
|
||||
`qa-lab` 应保持为通用 Markdown 运行器。每个场景 Markdown 文件都是一次测试运行的事实来源,并应定义:
|
||||
|
||||
- 场景元数据
|
||||
- 可选的类别、能力、lane 和风险元数据
|
||||
- 可选的类别、能力、测试通道和风险元数据
|
||||
- 文档和代码引用
|
||||
- 可选的插件要求
|
||||
- 可选的 Gateway 网关配置补丁
|
||||
- 可执行的 `qa-flow`
|
||||
|
||||
支撑 `qa-flow` 的可复用运行时表面允许保持通用且跨领域。例如,Markdown 场景可以组合传输侧 helper 和浏览器侧 helper,后者通过 Gateway 网关 `browser.request` 接缝驱动嵌入式 Control UI,而无需添加特殊情况 runner。
|
||||
支撑 `qa-flow` 的可复用运行时表面可以保持通用且跨领域。例如,Markdown 场景可以组合传输侧 helper 和浏览器侧 helper,后者通过 Gateway 网关 `browser.request` 接缝驱动嵌入式 Control UI,而无需添加特殊场景运行器。
|
||||
|
||||
场景文件应按产品能力分组,而不是按源代码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 做实现可追溯性。
|
||||
场景文件应按产品能力分组,而不是按源码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 提供实现可追溯性。
|
||||
|
||||
基线列表应保持足够宽,以覆盖:
|
||||
|
||||
- 私信和频道聊天
|
||||
- thread 行为
|
||||
- 消息动作生命周期
|
||||
- 私信和渠道聊天
|
||||
- 线程行为
|
||||
- 消息操作生命周期
|
||||
- cron 回调
|
||||
- 记忆召回
|
||||
- 模型切换
|
||||
- subagent handoff
|
||||
- 子智能体交接
|
||||
- 仓库读取和文档读取
|
||||
- 一个小型构建任务,例如 Lobster Invaders
|
||||
|
||||
## 提供商 mock lanes
|
||||
## Provider mock 测试通道
|
||||
|
||||
`qa suite` 有两个本地提供商 mock lanes:
|
||||
`qa suite` 有两个本地 provider mock 测试通道:
|
||||
|
||||
- `mock-openai` 是感知场景的 OpenClaw mock。它仍是仓库支持 QA 和 parity gate 的默认确定性 mock lane。
|
||||
- `aimock` 会启动一个由 AIMock 支撑的提供商服务器,用于实验性协议、fixture、record/replay 和 chaos 覆盖。它是增量能力,不会取代 `mock-openai` 场景调度器。
|
||||
- `mock-openai` 是具备场景感知能力的 OpenClaw mock。它仍然是仓库支持的 QA 和 parity gate 的默认确定性 mock 测试通道。
|
||||
- `aimock` 会启动一个由 AIMock 支持的 provider 服务器,用于实验性协议、fixture、record/replay 和混沌覆盖。它是增量能力,不会取代 `mock-openai` 场景分发器。
|
||||
|
||||
provider-lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile staging 需求,以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商 registry 路由,而不是按提供商名称分支。
|
||||
Provider 测试通道实现位于 `extensions/qa-lab/src/providers/` 下。每个 provider 都拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求,以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过 provider 注册表路由,而不是按 provider 名称分支。
|
||||
|
||||
## 传输适配器
|
||||
|
||||
`qa-lab` 为 Markdown QA 场景拥有一个通用传输接缝。`qa-channel` 是该接缝上的第一个适配器,但设计目标更广:未来真实或合成的渠道应接入同一个 suite runner,而不是添加特定于传输的 QA runner。
|
||||
`qa-lab` 为 Markdown QA 场景拥有一个通用传输接缝。`qa-channel` 是该接缝上的第一个适配器,但设计目标更广:未来真实或合成的渠道都应接入同一个 suite 运行器,而不是添加特定传输的 QA 运行器。
|
||||
|
||||
在架构层面,拆分如下:
|
||||
|
||||
- `qa-lab` 拥有通用场景执行、worker 并发、产物写入和报告。
|
||||
- 传输适配器拥有 Gateway 网关配置、就绪性、入站和出站观察、传输动作,以及标准化传输状态。
|
||||
- 传输适配器拥有 Gateway 网关配置、就绪性、入站和出站观测、传输操作以及规范化传输状态。
|
||||
- `qa/scenarios/` 下的 Markdown 场景文件定义测试运行;`qa-lab` 提供执行它们的可复用运行时表面。
|
||||
|
||||
### 添加渠道
|
||||
@ -340,49 +340,49 @@ provider-lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供
|
||||
1. 该渠道的传输适配器。
|
||||
2. 覆盖该渠道契约的场景包。
|
||||
|
||||
当共享 `qa-lab` host 可以拥有该流程时,不要添加新的顶层 QA 命令根。
|
||||
当共享的 `qa-lab` 宿主可以拥有流程时,不要添加新的顶层 QA 命令根。
|
||||
|
||||
`qa-lab` 拥有共享 host 机制:
|
||||
`qa-lab` 拥有共享宿主机制:
|
||||
|
||||
- `openclaw qa` 命令根
|
||||
- suite 启动和 teardown
|
||||
- suite 启动和拆卸
|
||||
- worker 并发
|
||||
- 产物写入
|
||||
- 报告生成
|
||||
- 场景执行
|
||||
- 旧版 `qa-channel` 场景的兼容别名
|
||||
|
||||
Runner 插件拥有传输契约:
|
||||
运行器插件拥有传输契约:
|
||||
|
||||
- `openclaw qa <runner>` 如何挂载到共享 `qa` 根下
|
||||
- 如何将 `openclaw qa <runner>` 挂载到共享 `qa` 根之下
|
||||
- 如何为该传输配置 Gateway 网关
|
||||
- 如何检查就绪性
|
||||
- 如何注入入站事件
|
||||
- 如何观察出站消息
|
||||
- 如何暴露 transcript 和标准化传输状态
|
||||
- 如何执行传输支持的动作
|
||||
- 如何观测出站消息
|
||||
- 如何暴露转录和规范化传输状态
|
||||
- 如何执行传输支持的操作
|
||||
- 如何处理特定于传输的重置或清理
|
||||
|
||||
新渠道的最低采纳标准:
|
||||
新渠道的最低采用门槛:
|
||||
|
||||
1. 保持 `qa-lab` 作为共享 `qa` 根的 owner。
|
||||
2. 在共享的 `qa-lab` host seam 上实现传输 runner。
|
||||
3. 将特定于传输协议的机制保留在 runner 插件或渠道 harness 中。
|
||||
4. 将 runner 挂载为 `openclaw qa <runner>`,而不是注册一个竞争性的根命令。Runner 插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;延迟 CLI 和 runner 执行应放在单独的入口点之后。
|
||||
5. 在主题化的 `qa/scenarios/` 目录下编写或改写 Markdown 场景。
|
||||
6. 对新场景使用通用场景 helper。
|
||||
7. 除非仓库正在进行有意的迁移,否则保持现有兼容性别名可用。
|
||||
1. 保持 `qa-lab` 作为共享 `qa` 根命令的所有者。
|
||||
2. 在共享的 `qa-lab` 主机接缝上实现传输运行器。
|
||||
3. 将传输特定机制保留在运行器插件或渠道 harness 内。
|
||||
4. 将运行器挂载为 `openclaw qa <runner>`,而不是注册一个竞争性的根命令。运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;懒加载 CLI 和运行器执行应保留在单独的入口点之后。
|
||||
5. 在主题化的 `qa/scenarios/` 目录下编写或改编 markdown 场景。
|
||||
6. 为新场景使用通用场景辅助函数。
|
||||
7. 除非仓库正在进行有意迁移,否则保持现有兼容别名可用。
|
||||
|
||||
决策规则很严格:
|
||||
|
||||
- 如果行为可以在 `qa-lab` 中一次性表达,就放在 `qa-lab` 中。
|
||||
- 如果行为依赖某一个渠道传输协议,就保留在对应的 runner 插件或插件 harness 中。
|
||||
- 如果某个场景需要一种不止一个渠道能使用的新能力,请添加通用 helper,而不是在 `suite.ts` 中添加特定于渠道的分支。
|
||||
- 如果某个行为只对一种传输协议有意义,就保持该场景为特定传输协议场景,并在场景契约中明确说明。
|
||||
- 如果行为可以在 `qa-lab` 中表达一次,就把它放在 `qa-lab` 中。
|
||||
- 如果行为依赖于某一个渠道传输,就把它保留在该运行器插件或插件 harness 中。
|
||||
- 如果某个场景需要一项可被多个渠道使用的新能力,请添加通用辅助函数,而不是在 `suite.ts` 中添加渠道特定分支。
|
||||
- 如果某个行为只对一种传输有意义,请保持场景为传输特定,并在场景契约中明确说明。
|
||||
|
||||
### 场景 helper 名称
|
||||
### 场景辅助函数名称
|
||||
|
||||
新场景首选的通用 helper:
|
||||
新场景首选的通用辅助函数:
|
||||
|
||||
- `waitForTransportReady`
|
||||
- `waitForChannelReady`
|
||||
@ -397,22 +397,21 @@ Runner 插件拥有传输契约:
|
||||
- `formatTransportTranscript`
|
||||
- `resetTransport`
|
||||
|
||||
兼容性别名仍可用于现有场景 — `waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus` — 但新场景编写应使用通用名称。这些别名的存在是为了避免一次性迁移,而不是未来的模式。
|
||||
兼容别名仍可用于现有场景 — `waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus` — 但新场景编写应使用通用名称。这些别名的存在是为了避免一次性迁移,而不是作为未来的模型。
|
||||
|
||||
## 报告
|
||||
|
||||
`qa-lab` 会根据观测到的总线时间线导出 Markdown 协议报告。
|
||||
`qa-lab` 会从观察到的总线时间线导出 Markdown 协议报告。
|
||||
报告应回答:
|
||||
|
||||
- 哪些内容有效
|
||||
- 哪些内容失败
|
||||
- 哪些内容仍被阻塞
|
||||
- 哪些有效
|
||||
- 哪些失败
|
||||
- 哪些仍然受阻
|
||||
- 哪些后续场景值得添加
|
||||
|
||||
要查看可用场景清单 — 在评估后续工作规模或接入新传输协议时很有用 — 运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。
|
||||
要查看可用场景清单 — 在评估后续工作规模或接入新传输时很有用 — 运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。
|
||||
|
||||
对于角色和风格检查,请跨多个实时模型 ref 运行同一个场景,
|
||||
并编写一份经过评审的 Markdown 报告:
|
||||
对于角色和风格检查,请在多个实时模型引用上运行同一场景,并编写经过评判的 Markdown 报告:
|
||||
|
||||
```bash
|
||||
pnpm openclaw qa character-eval \
|
||||
@ -431,39 +430,16 @@ pnpm openclaw qa character-eval \
|
||||
--judge-concurrency 16
|
||||
```
|
||||
|
||||
该命令运行本地 QA 网关子进程,而不是 Docker。角色评估
|
||||
场景应通过 `SOUL.md` 设置 persona,然后运行普通用户轮次,
|
||||
例如聊天、工作区帮助和小型文件任务。不应告知候选模型它正在被评估。该命令会保留每份完整
|
||||
转录,记录基本运行统计信息,然后让 judge 模型以快速模式并在支持时使用
|
||||
`xhigh` reasoning,按自然度、风格感和幽默感对运行结果排名。
|
||||
比较提供商时使用 `--blind-judge-models`:judge prompt 仍会获得
|
||||
每份转录和运行状态,但候选 ref 会替换为中性
|
||||
标签,例如 `candidate-01`;报告会在解析后将排名映射回真实 ref。
|
||||
候选运行默认使用 `high` thinking;GPT-5.5 使用 `medium`,
|
||||
支持 `xhigh` 的旧版 OpenAI 评估 ref 使用 `xhigh`。使用
|
||||
`--model provider/model,thinking=<level>` 内联覆盖特定候选项。`--thinking <level>` 仍会设置
|
||||
全局 fallback,旧的 `--model-thinking <provider/model=level>` 形式
|
||||
会保留用于兼容。
|
||||
OpenAI 候选 ref 默认使用快速模式,以便在
|
||||
提供商支持时使用优先处理。当单个候选项或 judge 需要覆盖时,内联添加 `,fast`、`,no-fast` 或 `,fast=false`。只有当你想
|
||||
强制每个候选模型都启用快速模式时,才传入 `--fast`。候选项和 judge 的持续时间会
|
||||
记录在报告中用于基准分析,但 judge prompt 会明确要求
|
||||
不要按速度排名。
|
||||
候选模型和 judge 模型运行都默认并发 16。当提供商限制或本地网关
|
||||
压力使运行噪声过大时,降低
|
||||
`--concurrency` 或 `--judge-concurrency`。
|
||||
未传入候选 `--model` 时,角色评估默认使用
|
||||
`openai/gpt-5.5`、`openai/gpt-5.2`、`openai/gpt-5`、`anthropic/claude-opus-4-6`、
|
||||
`anthropic/claude-sonnet-4-6`、`zai/glm-5.1`、
|
||||
`moonshot/kimi-k2.5` 和
|
||||
`google/gemini-3.1-pro-preview`。
|
||||
未传入 `--judge-model` 时,judge 默认使用
|
||||
`openai/gpt-5.5,thinking=xhigh,fast` 和
|
||||
`anthropic/claude-opus-4-6,thinking=high`。
|
||||
该命令会运行本地 QA gateway 子进程,而不是 Docker。角色评估场景应通过 `SOUL.md` 设置 persona,然后运行普通用户轮次,例如聊天、工作区帮助和小型文件任务。不应告知候选模型它正在被评估。该命令会保留每份完整转录,记录基本运行统计信息,然后以快速模式请求评判模型,并在支持的情况下使用 `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`、`,no-fast` 或 `,fast=false`。仅当你想强制所有候选模型开启快速模式时,才传入 `--fast`。候选和评判持续时间会记录在报告中用于基准分析,但评判提示会明确说明不要按速度排名。
|
||||
候选和评判模型运行默认并发数均为 16。当提供商限制或本地 gateway 压力导致运行噪声过大时,降低 `--concurrency` 或 `--judge-concurrency`。
|
||||
未传入候选 `--model` 时,角色评估默认使用 `openai/gpt-5.5`、`openai/gpt-5.2`、`openai/gpt-5`、`anthropic/claude-opus-4-6`、`anthropic/claude-sonnet-4-6`、`zai/glm-5.1`、`moonshot/kimi-k2.5` 和 `google/gemini-3.1-pro-preview`。
|
||||
未传入 `--judge-model` 时,评判默认使用 `openai/gpt-5.5,thinking=xhigh,fast` 和 `anthropic/claude-opus-4-6,thinking=high`。
|
||||
|
||||
## 相关文档
|
||||
|
||||
- [Matrix QA](/zh-CN/concepts/qa-matrix)
|
||||
- [QA Channel](/zh-CN/channels/qa-channel)
|
||||
- [QA channel](/zh-CN/channels/qa-channel)
|
||||
- [测试](/zh-CN/help/testing)
|
||||
- [Dashboard](/zh-CN/web/dashboard)
|
||||
- [仪表板](/zh-CN/web/dashboard)
|
||||
|
||||
Loading…
Reference in New Issue
Block a user