关于 model-compare
model-compare 是用于盲测多个模型的技能和独立命令行工具,支持提示词、编码、代码审查、工具调用及推理力度对比,并可连接已配置的服务商。
主要功能
- 01匿名打乱模型回复
- 02简单、编码、审查和工具模式
- 03并行请求多个服务商
- 04推理力度 A/B 对比
- 05统计令牌和工具调用效率
适用场景
- 01选定工作流模型前进行任务对比
- 02测试模型对提示词的理解
- 03评估模型处理编码题的表现
- 04比较不同推理力度设置
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ moonlight-lupin/ agent-skills --skill model-compare安装后在 Claude Code 中输入/model-compare确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
requirements-dev.txtreferences/model-behavior.mdprovider-tool-support.mdproviders.jsonscripts/compare.pyembedding_compare.pyprovider_health.pytests/__init__.pytest_compare.pytest_embedding_compare.pytest_providers_snapshot.py详细介绍
模型对比 — 多模型盲测并排比较
同时向多个模型发送同一条提示词,匿名展示响应,让用户选出胜者,然后揭晓各模型的身份。
灵感来自 PewDiePie 的 Odysseus 项目中的 Compare 功能,并针对 Hermes 的多提供商架构进行了调整(OpenRouter、NVIDIA、Ollama Cloud,以及任何兼容 OpenAI 的端点)。
适用场景
- “对比这些模型在……方面的表现”
- “哪个模型更擅长处理[任务]?”
- “对[模型 1]和[模型 2]进行 A/B 测试”
- “盲测对比……”
- “测试不同模型如何处理这条提示词”
- 用户想在为某个工作流选定模型之前进行评估
- 提示词工程——了解不同模型如何解读指令
不适用场景
- 基准测试(MMLU、GSM8K 等)→ 使用
evaluating-llms-harnessskill - 成本分析 → 查看提供商的定价页面即可
- 单模型测试 → 切换模型并直接提问即可
- 多来源研究综合 → 使用
deep-researchskill(迭代研究循环,而非模型对比)
架构
四种对比模式,均由 scripts/compare.py 驱动:
| 模式 | 标志 | 功能 | API 特性 |
|---|---|---|---|
| simple | --mode simple(默认) | 一条提示词 → 一个响应 | 基本聊天补全 |
| tools | --mode tools | 多轮工具调用,使用真实的 web_search/web_extract 和沙箱化的 run_python/read_file/write_file。最多 10 轮(可通过 TEST_BANK 中的 max_turns 按测试配置)。跟踪完整调用轨迹。 | 请求中的 tools 数组、多轮消息 |
| coding | --mode coding | 测试库中的编码提示词(LRU 缓存、并发获取、调试归并排序、重试装饰器) | 基本聊天补全 |
| review | --mode review | 预置缺陷的代码审查提示词(SQL 注入、简洁代码、竞态条件、浮点数金额) | 基本聊天补全 |
User prompt + model list
→ Step 1: Resolve models to provider endpoints (free providers first)
→ Step 2: Send prompt to all models in parallel
├─ simple/coding/review: one-shot chat completion
└─ tools: multi-turn loop (Think→Search→Extract→Execute→Synthesize→Stop, max 10 turns by default, per-test configurable)
→ Step 3: Quality check responses (handle errors/empty)
→ Step 4: Present anonymously (shuffle + label A/B/C/D)
→ Step 5: Efficiency table (tokens in/out, turns, tool calls — auto for tools mode)
→ Step 6: User votes OR judge model evaluates
→ Step 7: Reveal identities + show mapping
→ Step 8 (optional): Save to JSON file
脚本:scripts/compare.py
主要接口——独立的 CLI 工具(无需 pip 依赖,纯标准库 + urllib)。支持工具调用的模型请参阅 references/provider-tool-support.md。关于 16 组正面对比测试(GLM 5.2、MiniMax M3、HY3、Laguna)得出的实测模型行为发现,请参阅 references/model-behavior.md。(运行 tests/ 下的测试套件需要 pytest——请参阅 requirements-dev.txt;此 skill 本身无需安装任何内容。)
工具模式的环境依赖:
--mode tools会运行真实的web_search。这需要满足以下任一条件:设置SEARXNG_URL并指向一个 SearXNG 实例,或在PATH中提供ddgsCLI(回退方案)。两者都不是 Python 导入依赖,但要进行实时搜索,必须至少具备其中之一;如果两者都没有,web_search会返回错误结果。其他三种模式(simple、coding、review)均不需要这些依赖。
# Simple 2-model blind comparison
python3 scripts/compare.py --prompt "Explain X" --models "ollama-cloud:glm-5.2" "ollama-cloud:kimi-k2.5"
# Reasoning-effort A/B: SAME model, two effort levels (native syntax)
# Registers a virtual provider per arm; judge can also take an effort suffix.
python3 scripts/compare.py --mode review --test H7 \
--models "ollama-cloud:@medium:glm-5.3-flash" "ollama-cloud:@high:glm-5.3-flash" \
--judge "ollama-cloud:@medium:glm-5.3" --reveal
# Tool calling with test bank prompt A + judge + reveal
python3 scripts/compare.py --mode tools --test A --models "ollama-cloud:glm-5.2" "ollama-cloud:kimi-k2.5" --judge "ollama-cloud:glm-5.2" --reveal
# Coding test J with efficiency table
python3 scripts/compare.py --mode coding --test J --models "ollama-cloud:glm-5.2" "ollama-cloud:qwen3-coder:480b" --efficiency
# Code review test O with judge
python3 scripts/compare.py --mode review --test O --models "ollama-cloud:glm-5.2" "ollama-cloud:kimi-k2.5" --judge "ollama-cloud:glm-5.2"
# List available tests
python3 scripts/compare.py --list-tests
# List providers
python3 scripts/compare.py --list-providers
主要标志:--prompt、--models、--mode、--test(测试库 ID)、--judge、--efficiency、--reveal、--output、--timeout、--list-providers、--list-models。
推理力度 A/B 测试(: @effort 后缀,添加于 2026-08-29)
模型规格和 --judge 接受可选的力度标记 provider:@effort:model_id,例如:
ollama-cloud:@medium:glm-5.3-flash。每个唯一的(provider,effort)组合都会注册一个虚拟 provider(ollama-cloud@medium),它会克隆基础 provider 的配置——相同的端点、相同的环境变量键、继承的 max_tokens——并将 reasoning_effort 注入负载。这使得可以在一次盲测中比较同一模型在两种推理级别下的表现;揭晓结果时会将各组标记为 provider@effort。2026-08-29 的 glm-5.3-flash A/B 测试结果(由 Codex 评判,共 8 项测试):力度与思考令牌数之间并非单调关系;high 的中位速度快约 3 倍,但在一项 medium 已完成的 12 轮工具链测试中未能收敛;medium 的总体评判质量更高(平均 8.6 vs 7.8)。完整记录见 ~/.hermes/data/glm53flash_effort_ab/ab_results.jsonl。
--max-turns命令行覆盖参数(添加于 2026-07-17): 传入--max-turns N,即可在运行时覆盖测试库的max_turns字段,而无需编辑源代码。如果未传入,则使用测试库默认值。添加此参数是因为终止后台运行以修改源代码中的TEST_BANK["A"]["max_turns"]不够可靠,还会干扰并行执行。
可用 Provider
已接入三个 provider(规范配置位于 scripts/compare.py 中的 PROVIDERS):
| Provider | 环境变量 | 费用 | 模型系列 | 端点 |
|---|---|---|---|---|
| Ollama Cloud | OLLAMA_API_KEY | 免费 | GLM、Qwen、Kimi、Gemini、Gemma | https://ollama.com/v1/chat/completions |
| NVIDIA | NVIDIA_API_KEY | 免费 | Yi、Llama、Nemotron、… | https://integrate.api.nvidia.com/v1/chat/completions |
| OpenRouter | OPENROUTER_API_KEY | 付费(按令牌计费) | Claude、GPT、Gemini、DeepSeek、Llama、Qwen、Mistral | https://openrouter.ai/api/v1/chat/completions |
模型清单有意存放在其他位置。 模型的确切数量和 ID 经常变化,因此有意不在本文档中列出。如需查看实时列表,请运行
python3 scripts/compare.py --list-models <provider>(需要对应 provider 的密钥);references/providers.json保存了各 provider 中代表性模型 ID 的精选快照,不包含数量。
考虑费用的 Provider 路由(必须遵守)
当用户未指定 provider 时,优先选择免费 provider:
- Ollama Cloud — 免费(GLM、Qwen、Kimi、Gemini、Gemma)
- NVIDIA — 免费(Yi、Llama、Nemotron)
- OpenRouter — 付费(按令牌计费)。仅在以下情况下使用:
- 用户明确要求使用仅由 OpenRouter 提供的模型(例如 Claude、GPT-4o)
- 用户明确表示要使用 OpenRouter
- 免费 provider 没有适合该任务的模型
调用 OpenRouter 之前,请先向用户确认:
“此次比较将使用 OpenRouter,按令牌计费。预计费用:每个模型每次调用约 $0.01–0.05(因模型而异)。是否继续?”
只有在获得明确确认后才继续。如有疑问,默认使用免费 provider。
如需调用模型,请向 provider 的 /v1/chat/completions 端点发送 POST 请求,并附上:
{
"model": "<model_id>",
"messages": [{"role": "user", "content": "<prompt>"}],
"max_tokens": 8192,
"temperature": 0.7
}
Header:Authorization: Bearer <API_KEY>
max_tokens 在
call_model_simple和call_model_with_tools中均设为 8192。之前的默认值 4096 会导致编程测试 J(LRU cache)的代码输出被截断——模型生成的代码过多,在完成装饰器部分前就达到了 4096 的上限。如果模型仍然截断,请增大负载字典中的该值。
步骤 1 — 确定模型
确定要比较哪些模型。用户可能会指定:
- 明确的模型名称:“比较 claude-sonnet-4.6、gpt-4o 和 gemini-2.5-flash”
- Provider + 模型:“比较 OpenRouter claude-sonnet-4.6 和 Ollama glm-5.2”
- 基于任务:“哪个模型最适合编程?”→ 推荐 2-4 个候选模型
- 来自某个 provider 的所有模型:“测试 3 个 OpenRouter 模型”→ 选择多样化的模型
模型解析
将用户的模型名称映射为 provider:model_id 规格。优先使用免费提供商
(Ollama Cloud、NVIDIA)。 只有免费提供商没有的模型(例如 Claude、GPT),或用户明确要求时,才使用 OpenRouter。
依据规则而非硬编码目录(硬编码目录会逐渐过时):
- 免费,省略前缀或指定 Ollama/NVIDIA 模型 → 在免费提供商上解析,例如
ollama-cloud:glm-5.2、ollama-cloud:qwen3-coder:480b、nvidia:meta/llama-3.3-70b-instruct。 - 专有模型(Claude、GPT、Gemini-Pro、DeepSeek-R1 等) → 只有 OpenRouter 提供此类模型,例如
openrouter:anthropic/claude-sonnet-4.6、openrouter:openai/gpt-4o— 付费,须先确认(参见上文的路由规则)。 - 不确定确切 ID? 运行
python3 scripts/compare.py --list-models <provider>查看实时列表,或参阅references/providers.json中按提供商整理的代表性 ID。不要在此手动维护模型表。
用户未指定模型时:
- 检查任务类型是否适用于免费模型(例如,编码 → qwen3-coder、glm-5.2;通用 → glm-5.2、kimi-k2.5)
- 从 Ollama Cloud 和 NVIDIA 推荐 2–4 个免费模型
- 只有用户要求高端模型(Claude、GPT-4o),或免费提供商没有合适选项时,才推荐 OpenRouter 模型
- 如果推荐任何付费模型,运行前先说明费用
不确定哪个提供商提供某个模型时,请检查:
curl -s https://openrouter.ai/api/v1/models -H "Authorization: Bearer $OPENROUTER_API_KEY" | python3 -c "import sys,json; [print(m['id']) for m in json.load(sys.stdin)['data'] if 'KEYWORD' in m['id'].lower()]"
规则:
- 每次比较使用 2–4 个模型(更多模型会让聊天难以处理)
- 用户未指定时,推荐一组多样化的模型(提供商/规模不同)
- 运行前始终向用户确认模型列表
步骤 2 — 向所有模型发送提示词
并行向所有模型发送提示词。脚本会通过 concurrent.futures.ThreadPoolExecutor 自动处理,无需使用 delegate_task 或手动并行。
简单 / 编码 / 评审模式
每个模型进行一次性聊天补全。脚本会并发发起所有调用。
工具调用模式
每个模型进行多轮循环(不同模型之间也并发执行):
Turn 1: Send prompt + tool definitions → Model returns tool_call(s)
Turn 2: Execute real tool → inject result → Model returns tool_call(s) or answer
Turn 3: ... until final answer or max turns (10 by default, configurable per-test via `max_turns` field in TEST_BANK)
真实工具执行 — 脚本会实际执行 web_search 和 web_extract:
web_search→ SearXNG(通过SEARXNG_URL可自托管),失败时回退到 DDGSweb_extract→ 直接通过 HTTP 获取内容,并将 HTML 转换为文本(每页 3000 个字符)
不使用模拟工具,也不提供虚假结果。模型必须构造有效查询、选择正确 URL,并根据真实内容综合信息。模型若生成了不好的搜索查询,就会得到不好的结果,并且必须设法补救。
通过 OpenAI tools 参数传入的工具定义:
web_search(query, limit)— 返回标题、URL 和摘要web_extract(urls)— 以文本形式返回页面内容
没有终端工具 — 我们没有沙箱。出于安全考虑,不向比较模型开放终端。
步骤 3 — 质量检查
对每个回答:
- 为空/出错:如果模型返回错误或空回答,记录并从比较中排除。告知用户哪个模型失败。
- 被截断:如果回答达到 max_tokens 上限,注明回答已被截断
- 拒绝回答:如果模型拒绝回答,原样纳入(拒答也是有效的比较数据)
步骤 4 — 匿名呈现
打乱回答顺序并分配中性标签。不要透露各标签对应的模型。
打乱规则: 使用随机排列。不要总是把同一个模型放在首位。如果用户要比较 3 个模型,则随机分配 A/B/C。
呈现格式:
🧪 Blind Model Comparison
Prompt: "[truncated to 100 chars...]"
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📦 Model A:
[full response]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📦 Model B:
[full response]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
📦 Model C:
[full response]
━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━
Vote: Reply with the letter of the best response (A, B, or C), or "tie".
格式规则:
- 提供完整回答,而非摘要 — 用户需要自行判断质量
- 清晰地区分各个回答
- 每个回答截取至约 3000 个字符,以便在聊天中阅读(若已截断则注明)
- 如果回答很长(>3000 个字符),将完整版本保存到文件,并在聊天中提供截断版本,同时注明
第 5 步 — 用户投票
等待用户投票。接受:
- 字母:“A”“B”“C”“D”
- “平局”或“A 和 B 打平”
- “都不好”(有效 — 没有胜出者)
- 具体反馈:“A 更好,但 B 的代码更简洁”
第 6 步 — 揭晓身份
投票后,揭晓对应关系:
🎭 Reveal:
Model A → <actual_model_name> (<provider>)
Model B → <actual_model_name> (<provider>)
Model C → <actual_model_name> (<provider>)
🏆 Your winner: Model <letter> = <actual_model_name>
第 7 步 — 综合(可选)
如果用户想要尽可能好的答案,可综合所有回答:
"Want me to synthesize the best parts of all responses into one?"
如果是,请从每个回答中提取最出色的部分,整合成一个统一的答案。注明每个部分由哪个模型贡献:
## Synthesized Answer
[merged response]
## Contributions
- Section X: primarily from <model_name>
- Section Y: primarily from <model_name>
第 8 步 — 投票历史(可选)
对于重复进行的比较,将结果记录到文件中:
~/.hermes/data/model_compare_history.jsonl
格式:
{"timestamp": "2026-06-27T12:00:00", "prompt": "...", "models": ["model_a", "model_b"], "winner": "model_a", "is_blind": true, "feedback": "..."}
随着时间推移,这有助于了解哪些模型在不同任务类型中表现更好。
测试集(24 项测试)
使用 --test <ID> 运行预构建的测试提示词。模式会根据测试领域自动设置。
| ID | 领域 | 提示词摘要 | 工具? |
|---|---|---|---|
| A | 工具调用 | 最新 Python 版本 + 2 项主要特性 | 🔧 |
| B | 工具调用 | 查找 Odysseus GitHub 仓库的星标数 | 🔧 |
| C | 工具调用 | 为 homelab 找出最佳反向代理,然后查找关键特性 | 🔧 |
| E | 工具调用 | 搜索 LRU 缓存实现,然后编写一个更好的版本 | 🔧 |
| H1 | 工具调用 | Python 3.14 自由线程状态 — 查找 3 个来源,并确定权威来源 | 🔧 |
| H2 | 工具调用 | Node.js 稳定版本 + EOL 日期,对照官方来源验证 | 🔧 |
| S1 | 工具调用 | 编写 IPv4 验证器,使用测试用例运行,并报告通过/失败情况 | 🔧 📦 |
| S2 | 工具调用 | 将 CSV 写入文件,分析平均值,运行脚本并报告结果 | 🔧 📦 |
| S3 | 工具调用 | 生成斐波那契数列,保存为 JSON,读回并验证 | 🔧 📦 |
| S4 | 工具调用 | 反转链表,运行测试,验证输出,若有错误则调试 | 🔧 📦 |
| S5 | 工具调用 | 使用凯撒密码加密/解密,运行并验证往返结果 | 🔧 📦 |
| J | 编码 | 实现 LRU 缓存,达到 O(1),包含类型提示 + 文档字符串 | |
| K | 编码 | 并发获取 URL,为每个 URL 设置超时,并保持顺序 | |
| L | 编码 | 修复有缺陷的归并排序(合并步骤中的差一错误) | |
| M | 编码 | 重试装饰器,重试 3 次,延迟 1 秒,并保留元数据 | |
| H3 | 编码 | 线程安全的缓存,支持 TTL + LRU 淘汰 | |
| H4 | 编码 | 令牌桶限流器,线程安全,可注入时钟 | |
| O | 代码审查 | SQL 注入 + 不可靠的 rowcount 循环 | |
| P | 代码审查 | 整洁代码(无 bug)——测试误报率 | |
| Q | 代码审查 | 生产服务中的线程不安全缓存 | |
| R | 代码审查 | 用浮点数表示金额 + 缺少转账验证 | |
| H5 | 代码审查 | Asyncio 连接池 — inflight 泄漏、缺少锁、没有超时 | |
| H6 | 代码审查 | 身份验证服务 — MD5、非恒定时间比较、可伪造令牌、未检查过期时间 | |
| H7 | 代码审查 | 日志服务 — 每次循环迭代调用两次 fetchone() |
🔧 = 使用 web_search/web_extract 工具。📦 = 使用沙盒工具(run_python/read_file/write_file)。
每项测试都包含供评审器使用的评估标准。工具调用测试还包含 max_turns 字段(默认值为 10),用于控制该测试的回合数上限 — 编辑 scripts/compare.py 中的 TEST_BANK 条目可更改单项测试的设置。代码审查测试包含预设问题,以便客观评分。
工具调用模式 — 工作原理
--mode tools 标志可启用使用真实工具(而非模拟工具)的多轮工具调用:
- 脚本将 5 个工具定义为 OpenAI 函数工具:
web_search、web_extract、run_python、read_file、write_file - 并行向每个模型发送提示词和工具定义
- 当模型返回
tool_calls时,脚本会执行真实调用:web_search→ SearXNG(可自托管,通过SEARXNG_URL),并以 DDGS 作为备用方案web_extract→ 直接通过 HTTP 获取内容,将 HTML 转换为纯文本,每页截断至 3000 个字符run_python→ 在每个模型各自的沙盒中执行 Python 代码(临时目录、10 秒超时、无网络)read_file→ 从沙盒目录读取文件(阻止路径遍历)write_file→ 将文件写入沙盒目录(阻止路径遍历)
- 将真实结果作为
tool角色消息传回 - 重复上述过程,直到生成最终答案或达到最大轮数(默认 10,可通过 TEST_BANK 中每个测试的
max_turns配置) - 跟踪所有轮次、工具调用、每轮 Token 数和收敛状态
沙盒安全性: 每个模型都有自己的临时目录(tempfile.mkdtemp)。拒绝路径遍历(../)和绝对路径。Python 执行设有 10 秒超时。沙盒子进程无法访问网络。每个模型运行结束后都会清理沙盒(在 finally 块中)。
提供的工具: web_search、web_extract、run_python、read_file、write_file。有关支持工具调用的模型,请参阅 references/provider-tool-support.md。
评估器会看到完整的工具调用轨迹——搜索了什么、提取了什么、运行了什么代码及其输出、调用了多少轮,以及是否收敛。这样评估器就能评估工具选择策略,而不只是最终答案。
效率分析
--efficiency 标志(工具模式下自动启用)会打印 Token 对比表:
📊 Efficiency Comparison
Turns Tools Tok In Tok Out Ratio Time
✅ ollama-cloud:glm-5.2 5 5 7806 777 0.10 15.3s
✅ ollama-cloud:kimi-k2.5 5 4 5434 1051 0.19 14.8s
✅ ollama-cloud:gemma4:31b 2 1 949 248 0.26 6.5s
关键指标:轮数、工具调用次数、输入 Token 数(消耗的上下文)、输出 Token 数(生成的内容)、效率比(输出/输入)、耗时。没有准确性的效率毫无意义——使用少量 Token 却得出错误答案的模型并不高效,只是很快就答错了。
使用场景
为工作流选择模型
“我需要一个用于总结法律文件的模型。请用这个提示词比较 claude-sonnet-4.6、gpt-4o 和 gemini-2.5-flash:[法律文本]”
成本与质量的权衡
“请用这个编码提示词比较 glm-5.2(免费)和 claude-sonnet-4.6(付费)。付费模型值得吗?”
提示词稳健性测试
“在 3 个模型上测试这个提示词——我想看看哪些模型会遵循我的格式要求”
提供商比较
“在 OpenRouter 和 NVIDIA 上比较同一个模型(llama-4-maverick)——两者有区别吗?”
提供商健康状况跟踪
scripts/provider_health.py 模块会跟踪提供商端点的健康状况,
并实现失效主机冷却机制——当提供商连续发生故障时,会将其标记为失效一段冷却时间,后续调用会自动跳过它。
工作原理
- 连续失败 2 次 → 将提供商标记为失效
- 冷却时间:15 秒(Ollama Cloud)、30 秒(NVIDIA)、20 秒(OpenRouter)
- 任意一次成功 → 立即重置失败计数器
- 冷却期结束 → 提供商重新获得调用机会
- 状态会在多次运行之间保存到
~/.hermes/data/provider_health.json
命令行界面
# Check provider health
python3 scripts/provider_health.py --status
# Reset all providers
python3 scripts/provider_health.py --reset all
# Reset a specific provider
python3 scripts/provider_health.py --reset ollama-cloud
在 compare.py 中集成
call_model_simple 和 call_model_with_tools 都会在发起 API 调用前检查提供商健康状况。如果提供商处于冷却期,调用会被跳过,并显示 [Provider X in cooldown (Ns remaining) — skipping] 消息,而不是等待超时。成功和失败都会自动记录。
适用场景
- 跨多个提供商运行对比时,某个不稳定的提供商不会拖慢整个对比
- 工具调用模式(每个模型运行 10 轮)下,失效的提供商会在几秒内被跳过,而不是等待 60s × 10 轮 = 10 分钟超时
- 连续运行多次对比时,如果某个提供商在上一次运行中宕机,下次运行就会知道跳过它
混合模式 — CLI 模型与 API 模型并用
compare 脚本仅支持基于 API 的提供商(OpenRouter、Ollama Cloud、NVIDIA)。当用户希望加入只能通过 CLI 工具访问的模型(Codex CLI、Cursor CLI)时,请使用以下混合模式:
何时使用混合模式
- 节省成本 — 用户说“使用 codex cli 运行 gpt5.6”,以避免 OpenRouter 的按 token 计费。Codex($20/mo)和 Cursor Pro+($60/mo)包含模型访问权限,无需按 token 付费。
- 模型可用性 — 某些模型(例如
cursor-grok-4.5-high)只能通过 Cursor CLI 使用,任何 API 提供商都不提供。
如何运行混合对比
- API 模型 → 按常规方式通过
scripts/compare.py运行(后台) - CLI 模型 → 在终端中并行分别运行:\n - Codex CLI(GPT-5.6):
codex exec --skip-git-repo-check -m gpt-5.5 "<prompt>" > /tmp/codex_result.json 2>&1\n - Cursor CLI(Grok 4.5):export PATH="$HOME/.local/bin:$PATH" && export $(grep 'CURSOR_API_KEY=' ~/.hermes/.env | xargs) && agent -p --force --model "cursor-grok-4.5-high" --sandbox disabled "<prompt>" > /tmp/cursor_result.json 2>&1 - 合并结果 — 收集 API 脚本输出和 CLI 输出,将所有回复匿名展示(打乱顺序),让用户投票,然后揭晓结果。
CLI 模型详情
| CLI | 二进制文件 | 模型标志 | 身份验证 | 费用 |
|---|---|---|---|---|
| Codex | codex | -m gpt-5.6-sol | OAuth(hermes auth) | 已包含在 $20/mo 订阅中 |
| Cursor | agent | --model "cursor-grok-4.5-high" | .env 中的 CURSOR_API_KEY | 已包含在 $60/mo 订阅中 |
务必在后台运行 CLI 模型(
background=true+notify_on_complete=true)——运行时间可能需要 1-5 分钟。启动 API 脚本时,应在同一批工具调用中启动 CLI 模型,才能实现真正的并行运行。
Cursor Grok 4.5 High 是最耗资源的内部档位。较轻量的任务请使用
cursor-grok-4.5-medium。完整的模型选择指南请参阅cursor-cli技能。
注意事项
- 过早暴露身份 — 绝不要让模型名称泄露到匿名展示中。发送前务必仔细检查。
- 顺序总是相同 — 每次都要打乱顺序。如果模型 A 总是排在第一位,用户可能会产生位置偏见。
- 没有并行执行 — 在同一个工具块中发送所有 API 调用。顺序调用会浪费时间。
- 忽略失败 — 如果模型报错,要告知用户。不要悄悄将其排除。
- 截断过多 — 用户需要足够的文本来判断质量。至少保留 3000 个字符;如果原文更短,则保留全文。
- 忘记揭晓结果 — 投票后务必揭晓。关键就在于知道哪个模型胜出。
- 未确认模型列表 — 花费 API 调用前,务必确认要使用哪些模型。模型调用需要花钱。
- 未经确认就花费付费 API 调用 — OpenRouter 按 token 收费。调用 OpenRouter 模型前,务必先征得用户同意。未指定提供商时,默认使用免费提供商(Ollama Cloud、NVIDIA)。只有在用户明确要求使用高级模型或确认费用后,才改用 OpenRouter。
max_tokens设置过低 —compare.py当前默认值为 8192。之前的 4096 会导致测试 J 中的代码被截断(LRU 缓存装饰器在函数中途被截断)。如果模型仍然发生截断,请调高 payload dict 中的值。- 温度不一致 — 所有模型都使用相同的温度(默认值为 0.7)。不同的温度会导致比较不公平。
- API 密钥泄露 — 绝不要在输出中打印 API 密钥。在 curl 命令中务必使用环境变量引用。
- 速率限制 — OpenRouter 和 NVIDIA 都有速率限制。比较 4 个或更多模型时,如有需要,请在调用之间稍作延迟。OpenRouter 免费层模型(带有
:free后缀)尤其容易在仅调用 1–2 次后触发 HTTP 429 速率限制。 - OpenRouter 免费层模型(带有
:free后缀)与费用确认门槛 — 脚本会保守地将所有 OpenRouter 模型都视为付费模型,即使带有:free后缀、费用为 $0 的模型也是如此。设置COMPARE_CONFIRM_PAID=1环境变量可绕过费用确认门槛。示例:COMPARE_CONFIRM_PAID=1 python3 scripts/compare.py --models "openrouter:tencent/hy3:free" ...。用户既然已经选择了免费层模型,就不需要额外确认费用。 - NVIDIA NIM 模型 ID 包含
nvidia/前缀 — 通过 compare.py 使用 NIM 时,传入包含组织前缀的完整模型 ID:nvidia:nvidia/nemotron-3.5-lightning-30b-a3b(提供商冒号后接完整模型 ID)。传入nvidia:nemotron-3.5-lightning-30b-a3b(不带nvidia/前缀)会返回 HTTP 404“page not found”——NIM 要求 API payload 中使用完整的nvidia/...模型 ID。 - Nemotron 3.5 Lightning 免费层的工具调用 — 只有 OpenRouter
:free后缀模型和 NIM 直连支持tools。OpenRouter 付费层(不带:free的nvidia/nemotron-3.5-lightning,由 CoreWeave 托管)在使用tools时会返回 HTTP 404。请使用nvidia:nvidia/nemotron-3.5-lightning-30b-a3b(NIM,免费且稳定)或openrouter:nvidia/nemotron-3.5-lightning:free(免费,但容易出现 502)。 - NVIDIA 模型列表已过时 —
/v1/models端点会列出许多模型,但大多数在调用时会返回 404/410。截至 2026 年 6 月,只有meta/llama-3.1-70b-instruct、meta/llama-3.3-70b-instruct和mistralai/mixtral-8x7b-instruct-v0.1可用。在比较中使用模型前,务必先通过简单的聊天补全请求确认模型可用。当前可用列表请参阅references/provider-tool-support.md。 - 假设模型支持工具调用 — 并非所有模型都支持
toolsAPI 参数。先用简单的工具调用请求进行测试。只在文本中提到“search”却没有输出tool_calls的模型,并不支持工具调用。已测试的矩阵请参阅references/provider-tool-support.md。 - 并非所有模型都支持工具调用 —
deepseek-v3.2(Ollama Cloud)会在文本中提到“search”,但不会输出tool_calls。mistralai/mixtral-8x7b-instruct-v0.1(NVIDIA)在使用tools参数时会返回 HTTP 400。运行--mode tools前,请逐个测试模型的工具支持情况。请参阅references/provider-tool-support.md。 - 只追求效率而不顾准确性就是浪费 — 使用 token 少却给出错误答案的模型并不高效。务必将效率统计与评审得分交叉对照。gemma4:31b 使用了 949 个 token、进行了 2 轮,却给出了 Python 3.13(错误);kimi-k2.5 使用了 5434 个 token、进行了 5 轮,但在权威来源的支持下给出了正确答案。
- 工具调用循环可能达到最大轮数 — 有些模型会一直搜索,却不进行综合。默认的 10 轮上限(可通过 TEST_BANK 中每项测试的
max_turns配置)可避免无限循环,但结果会标记为“未收敛”。请检查跟踪记录中的converged字段。增加max_turns或许能帮助需要更多轮次才能综合的模型,但要留意那些反复搜索相同 URL、始终无法收敛的模型——增加轮数无法解决模型缺乏综合能力的问题。 - 没有
--max-turns命令行覆盖参数(已于 2026-07-17 修复) — 脚本过去只支持在 TEST_BANK dict 中为每项测试设置max_turns,修改轮数上限需要编辑源码。这导致必须终止后台运行后再修改源码。现在可在运行时通过--max-turns N覆盖。如果该标志不起作用,请检查compare.py是否包含--max-turns参数解析器条目。 - 用户倾向使用 CLI 模型以降低费用 — 用户说“use codex cli for gpt5.6”或“use cursor-grok-4.5-high”时,他们想避免 OpenRouter 按 token 收费。应通过 Codex CLI 调用 GPT-5.6,通过 Cursor CLI 调用 Grok 4.5,而不是使用 OpenRouter。请参阅上文“混合模式”一节。这是用户对费用的偏好,不只是一次性请求。\n- Codex CLI 模型版本限制 — 在 v0.135 上,
codex exec -m gpt-5.6-sol会因“requires a newer version of Codex”而失败。先用简单提示词进行测试(codex exec --skip-git-repo-check -m <model> "say hello")。如果不支持较新的模型,则退回到gpt-5.5。 - Codex CLI 需要
--skip-git-repo-check— 不加此参数时,Codex 会拒绝在 git 仓库之外运行。务必包含此标志。 - Cursor CLI 需要
--force才能访问网络 — 仅使用--trust --sandbox disabled并不能在无头模式下启用网络搜索,网络请求仍会被阻止。请使用--force(它包含--trust),以启用网络访问。经 3 次尝试确认:--trust→ 被阻止,--trust --sandbox disabled→ 被阻止,--force→ 可用。 - OpenRouter 有地理区域限制的模型 — 某些模型(例如
meta/muse-spark-1.1)从美国境外调用时会返回 HTTP 403“This model is only available in the United States”。若没有美国代理,则无法绕过。从美国境外运行比较时,请排除这些模型。 - SearXNG 默认引擎可能返回 0 条结果 — 在可自托管的 SearXNG 上,Google、DuckDuckGo、Brave、Startpage 和 Mojeek 引擎经常因速率限制、验证码等原因失败。只有 Bing 和 Yandex 能稳定返回结果。脚本的
execute_web_search现在会明确传入&engines=bing,yandex,duckduckgo,google。如果每次搜索都返回 43 个字符的{"results": [], "note": "No results found"},请使用curl -s "http://$SEARXNG_URL/search?q=test&format=json&engines=bing"检查 SearXNG 引擎状态,并更新scripts/compare.py中的引擎列表。 - DDGS CLI 语法已更改 — 旧语法
ddgs --json -q ... -m ...已无法使用。新 CLI 使用ddgs text -q ... -m ... -o <file>(输出到文件,而非标准输出)。脚本的 DDGS 回退方案已更新为使用新语法。如果回退方案失败,请使用ddgs text --help验证。 - 后台进程未导出 SEARXNG_URL — 脚本的
load_env()函数会从~/.hermes/.env加载该环境变量,但如果通过后台进程传入--mode tools(例如使用terminal(background=true)),请确保在命令中显式执行export SEARXNG_URL=http://...。load_env()函数只会设置尚未存在于os.environ中的变量,而后台 shell 启动时携带的环境变量很少。 - compare.py 至少需要 2 个模型 — 如果只传入一个模型,脚本会退出并提示“Error: need at least 2 models to compare”。因速率限制而要重试单个模型时,请改用直接的 curl API 调用,而不是该脚本。
- 比较推理力度现已原生支持(v1.2.0) — 在
--models和--judge上使用provider:@effort:model_id语法(请参阅上文“推理力度 A/B 测试”一节)。旧的包装器驱动模式(/root/.hermes/cache/ab_effort_run.py、在加载器脚本中注册虚拟提供商)仍适用于带有逐项测试真实答案评审的多测试电池;原生语法则适用于单次运行比较。对于 CLI 评审器(例如 Codex gpt-5.6-sol):将评分标准和匿名回答写入临时文件,运行codex exec --skip-git-repo-check -m gpt-5.6-sol "Read the file <path> and follow the instructions inside",从 stdout 和 stderr 中解析 JSON,并为每项测试打乱 Response 1/2 的顺序。code_review测试的真实答案来自 TEST_BANK 中的evaluation和planted_issues键(而非evaluation_criteria)。已知发现(glm-5.3-flash,2026-08-29):推理力度与推理 token 数量之间并非单调关系(高力度 ≠ 更多思考);在较长的工具链中,高力度出现 12 轮后仍未收敛,而中力度成功收敛;质量方面中力度以 4-2-2 获胜(平均分 8.6 对 7.8),高力度的中位耗时约快 3 倍。 - Kimi K3 在 OpenRouter 上受到速率限制 —
moonshotai/kimi-k3在共享的 OpenRouter 资源池上会触发 HTTP 429,尤其是在并行运行多个测试时。请等待 15–30 秒后重试,或向 OpenRouter 添加 Moonshot API 密钥(BYOK),以获得专属速率限制。 - 沙箱测试(S1–S5)需要支持 5 个工具的模型 — 沙箱测试会将全部 5 个工具定义(web_search、web_extract、run_python、read_file、write_file)传给模型。有些模型可能不支持使用 5 个工具进行工具调用,或者一次只能使用 1–2 个工具。如果模型未通过沙箱测试,但通过了研究测试(A/B/C),那么它可能是被工具定义的数量压垮了。请先使用较简单的沙箱提示词进行测试。
- 沙箱中的 Python 执行并未与网络隔离 —
run_python工具使用subprocess.run([sys.executable, script])运行代码,如果代码导入urllib或socket,就可以发起网络调用。10 秒超时可以限制造成的损害,但这并非真正的沙箱。如需生产环境加固,请考虑在容器或 seccomp 过滤器中运行。对于模型比较,10 秒超时已足够。 - 每个模型运行结束后都会清理沙箱临时文件 —
run_tool_loop函数会为每个模型创建一个临时目录,并在finally块中清理。如果模型写入文件后需要在后续轮次中读回,该操作可以正常进行(同一个沙箱目录会在各轮次间持续存在)。但如果脚本在运行中途崩溃,finally块仍会执行清理。 - 沙箱输出会截断至 2000 个字符 —
run_python返回的 stdout 和 stderr 各自会截断至 2000 个字符。如果模型生成大量输出(例如打印大型列表),截断后的输出可能会让模型困惑。在沙箱测试中,能够简洁地格式化输出的模型表现会更好。
相关项目
Odysseus — PewDiePie 的可自托管 AI 工作空间 — 包含一项“比较”功能,可盲测并排比较模型,在理念上与此项目的目标相似(匿名展示、评估、揭晓)。本技能采用不同的方式:仅使用提示词和标准库脚本,不提供 UI,旨在任何 Agent 的工具循环中运行,而非作为独立的 Web 应用。Odysseus 还报告称,经过微调的 Qwen 32B 模型在 Aider Polyglot 基准测试中的得分为 39%——这为模型比较校准提供了有用的数据点。