331 lines
12 KiB
Markdown
331 lines
12 KiB
Markdown
# AgentEvalTool v0.3.0 「拓」开发计划
|
||
|
||
**开发版本**: v0.3.0-dev
|
||
**制定日期**: 2026-07-17
|
||
**代码基线**: `9293f9e`
|
||
**上一版本**: v0.2.0-dev
|
||
**核心目标**: 建立统一模型配置中心,消除工程内分散的大模型连接配置
|
||
**状态**: 开发完成,待 t480 发布验证
|
||
|
||
---
|
||
|
||
## 一、版本说明
|
||
|
||
本次新增的是向后兼容的平台能力,按照语义化版本规则从
|
||
`0.2.0-dev` 升级为 `0.3.0-dev`。
|
||
|
||
此前以 v0.3/v0.4 任务名开发的以下能力已经进入当前代码基线,不再列为本版本待办:
|
||
|
||
- 异步评估规则和统一 LLM 响应解析
|
||
- HTTP、tutu-api、OpenClaw 三类评测通道
|
||
- semantic similarity、JSON schema、safety 等评估规则
|
||
- all、any、weighted 规则组合
|
||
- Webhook、Markdown 报告、对比报告
|
||
- 场景模板、WebSocket 重连、页面懒加载
|
||
- 原始文件管理重构和位置展示
|
||
- 194 个后端测试基线
|
||
|
||
v0.3.0-dev 从提交 `9293f9e` 开始,模型配置中心是本版本唯一的核心功能主线。
|
||
|
||
---
|
||
|
||
## 二、现状与问题
|
||
|
||
当前除 OpenClaw 外,模型连接信息分散在场景和规则参数中:
|
||
|
||
| 使用位置 | 当前配置 | 问题 |
|
||
|---|---|---|
|
||
| 动态用例生成 | `Scenario.llm_config` | URL、Key、模型随场景重复保存 |
|
||
| LLM 评分 | `llm_score.params` | 凭据嵌在用例 JSON 中 |
|
||
| 语义相似度 | `semantic_similarity.params` | embedding 配置无法复用 |
|
||
| 安全检测 | `safety.params` | moderation 配置无法复用 |
|
||
|
||
现有场景 API 会返回完整 `llm_config`,规则参数也可能通过场景和运行日志返回,
|
||
因此 API Key 存在明文存储和响应泄露风险。三个模型调用实现还分别直接使用
|
||
`httpx`,认证、超时和错误处理没有统一入口。
|
||
|
||
以下内容不纳入模型配置中心:
|
||
|
||
- OpenClaw 自身使用的模型,由 OpenClaw 独立管理。
|
||
- tutu-api、HTTP、OpenClaw 评测通道配置,它们属于评测对象连接。
|
||
- Prompt、temperature、评分阈值、参考答案等业务参数。
|
||
|
||
---
|
||
|
||
## 三、目标架构
|
||
|
||
```text
|
||
模型配置页面
|
||
|
|
||
v
|
||
ModelConfig API -> ModelConfigService -> model_configs
|
||
-> 密钥加密/解密
|
||
-> 引用检查
|
||
|
|
||
v
|
||
ModelGateway
|
||
|-- chat() -> 动态用例生成 / LLM 评分
|
||
|-- embed() -> 语义相似度
|
||
`-- moderate() -> 安全检测
|
||
|
||
评测场景只保存 model_config_id 或用途绑定,不保存 URL、Key、模型名称。
|
||
```
|
||
|
||
核心原则:
|
||
|
||
1. 模型配置只在一个页面维护。
|
||
2. 业务模块只引用配置 ID,不接触明文凭据。
|
||
3. 所有模型请求通过 `ModelGateway` 发出。
|
||
4. 能力类型必须匹配,chat 配置不能用于 embedding 或 moderation。
|
||
5. 模型配置变更只影响后续运行,历史运行保留不含密钥的配置快照。
|
||
|
||
---
|
||
|
||
## 四、数据设计
|
||
|
||
### 4.1 model_configs
|
||
|
||
新增 `model_configs` 表:
|
||
|
||
| 字段 | 类型 | 说明 |
|
||
|---|---|---|
|
||
| `id` | UUID | 主键 |
|
||
| `name` | string | 唯一配置名称 |
|
||
| `provider` | string | V1 为 `openai_compatible` |
|
||
| `capability` | string | `chat`、`embedding`、`moderation` |
|
||
| `endpoint_url` | string | 完整 API Endpoint |
|
||
| `model_name` | string/null | 模型名称,moderation 可为空 |
|
||
| `api_key_encrypted` | string/null | 加密后的 API Key |
|
||
| `enabled` | bool | 是否允许新任务使用 |
|
||
| `is_default` | bool | 当前能力的默认配置 |
|
||
| `description` | string | 备注 |
|
||
| `created_at` | datetime | 创建时间 |
|
||
| `updated_at` | datetime | 更新时间 |
|
||
|
||
约束:
|
||
|
||
- `name` 唯一。
|
||
- 每种 capability 最多一个默认配置。
|
||
- Endpoint 必须是 HTTP 或 HTTPS URL。
|
||
- chat/embedding 必须填写 `model_name`。
|
||
|
||
### 4.2 scenario_model_bindings
|
||
|
||
新增场景模型用途绑定表:
|
||
|
||
| 字段 | 说明 |
|
||
|---|---|
|
||
| `scenario_id` | 场景 ID |
|
||
| `purpose` | `generator`、`judge`、`embedding`、`moderation` |
|
||
| `model_config_id` | 模型配置 ID |
|
||
|
||
`(scenario_id, purpose)` 建立唯一约束。删除场景时级联删除绑定;被绑定的模型配置禁止删除。
|
||
|
||
### 4.3 运行快照
|
||
|
||
运行开始时保存不含密钥的模型快照:
|
||
|
||
- 配置 ID和名称
|
||
- provider 和 capability
|
||
- endpoint URL
|
||
- model name
|
||
- 配置的 `updated_at`
|
||
|
||
运行中的调用使用启动时已经解析的不可变运行时配置,避免任务执行期间修改配置导致同一次评测前后不一致。
|
||
|
||
---
|
||
|
||
## 五、API 计划
|
||
|
||
新增 `/api/model-configs` Router:
|
||
|
||
| 方法 | 路径 | 作用 |
|
||
|---|---|---|
|
||
| `GET` | `/api/model-configs` | 列表,支持 capability/enabled 筛选 |
|
||
| `POST` | `/api/model-configs` | 创建配置 |
|
||
| `GET` | `/api/model-configs/{id}` | 查询详情 |
|
||
| `PUT` | `/api/model-configs/{id}` | 更新配置 |
|
||
| `DELETE` | `/api/model-configs/{id}` | 删除未引用配置 |
|
||
| `POST` | `/api/model-configs/{id}/test` | 按能力执行连接测试 |
|
||
| `GET` | `/api/model-configs/{id}/references` | 查询引用场景 |
|
||
|
||
安全约束:
|
||
|
||
- 任何 GET 响应都不返回 `api_key_encrypted` 或明文 Key。
|
||
- 响应只包含 `has_api_key`。
|
||
- PUT 未提供 `api_key` 时保留原密钥。
|
||
- 只有显式 `clear_api_key=true` 才清除密钥。
|
||
- 删除被引用的配置返回 `409 Conflict`。
|
||
- 禁用或能力不匹配的配置在启动评测前返回明确错误。
|
||
|
||
---
|
||
|
||
## 六、前端计划
|
||
|
||
### 6.1 模型配置页面
|
||
|
||
新增侧边栏菜单“模型配置”,路由 `/models`,位于“评测对象”和“评测场景”之间。
|
||
|
||
页面采用表格加编辑抽屉:
|
||
|
||
- 表格列:名称、能力、服务商、模型、Endpoint、状态、默认、引用数、测试状态、操作。
|
||
- 顶部提供能力筛选、状态筛选、搜索和新增按钮。
|
||
- 操作提供测试、编辑、启停、删除。
|
||
- API Key 已存在时显示“已配置”,不回填原值。
|
||
- 测试连接显示调用耗时和错误摘要,不显示请求凭据。
|
||
|
||
### 6.2 场景页面
|
||
|
||
删除现有动态用例区域中的 API URL、API Key 和模型名称输入框,改为“模型引用”:
|
||
|
||
| 场景能力 | 选择项 | 过滤能力 |
|
||
|---|---|---|
|
||
| 动态用例 | 问题生成模型 | chat |
|
||
| `llm_score` | 评分模型 | chat |
|
||
| `semantic_similarity` | 向量模型 | embedding |
|
||
| `safety` moderation | 内容审核模型 | moderation |
|
||
|
||
下拉框只显示已启用且能力匹配的配置。默认模型只用于新建场景时预选,保存后记录明确 ID。
|
||
|
||
场景模板移除占位 URL 和 API Key,模板应用后要求选择对应能力的模型配置。
|
||
|
||
---
|
||
|
||
## 七、后端重构计划
|
||
|
||
新增模块:
|
||
|
||
```text
|
||
backend/agenteval/
|
||
|-- services/model_configs.py
|
||
|-- storage/model_config_repository.py
|
||
|-- model_gateway.py
|
||
`-- web/routers/model_configs.py
|
||
```
|
||
|
||
职责划分:
|
||
|
||
- Repository 负责模型配置和场景绑定的数据库操作。
|
||
- Service 负责校验、默认配置、引用检查、密钥处理和连接测试。
|
||
- ModelGateway 负责 chat、embedding、moderation 请求和响应规范化。
|
||
- EvalEngine 负责解析场景用途绑定并将 Gateway 注入规则运行上下文。
|
||
- LLM 规则只保留 criteria、min_score、reference 等业务参数。
|
||
|
||
V1 只实现 OpenAI-compatible 协议,但保留 provider 字段,后续可增加独立适配器。
|
||
|
||
---
|
||
|
||
## 八、密钥方案
|
||
|
||
新增依赖 `cryptography`,使用 Fernet 加密 API Key。新增环境变量:
|
||
|
||
```text
|
||
AGENTEVAL_SECRET_KEY=<fernet-key>
|
||
```
|
||
|
||
要求:
|
||
|
||
- t480 的 `.env` 在执行数据迁移前手动配置密钥。
|
||
- 部署脚本 pre-flight 检查远端密钥是否存在,但不打印密钥。
|
||
- 密钥不得进入数据库明文字段、API、日志、运行快照或 WebSocket 事件。
|
||
- 密钥文件或环境变量需要与数据库一起备份,否则加密配置无法恢复。
|
||
|
||
本版本不实现在线密钥轮换;密钥轮换另立任务。
|
||
|
||
---
|
||
|
||
## 九、旧数据迁移
|
||
|
||
采用“新增结构、双读兼容、迁移数据、最后清理”的顺序:
|
||
|
||
1. Alembic 创建新表,不立即删除 `scenarios.llm_config`。
|
||
2. 新代码优先读取中心配置,缺少绑定时兼容旧配置。
|
||
3. 提供 `scripts/migrate_model_configs.py --dry-run` 输出迁移报告。
|
||
4. 按 capability、Endpoint、model 和 API Key 指纹去重创建配置。
|
||
5. 将旧动态生成配置迁移为 `generator` 绑定。
|
||
6. 将 llm_score、semantic、safety 的内联连接参数迁移为对应用途绑定。
|
||
7. 迁移成功后移除用例 JSON 中的 URL、Key 和模型字段。
|
||
8. 同一场景同一用途存在多个不同模型时不自动覆盖,保留旧配置并列入冲突报告。
|
||
9. 验证 t480 数据后,再在后续版本删除旧 `llm_config` 字段和兼容代码。
|
||
|
||
迁移脚本必须幂等,可重复执行,不得在部分失败时留下半迁移状态。
|
||
|
||
---
|
||
|
||
## 十、开发阶段
|
||
|
||
| 阶段 | 主要任务 | 交付条件 | 状态 |
|
||
|---|---|---|---|
|
||
| M0 版本基线 | 升级 `0.3.0-dev`、更新计划 | 版本源和前端版本一致 | 已完成 |
|
||
| M1 数据与安全 | Alembic、Repository、Service、Fernet、单测 | CRUD 和密钥测试通过 | 已完成 |
|
||
| M2 API 与页面 | REST API、连接测试、模型配置页面 | 可完整管理三类配置 | 已完成 |
|
||
| M3 业务接入 | ModelGateway、Engine、四类用途、场景选择器 | 工程无新增内联模型凭据 | 已完成 |
|
||
| M4 迁移与发布 | 迁移脚本、兼容测试、文档、t480 完整部署 | 线上数据迁移且健康检查通过 | 代码完成,待发布验证 |
|
||
|
||
预计总工作量 9.5-13.5 PD。M1 完成后才能并行推进 M2 和部分 M3;M4 必须最后执行。
|
||
|
||
本次开发以一个完整功能提交交付,发布后通过健康接口记录实际 commit。
|
||
|
||
---
|
||
|
||
## 十一、测试计划
|
||
|
||
### 后端
|
||
|
||
- ModelConfig Repository CRUD 和唯一约束。
|
||
- 默认配置切换和 capability 校验。
|
||
- API Key 加密、解密、掩码和清除语义。
|
||
- API CRUD、连接测试、引用查询和删除冲突。
|
||
- ModelGateway chat/embed/moderate 请求格式和错误处理。
|
||
- 动态用例、llm_score、semantic、safety 使用中心配置。
|
||
- 禁用配置、缺少配置、错误能力的失败信息。
|
||
- 旧配置迁移、重复配置合并、冲突和回滚。
|
||
- 场景、运行日志和 WebSocket 响应中不存在明文密钥。
|
||
|
||
### 前端
|
||
|
||
- TypeScript 类型检查和生产构建。
|
||
- 模型配置列表、筛选、编辑、测试、禁用、删除状态。
|
||
- API Key 不回填,留空更新不清除旧值。
|
||
- 场景模型选择按 capability 过滤。
|
||
- 桌面和 720px 窄屏无重叠或文本溢出。
|
||
|
||
### 回归
|
||
|
||
- 当前 194 个测试保持通过。
|
||
- tutu-api、HTTP 和 OpenClaw 评测通道不受影响。
|
||
- OpenClaw 页面和代理配置不接入模型中心。
|
||
- 原始文件、报告和评测执行流程保持可用。
|
||
|
||
---
|
||
|
||
## 十二、发布门槛
|
||
|
||
发布到 t480 前必须满足:
|
||
|
||
1. `pytest -q` 全部通过。
|
||
2. `ruff check backend/` 通过。
|
||
3. `npx tsc --noEmit` 通过。
|
||
4. `npm run build` 通过。
|
||
5. Alembic 在现有数据库副本上升级成功。
|
||
6. 迁移脚本 dry-run 无未处理冲突,或冲突已人工确认。
|
||
7. API 和日志中检索不到旧明文 API Key。
|
||
8. 四类模型用途至少各完成一次模拟集成测试。
|
||
9. 代码推送 Gitea 后执行完整 `scripts/deploy-t480.sh`。
|
||
10. `/api/health` 返回 `version=0.3.0-dev` 且 commit 与 Gitea 一致。
|
||
|
||
---
|
||
|
||
## 十三、完成定义
|
||
|
||
v0.3.0-dev 功能完成需要同时满足:
|
||
|
||
- 新增“模型配置”页面,可管理 chat、embedding、moderation 配置。
|
||
- 除 OpenClaw 外,工程页面不再编辑模型 URL、API Key 和模型名称。
|
||
- 场景和规则只保存模型配置引用及业务参数。
|
||
- 所有模型调用统一通过 ModelGateway。
|
||
- API Key 加密存储,所有读取接口只返回掩码状态。
|
||
- 被引用配置不可删除,禁用配置不可启动新评测。
|
||
- 旧配置完成无损迁移,兼容期内仍可回退。
|
||
- t480 完整部署后版本、commit、数据库和前端资源全部验证通过。
|