# AgentEvalTool v0.2 版本发布说明 **版本**: v0.2.0 **日期**: 2026-07-14 **状态**: 已发布(t480 开发线) **代号**: 「稳」(Stability milestone) **作者**: AgentEval Team --- ## 一、版本定位 v0.2 是 v0.1 MVP 之后的**第一个稳定性里程碑**,遵循「先稳后拓」的两步走战略中的第一步。核心目标: > 让核心闭环(定义评测 → 执行评测 → 查看报告)具备**生产可用性**,为后续的平台化扩展(v0.3)打下坚实的工程基础。 **战略上下文** ``` v0.1 (2026-07-09) MVP 闭环跑通 │ ├── v0.2 (2026-07-14) ← 你在这里:稳定性 + 工程债 + 安全基线 │ └── v0.3 (规划中) 多通道 + 规则扩展 + OpenClaw 深度集成 ``` **关键决策**(用户确认 2026-07-14) - 定位:两步走,先稳后拓 - 规模:个人/小团队(<10 人),SQLite 足够 - 引擎:**async 全面重构** - OpenClaw:**深度集成,插件双向调用** --- ## 二、主要变更 ### 2.1 EvalEngine 全面异步化(核心改造) | 项目 | v0.1 | v0.2 | |---|---|---| | Engine 模型 | 同步串行,阻塞 event loop | 全 async/await,协作式并发 | | 取消机制 | 假取消(只改 DB 状态) | 真取消(asyncio.Event + CancelledError) | | 超时配置 | 硬编码 30s/60s | `TimeoutConfig` 数据类,可配置 | | 并发执行 | 不支持 | `max_concurrent_cases` + Semaphore | | 通道抽象 | 同步 `send`/`poll_reply` | 全 async,支持 poll 与 push 两种实现 | | HTTP 客户端 | `requests`(每次新建连接) | `httpx.AsyncClient`(连接池复用) | **关键文件改动** - `backend/agenteval/evaluation/engine.py` — 全量 async 重写,`run()`/`_run_case()`/`_generate_messages()` 全部 async - `backend/agenteval/channels/base.py` — `EvalChannel` 三个方法全部 `async def` - `backend/agenteval/channels/tutu.py` — `requests` → `httpx.AsyncClient`,实例级连接池 - `backend/agenteval/web/routers/runs.py` — `BackgroundTasks` → `asyncio.Task` 注册表 + 真取消 - `backend/agenteval/web/websocket.py` — 删除 `broadcast_sync` 桥接,新增 `emit()` 异步回调 - `backend/cli/run.py` + `cli/target.py` — `asyncio.run()` 包装,CLI 签名不变 ### 2.2 安全基线(P0) | 项 | v0.1 | v0.2 | |---|---|---| | 配置管理 | 硬编码在源码 | Pydantic Settings + `.env` 文件 | | JWT token | 明文存 `config/config.json` 已 commit | `.gitignore` 保护,`.env.example` 模板 | | CORS | `allow_origins=["*"]` 硬编码 | 从 `settings.allowed_origins` 读取 | | API 鉴权 | 无 | `X-API-Key` middleware(未配置时 no-op) | | OpenClaw proxy | 硬编码 origin/token | 全部从 settings 读取 | | OpenClaw Origin | 硬编码 `http://192.168.8.145:8001` | **从 `allowed_origins` 自动推导** | **关键文件改动** - `backend/agenteval/config/settings.py` — Pydantic Settings 模块,`@model_validator` 自动推导 `openclaw_ws_origin` - `backend/agenteval/web/deps.py` — 集中 `get_db` + `require_api_key` - `backend/agenteval/web/routers/proxy.py` — 零硬编码,全部从 settings 读取 - `.gitignore` / `.env.example` / `config/config.example.json` — 新建 ### 2.3 存储层去债 | 项 | v0.1 | v0.2 | |---|---|---| | Schema 迁移 | `create_all()` 一次性 | Alembic + 版本化 migration | | `get_db` | 5 个 router 重复定义 | 集中到 `web/deps.py` | | `utcnow()` | 已废弃的 `datetime.utcnow()` | `datetime.now(timezone.utc)` | | 级联删除 | 无 | ORM 级联 `EvalRunDB → turns/results` | **关键文件改动** - `migrations/` — Alembic 初始化,baseline migration `15c107310eea_baseline_add_llm_config.py` - `backend/agenteval/storage/db.py` — 添加 `Relationship` + `cascade="all, delete-orphan"` - `backend/agenteval/storage/repository.py` — 新增 `RunRepository.delete()` - `deploy/t480/Dockerfile` — CMD 改为 `alembic upgrade head && agenteval server start` ### 2.4 前端重构 | 项 | v0.1 | v0.2 | |---|---|---| | `useRunSession` | 7 个 useState + 120 行 `applyEvent` | `useReducer` + 纯函数 reducer | | 对话渲染 | CaseBlock/CaseDetail/Reports 三处重复 | 抽出 `TurnList` 公用组件 | | AI 生成消息 | 两处重复 | 抽出 `GeneratedMessages` | | 工具函数 | 分散在页面文件 | 集中到 `utils/date.ts` / `utils/colors.ts` | | Reports 页 URL query | 不读取 `?run=xxx` | 支持,可分享链接 | **关键文件改动** - `frontend/web/src/hooks/sessionReducer.ts` — 纯函数 reducer(300+ 行),可单测 - `frontend/web/src/hooks/useRunSession.ts` — useReducer 化 - `frontend/web/src/components/TurnList.tsx` / `GeneratedMessages.tsx` — 新建 - `frontend/web/src/utils/date.ts` / `colors.ts` — 新建 - `frontend/web/src/pages/Reports.tsx` — 支持 `?run=xxx` URL query ### 2.5 测试基线(从 0 起步) | 测试文件 | 数量 | 覆盖 | |---|---|---| | `tests/unit/test_engine.py` | 10 | async engine 并发/取消/超时/send 失败 | | `tests/unit/test_cascade.py` | 3 | ORM 级联删除(target/scenario/run) | | `tests/unit/test_settings.py` | 6 | `openclaw_ws_origin` 自动推导逻辑 | | `tests/integration/test_runs_api.py` | 5 | API 集成(list/start/cancel/logs/404) | | **合计** | **24** | **57% 整体覆盖率**(engine 61%, runs.py 86%, db.py 94%) | **基础设施** - `tests/conftest.py` — tmp SQLite fixture + 表结构 sanity check - `tests/unit/mock_channel.py` — 可配置 MockChannel(延迟/失败/缺失回复) - `pyproject.toml` — `asyncio_mode=auto`, `pythonpath=["backend", "."]` ### 2.6 部署规范化 | 项 | v0.1 | v0.2 | |---|---|---| | 版本号 | 前后端独立维护 | **pyproject.toml 单一数据源** | | 部署流程 | 手动 rsync + docker compose up | `scripts/deploy-t480.sh` 一键部署 | | 镜像 tag | 仅 `latest` | `` + `latest` 双 tag | | 构建元数据 | 无 | `/api/health` 返回 `version/commit/built_at` | | 部署验证 | 人工 | 脚本自动 curl + 校验 version/commit | | .env 挂载 | 无 | docker-compose 挂载 `.env` 进容器 | **关键文件改动** - `scripts/deploy-t480.sh` — 一键部署脚本(build/sync/rebuild/verify) - `scripts/sync_version.py` — 版本号同步脚本 - `backend/agenteval/version.py` — 版本 + 构建元数据模块 - `deploy/t480/Dockerfile` — `ARG BUILD_COMMIT/BUILD_TIME` → `ENV AGENTEVAL_BUILD_*` - `deploy/t480/docker-compose.yml` — 挂载 `.env` + `env_file` - `AGENT.md` — 新部署流程 + 镜像 tag 约定 + 踩坑 #6/#7 --- ## 三、关键 Bug 修复 | 编号 | 问题 | 根因 | 修复 | |---|---|---|---| | BUG-1 | 评测执行页点任务记录报 React #310 错误 | `useMemo` 在 early return 之后,违反 Hooks 规则 | 移动 `useMemo` 到 early return 之前 | | BUG-2 | AI 助手页面显示登录页 | proxy.py 重构后 `openclaw_ws_origin` 默认 `None`,OpenClaw 拒收 WS | `@model_validator` 从 `allowed_origins` 自动推导 | | BUG-3 | 评测执行页回到老版本 | rsync 排除了 `frontend/web/dist`,t480 跑旧 dist | `deploy-t480.sh` 强制 `npm run build` 后再 rsync | | BUG-4 | 容器启动报 `duplicate column: llm_config` | t480 DB 已手动 ALTER,但 Alembic 不知道 | `docker run alembic stamp head` 标记 baseline | | BUG-5 | `cancel` API 是假取消 | 只改 DB 状态,Engine 线程继续跑 | Engine 接受 `cancel_token`,每个 case 边界检查 | --- ## 四、架构演进图 ``` v0.1 (MVP) ├── 同步 EvalEngine → BackgroundTasks → SQLite (StaticPool) ├── 单通道 (tutu-api) / 3 规则 / HTML+JSON 报告 ├── 零测试 / 硬编码敏感信息 / 无鉴权 └── 手动 rsync + docker compose up v0.2 「稳」 ← 当前版本 ├── async Engine + Semaphore + CancelToken → asyncio.Task 注册表 ├── SQLite (aiosqlite 预留) + Alembic 迁移 ├── APIKey 鉴权 / .env 配置 / 24 单测 + 集成测试 / CI 配置就位 ├── 前端 useReducer 重构 useRunSession / 抽出 TurnList/GeneratedMessages └── scripts/deploy-t480.sh 一键部署 + 镜像版本 tag + /api/health 验证 v0.3 「拓」(规划中) ├── 多通道 (tutu/http/openclaw) 插件化 ├── 7 种规则 + 组合逻辑 (AND/OR/weighted) ├── 报告对比 + 模板外置 ├── OpenClaw webhook 双向集成 └── 前端路由 + TanStack Query ``` --- ## 五、文件改动统计 ``` 新增文件 (20): backend/agenteval/config/__init__.py backend/agenteval/config/settings.py backend/agenteval/version.py backend/agenteval/web/deps.py migrations/{alembic.ini, env.py, script.py.mako, README} migrations/versions/15c107310eea_baseline_add_llm_config.py scripts/deploy-t480.sh scripts/sync_version.py tests/{conftest.py, __init__.py} tests/unit/{mock_channel.py, test_engine.py, test_cascade.py, test_settings.py} tests/integration/test_runs_api.py frontend/web/src/hooks/sessionReducer.ts frontend/web/src/hooks/useTicker.ts frontend/web/src/components/{TurnList, GeneratedMessages}.tsx frontend/web/src/utils/{date, colors}.ts .gitignore, .env.example, config/config.example.json 重大改动 (10): backend/agenteval/evaluation/engine.py (async 重写) backend/agenteval/channels/{base, tutu}.py (async + httpx) backend/agenteval/web/app.py (lifespan + /api/health) backend/agenteval/web/routers/{runs, targets, scenarios, reports, stats, proxy}.py backend/agenteval/storage/db.py (Relationship + cascade) frontend/web/src/hooks/useRunSession.ts (useReducer) frontend/web/src/pages/Reports.tsx (?run=xxx URL query) deploy/t480/{Dockerfile, docker-compose.yml} pyproject.toml, AGENT.md ``` --- ## 六、已知问题 | 编号 | 问题 | 影响 | 计划修复 | |---|---|---|---| | KNOWN-1 | Repository 未抽象泛型基类 | 4 个 Repository 重复代码 | v0.3 评估收益后决定 | | KNOWN-2 | `_generate_messages` 未测试 | LLM 动态用例生成路径无覆盖 | v0.2 后续补 | | KNOWN-3 | `commit=no-git`(项目未 git init) | `/api/health` 无法显示真实 SHA | 用户决定后 `git init` | | KNOWN-4 | 前端无单元测试 | reducer 已抽出但未写测试 | v0.3 引入 vitest | | KNOWN-5 | Rules 覆盖率低(15-30%) | 规则逻辑无测试 | v0.3 规则扩展时同步补 | --- ## 七、部署验证 **t480 当前状态**(2026-07-14) ```bash $ curl http://192.168.8.145:8001/api/health { "status": "ok", "version": "0.2.0-dev", "commit": "no-git", "built_at": "2026-07-14T10:33:41Z" } $ docker ps agenteval Up (healthy) t480-agenteval:0.2.0-dev openclaw-eval Up (healthy) ghcr.io/openclaw/openclaw:latest ``` **一键部署命令** ```bash scripts/deploy-t480.sh # 完整部署 scripts/deploy-t480.sh --skip-build # 仅代码变更 scripts/deploy-t480.sh --dry-run # 预览 ``` --- ## 八、下一步:v0.3 「拓」 v0.3 聚焦**平台化能力扩展**,预估工作量 4-5 周: | 模块 | 目标 | 优先级 | |---|---|---| | 消息通道扩展 | HTTP + OpenClaw 通道实现 + entry_points 插件发现 | P0 | | 评估规则扩展 | semantic_similarity / json_schema / safety / coherence + 组合逻辑 | P0 | | OpenClaw 深度集成 | skill 触发评测 + webhook 完成通知(双向) | P1 | | 报告能力升级 | 对比报告 / Markdown 导出 / 模板外置 | P1 | | 场景能力增强 | 内置模板库 + 参数化场景 | P2 | | 前端体验升级 | React Router data router + TanStack Query + 对比视图 | P2 | --- ## 九、致谢 v0.2 的完成得益于以下关键决策: - 用户坚持「先稳后拓」的战略定力,避免了在 MVP 阶段过早平台化 - 选择 async 全面重构而非 Celery/RQ 任务队列,降低了运维复杂度 - 接受「小团队规模不需要多租户/PostgreSQL」的务实判断,避免了过度设计 **下一个里程碑:v0.3 「拓」,预计 2026-08 中旬。**