# AgentEvalTool — AI Agent 项目知识 > 本文件为 AI 助手提供项目上下文,帮助快速理解项目并参与开发。 ## 项目概述 **AgentEvalTool** 是智能体质量评估工具集平台,评估 AI 数字员工(大模型 + RAG)和 AI 助手(OpenClaw)的服务质量。核心闭环:定义评估 → 执行评估 → 分析结果 → 改进优化。 - **当前版本**: v0.2.0(2026-07-14,里程碑「稳」) - **运行环境**: 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-08) | 多通道 + 规则扩展 + OpenClaw 深度集成 | 📋 规划中 | | v0.4 | 「展」 | 远景 | 多租户 / SSO / 监控告警 / 对外服务 | 💭 远景 | 详细路线图见 [docs/release-notes-v0.2.md](docs/release-notes-v0.2.md) 第八节。 ## 技术栈 ### 后端 - **框架**: FastAPI + Uvicorn - **ORM**: SQLModel(基于 SQLAlchemy) - **CLI**: Typer + Rich - **数据库**: SQLite(StaticPool 模式) - **模板引擎**: Jinja2(HTML 报告) - **关键依赖**: Pydantic v2、requests、PyYAML ### 前端 - **框架**: React 18 + TypeScript + Vite 5 - **UI 库**: Ant Design 5.x + ProComponents - **代码编辑**: Monaco Editor(JSON 场景编辑) - **图表**: @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) ### 数据模型 - `EvalTarget` → `EvalRun` ← `Scenario` - `EvalRun` → `Turn`(对话轮次) - `EvalRun` → `EvalResult`(规则结果) ## 部署知识 ### t480 测试服务器 - **地址**: sola-t480(192.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:` 和 `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:` 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`) ### 镜像 tag 约定 - `t480-agenteval:` — 不可变, 对应某次具体构建 - `t480-agenteval:latest` — 可变, 总是指向最新部署 - 回滚: `docker tag t480-agenteval: 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 端点先创建 run(pending),返回 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 agenteval scenario import data/scenarios/xxx.yaml agenteval scenario list agenteval run start --target-id --scenario-id agenteval run list agenteval report show --format json agenteval report generate --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` 做 lint(line-length 120, target py310) - 前端 TypeScript 使用 `tsc --noEmit` 类型检查 - 文档文件名带版本号(如 `architecture-v1.0.md`) - 用户偏好简体中文交互