mirror of
https://github.com/jxxghp/MoviePilot.git
synced 2026-11-01 21:07:01 +08:00
docs(agent): record Gemini evaluation and harness boundaries
This commit is contained in:
@@ -39,29 +39,31 @@ uv run --locked --no-sync python -m scripts.evaluation --live \
|
||||
--output report.json
|
||||
```
|
||||
|
||||
### 2026-09-11 供应商实测
|
||||
### 2026-09-11 Google Gemini 供应商实测
|
||||
|
||||
本轮使用 Agnes AI Hub 的 `agnes-2.5-pro`,推理档位为供应商支持的最高档 `xhigh`,通过 Responses provider 配置和环境变量传递凭据。`max` 请求被供应商以 400 拒绝(支持档位为 `low`、`medium`、`xhigh`),因此不能把失败的 `max` 请求算作模型能力证据。
|
||||
本轮使用 Google Gemini `gemini-2.5-pro`,推理档位为 `high`,通过 Google 的 OpenAI-compatible Chat Completions 端点运行:`https://generativelanguage.googleapis.com/v1beta/openai`。报告只记录供应商主机、模型、协议和用量,不记录凭据。它是独立基线,不能和此前 Agnes 或原生 Codex 的结果合并。
|
||||
|
||||
此前 `66d288ffc` 提交的隔离评测中,`dedup_existing` 通过(8 次模型调用,约 50 秒);`unknown_download` 和 `honest_unknown` 均有真实模型响应,但最终报告未通过独立 JSON 验收(各达到 12 次调用上限)。这组结果说明当时实现已经能进行真实供应商评测,也明确暴露了复杂场景的收敛问题,不能据此宣称已达到 Codex 整体水平。
|
||||
`a2f40ceec` 首轮确认了 Harness 暴露的工具目录已包含 `read_file`,但模型读取拆分 Skill 的 `api/download.md` 时被错误的临时路径权限拒绝。`7195a29c3` 将非管理员读取根绑定到本次临时 Agent 目录后,模型已经成功读取 `api/download.md` 和 `api/site.md`;这证明 `read_skill -> supporting_files -> read_file` 链路在真实模型运行中可用。
|
||||
|
||||
最终提交 `abd3cea92` 在同一 `agnes-2.5-pro + xhigh` 配置下重跑 `dedup_existing` 两次:第一次完成 6 次模型请求后收到 403,第二次首个请求即收到 403;两次均未通过,分别为 `usage_complete=false`、`agent_execution_success=false`。这组结果是供应商访问状态的失败证据,不能与此前通过样本混合为当前代码的通过结论。
|
||||
`8c0746172` 将 `download.add` 的最小 `torrent_in` 合同直接补入下载分类文档并把 Skill 升到 v30。当前三场景证据如下(报告保存在本机 `/tmp`,未提交仓库):
|
||||
|
||||
后续提交 `72aabe12f` 只抽取 WebAgent 事件生成私有 helper 以满足复杂度门禁,仍按代码轮次重新运行 `dedup_existing` 一次;首个模型请求即收到 403,报告为 `intelligence_evaluated=false`、`usage_complete=false`、`agent_execution_success=false`。因此当前供应商访问状态仍未提供可用的最新通过样本。
|
||||
| 场景 | 结果 | 证据与失败边界 |
|
||||
| --- | --- | --- |
|
||||
| `dedup_existing` | 未通过 | `/tmp/moviepilot-agent-round-8c0746172-gemini-dedup.json`;真实读取到订阅和下载,未重复写入,但报告仍带有未请求的站点 ID,部分重复运行还会先发错误查询。 |
|
||||
| `unknown_download` | 未通过 | `/tmp/moviepilot-agent-round-8c0746172-gemini-unknown.json`;模型持续探索错误或无关读取,达到 12 次模型调用上限并返回技术失败/无最终 JSON,尚未稳定收敛到写入后核验。 |
|
||||
| `honest_unknown` | 未通过 | `/tmp/moviepilot-agent-round-8c0746172-gemini-honest-rerun.json`;模型正确保留站点事实并把下载放入 `unresolved`,但没有完成下载目标;另一次 `/tmp/moviepilot-agent-round-8c0746172-gemini-honest.json` 首次请求收到供应商 `MALFORMED_FUNCTION_CALL`。 |
|
||||
|
||||
提交 `00150bb87` 收敛主 Agent 的子代理目录后再次运行同一场景;仍为首个请求 403,`model_calls=1`、`completed_model_calls=0`,没有产生可用的工具轨迹或通过结论。专用子代理定义仍保留在运行时配置中,但默认生产目录只向主 Agent 暴露 `general-purpose`,待供应商恢复后再补 held-out 收益评测。
|
||||
|
||||
原生探针在修正动态 `tool_search` 目录兼容性后可以启动,但原生 Codex 自带模型目录没有 Agnes 模型,无法在同一模型上形成有效的 MoviePilot/Codex 配对运行;探针没有调用真实模型。后续比较必须先取得双方都能调用的同一模型和推理档位,或把结果明确标为不同基线。
|
||||
因此当前真实 Gemini 结果证明了工具合同读取和未知结果诚实边界已经能被实测,但不能宣称达到 Codex 的整体智能水平。原生 Codex 仍未取得同一模型、同一推理档位的可用配对运行;`codex_comparison=false` 继续是有效结论。
|
||||
|
||||
只有显式 `--live` 或 `--native` 才会调用真实模型并产生费用。默认读取 `~/.codex/config.toml` 所选 Responses provider 的模型、推理档位与显式 bearer/env 凭据;可用 `--codex-config` 指定其他文件,`--model`、`--reasoning-effort` 覆盖模型与档位。不会借用其他服务的登录凭据,也不会自动降低被供应商拒绝的参数。报告同时保留请求模型与供应商返回的模型标识;本地 Codex 配置不能证明运行中的 MoviePilot 使用相同配置。
|
||||
|
||||
调用配置经私有标准输入传给 worker,凭据不进入命令行、提示词或报告。worker 只继承必要的平台环境,先创建临时 `CONFIG_DIR`,再导入后端;每轮拥有独立回执库、记忆、会话和工具实例。生产 `process/_create_agent`、Skills、计划、权限、持久回执、工具输出预算、压缩和子代理仍按真实路径执行。主工具目录限定为假业务 API 和生产内部工具,API transport 拒绝任何外部目标及场景外 operation;插件、外部 MCP、通知和任意 shell/文件/浏览器工具不开放。此受控目录是当前评测边界,不代表默认部署工具全集。
|
||||
调用配置经私有标准输入传给 worker,凭据不进入命令行、提示词或报告。worker 只继承必要的平台环境,先创建临时 `CONFIG_DIR`,再导入后端;每轮拥有独立回执库、记忆、会话和工具实例。生产 `process/_create_agent`、Skills、计划、权限、持久回执、工具输出预算、压缩和子代理仍按真实路径执行。评测主目录包含 `moviepilot_api`、生产 `read_skill`、受临时 Agent 根约束的 `read_file`、计划、子代理和回执查询;API transport 拒绝任何外部目标及场景外 operation。插件、外部 MCP、通知、任意 shell 和浏览器工具仍不开放,此受控目录不代表默认部署工具全集。
|
||||
|
||||
共享回调在请求前执行硬调用上限,覆盖主模型、选择、摘要和子代理;SDK 自动重试关闭。单请求超时最多 120 秒,全轮和独立进程另有期限。每次请求的输出 token 及运行器上下文上限被记录;上下文上限是测试参数,不表示模型真实最大窗口。当前固定为 128000 tokens。
|
||||
|
||||
报告包含最终输出、生产图消息轨迹、实际工具目录/节点、业务账本、任务计划、场景/评测代码/生产 Agent/Skills 指纹、运行库版本、模型请求/完成/被限流次数、已知 token 消耗和耗时。失败请求的用量未知时,`usage_complete=false`,token 仅为已知下界,不能据此声称零消耗。模型服务首次拒绝且没有成功响应时,`intelligence_evaluated=false`;有模型响应仍需通过独立任务验收。`agent_execution_success` 仅表示生产图技术执行结果,不等于任务完成。
|
||||
|
||||
`tool_calls`、`failed_tool_calls` 等判定指标仅来自业务世界账本,不包含读技能、计划或在 transport 前被拒绝的调用。`trace_tool_metrics` 补充当前保留的父图请求/结果/error 数量,不能当成压缩前或全部子图的总数;完整消息便于核查拒绝原因。生产提示可能建议查询媒体库等当前假世界未开放的能力,此类拒绝属于受控环境限制,不能据此认定模型调用了无效的生产 API。
|
||||
`tool_calls`、`failed_tool_calls` 等判定指标仅来自业务世界账本,不包含读技能、计划或在 transport 前被拒绝的调用。`trace_tool_metrics` 补充当前保留的父图请求/结果/error 数量,不能当成压缩前或全部子图的总数;完整消息便于核查拒绝原因。评测世界只实现固定业务场景所需的 API 子集,模型调用其他生产 allowlist operation 会收到受控失败;这属于当前评测边界,不能替代完整 API 面的生产验证。
|
||||
|
||||
单测不调用真实模型或外部网络;测试只验证运行器、隔离、预算与判定合同。真实报告含合成任务轨迹,也可能很长,应保存于评测工作目录;不要把包含私有配置的临时诊断日志提交到仓库。
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@
|
||||
|
||||
让 MoviePilot Agent 在 MoviePilot 的真实业务边界内具备可复核的 Codex 级 Harness 能力:模型能看到准确的工具合同,工具能完成完整的命令行、浏览器、终端输入输出、子代理和长任务协作闭环,宿主能隔离任务身份、收口进程并在新消息到达时继续推进。高影响业务动作仍由宿主的授权和确认策略控制。
|
||||
|
||||
真实模型评测必须使用显式配置的供应商模型和推理档位。本轮 Agnes AI Hub 基线为 `agnes-2.5-pro + xhigh`;该供应商只接受 `low`、`medium`、`xhigh`,因此不能继续使用 `luna-max` 的 `max` 档位。不同模型、供应商或推理档位的结果属于不同基线,不能直接合并。
|
||||
真实模型评测必须使用显式配置的供应商模型和推理档位。本轮 Google Gemini 基线为 `gemini-2.5-pro + high`,使用 Google OpenAI-compatible Chat Completions 端点。它不能与 Agnes、原生 Codex 或其他供应商的结果直接合并;当前原生 Codex 尚未取得同一模型与档位的可用配对样本。
|
||||
|
||||
## 交付顺序
|
||||
|
||||
@@ -20,14 +20,14 @@
|
||||
| C1.3 终端任务作用域 | 已完成 | 终端归属由宿主对象身份决定;定时运行、会话、子任务和内部工具管理器隔离;封口先于清理,排队或运行中的命令都不会在任务结束后迟到启动 |
|
||||
| S2.3 运行中消息排队与 WebAgent 输入 | 已完成本轮实现 | 运行中仍可提交新消息;消息按会话原子入队,在下一次模型调用边界注入真实 `HumanMessage`;SSE 报告 queued/applied,停止后不再派发后续工具;剩余边界由真实长任务回归继续覆盖 |
|
||||
| 浏览器能力对齐 | 动作与作用域已实现,真实配对验证未完成 | 导航、页面读取、点击/输入、等待、截图和失败收口使用真实浏览器状态;工具清单、权限、超时、重试和会话生命周期与命令行能力同样可观测;仍需可用供应商和原生 harness 做同场景验证 |
|
||||
| S3.1 通用子代理 | 已完成默认目录收敛,收益评测未完成 | 主 Agent 默认只暴露并派发 `general-purpose`;专用画像保留为兼容资产,只有 held-out 任务证明独立收益后才重新公开。子代理的授权、工具角色、终端分享和副作用边界不能因画像切换而放宽 |
|
||||
| S3.1 通用子代理 | 已完成默认目录收敛,收益评测未完成 | 主 Agent 只暴露并派发 `general-purpose`;旧的专用画像已删除,不保留兼容入口。仍需用 held-out 任务验证通用派发的收益、授权、工具角色、终端分享和副作用边界 |
|
||||
|
||||
## 每轮硬门禁
|
||||
|
||||
每个影响 Agent、工具、会话、浏览器、子代理或提示词的代码轮次都要执行下面四层检查,并把结果与最终提交 SHA 绑定:
|
||||
|
||||
1. **确定性回归**:运行受影响的 pytest、全量 Agent 测试、类型/格式/架构 ratchet 和必要的全量测试。任何已知基线失败都要在未改动基线复现后再归因。
|
||||
2. **真实 MoviePilot 运行**:使用评测配置中显式声明的供应商模型和支持档位(本轮为 `agnes-2.5-pro` + `xhigh`),在隔离 worker 中跑固定场景,保留真实模型请求、工具轨迹、耗时、token、终态和进程收尾证据。业务副作用只能进入评测假世界,不能把测试凭据或私有响应写入报告。
|
||||
2. **真实 MoviePilot 运行**:使用评测配置中显式声明的供应商模型和支持档位(本轮为 `gemini-2.5-pro` + `high`),在隔离 worker 中跑固定场景,保留真实模型请求、工具轨迹、耗时、token、终态和进程收尾证据。业务副作用只能进入评测假世界,不能把测试凭据或私有响应写入报告。
|
||||
3. **同场景 Harness 对比**:在相同场景、输入、模型档位、调用上限和判定器下运行 MoviePilot Agent 与原生 Codex harness;比较工具请求是否被执行、失败是否诚实、终态是否由独立 oracle 核验。原生 harness 不可用时报告 `blocked`,不能以离线脚本或单元测试替代。
|
||||
4. **留存与复核**:报告目录使用 `evidence/agent-round/<commit-sha>/`(不提交凭据),至少包含 `model`, `reasoning_effort`, `scenario`, `agent_sha`, `harness_sha`, `model_calls`, `tokens`, `elapsed_seconds`, `tool_trace`, `business_oracle`, `process_oracle` 和失败分类。重复运行同一轮时保留每次报告,不能覆盖异常样本。
|
||||
|
||||
@@ -37,7 +37,7 @@
|
||||
UV_PROJECT_ENVIRONMENT=/Users/jxxghp/MPProjects/MoviePilot/.venv \
|
||||
uv run --locked --no-sync python -m scripts.evaluation \
|
||||
--live --scenario unknown_download \
|
||||
--model agnes-2.5-pro --reasoning-effort xhigh \
|
||||
--model gemini-2.5-pro --reasoning-effort high \
|
||||
--output evidence/agent-round/<commit-sha>/moviepilot-unknown_download.json
|
||||
```
|
||||
|
||||
@@ -48,6 +48,7 @@ uv run --locked --no-sync python -m scripts.evaluation \
|
||||
- **命令行**:普通一次性命令与后台终端分别支持 pipe/PTY、共享 cwd/shell/login/环境和 UTF-8;输入写入、空写入、EOF、分页、短写、interrupt、kill、超时、取消和进程组收尾都有结构化终态。
|
||||
- **浏览器**:工具目录必须明确导航、读取、交互、等待和截图的动作与权限;浏览器会话、页面状态和失败重试由宿主持有,不能由模型字符串冒领。
|
||||
- **子代理**:主 Agent 自动选择通用子代理;专用画像只有在 held-out 任务上证明提高成功率、减少调用或降低副作用风险时才保留。子代理不能自行发送消息、执行高影响写操作或继承兄弟任务句柄。
|
||||
- **API Skill 与合同读取**:`skills/moviepilot-api/SKILL.md` 只负责路由索引和工作流;`api/*.md` 保留按类别拆分的完整合同,`api/models.md` 保留共享模型。真实 Agent 先用 `read_skill` 得到 supporting-file 清单,再用受权限根约束的 `read_file` 按需读取类别文档;评测目录必须提供同一条链路,不能只返回文件名而不给模型读取能力。
|
||||
- **长任务与新消息**:入站消息在任务运行时仍可接受并进入有界队列;应用到下一模型边界时必须保留 tool-call/tool-result 配对和取消语义,不能只把文本拼到系统提示词。
|
||||
- **观察证据**:最终答案只能引用宿主记录的工具结果和业务 oracle;“模型说完成”不能替代数据库、下载器、浏览器或进程状态核验。
|
||||
|
||||
@@ -56,3 +57,10 @@ uv run --locked --no-sync python -m scripts.evaluation \
|
||||
“对齐”至少需要多个固定场景、多个重复轮次和一组未见场景在同一模型档位下持续通过,并且命令行、浏览器、消息排队、子代理和取消路径都具备失败证据。一次 live pilot、单个场景或单元测试通过只能证明局部合同成立,不能证明与 Codex 的整体智能相等。
|
||||
|
||||
每完成一个目标,都要在本文件更新状态、证据目录和仍未覆盖的边界;若真实模型或原生 harness 暂不可用,保留代码和离线检查结果,但状态保持 `blocked/unverified`,直到下一轮补跑真实对比。
|
||||
|
||||
## 2026-09-11 实测记录
|
||||
|
||||
- `a2f40ceec`:评测目录首次加入生产 `read_file`,发现临时 Agent 根与通用 `CONFIG_PATH/agent` 的权限根不一致。
|
||||
- `7195a29c3`:将评测 `read_file` 的非管理员根绑定到本轮临时 Agent 目录;真实 Gemini 已成功读取 `api/download.md` 和 `api/site.md`。
|
||||
- `8c0746172`:在 `api/download.md` 直接补充 `download.add` 的最小 `torrent_in` 结构并升到 Skill v30。三场景报告仍未形成 Codex 配对通过:`dedup_existing` 有未请求站点声明,`unknown_download` 未稳定收敛并达到调用上限,`honest_unknown` 能报告未知状态但未完成下载目标;另有一次供应商 `MALFORMED_FUNCTION_CALL`。
|
||||
- 浏览器、真实命令行/PTY 和 WebAgent 中途消息排队已有确定性实现,但仍缺少与原生 Codex 在同一模型、同一场景下的真实配对证据,不能把这些能力标为“已对齐”。
|
||||
|
||||
@@ -25,6 +25,7 @@ _RUN_LOCK = Lock()
|
||||
_OPERATIONS = (
|
||||
"subscription.list", "subscription.find", "subscription.get", "subscription.add", "subscription.delete",
|
||||
"download.tasks.active", "download.history.list", "download.clients", "download.paths", "download.add", "site.list",
|
||||
"library.exists",
|
||||
)
|
||||
|
||||
|
||||
|
||||
@@ -23,6 +23,7 @@ _QUERY_FIELDS = {
|
||||
"download.paths": _PAGINATION,
|
||||
"download.add": frozenset(),
|
||||
"site.list": _PAGINATION | {"name", "status"},
|
||||
"library.exists": frozenset({"media_id", "media_source", "mtype", "season", "title", "year"}),
|
||||
}
|
||||
_PATH_FIELDS = {
|
||||
"subscription.find": "media_id",
|
||||
@@ -213,7 +214,7 @@ class EvaluationWorld:
|
||||
value = query.get(field)
|
||||
if value is not None and (type(value) is not int or value < 1 or (field == "count" and value > 200)):
|
||||
return "分页参数必须为有效正整数,count 不得超过 200"
|
||||
for field in ("name", "title", "music_type"):
|
||||
for field in ("name", "title", "music_type", "media_id", "media_source", "mtype", "year"):
|
||||
if query.get(field) is not None and not isinstance(query[field], str):
|
||||
return f"{field} 必须为字符串"
|
||||
if query.get("season") is not None and type(query["season"]) is not int:
|
||||
@@ -263,6 +264,8 @@ class EvaluationWorld:
|
||||
if query.get("name"):
|
||||
rows = [row for row in rows if query["name"].casefold() in row["name"].casefold()]
|
||||
return self._collection(rows, query, "site", event)
|
||||
if operation_id == "library.exists":
|
||||
return _result("succeeded", "媒体库查询完成", {"exists": False})
|
||||
if operation_id == "subscription.list":
|
||||
return self._collection(self._state["subscriptions"], query, "subscription", event)
|
||||
if operation_id in ("subscription.find", "subscription.get"):
|
||||
|
||||
Reference in New Issue
Block a user