AgentEvalTool/AGENT.md
sinohqb 25b4c98dc8
Some checks failed
CI / test (push) Has been cancelled
docs(release): v0.5「准」发布说明与里程碑收尾
版本升至 0.5.0-dev;新增 release-notes-v0.5.md(判定语义 + 场景版本化
+ 领域文档基线);AGENT.md/AGENTS.md 更新里程碑路线图、判定语义速查与
CONTEXT.md/ADR 指引。
2026-07-29 15:43:15 +08:00

236 lines
11 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

# AgentEvalTool — AI Agent 项目知识
> 本文件为 AI 助手提供项目上下文,帮助快速理解项目并参与开发。
## 项目概述
**AgentEvalTool** 是智能体质量评估工具集平台,评估 AI 数字员工(大模型 + RAG和 AI 助手OpenClaw的服务质量。核心闭环定义评估 → 执行评估 → 分析结果 → 改进优化。
- **当前版本**: v0.5.0-dev2026-07-29 发布至 t480里程碑「准」
- **运行环境**: t480 测试服务器192.168.8.145:8001
- **语言**: Python 3.11(后端) + TypeScript/React 18前端
## 里程碑路线图
| 版本 | 代号 | 日期 | 主题 | 状态 |
|---|---|---|---|---|
| v0.1 | MVP | 2026-07-09 | 核心闭环跑通 | ✅ 已发布 |
| v0.2 | 「稳」 | 2026-07-14 | async 引擎 + 安全基线 + 测试 + 部署规范化 | ✅ 已发布(t480) |
| v0.3 | 「拓」 | 2026-07-17 | 多通道 + 规则扩展 + 模型配置中心 | ✅ 已发布(t480) |
| v0.4 | 「联」 | 2026-07-28 | AI 助手标准化(triggered_by) + 登录 + 仪表盘重构 | ✅ 已发布(t480) |
| **v0.5** | **「准」** | **2026-07-29** | **判定语义(期望叠加/连通用例) + 场景版本化 + 领域文档基线** | **✅ 已发布(t480)** |
| v0.6 | — | 规划中 | volcengine-102 同步 / 前端测试 / 报告聚合看板 / 多模态 | 📋 待规划 |
详细内容见 [docs/release-notes-v0.5.md](docs/release-notes-v0.5.md)。领域术语的唯一词汇表在 [CONTEXT.md](CONTEXT.md),关键决策在 [docs/adr/](docs/adr/)。
## 技术栈
### 后端
- **框架**: FastAPI + Uvicorn
- **ORM**: SQLModel基于 SQLAlchemy
- **CLI**: Typer + Rich
- **数据库**: SQLiteStaticPool 模式)
- **模板引擎**: Jinja2HTML 报告)
- **关键依赖**: Pydantic v2、requests、PyYAML
### 前端
- **框架**: React 18 + TypeScript + Vite 5
- **UI 库**: Ant Design 5.x + ProComponents
- **代码编辑**: Monaco EditorJSON 场景编辑)
- **图表**: @ant-design/charts
- **路由**: react-router-dom v6
- **HTTP**: axios带请求拦截器和统一错误提示
## 项目结构
```
AgentEvalTool/
├── backend/
│ ├── agenteval/ # 核心 Python 库
│ │ ├── agents/ # EvalAgent 抽象SimpleAgent
│ │ ├── channels/ # 消息通道TutuApiChannel
│ │ ├── evaluation/ # 评测引擎 + 规则
│ │ │ └── rules/ # keyword_match, response_time, llm_score
│ │ ├── scenarios/ # 场景加载/校验
│ │ ├── storage/ # SQLite + Repository 模式
│ │ └── web/ # FastAPI 后端
│ │ ├── routers/ # targets, scenarios, runs, reports, stats
│ │ └── websocket.py # WebSocket 实时进度推送
│ ├── cli/ # CLI 入口Typer
│ └── plugins/openclaw/ # OpenClaw 插件示例
├── frontend/web/ # React 前端Vite + Ant Design
├── config/config.json # tutu-api 配置(敏感信息)
├── data/ # SQLite DB + 场景 YAML + 报告输出
├── deploy/t480/ # Docker 部署配置
├── docs/ # 版本化文档集
├── scripts/mock_call.py # 历史参考脚本
└── pyproject.toml # hatchling 构建 + 依赖定义
```
## 核心架构
### 消息通道EvalChannel
- 抽象接口:`send()` / `poll_reply()` / `health_check()`
- V1 实现:`TutuApiChannel`HTTP + Bearer Token + questionMsgId 配对)
- 工厂模式:`ChannelFactory` 按 channel_type 创建实例
### 评测引擎EvalEngine
- 遍历 Scenario.cases → 每个 case 遍历 messages多轮对话
- 发送消息 → 轮询回复 → 记录 Turn → 执行规则 → 保存 EvalResult
- 支持 `progress_callback` 实时推送事件WebSocket 集成)
- 支持 `existing_run` 参数复用已有 run 记录
### 评估规则EvalRule
- `keyword_match`:关键词包含/排除匹配
- `response_time`:响应时间阈值检查
- `llm_score`LLM-as-judge 评分OpenAI 兼容 API
### 判定语义v0.5 起)
- **期望叠加**case 的 `expectation` 始终派生隐式 llm_score 规则,与显式规则叠加(隐式是 rule_logic 之外的硬约束reason 带 `[期望]` 前缀)
- **连通用例**:无规则且无期望的用例是合法的连通性验证,报告层标注 `connectivity``judged_pass_rate` 剔除连通用例,`pass_rate` 口径不变(含执行失败,见 ADR-0002
- **场景版本**`Scenario.version` 系统维护(仅考纲字段变更升版,见 ADR-0001运行创建时快照 `EvalRun.scenario_version`,对比报告要求同场景同版本
### 数据模型
- `EvalTarget``EvalRun``Scenario`
- `EvalRun``Turn`(对话轮次)
- `EvalRun``EvalResult`(规则结果)
## 部署知识
### t480 测试服务器
- **地址**: sola-t480192.168.8.145
- **端口**: 8001映射容器内 8000
- **部署方式**: Docker Compose 双容器agenteval + openclaw-eval
- **Python 镜像**: python:3.11.15-slim-bookworm
- **APT/Pip 镜像**: 阿里云(绕过 GFW
### 版本号(单一数据源)
- **pyproject.toml** 是版本号的唯一来源
- **package.json** 的版本号由 `scripts/sync_version.py` 自动同步
- 每次部署前必须运行 `python3 scripts/sync_version.py`deploy 脚本会自动做)
- 镜像 tag 同时打 `t480-agenteval:<version>``t480-agenteval:latest`
### 部署流程(标准)
```bash
# 推荐: 一键部署build/sync/rebuild/verify 全包)
scripts/deploy-t480.sh
# 仅代码变更(跳过镜像重建, backend 通过 volume 热加载)
scripts/deploy-t480.sh --skip-build
# 预览命令, 不实际执行
scripts/deploy-t480.sh --dry-run
```
脚本会自动:
1. 同步版本号 `pyproject.toml → package.json`
2. `npm run build` 构建前端
3. rsync 代码 + dist 到 t480
4. `docker compose build --build-arg BUILD_COMMIT=... --build-arg BUILD_TIME=...`
5. `docker tag t480-agenteval:<version>`
6. `docker compose up -d`(容器启动时自动跑 `alembic upgrade head`
7. curl `/api/health` 验证版本号和 commit 一致
### 部署验证
```bash
curl http://192.168.8.145:8001/api/health
# 返回: {"status":"ok","version":"0.2.0-dev","commit":"abc1234","built_at":"2026-07-14T10:33:41Z"}
# 如果 version 不匹配本地 pyproject.toml → 部署失败, 脚本会报错退出
```
### 关键 Volume 挂载
- `data/``/app/data`SQLite DB + 报告 + openclaw 状态, 可写)
- `config/config.json``/app/config/config.json:ro`
- `frontend/web/dist/``/app/frontend/web/dist:ro`**必须 build 后再部署**
- `backend/``/app/backend:ro`(代码热更新)
- `.env``/app/.env:ro`Pydantic Settings 配置, 见 `.env.example`
### 鉴权v0.4 起)
- `AGENTEVAL_ADMIN_PASSWORD`:设置后 Web UI 需登录(会话 token, 关浏览器失效);不设则无登录门
- `AGENTEVAL_API_KEY`机器调用凭据X-API-Keydeploy 脚本会把它写入 openclaw 工作区
`data/openclaw/agenteval-api-key`, agenteval-run skill 自动读取
- 两个凭据任一匹配即放行(`web/deps.py: require_auth``/api/health` 与 `/api/auth/*` 始终开放
### 镜像 tag 约定
- `t480-agenteval:<version>` — 不可变, 对应某次具体构建
- `t480-agenteval:latest` — 可变, 总是指向最新部署
- 回滚: `docker tag t480-agenteval:<old-version> t480-agenteval:latest && docker compose up -d`
## 重要踩坑记录
### 1. SQLite + FastAPI 必须用 StaticPool
- 默认 QueuePool 在多线程环境下快速耗尽
- `check_same_thread=False` + `StaticPool` 是 SQLite 的正确配置
### 2. Docker COPY vs Volume 挂载
- Dockerfile 中 `COPY backend ./backend` 烘焙的代码不会随 rsync 更新
- 必须通过 volume 挂载 `backend/` 才能实现代码热更新
- 只有 Dockerfile 或 Python 依赖变更时才需要 `--build`
### 3. Session 生命周期管理
- 所有 Router 必须使用 `Depends(get_db)` 管理 Session
- `get_db()` 是 generator`finally` 中 `session.close()` 确保连接释放
- 后台任务也需要 `try/finally` 关闭 Session
### 4. EvalEngine.run() 与 API 端点的 run 创建
- API 端点先创建 runpending返回 run_id 给前端
- 后台任务通过 `existing_run` 参数复用该记录,避免重复创建
### 5. 中国网络环境
- Docker Hub 和 npm 在国内访问极慢或被墙
- 使用阿里云 APT/Pip 镜像
- Clash 代理不可靠时,优先使用镜像策略
### 6. 前端 dist 必须显式构建再部署
- `frontend/web/dist/` 是构建产物, 不是源码
- rsync 时如果 `--exclude='frontend/web/dist'`, t480 会一直跑旧 dist, 看起来像"页面回到老版本"
- 必须 `npm run build` 之后再 rsync, 或者直接用 `scripts/deploy-t480.sh`(自动做这两步)
- 部署后用 `curl /api/health` 验证 version/commit 和本地一致, 脚本会自动做
### 7. OpenClaw 免登录依赖 Origin 注入
- OpenClaw 的 `gateway.controlUi.allowedOrigins` 检查 WebSocket 的 Origin header
- `proxy.py` 必须注入 `origin=http://192.168.8.145:8001`(或 settings.allowed_origins 的第一项)
- 如果 Origin 缺失, OpenClaw 拒收 WS 连接, SPA 会显示登录页
- v0.2 起 `openclaw_ws_origin``allowed_origins` 自动推导, 不再硬编码
## CLI 命令速查
```bash
agenteval target add --name "名称" --config config/config.json
agenteval target list
agenteval target test <id>
agenteval scenario import data/scenarios/xxx.yaml
agenteval scenario list
agenteval run start --target-id <id> --scenario-id <id>
agenteval run list
agenteval report show <run-id> --format json
agenteval report generate <run-id> --format html
agenteval server start --host 0.0.0.0 --port 8000
```
## 当前数据t480
- **评测对象**: 1社区医院AI客服tutu-api 通道)
- **评测场景**: 2社区医院基础服务评测 + 科室导航与挂号咨询)
- **API 端点**: `http://192.168.8.145:8001/`
- **WebSocket**: `ws://192.168.8.145:8001/ws/runs/{run_id}`
## 开发约定
- Python 代码使用 `ruff` 做 lintline-length 120, target py310
- 前端 TypeScript 使用 `tsc --noEmit` 类型检查
- 文档文件名带版本号(如 `architecture-v1.0.md`
- 用户偏好简体中文交互
## CI 检查
- `scripts/ci-check.sh` 一键跑:版本号一致性 + ruff + pytest + tsc`--fast` 跳过 tsc
- 本地 `git push` 会自动触发 pre-push hook 执行 `ci-check.sh --fast``.git/hooks/pre-push`,新 clone 需手动重装)
- Gitea Actions 工作流:`.gitea/workflows/ci.yml`(需 Gitea 实例启用 Actions + 注册 runner 才生效)
- 紧急绕过:`git push --no-verify`(仅限救急,事后必须补跑)