218 lines
8.1 KiB
Markdown
218 lines
8.1 KiB
Markdown
# Batch J Worker C:ACP 稳定性与 benchmark checklist 草案
|
||
|
||
> 创建时间:2026-05-21
|
||
>
|
||
> 只读审查,不修改代码。
|
||
|
||
## 1. 读取过的关键文件
|
||
|
||
| 文件 | 行数 | 内容 |
|
||
|------|------|------|
|
||
| `design/07-ai/process/7-15-page-ai-acp-agent-runtime-unified-layer-v1.md` | 1029 | ACP 统一层设计:架构、协议、session lifecycle |
|
||
| `design/07-ai/process/7-34-acp-runtime-cleanup-availability-stability-tail-v1.md`| 300+ | 本任务上游:P0/P1/P2 checklist |
|
||
| `design/07-ai/done/7-25-acp-session-runtime-enhancement-plan-v1.md` | 371 | Session 持久化与管理增强规划 |
|
||
| `design/07-ai/done/7-30-acp-session-load-resume-checklist-v1.md` | ~80 | `session/load` 闭环已归档 |
|
||
| `design/07-ai/done/7-31-acp-permission-decision-loop-checklist-v1.md` | ~80 | Permission 决策闭环已归档 |
|
||
| `design/07-ai/done/7-32-acp-tool-location-and-open-action-checklist-v1.md` | ~80 | Tool locations + open action 已归档 |
|
||
| `design/07-ai/done/7-33-acp-session-info-plan-ui-checklist-v1.md` | ~80 | Session info + plan UI 已归档 |
|
||
| `rust/crates/mnote-web/src/acp_runtime.rs` | 500+ | Runtime lifecycle manager |
|
||
| `rust/crates/mnote-web/src/acp_session_manager.rs` | 700+ | Session lifecycle + event dispatch |
|
||
| `rust/crates/mnote-web/src/acp_bridge.rs` | 400+ | ACP ↔ SSE bridge |
|
||
| `rust/crates/mnote-web/src/acp_client.rs` | 746 | JSON-RPC 2.0 client |
|
||
| `rust/crates/mnote-web/src/acp_types.rs` | 800 | ACP 协议类型定义 |
|
||
|
||
## 2. ACP 多会话稳定性 smoke 最小脚本方案
|
||
|
||
### 2.1 测试目标
|
||
|
||
验证 ACP runtime 在处理 3+ 并发 session 时的稳定性:session 创建、prompt 流式、cancel、子进程异常恢复、事件去重。
|
||
|
||
### 2.2 测试设计
|
||
|
||
**方案类型**:Playwright 独立脚本 + Rust 端到端测试
|
||
|
||
**输入**:
|
||
1. 3 个参数化的 ACP run profile(reasonix + hermes × 2 不同 profile)
|
||
2. 每个 session 的 prompt 文本(简单固定 prompt:"请用中文说'你好',不要做其他操作")
|
||
3. 超时配置(每个 run 最长 15s)
|
||
|
||
**操作步骤**:
|
||
|
||
```
|
||
Step 1: 创建 3 个 ACP session(POST /api/hermes/client/sessions)
|
||
├─ session_1: profile=reasonix
|
||
├─ session_2: profile=hermes (profile=mnoteai)
|
||
└─ session_3: profile=hermes (profile=default)
|
||
|
||
Step 2: 在 3 个 session 上启动 run(POST /api/hermes/client/sessions/{id}/runs)
|
||
并发发起,每个 session 间隔 ≤500ms
|
||
|
||
Step 3: 通过 SSE 流式读取事件(GET /api/hermes/client/events/{run_id})
|
||
对每个 run 读取到 run.completed 或超时 15s
|
||
记录:message.delta 事件数量、tool.started、tool.completed
|
||
|
||
Step 4: cancel 验证
|
||
Step 2 后立即 cancel session_2(POST /api/hermes/client/runs/{run_id}/abort)
|
||
验证收到 run.failed / abort.completed
|
||
|
||
Step 5: 验证事件去重
|
||
对 session_1 的 SSE 流,检查 textDelta 的 deduplication 逻辑
|
||
(accumulated text 不重复增长)
|
||
|
||
Step 6: 清理
|
||
删除 3 个 session(DELETE /api/hermes/client/sessions/{session_id})
|
||
```
|
||
|
||
**断言**:
|
||
|
||
| # | 断言 | 优先级 |
|
||
|---|------|--------|
|
||
| 1 | 3 个 session 均创建成功(返回 200 + sessionId) | P0 |
|
||
| 2 | 3 个 run 均收到 `run.completed`(无超时) | P0 |
|
||
| 3 | session_2 的 cancel 在 3s 内生效(收到 `run.failed` 或 `abort.completed`) | P0 |
|
||
| 4 | 所有 SSE 流在 `run.completed` 后 500ms 内自动关闭(无泄漏) | P1 |
|
||
| 5 | session_1 的 message.delta 累计 length 不小于 4(中文"你好") | P1 |
|
||
| 6 | 事件去重正常:textDelta 无重复或突然截断 | P1 |
|
||
| 7 | 3 个 session 互相不干扰(事件不交叉) | P1 |
|
||
| 8 | ACP 子进程数 = session 数(无 zombie) | P2(度量) |
|
||
|
||
**证据文件**:
|
||
- `artifacts/acp-stability/events-session-1.jsonl`
|
||
- `artifacts/acp-stability/events-session-2.jsonl`
|
||
- `artifacts/acp-stability/events-session-3.jsonl`
|
||
- `artifacts/acp-stability/runtime-metrics.json`
|
||
- `artifacts/acp-stability/process-list.txt`(`ps aux | grep -E 'hermes|acp'`)
|
||
|
||
### 2.3 浏览器可见验证点
|
||
|
||
1. **session 列表** — 打开页面 AI drawer → session list 应显示 3 个活跃 session
|
||
2. **run 状态** — 每个 session 的 run 状态从 `sending` → `running` → `completed`
|
||
3. **cancel 反馈** — 被 cancel 的 session 显示 "已请求停止" + 后续不再有 tool call
|
||
4. **无 UI 异常** — 无 502/500 错误,无工具 manifest 加载失败
|
||
|
||
建议截图:
|
||
- 3 session 同时运行的页面 AI drawer 快照
|
||
- cancel 后的 UI 状态
|
||
- 清理后 session 列表为空
|
||
|
||
## 3. Reasonix cache benchmark 最小脚本方案
|
||
|
||
### 3.1 测试目标
|
||
|
||
对比 Hermes / Reasonix 在相同 prompt 下的首次运行、二次运行(cache 命中)的耗时差异。
|
||
|
||
### 3.2 测试设计
|
||
|
||
**输入**:
|
||
|
||
| 维度 | 值 |
|
||
|------|-----|
|
||
| Prompt | "读取当前页面,列出前三段的主题"(约 20 token) |
|
||
| 样本数 | 每 runtime × 2(cold + cached)= 4 次 |
|
||
| Runtime | Hermes (mnoteai profile)、Reasonix |
|
||
| 页面 | 已知内容的本地 Markdown 文档(>50 行) |
|
||
|
||
**操作步骤**:
|
||
|
||
```
|
||
Step 1: 预热
|
||
创建一个 ACP session(profile=reasonix),发送 prompt,等待完成,删除 session
|
||
|
||
Step 2: 冷启动测试(Reasonix)
|
||
新 session(profile=reasonix)→ prompt → 计时 → 记录 total_ms
|
||
|
||
Step 3: Cache 命中测试(Reasonix)
|
||
同一 session re-prompt → 计时 → 记录 total_ms
|
||
注意:确保 prompt 内容一致,观察 response 中是否有 cache hit 提示
|
||
|
||
Step 4: 冷启动测试(Hermes)
|
||
新 session(profile=hermes/mnoteai)→ prompt → 计时 → 记录 total_ms
|
||
|
||
Step 5: Cache 命中测试(Hermes)
|
||
同一 session re-prompt → 计时 → 记录 total_ms
|
||
|
||
Step 6: 重复 Step 2-5 共 1 轮(共 8 次测量)
|
||
```
|
||
|
||
**输出格式**(JSON):
|
||
|
||
```json
|
||
{
|
||
"schema": "mnote.acp_cache_benchmark.v1",
|
||
"timestamp": "2026-05-21T12:00:00Z",
|
||
"runs": [
|
||
{
|
||
"runtime": "reasonix",
|
||
"phase": "cold",
|
||
"trial": 1,
|
||
"totalMs": 4230,
|
||
"firstTokenMs": 1200,
|
||
"completionMs": 3030,
|
||
"toolCalls": 1,
|
||
"messageCharCount": 85,
|
||
"cacheHit": false
|
||
},
|
||
{
|
||
"runtime": "reasonix",
|
||
"phase": "cached",
|
||
"trial": 1,
|
||
"totalMs": 890,
|
||
"firstTokenMs": 210,
|
||
"completionMs": 680,
|
||
"toolCalls": 1,
|
||
"messageCharCount": 85,
|
||
"cacheHit": true
|
||
}
|
||
],
|
||
"summary": {
|
||
"reasonixColdAvgMs": 4440,
|
||
"reasonixCachedAvgMs": 920,
|
||
"hermesColdAvgMs": 5100,
|
||
"hermesCachedAvgMs": 3100,
|
||
"speedupRatio": 4.8
|
||
}
|
||
}
|
||
```
|
||
|
||
### 3.3 浏览器验证点
|
||
|
||
1. **页面 AI drawer 运行时选择器** — 切换 hermes/reasonix 时的 UI 响应
|
||
2. **首次对话速度** — 冷启动时 UI 从 "thinking" 到首次 token 的延迟
|
||
3. **cache 提示** — Reasonix cached run 的 tool.call/complete 速度应更快
|
||
4. **内存观察** — 浏览器 devtools → Performance → JS heap 无异常增长
|
||
|
||
### 3.4 建议测试脚本存放位置
|
||
|
||
```
|
||
scripts/task-acp-stability-smoke.js ← 多会话稳定性
|
||
scripts/task-acp-cache-benchmark.js ← cache benchmark
|
||
```
|
||
|
||
参考已有:`scripts/task-page-block-ai-tools-smoke.js`、`scripts/task-hermes-page-ai-baseline-smoke.js`。
|
||
|
||
## 4. P0 vs P2 归类
|
||
|
||
| 测试项 | 级别 | 理由 |
|
||
|--------|------|------|
|
||
| 3 个 session 创建 + 正常完成 | **P0** | 并发是基本稳定性要求 |
|
||
| Cancel 在合理时间内生效 | **P0** | UX 基础:用户停止必须工作 |
|
||
| SSE 流在 run 完成后关闭 | **P1** | 防止资源泄漏 |
|
||
| 事件去重正确 | **P1** | 文本重复或截断影响 UX |
|
||
| Session 间事件不交叉 | **P1** | 数据隔离是基本正确性 |
|
||
| Cold vs cached 耗时对比 | **P2** | 度量性质,不影响正确性 |
|
||
| 子进程数量 | **P2** | 度量性质 |
|
||
| 具体第一 token 时间 | **P2** | 度量性质 |
|
||
|
||
## 5. 建议的现有 targeted test
|
||
|
||
```bash
|
||
# 现有 ACP 单元测试(可复用)
|
||
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_session_manager -- --test-threads=1
|
||
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp_bridge -- --test-threads=1
|
||
cd /mnt/Data1T/mnote/rust && cargo test -p mnote-web acp -- --test-threads=1
|
||
|
||
# 现有 smoke 测试(参考模式)
|
||
node scripts/task-page-block-ai-tools-smoke.js
|
||
node scripts/task-hermes-page-ai-baseline-smoke.js
|
||
```
|