diff --git a/docs/zh-CN/concepts/mantis.md b/docs/zh-CN/concepts/mantis.md new file mode 100644 index 000000000..3109480d4 --- /dev/null +++ b/docs/zh-CN/concepts/mantis.md @@ -0,0 +1,350 @@ +--- +read_when: + - 为 OpenClaw 缺陷构建或运行实时视觉 QA + - 为拉取请求添加前后验证 + - 添加 Discord、Slack、WhatsApp 或其他实时传输场景 + - 调试需要截图、浏览器自动化或 VNC 访问的 QA 运行 +summary: Mantis 是用于在实时传输上复现 OpenClaw 缺陷、捕获修复前后证据并将工件附加到拉取请求的可视化端到端验证系统。 +title: Mantis +x-i18n: + generated_at: "2026-05-03T14:30:20Z" + model: gpt-5.5 + provider: openai + source_hash: d4ce96f271703e06036a893c01a88562d9c336f7781a0b91a15dc3d5bb41a2e7 + source_path: concepts/mantis.md + workflow: 16 +--- + +Mantis 是 OpenClaw 端到端验证系统,面向需要真实运行时、真实传输协议和可见证据的错误。它会针对已知的坏 ref 运行一个场景,捕获证据,再针对候选 ref 运行相同场景,并将对比结果发布为 artifact,维护者可以从 PR 或本地命令中检查这些 artifact。 + +Mantis 从 Discord 开始,因为 Discord 给了我们一条高价值的第一条验证线路:真实机器人凭证、真实 guild 渠道、reaction、thread、原生命令,以及一个浏览器 UI,让人类可以直观看到传输协议显示了什么。 + +## 目标 + +- 使用用户看到的相同传输形态,复现 GitHub issue 或 PR 中的错误。 +- 在应用修复前,基于 baseline ref 捕获一个 **before** artifact。 +- 在应用修复后,基于候选 ref 捕获一个 **after** artifact。 +- 尽可能使用确定性 oracle,例如 Discord REST reaction 读取或渠道 transcript 检查。 +- 当错误有可见 UI 表面时捕获截图。 +- 从智能体控制的 CLI 在本地运行,也能从 GitHub 远程运行。 +- 保留足够的机器状态,以便在登录、浏览器自动化或提供商凭证卡住时进行 VNC 救援。 +- 当运行被阻塞、需要手动 VNC 帮助或完成时,向操作员 Discord 渠道发布简短状态。 + +## 非目标 + +- Mantis 不是单元测试的替代品。修复被理解后,一次 Mantis 运行通常应该转化为更小的回归测试。 +- Mantis 不是常规的快速 CI gate。它更慢,使用实时凭证,并且仅用于实时环境确实重要的错误。 +- Mantis 正常运行时不应需要人工参与。手动 VNC 是救援路径,不是理想路径。 +- Mantis 不会在 artifact、日志、截图、Markdown 报告或 PR 评论中存储原始密钥。 + +## 所有权 + +Mantis 位于 OpenClaw QA 栈中。 + +- OpenClaw 拥有场景运行时、传输适配器、证据 schema,以及 `pnpm openclaw qa mantis` 下的本地 CLI。 +- QA Lab 拥有实时传输 harness 组件、浏览器捕获 helper 和 artifact 写入器。 +- Crabbox 在需要远程 VM 时拥有预热的 Linux 机器。 +- GitHub Actions 拥有远程工作流入口点和 artifact 保留策略。 +- ClawSweeper 拥有 GitHub 评论路由:解析维护者命令、分发工作流,并发布最终 PR 评论。 +- 当场景需要智能体式设置、调试或卡住状态报告时,OpenClaw 智能体通过 Codex 驱动 Mantis。 + +这个边界让传输知识留在 OpenClaw,机器调度留在 Crabbox,维护者工作流粘合层留在 ClawSweeper。 + +## 命令形态 + +第一个本地命令会验证 Discord 机器人、guild、渠道、消息发送、reaction 发送和 artifact 路径: + +```bash +pnpm openclaw qa mantis discord-smoke \ + --output-dir .artifacts/qa-e2e/mantis/discord-smoke +``` + +后续的 before 和 after runner 应接受这种形态: + +```bash +pnpm openclaw qa mantis run \ + --transport discord \ + --scenario discord-status-reactions-tool-only \ + --baseline origin/main \ + --candidate HEAD \ + --output-dir .artifacts/qa-e2e/mantis/local-discord-status-reactions +``` + +GitHub smoke 工作流是 `Mantis Discord Smoke`。before 和 after GitHub 工作流应接受等价输入: + +- `transport`:第一个版本使用 `discord`。 +- `scenario`:一个或多个场景 ID。 +- `baseline_ref`:默认 `origin/main`,或关联 issue 中报告的坏 tag。 +- `candidate_ref`:PR head SHA。 +- `machine_provider`:默认 `aws`,后续可 fallback 到 `hetzner`。 +- `post_to_pr`:ClawSweeper 是否应评论结果。 + +ClawSweeper 命令示例: + +```text +@clawsweeper mantis discord discord-status-reactions-tool-only +@clawsweeper verify e2e discord +``` + +第一个命令显式且聚焦场景。第二个后续可以根据 label、变更文件和 ClawSweeper review 发现,将 PR 或 issue 映射到推荐的 Mantis 场景。 + +## 运行生命周期 + +1. 获取凭证。 +2. 分配或复用 VM。 +3. 为 baseline ref 准备干净 checkout。 +4. 安装依赖,并只构建场景需要的内容。 +5. 使用隔离状态目录启动子 OpenClaw Gateway 网关。 +6. 配置实时传输协议、提供商、模型和浏览器 profile。 +7. 运行场景并捕获 baseline 证据。 +8. 停止 Gateway 网关并保留日志。 +9. 在同一 VM 中准备候选 ref。 +10. 运行相同场景并捕获候选证据。 +11. 对比 oracle 结果和视觉证据。 +12. 写入 Markdown、JSON、日志、截图和可选 trace artifact。 +13. 上传 GitHub Actions artifact。 +14. 发布简短的 PR 或 Discord 状态消息。 + +场景应能以两种不同方式失败: + +- **错误已复现**:baseline 以预期方式失败。 +- **Harness 失败**:环境设置、凭证、Discord API、浏览器或提供商在错误 oracle 产生意义之前失败。 + +最终报告必须区分这些情况,避免维护者把不稳定环境和产品行为混淆。 + +## Discord MVP + +第一个场景应面向 guild 渠道中的 Discord 状态 reaction,其中源回复投递模式是 `message_tool_only`。 + +为什么它是很好的 Mantis 种子: + +- 它在 Discord 中表现为触发消息上的 reaction,可见。 +- 它通过 Discord 消息 reaction 状态提供强 REST oracle。 +- 它会覆盖真实 OpenClaw Gateway 网关、Discord 机器人凭证、消息分发、源回复投递模式、状态 reaction 状态和模型 turn 生命周期。 +- 它足够窄,可以让第一版实现保持真实可靠。 + +预期场景形态: + +```yaml +id: discord-status-reactions-tool-only +transport: discord +baseline: + expect: + reproduced: true +candidate: + expect: + fixed: true +config: + messages: + ackReaction: "👀" + ackReactionScope: "group-mentions" + groupChat: + visibleReplies: "message_tool" + statusReactions: + enabled: true + timing: + debounceMs: 0 +discord: + requireMention: true + notifyChannel: operator-notify +evidence: + rest: + messageReactions: true + browser: + screenshotMessageRow: true +``` + +Baseline 证据应显示排队的 acknowledgement reaction,但在 tool-only 模式下没有生命周期转换。Candidate 证据应显示当 `messages.statusReactions.enabled` 被显式设为 true 时,生命周期状态 reaction 正在运行。 + +## 现有 QA 组件 + +Mantis 应构建在现有私有 QA 栈之上,而不是从零开始: + +- `pnpm openclaw qa discord` 已经运行一条带 driver 和 SUT 机器人的实时 Discord 线路。 +- 实时传输 runner 已经在 `.artifacts/qa-e2e/` 下写入报告和 observed-message artifact。 +- Convex credential lease 已经为共享实时传输凭证提供独占访问。 +- 浏览器控制服务已经支持截图、snapshot、headless 托管 profile 和远程 CDP profile。 +- QA Lab 已经有用于传输形态测试的 debugger UI 和 bus。 + +第一版 Mantis 实现可以是这些组件之上的一个轻量 before/after runner,再加一层视觉证据。 + +## 证据模型 + +每次运行都会写入稳定的 artifact 目录: + +```text +.artifacts/qa-e2e/mantis// + mantis-report.md + mantis-summary.json + baseline/ + summary.json + discord-message.json + screenshot-message-row.png + gateway-debug/ + candidate/ + summary.json + discord-message.json + screenshot-message-row.png + gateway-debug/ + comparison.json + run.log +``` + +`mantis-summary.json` 应是机器可读的事实来源。Markdown 报告用于 PR 评论和人工 review。 + +summary 必须包含: + +- 被测试的 ref 和 SHA +- 传输协议和场景 ID +- 机器提供商和机器 ID 或 lease ID +- 不含密钥值的凭证来源 +- baseline 结果 +- candidate 结果 +- 错误是否在 baseline 上复现 +- candidate 是否修复了它 +- artifact 路径 +- 已脱敏的设置或清理问题 + +截图是证据,不是密钥。它们仍需要遵守脱敏纪律:私有渠道名称、用户名或消息内容可能会出现。对于公开 PR,在脱敏方案更成熟前,优先使用 GitHub Actions artifact 链接,而不是内联图片。 + +## 浏览器和 VNC + +浏览器线路有两种模式: + +- **Headless 自动化**:CI 默认模式。Chrome 启用 CDP 运行,Playwright 或 OpenClaw 浏览器控制会捕获截图。 +- **VNC 救援**:当登录、MFA、Discord 反自动化或视觉调试需要人工介入时,在同一 VM 上启用。 + +Discord observer 浏览器 profile 应足够持久,避免每次运行都登录,但要与个人浏览器状态隔离。profile 属于 Mantis 机器池,不属于开发者笔记本电脑。 + +当 Mantis 卡住时,它会发布一条 Discord 状态消息,包含: + +- run id +- scenario id +- machine provider +- artifact directory +- 可用时的 VNC 或 noVNC 连接说明 +- 简短阻塞原因文本 + +第一版私有部署可以把这些消息发布到现有操作员渠道,之后再迁移到专用 Mantis 渠道。 + +## 机器 + +第一版远程实现中,Mantis 应优先通过 Crabbox 使用 AWS。Crabbox 为我们提供预热机器、lease 跟踪、hydration、日志、结果和清理。如果 AWS 容量太慢或不可用,则在同一机器接口后添加 Hetzner 提供商。 + +最低 VM 要求: + +- 安装了支持桌面能力的 Chrome 或 Chromium 的 Linux +- 用于浏览器自动化的 CDP 访问 +- 用于救援的 VNC 或 noVNC +- Node 22 和 pnpm +- OpenClaw checkout 和依赖缓存 +- 使用 Playwright 时的 Playwright Chromium 浏览器缓存 +- 足够的 CPU 和内存,用于一个 OpenClaw Gateway 网关、一个浏览器和一次模型运行 +- 到 Discord、GitHub、模型提供商和凭证 broker 的出站访问 + +VM 不应在预期凭证或浏览器 profile 存储之外保留长期有效的原始密钥。 + +## 密钥 + +远程运行的密钥位于 GitHub 组织或仓库 secrets 中,本地运行的密钥位于本地操作员控制的 secret 文件中。 + +推荐 secret 名称: + +- `OPENCLAW_QA_DISCORD_MANTIS_BOT_TOKEN` +- `OPENCLAW_QA_DISCORD_DRIVER_BOT_TOKEN` +- `OPENCLAW_QA_DISCORD_SUT_BOT_TOKEN` +- `OPENCLAW_QA_DISCORD_GUILD_ID` +- `OPENCLAW_QA_DISCORD_CHANNEL_ID` +- `OPENCLAW_QA_DISCORD_NOTIFY_CHANNEL_ID` +- `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1` 用于公开 GitHub artifact 上传 +- `OPENCLAW_QA_CONVEX_SITE_URL` +- `OPENCLAW_QA_CONVEX_SECRET_CI` + +长期来看,Convex credential pool 应保持为实时传输凭证的常规来源。GitHub secrets 用于 bootstrap broker 和 fallback 线路。 + +Mantis runner 绝不能打印: + +- Discord bot token +- 提供商 API key +- 浏览器 cookie +- auth profile 内容 +- VNC 密码 +- 原始凭证 payload + +公开 artifact 上传也应脱敏 Discord 目标元数据,例如机器人、guild、渠道和消息 ID。GitHub smoke 工作流因此启用 `OPENCLAW_QA_REDACT_PUBLIC_METADATA=1`。 + +如果 token 被意外粘贴到 issue、PR、聊天或日志中,在新 secret 存储后轮换它。 + +## GitHub Artifact 和 PR 评论 + +第一版 GitHub 实现应将截图上传为 Actions artifact,并从 PR 评论中链接它们。待脱敏、保留策略和公开/私有仓库行为确定后,再支持内联图片。 + +PR 评论应简短: + +```md +Mantis Discord verification: pass + +- Scenario: `discord-status-reactions-tool-only` +- Baseline: reproduced on `` +- Candidate: fixed on `` +- Evidence: +- Screenshots: baseline and candidate message-row captures in the artifact +``` + +当运行失败是因为 harness 失败时,评论必须说明这一点,而不是暗示 candidate 失败。 + +## 私有部署说明 + +私有部署中可能已经有一个 Mantis Discord 应用。如果该应用具备正确的机器人权限并且可以安全轮换,请复用它,而不是创建另一个应用。 + +通过机密或部署配置设置初始操作员通知渠道。它可以先指向现有的维护者或运维渠道,然后在专用 Mantis 渠道存在后再迁移过去。 + +不要在本文档中放入 guild ID、渠道 ID、bot token、浏览器 cookie 或 VNC 密码。将它们存储在 GitHub 机密、凭证代理或操作员的本地机密存储中。 + +## 添加场景 + +Mantis 场景应声明: + +- id 和标题 +- 传输协议 +- 必需凭证 +- 基线 ref 策略 +- 候选 ref 策略 +- OpenClaw 配置补丁 +- 设置步骤 +- 触发输入 +- 预期基线判据 +- 预期候选判据 +- 视觉捕获目标 +- 超时预算 +- 清理步骤 + +场景应优先使用小型、类型化的判据: + +- 用于表情回应 bug 的 Discord 表情回应状态 +- 用于消息串接 bug 的 Discord 消息引用 +- 用于 Slack bug 的 Slack thread ts 和表情回应 API 状态 +- 用于电子邮件 bug 的电子邮件消息 ID 和标头 +- 当 UI 是唯一可靠可观测对象时的浏览器截图 + +视觉检查应作为补充。如果平台 API 能证明该 bug,就使用 API 作为通过/失败判据,并将截图保留用于增强人工信心。 + +## 提供商扩展 + +在 Discord 之后,同一个运行器可以添加: + +- Slack:表情回应、线程、应用提及、模态框、文件上传。 +- 电子邮件:在连接器不足时,使用 `gog` 进行 Gmail 凭证和消息串接。 +- WhatsApp:二维码登录、重新识别、消息送达、媒体、表情回应。 +- Telegram:群组提及门控、命令、可用时的表情回应。 +- Matrix:加密房间、线程或回复关系、重启后恢复。 + +每种传输协议都应有一个低成本烟雾测试场景,以及一个或多个 bug 类别场景。高成本视觉场景应保持为选择性启用。 + +## 待解决问题 + +- 当复用现有 Mantis bot 时,哪个 Discord bot 应作为驱动方,哪个应作为被测系统? +- 第一阶段中,观察者浏览器登录应使用真人 Discord 账号、测试账号,还是仅使用 bot 可读的 REST 证据? +- GitHub 应为 PR 保留 Mantis 工件多久? +- ClawSweeper 何时应自动推荐 Mantis,而不是等待维护者命令? +- 对于公开 PR,截图是否应在上传前做脱敏或裁剪? diff --git a/docs/zh-CN/concepts/qa-e2e-automation.md b/docs/zh-CN/concepts/qa-e2e-automation.md index 54ac37898..a49c46705 100644 --- a/docs/zh-CN/concepts/qa-e2e-automation.md +++ b/docs/zh-CN/concepts/qa-e2e-automation.md @@ -3,66 +3,68 @@ read_when: - 了解 QA 栈如何协同工作 - 扩展 qa-lab、qa-channel 或传输适配器 - 添加由仓库支持的 QA 场景 - - 围绕 Gateway 网关仪表盘构建更接近真实场景的 QA 自动化 -summary: QA 栈概览:qa-lab、qa-channel、仓库驱动的场景、实时传输通道、传输适配器和报告。 + - 围绕 Gateway 网关仪表板构建更高真实度的质量保证自动化 +summary: QA 栈概览:qa-lab、qa-channel、仓库支持的场景、实时传输通道、传输适配器和报告。 title: QA overview x-i18n: - generated_at: "2026-05-02T20:01:39Z" + generated_at: "2026-05-03T14:30:27Z" model: gpt-5.5 provider: openai - source_hash: 1f1cba04d6624bb1e0fc54105bd836f16ada0ba1cc1de9ab7065b90220e23bdf + source_hash: 34f7fe679845af5b9aca182b880ff4e797496ef1c4c56c23993d5e63f3035156 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`、未来的运行器插件:实时传输适配器,用于在子 QA Gateway 网关内驱动真实渠道。 -- `qa/`:由仓库支持的种子资产,用于启动任务和基线 QA 场景。 +- `extensions/qa-channel`:合成消息渠道,包含私信、渠道、话题串、反应、编辑和删除界面。 +- `extensions/qa-lab`:调试器 UI 和 QA 总线,用于观察转录、注入入站消息,以及导出 Markdown 报告。 +- `extensions/qa-matrix`、未来的运行器插件:实时传输适配器,用于在子 QA Gateway 网关中驱动真实渠道。 +- `qa/`:由仓库提供的种子资产,用于启动任务和基线 QA 场景。 +- [Mantis](/zh-CN/concepts/mantis):针对需要真实传输协议、浏览器截图、VM 状态和 PR 证据的错误,进行修复前后的实时验证。 ## 命令界面 -每个 QA 流程都在 `pnpm openclaw qa ` 下运行。许多流程有 `pnpm qa:*` 脚本别名;两种形式都受支持。 +每个 QA 流程都在 `pnpm openclaw qa ` 下运行。许多命令有 `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` 文件,并写入智能体一致性报告。 | -| `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` 提供商服务器。 | -| `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 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 提供商服务器。 | +| `qa mock-openai` | 仅启动具备场景感知能力的 `mock-openai` 提供商服务器。 | +| `qa credentials doctor` / `add` / `list` / `remove` | 管理共享的 Convex 凭证池。 | +| `qa matrix` | 针对一次性 Tuwunel 主服务器的实时传输通道。参见 [Matrix QA](/zh-CN/concepts/qa-matrix)。 | +| `qa telegram` | 针对真实私有 Telegram 群组的实时传输通道。 | +| `qa discord` | 针对真实私有 Discord 服务器渠道的实时传输通道。 | +| `qa mantis` | 规划中的实时传输错误修复前后验证运行器。参见 [Mantis](/zh-CN/concepts/mantis)。 | ## 操作员流程 -当前 QA 操作员流程是一个双窗格 QA 站点: +当前 QA 操作员流程是一个双栏 QA 站点: -- 左侧:包含智能体的 Gateway 网关仪表板(Control UI)。 +- 左侧:包含智能体的 Gateway 网关仪表板(控制 UI)。 - 右侧:QA Lab,显示类似 Slack 的转录和场景计划。 -运行方式: +使用以下命令运行: ```bash pnpm qa:lab:up ``` -这会构建 QA 站点,启动 Docker 支持的 Gateway 网关通道,并公开 QA Lab 页面,操作员或自动化循环可在该页面给智能体分配 QA 任务、观察真实渠道行为,并记录哪些有效、失败或仍被阻塞。 +这会构建 QA 站点,启动 Docker 支持的 Gateway 网关通道,并公开 QA Lab 页面;操作员或自动化循环可以在该页面向智能体下发 QA 任务、观察真实渠道行为,并记录哪些可用、哪些失败、哪些仍被阻塞。 -为了更快迭代 QA Lab UI,而不必每次都重新构建 Docker 镜像,请使用 bind-mounted QA Lab 包启动栈: +如果想在不每次重建 Docker 镜像的情况下更快迭代 QA Lab UI,请使用绑定挂载的 QA Lab 包启动栈: ```bash pnpm openclaw qa docker-build-image @@ -71,88 +73,88 @@ 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` 会在变更时重建该包,当 QA Lab 资产哈希变化时,浏览器会自动重新加载。 +`qa:lab:up:fast` 让 Docker 服务使用预构建镜像,并将 `extensions/qa-lab/web/dist` 绑定挂载到 `qa-lab` 容器中。`qa:lab:watch` 会在变更时重建该包,并且当 QA Lab 资产哈希变化时,浏览器会自动重新加载。 -若要运行本地 OpenTelemetry trace smoke,请执行: +如需本地 OpenTelemetry 跟踪冒烟测试,请运行: ```bash pnpm qa:otel:smoke ``` -该脚本会启动本地 OTLP/HTTP trace 接收器,在启用 `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 工件旁写入 `otel-smoke-summary.json`。 +该脚本会启动本地 OTLP/HTTP 跟踪接收器,在启用 `diagnostics-otel` 插件的情况下运行 `otel-trace-smoke` QA 场景,然后解码导出的 protobuf span,并断言发布关键结构:必须存在 `openclaw.run`、`openclaw.harness.run`、`openclaw.model.call`、`openclaw.context.assembled` 和 `openclaw.message.delivery`;成功轮次中的模型调用不得导出 `StreamAbandoned`;原始诊断 ID 和 `openclaw.content.*` 属性必须保留在跟踪之外。它会将 `otel-smoke-summary.json` 写在 QA 套件工件旁边。 -可观测性 QA 仅保留在源码 checkout 中。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。更改诊断插桩时,请从已构建的源码 checkout 运行 `pnpm qa:otel:smoke`。 +可观测性 QA 仅保留在源码检出中。npm tarball 会有意省略 QA Lab,因此包 Docker 发布通道不会运行 `qa` 命令。更改诊断插桩时,请在已构建的源码检出中使用 `pnpm qa:otel:smoke`。 -若要运行传输真实的 Matrix smoke 通道,请执行: +如需传输真实的 Matrix 冒烟通道,请运行: ```bash pnpm openclaw qa matrix --profile fast --fail-fast ``` -此通道的完整 CLI 参考、配置文件/场景目录、环境变量和工件布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。简要来说:它会在 Docker 中配置一次性 Tuwunel homeserver,注册临时 driver/SUT/observer 用户,在限定到该传输的子 QA Gateway 网关内运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、observed-events 工件和合并输出日志。 +该通道的完整 CLI 参考、配置文件/场景目录、环境变量和工件布局位于 [Matrix QA](/zh-CN/concepts/qa-matrix)。概览:它会在 Docker 中预置一次性 Tuwunel 主服务器,注册临时驱动/SUT/观察者用户,在限定到该传输协议的子 QA Gateway 网关中运行真实 Matrix 插件(不使用 `qa-channel`),然后在 `.artifacts/qa-e2e/matrix-/` 下写入 Markdown 报告、JSON 摘要、观察到的事件工件,以及合并输出日志。 -对于传输真实的 Telegram 和 Discord smoke 通道: +如需传输真实的 Telegram 和 Discord 冒烟通道: ```bash pnpm openclaw qa telegram pnpm openclaw qa discord ``` -两者都面向一个已有真实渠道,并使用两个机器人(driver + SUT)。所需环境变量、场景列表、输出工件和 Convex 凭据池记录在下面的 [Telegram 和 Discord QA 参考](#telegram-and-discord-qa-reference) 中。 +两者都面向已有真实渠道,并使用两个机器人(驱动 + SUT)。所需环境变量、场景列表、输出工件和 Convex 凭证池记录在下面的 [Telegram 和 Discord QA 参考](#telegram-and-discord-qa-reference)中。 -使用池化实时凭据之前,请运行: +使用池化实时凭证前,请运行: ```bash pnpm openclaw qa credentials doctor ``` -该 Doctor 会检查 Convex broker 环境,验证端点设置,并在维护者密钥存在时验证 admin/list 可达性。它只报告密钥的已设置/缺失状态。 +Doctor 会检查 Convex broker 环境,验证端点设置,并在存在维护者密钥时验证管理员/列表可达性。对于密钥,它只报告已设置/缺失状态。 -## 实时传输覆盖范围 +## 实时传输覆盖 -实时传输通道共享一个契约,而不是各自发明自己的场景列表形态。`qa-channel` 是广泛的合成产品行为 suite,不属于实时传输覆盖矩阵。 +实时传输通道共享一份契约,而不是各自发明自己的场景列表形状。`qa-channel` 是覆盖面较广的合成产品行为套件,不属于实时传输覆盖矩阵。 -| 通道 | 金丝雀 | 提及门控 | 机器人到机器人 | 允许列表阻断 | 顶层回复 | 重启恢复 | 话题串跟进 | 话题串隔离 | 回应观察 | 帮助命令 | 原生命令注册 | +| 通道 | 金丝雀 | 提及门控 | 机器人到机器人 | 允许列表阻断 | 顶层回复 | 重启恢复 | 话题串跟进 | 话题串隔离 | 反应观察 | 帮助命令 | 原生命令注册 | | -------- | ------ | -------- | -------------- | ------------ | -------- | -------- | ---------- | ---------- | -------- | -------- | ------------ | | Matrix | x | x | x | x | x | x | x | x | x | | | | Telegram | x | x | x | | | | | | | x | | | Discord | x | x | x | | | | | | | | x | -这会让 `qa-channel` 继续作为广泛的产品行为 suite,同时让 Matrix、Telegram 以及未来的实时传输共享一个显式的传输契约检查清单。 +这让 `qa-channel` 保持为覆盖面较广的产品行为套件,同时让 Matrix、Telegram 和未来的实时传输协议共享一份明确的传输契约检查清单。 -若要运行一个不把 Docker 带入 QA 路径的一次性 Linux VM 通道,请执行: +如果想使用一次性 Linux VM 通道,而不把 Docker 引入 QA 路径,请运行: ```bash pnpm openclaw qa suite --runner multipass --scenario channel-chat-baseline ``` -这会启动一个全新的 Multipass guest,安装依赖,在 guest 内构建 OpenClaw,运行 `qa suite`,然后把常规 QA 报告和摘要复制回主机上的 `.artifacts/qa-e2e/...`。 +这会启动一个全新的 Multipass 客户机,安装依赖,在客户机内构建 OpenClaw,运行 `qa suite`,然后将常规 QA 报告和摘要复制回主机上的 `.artifacts/qa-e2e/...`。 它复用与主机上 `qa suite` 相同的场景选择行为。 -主机和 Multipass suite 运行默认会使用隔离的 Gateway 网关 worker 并行执行多个所选场景。`qa-channel` 默认并发数为 4,并受所选场景数量限制。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 进行串行执行。 -任何场景失败时,该命令会以非零状态退出。如果你想获取工件但不希望失败退出码,请使用 `--allow-failures`。 -实时运行会转发对 guest 可行的受支持 QA 认证输入:基于环境的提供商密钥、QA live 提供商配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,以便 guest 可通过挂载的工作区写回。 +主机和 Multipass 套件运行默认使用隔离的 Gateway 网关 worker 并行执行多个已选场景。`qa-channel` 默认并发度为 4,并受所选场景数量限制。使用 `--concurrency ` 调整 worker 数量,或使用 `--concurrency 1` 串行执行。 +当任何场景失败时,该命令会以非零状态退出。当你想要工件但不想要失败退出码时,请使用 `--allow-failures`。 +实时运行会转发对客户机来说可行的受支持 QA 认证输入:基于环境变量的提供商密钥、QA 实时提供商配置路径,以及存在时的 `CODEX_HOME`。请将 `--output-dir` 保持在仓库根目录下,这样客户机就能通过挂载的工作区写回。 ## Telegram 和 Discord QA 参考 -Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景数量更多,并且需要 Docker 支持的 homeserver 配置。Telegram 和 Discord 更小,每个只有少量场景,没有配置文件系统,并针对已有真实渠道,因此它们的参考放在这里。 +Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景数量更多,并且需要 Docker 支持的主服务器预置。Telegram 和 Discord 更小,每个只有少量场景,没有配置文件系统,并且针对已有真实渠道,因此它们的参考保存在这里。 ### 共享 CLI 标志 两个通道都通过 `extensions/qa-lab/src/live-transports/shared/live-transport-cli.ts` 注册,并接受相同标志: -| 标志 | 默认值 | 说明 | +| 标志 | 默认值 | 描述 | | ------------------------------------- | --------------------------------------------------------- | --------------------------------------------------------------------------------------------------------------------- | | `--scenario ` | — | 仅运行此场景。可重复指定。 | -| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord}-` | 写入报告、摘要、观测到的消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 | +| `--output-dir ` | `/.artifacts/qa-e2e/{telegram,discord}-` | 写入报告/摘要/观测到的消息和输出日志的位置。相对路径会基于 `--repo-root` 解析。 | | `--repo-root ` | `process.cwd()` | 从中立 cwd 调用时的仓库根目录。 | -| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账号 id。 | -| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍可用)。 | -| `--model ` / `--alt-model ` | 提供商默认值 | 主模型/备用模型引用。 | -| `--fast` | 关闭 | 在支持的位置启用提供商快速模式。 | -| `--credential-source ` | `env` | 参见 [Convex 凭证池](#convex-credential-pool)。 | -| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | 当 `--credential-source convex` 时使用的角色。 | +| `--sut-account ` | `sut` | QA Gateway 网关配置中的临时账户 id。 | +| `--provider-mode ` | `live-frontier` | `mock-openai` 或 `live-frontier`(旧版 `live-openai` 仍然可用)。 | +| `--model ` / `--alt-model ` | 提供商默认值 | 主/备用模型引用。 | +| `--fast` | 关闭 | 支持时启用提供商快速模式。 | +| `--credential-source ` | `env` | 请参阅 [Convex 凭证池](#convex-credential-pool)。 | +| `--credential-role ` | CI 中为 `ci`,否则为 `maintainer` | `--credential-source convex` 时使用的角色。 | -任一场景失败时,两者都会以非零状态退出。`--allow-failures` 会写入工件,但不会设置失败退出码。 +任何场景失败时,两者都会以非零状态退出。`--allow-failures` 会写入工件,但不会设置失败退出码。 ### Telegram QA @@ -160,9 +162,9 @@ Matrix 有一个[专用页面](/zh-CN/concepts/qa-matrix),因为它的场景 pnpm openclaw qa telegram ``` -目标是一个真实的私有 Telegram 群组,其中有两个不同的机器人(driver + SUT)。SUT 机器人必须有 Telegram 用户名;当两个机器人都在 `@BotFather` 中启用 **Bot-to-Bot Communication Mode** 时,机器人到机器人的观测效果最佳。 +目标是一个真实的私有 Telegram 群组,使用两个不同的机器人(驱动器 + SUT)。SUT 机器人必须有 Telegram 用户名;当两个机器人都在 `@BotFather` 中启用 **机器人到机器人通信模式** 时,机器人到机器人的观测效果最佳。 -当 `--credential-source env` 时需要的环境变量: +使用 `--credential-source env` 时必需的环境变量: - `OPENCLAW_QA_TELEGRAM_GROUP_ID` — 数字聊天 id(字符串)。 - `OPENCLAW_QA_TELEGRAM_DRIVER_BOT_TOKEN` @@ -170,7 +172,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`): @@ -186,8 +188,8 @@ pnpm openclaw qa telegram 输出工件: - `telegram-qa-report.md` -- `telegram-qa-summary.json` — 包含从金丝雀开始的每条回复 RTT(driver 发送 → 观测到 SUT 回复)。 -- `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被遮盖。 +- `telegram-qa-summary.json` — 包含从金丝雀开始的每条回复 RTT(驱动器发送 → 观测到 SUT 回复)。 +- `telegram-qa-observed-messages.json` — 除非设置 `OPENCLAW_QA_TELEGRAM_CAPTURE_CONTENT=1`,否则正文会被脱敏。 ### Discord QA @@ -195,15 +197,15 @@ pnpm openclaw qa telegram pnpm openclaw qa discord ``` -目标是一个真实的私有 Discord guild 渠道,其中有两个机器人:一个由 harness 控制的 driver 机器人,以及一个由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT 机器人。验证渠道提及处理,以及 SUT 机器人是否已向 Discord 注册原生 `/help` 命令。 +目标是一个真实的私有 Discord 公会渠道,使用两个机器人:一个由 harness 控制的驱动机器人,以及一个由子 OpenClaw Gateway 网关通过内置 Discord 插件启动的 SUT 机器人。验证渠道提及处理,并验证 SUT 机器人已向 Discord 注册原生 `/help` 命令。 -当 `--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 机器人用户 id(否则该 lane 会快速失败)。 +- `OPENCLAW_QA_DISCORD_SUT_APPLICATION_ID` — 必须与 Discord 返回的 SUT 机器人用户 id 匹配(否则该通道会快速失败)。 可选: @@ -219,18 +221,18 @@ 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`,否则正文会被脱敏。 ### Convex 凭证池 -Telegram 和 Discord 两条 lane 都可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间为其发送 Heartbeat,并在关闭时释放它。池类型为 `"telegram"` 和 `"discord"`。 +Telegram 和 Discord 通道都可以从共享 Convex 池租用凭证,而不是读取上面的环境变量。传入 `--credential-source convex`(或设置 `OPENCLAW_QA_CREDENTIAL_SOURCE=convex`);QA Lab 会获取一个独占租约,在运行期间为其发送 Heartbeat,并在关闭时释放它。池类型为 `"telegram"` 和 `"discord"`。 -broker 在 `admin/add` 上验证的载荷形状: +代理在 `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 代理端点契约位于 [测试 → 通过 Convex 共享 Telegram 凭证](/zh-CN/help/testing#shared-telegram-credentials-via-convex-v1)(该章节名称早于 Discord 支持;两种类型的代理语义相同)。 ## 仓库支持的种子 @@ -239,22 +241,22 @@ broker 在 `admin/add` 上验证的载荷形状: - `qa/scenarios/index.md` - `qa/scenarios//*.md` -这些内容有意纳入 git,因此 QA 计划对人类和智能体都可见。 +这些文件有意纳入 git,因此 QA 计划对人类和智能体都可见。 -`qa-lab` 应保持为通用 Markdown 运行器。每个场景 Markdown 文件都是一次测试运行的事实来源,并应定义: +`qa-lab` 应保持为通用 Markdown runner。每个场景 Markdown 文件都是一次测试运行的事实来源,并且应定义: - 场景元数据 -- 可选的类别、能力、lane 和风险元数据 +- 可选的类别、能力、通道和风险元数据 - 文档和代码引用 -- 可选的插件要求 -- 可选的 Gateway 网关配置补丁 +- 可选插件要求 +- 可选 Gateway 网关配置补丁 - 可执行的 `qa-flow` -支撑 `qa-flow` 的可复用运行时表面允许保持通用和横切。例如,Markdown 场景可以组合传输侧 helper 与浏览器侧 helper,后者通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而无需添加特殊情况运行器。 +支撑 `qa-flow` 的可复用运行时表面可以保持通用且跨领域。例如,Markdown 场景可以将传输侧 helper 与浏览器侧 helper 组合起来,通过 Gateway 网关 `browser.request` seam 驱动嵌入式 Control UI,而无需添加特殊情况 runner。 -场景文件应按产品能力分组,而不是按源码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 实现实现可追溯性。 +场景文件应按产品能力分组,而不是按源代码树文件夹分组。文件移动时保持场景 ID 稳定;使用 `docsRefs` 和 `codeRefs` 实现实现可追溯性。 -基线列表应保持足够宽,以覆盖: +基线列表应保持足够广,以覆盖: - 私信和渠道聊天 - 线程行为 @@ -262,27 +264,27 @@ broker 在 `admin/add` 上验证的载荷形状: - cron 回调 - 记忆召回 - 模型切换 -- subagent 移交 +- 子智能体交接 - 仓库读取和文档读取 - 一个小型构建任务,例如 Lobster Invaders -## 提供商 mock lane +## 提供商模拟通道 -`qa suite` 有两条本地提供商 mock lane: +`qa suite` 有两个本地提供商模拟通道: -- `mock-openai` 是感知场景的 OpenClaw mock。它仍然是仓库支持 QA 和 parity gate 的默认确定性 mock lane。 -- `aimock` 会启动一个由 AIMock 支撑的提供商服务器,用于实验性协议、fixture、录制/回放和混沌覆盖。它是增量能力,并不会替代 `mock-openai` 场景分发器。 +- `mock-openai` 是可感知场景的 OpenClaw 模拟。它仍然是仓库支持的 QA 和一致性门禁的默认确定性模拟通道。 +- `aimock` 会启动一个 AIMock 支持的提供商服务器,用于实验性协议、fixture、录制/回放和 chaos 覆盖。它是增量能力,不会替代 `mock-openai` 场景分发器。 -提供商 lane 实现位于 `extensions/qa-lab/src/providers/` 下。每个提供商拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求以及 live/mock 能力标志。共享 suite 和 Gateway 网关代码应通过提供商 registry 路由,而不是按提供商名称分支。 +提供商通道实现在 `extensions/qa-lab/src/providers/` 下。每个提供商都拥有自己的默认值、本地服务器启动、Gateway 网关模型配置、auth-profile 暂存需求以及 live/mock 能力标志。共享套件和 Gateway 网关代码应通过提供商注册表路由,而不是基于提供商名称分支。 ## 传输适配器 -`qa-lab` 为 Markdown QA 场景拥有一个通用传输 seam。`qa-channel` 是该 seam 上的第一个适配器,但设计目标更宽:未来真实或合成渠道应接入同一个 suite 运行器,而不是添加传输特定的 QA 运行器。 +`qa-lab` 为 Markdown QA 场景拥有一个通用传输 seam。`qa-channel` 是该 seam 上的第一个适配器,但设计目标更广:未来的真实或合成渠道应接入同一个套件 runner,而不是添加传输特定的 QA runner。 -在架构层面,拆分如下: +在架构层面,划分如下: - `qa-lab` 拥有通用场景执行、worker 并发、工件写入和报告。 -- 传输适配器拥有 Gateway 网关配置、就绪状态、入站和出站观测、传输操作以及规范化传输状态。 +- 传输适配器拥有 Gateway 网关配置、就绪状态、入站和出站观测、传输操作以及标准化传输状态。 - `qa/scenarios/` 下的 Markdown 场景文件定义测试运行;`qa-lab` 提供执行它们的可复用运行时表面。 ### 添加渠道 @@ -290,51 +292,51 @@ broker 在 `admin/add` 上验证的载荷形状: 向 Markdown QA 系统添加渠道只需要两件事: 1. 该渠道的传输适配器。 -2. 覆盖渠道契约的场景包。 +2. 覆盖该渠道契约的场景包。 当共享 `qa-lab` host 可以拥有流程时,不要添加新的顶层 QA 命令根。 `qa-lab` 拥有共享 host 机制: - `openclaw qa` 命令根 -- suite 启动和 teardown +- 套件启动和拆除 - worker 并发 - 工件写入 - 报告生成 - 场景执行 - 旧版 `qa-channel` 场景的兼容别名 -运行器插件拥有传输契约: +Runner 插件拥有传输契约: -- `openclaw qa ` 如何挂载到共享 `qa` 根下 +- `openclaw qa ` 如何挂载在共享 `qa` 根之下 - 如何为该传输配置 Gateway 网关 - 如何检查就绪状态 - 如何注入入站事件 - 如何观测出站消息 -- 如何暴露 transcript 和规范化传输状态 -- 如何执行由传输支撑的操作 +- 如何暴露转录和标准化传输状态 +- 如何执行传输支持的操作 - 如何处理传输特定的重置或清理 -新渠道的最低采用标准: +新渠道的最低采用门槛: 1. 保持 `qa-lab` 作为共享 `qa` 根的所有者。 -2. 在共享 `qa-lab` host seam 上实现传输运行器。 -3. 将传输特定机制保留在运行器插件或渠道 harness 内。 -4. 将运行器挂载为 `openclaw qa `,而不是注册竞争性的根命令。运行器插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;懒加载 CLI 和运行器执行应放在单独入口点之后。 -5. 在按主题组织的 `qa/scenarios/` 目录下编写或改写 Markdown 场景。 +2. 在共享 `qa-lab` host seam 上实现传输 runner。 +3. 将传输特定机制保留在 runner 插件或渠道 harness 内。 +4. 将 runner 挂载为 `openclaw qa `,而不是注册竞争性的根命令。Runner 插件应在 `openclaw.plugin.json` 中声明 `qaRunners`,并从 `runtime-api.ts` 导出匹配的 `qaRunnerCliRegistrations` 数组。保持 `runtime-api.ts` 轻量;惰性 CLI 和 runner 执行应位于单独的入口点后面。 +5. 在按主题组织的 `qa/scenarios/` 目录下编写或改编 Markdown 场景。 6. 对新场景使用通用场景 helper。 7. 除非仓库正在进行有意迁移,否则保持现有兼容别名可用。 -决策规则很严格: +决策规则是严格的: -- 如果行为可以在 `qa-lab` 中表达一次,就放到 `qa-lab` 中。 -- 如果行为依赖某一个渠道传输,就将其保留在该运行器插件或插件 harness 中。 -- 如果场景需要不止一个渠道可使用的新能力,请添加通用 helper,而不是在 `suite.ts` 中添加渠道特定分支。 -- 如果某个行为只对一个传输有意义,就让该场景保持传输特定,并在场景契约中明确说明。 +- 如果行为可以在 `qa-lab` 中表达一次,就把它放在 `qa-lab` 中。 +- 如果行为依赖于某个渠道传输,将其保留在该 runner 插件或插件 harness 中。 +- 如果某个场景需要一个可供多个渠道使用的新能力,添加通用 helper,而不是在 `suite.ts` 中添加渠道特定分支。 +- 如果某个行为只对一个传输有意义,保持该场景为传输特定,并在场景契约中明确说明。 ### 场景 helper 名称 -新场景首选的通用 helper: +新场景优先使用的通用 helper: - `waitForTransportReady` - `waitForChannelReady` @@ -349,20 +351,22 @@ broker 在 `admin/add` 上验证的载荷形状: - `formatTransportTranscript` - `resetTransport` -兼容别名仍可用于现有场景:`waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus`,但新场景编写应使用通用名称。这些别名的存在是为了避免一次性迁移,而不是作为未来模型。 +现有场景仍可使用兼容别名 — `waitForQaChannelReady`、`waitForOutboundMessage`、`waitForNoOutbound`、`formatConversationTranscript`、`resetBus` — 但编写新场景时应使用通用名称。这些别名用于避免一次性迁移,而不是未来的模型。 ## 报告 -`qa-lab` 会从观测到的 bus timeline 导出 Markdown 协议报告。报告应回答: +`qa-lab` 从观测到的总线时间线导出 Markdown 协议报告。 +报告应回答: -- 哪些有效 -- 哪些失败 +- 哪些成功了 +- 哪些失败了 - 哪些仍被阻塞 - 哪些后续场景值得添加 -要查看可用场景清单,在评估后续工作量或接入新的传输协议时很有用,请运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 +要查看可用场景清单(在评估后续工作规模或接入新传输协议时很有用),运行 `pnpm openclaw qa coverage`(添加 `--json` 可获得机器可读输出)。 -要进行角色和风格检查,请在多个实时模型引用上运行同一个场景,并写入一份经评判的 Markdown 报告: +对于角色和风格检查,可在多个实时模型引用上运行同一场景, +并写出一份经过评审的 Markdown 报告: ```bash pnpm openclaw qa character-eval \ @@ -381,22 +385,40 @@ pnpm openclaw qa character-eval \ --judge-concurrency 16 ``` -该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评估场景应通过 `SOUL.md` 设置人格,然后运行普通用户轮次,例如聊天、工作区帮助和小文件任务。不应告知候选模型它正在接受评估。该命令会保留每份完整转录,记录基本运行统计,然后在支持的情况下以快速模式和 `xhigh` 推理请求评判模型按自然度、感觉和幽默感对运行结果进行排序。比较提供商时使用 `--blind-judge-models`:评判提示仍会获得每份转录和运行 Status,但候选引用会替换为中性标签,例如 `candidate-01`;报告会在解析后将排名映射回真实引用。 -候选运行默认使用 `high` 思考;GPT-5.5 使用 `medium`,支持该级别的较旧 OpenAI 评估引用使用 `xhigh`。可通过 `--model provider/model,thinking=` 内联覆盖特定候选。`--thinking ` 仍会设置全局回退,较旧的 `--model-thinking ` 形式会保留以保持兼容。 -OpenAI 候选引用默认使用快速模式,因此会在提供商支持时使用优先处理。当单个候选或评判模型需要覆盖时,可内联添加 `,fast`、`,no-fast` 或 `,fast=false`。仅当你想为每个候选模型强制启用快速模式时,才传递 `--fast`。报告中会记录候选和评判模型的耗时以用于基准分析,但评判提示会明确要求不要按速度排序。 -候选和评判模型运行都默认使用并发 16。当提供商限制或本地 Gateway 网关压力使运行噪声过大时,请降低 `--concurrency` 或 `--judge-concurrency`。 +该命令运行本地 QA Gateway 网关子进程,而不是 Docker。角色评估 +场景应通过 `SOUL.md` 设置人格,然后运行普通用户轮次, +例如聊天、工作区帮助和小型文件任务。不应告知候选模型 +它正在接受评估。该命令会保留每个完整 +对话记录,记录基本运行统计信息,然后以快速模式请求评审模型, +并在支持的情况下使用 `xhigh` 推理,按自然度、氛围和幽默感对运行结果进行排名。 +比较提供商时使用 `--blind-judge-models`:评审提示仍会获得 +每个对话记录和运行状态,但候选引用会替换为中性的 +标签,例如 `candidate-01`;报告会在解析后将排名映射回真实引用。 +候选运行默认使用 `high` thinking,GPT-5.5 使用 `medium`, +较旧且支持的 OpenAI 评估引用使用 `xhigh`。可用 +`--model provider/model,thinking=` 内联覆盖特定候选。 +`--thinking ` 仍会设置全局回退值,较旧的 `--model-thinking ` 形式 +会保留用于兼容。 +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` 时,评判模型默认使用 +未传入 `--judge-model` 时,评审默认使用 `openai/gpt-5.5,thinking=xhigh,fast` 和 `anthropic/claude-opus-4-6,thinking=high`。 ## 相关文档 - [Matrix QA](/zh-CN/concepts/qa-matrix) -- [QA 渠道](/zh-CN/channels/qa-channel) +- [QA channel](/zh-CN/channels/qa-channel) - [测试](/zh-CN/help/testing) -- [仪表盘](/zh-CN/web/dashboard) +- [仪表板](/zh-CN/web/dashboard)