Best for
- "Compare these models on..."
- "Which model is better for [task]?"
- "A/B test [model1] vs [model2]"
moonlight-lupin/agent-skills/mlops/model-compare/SKILL.md
Blind side-by-side multi-model comparison. Send one prompt to 2-4 models simultaneously, present responses anonymously (Model A / B / C / D), let the user pick a winner, then reveal identities and show which model won. Supports custom evaluation criteria, synthesis of responses, and vote history logging. Trigger when the user says "compare models", "test these models", "which model is better for", "A/B test", "blind comparison", "model evaluation", or wants to see how different AI models handle
Decision brief
Send one prompt to multiple models simultaneously, present responses anonymously, let the user pick a winner, then reveal which model is which.
Compatibility matrix
| Platform | Status | Evidence | What to check |
|---|---|---|---|
| Codex | Not declared | No explicit evidence | Portability before use |
| Claude Code | Not declared | No explicit evidence | Portability before use |
| Cursor | Not declared | No explicit evidence | Portability before use |
| Gemini CLI | Not declared | No explicit evidence | Portability before use |
Installation
The source command is displayed only when detected. A safe inspection prompt is always available so your agent can explain every action before execution.
npx skills add https://github.com/moonlight-lupin/agent-skills --skill "mlops/model-compare"Inspect the Agent Skill "model-compare" from https://github.com/moonlight-lupin/agent-skills/blob/78aee69209dc94cb90d5bed4fa8e2f3bfbb993ee/mlops/model-compare/SKILL.md at commit 78aee69209dc94cb90d5bed4fa8e2f3bfbb993ee. List every install step, command, network request, credential, file read/write, external action, and rollback step. Explain whether it fits my task. Do not install or execute anything until I approve.
Workflow
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"
Determine which models to compare. The user may specify: - Explicit model names: "compare claude-sonnet-4.6 vs gpt-4o vs gemini-2.5-flash" - Provider + model: "compare OpenRouter claude-sonnet-4.6 vs Ollama glm-5.2" - Task-based: "which model is best for coding?" → suggest 2-4 c…
Send the prompt to all models in parallel. The script handles this automatically via concurrent.futures.ThreadPoolExecutor — no need for delegatetask or manual parallelism.
One-shot chat completion per model. All calls fired concurrently by the script.
For each response: - Empty/error: if a model returns an error or empty response, note it and exclude from the comparison. Tell the user which model failed. - Truncated: if response hit maxtokens, note it was truncated - Refusal: if a model refused to answer, include it as-is (re…
Permission review
The documentation asks the agent to create, modify, or delete local files.
→ Step 8 (optional): Save to JSON fileThe documentation asks the agent to run terminal commands or scripts.
python3 scripts/compare.py --prompt "Explain X" --models "ollama-cloud:glm-5.2" "ollama-cloud:kimi-k2.5"The documentation asks the agent to run terminal commands or scripts.
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" --revealThe documentation includes network, browsing, or remote request actions.
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()]"The documentation asks the agent to create, modify, or delete local files.
| S2 | tool_calling | Write CSV to file, analyze averages, run script, report results | 🔧 📦 |The documentation includes network, browsing, or remote request actions.
| K | coding | Concurrent URL fetch with per-URL timeout, preserve order | |Evidence record
| Signal | Value | Evidence type | Meaning |
|---|---|---|---|
| Quality score | 95/100 | Computed | Documentation, specificity, maintenance, and trust rules |
| Repository stars | 16 | Source | Repository attention, not individual Skill quality |
| Compatibility | 0 platforms | Source | Declared in the catalog source record |
| Usage guide | automated source guide | Editorial | Generated or reviewed according to the visible evidence level |
Pinned source
Send one prompt to multiple models simultaneously, present responses anonymously, let the user pick a winner, then reveal which model is which.
Inspired by the Compare feature in PewDiePie's Odysseus project, adapted for Hermes's multi-provider architecture (OpenRouter, NVIDIA, Ollama Cloud, any OpenAI-compatible endpoint).
evaluating-llms-harness skilldeep-research skill (iterative research loop, not model comparison)Four comparison modes, all driven by scripts/compare.py:
| Mode | Flag | What it does | API feature |
|---|---|---|---|
| simple | --mode simple (default) | One prompt → one response | Basic chat completion |
| tools | --mode tools | Multi-turn tool calling with real web_search/web_extract + sandboxed run_python/read_file/write_file. 10-turn max (configurable per-test via max_turns in TEST_BANK). Tracks full trace. | tools array in request, multi-turn messages |
| coding | --mode coding | Test bank coding prompts (LRU cache, concurrent fetch, debug merge sort, retry decorator) | Basic chat completion |
| review | --mode review | Code review prompts with planted bugs (SQL injection, clean code, race condition, float-for-money) | Basic chat completion |
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.pyThe primary interface — a standalone CLI tool (no pip dependencies, pure stdlib + urllib). See references/provider-tool-support.md for which models support tool calling. For empirical model behavior findings from 16 head-to-head tests (GLM 5.2, MiniMax M3, HY3, Laguna), see references/model-behavior.md. (Running the test suite under tests/ needs pytest — see requirements-dev.txt; the skill itself needs nothing installed.)
Tool-mode environment dependency:
--mode toolsruns realweb_search. That needs eitherSEARXNG_URLset to a SearXNG instance or theddgsCLI available onPATH(the fallback). Neither is a Python import dependency, but one of them must be present for live search; without both,web_searchreturns an error result. The other three modes (simple,coding,review) need neither.
# Simple 2-model blind comparison
python3 scripts/compare.py --prompt "Explain X" --models "ollama-cloud:glm-5.2" "ollama-cloud:kimi-k2.5"
# 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
Key flags: --prompt, --models, --mode, --test (test bank ID), --judge, --efficiency, --reveal, --output, --timeout, --list-providers, --list-models.
--max-turnsCLI override (added 2026-07-17): Pass--max-turns Nto override the test bank'smax_turnsfield at runtime without editing source. If not passed, the test bank default is used. This was added because killing a background run to patchTEST_BANK["A"]["max_turns"]in source code is fragile and disrupts parallel execution.
Three providers are wired in (the canonical config is PROVIDERS in
scripts/compare.py):
| Provider | Env Var | Cost | Model families | Endpoint |
|---|---|---|---|---|
| Ollama Cloud | OLLAMA_API_KEY | Free | GLM, Qwen, Kimi, Gemini, Gemma | https://ollama.com/v1/chat/completions |
| NVIDIA | NVIDIA_API_KEY | Free | Yi, Llama, Nemotron, … | https://integrate.api.nvidia.com/v1/chat/completions |
| OpenRouter | OPENROUTER_API_KEY | Paid (per-token) | Claude, GPT, Gemini, DeepSeek, Llama, Qwen, Mistral | https://openrouter.ai/api/v1/chat/completions |
Model inventories live elsewhere, on purpose. Exact model counts and IDs drift constantly, so they are deliberately kept out of this doc. For the live list run
python3 scripts/compare.py --list-models <provider>(needs that provider's key);references/providers.jsonholds a curated, count-free snapshot with representative model IDs per provider.
When the user does not specify a provider, route to free providers first:
Before any OpenRouter call, confirm with the user:
"This comparison will use OpenRouter which has per-token costs. Estimated cost: ~$0.01–0.05 per model per call (varies by model). Proceed?"
Only proceed after explicit confirmation. When in doubt, default to free providers.
To call a model, POST to the provider's /v1/chat/completions endpoint with:
{
"model": "<model_id>",
"messages": [{"role": "user", "content": "<prompt>"}],
"max_tokens": 8192,
"temperature": 0.7
}
Header: Authorization: Bearer <API_KEY>
max_tokens is set to 8192 in both
call_model_simpleandcall_model_with_tools. The previous default of 4096 caused truncated code output on coding test J (LRU cache) — the model generated so much code it hit the 4096 limit before finishing the decorator section. If a model still truncates, increase the value in the payload dict.
Determine which models to compare. The user may specify:
Map the user's model names to a provider:model_id spec. Free providers
(Ollama Cloud, NVIDIA) are preferred. OpenRouter is only used for models not
on a free provider (e.g. Claude, GPT) or when the user explicitly asks for it.
The rules, not a hardcoded catalogue (which would rot):
ollama-cloud:glm-5.2, ollama-cloud:qwen3-coder:480b,
nvidia:meta/llama-3.3-70b-instruct.openrouter:anthropic/claude-sonnet-4.6,
openrouter:openai/gpt-4o — paid, confirm first (see routing rule above).python3 scripts/compare.py --list-models <provider> for the live list, or see references/providers.json for a
curated set of representative IDs per provider. Don't hand-maintain a model
table here.When user doesn't specify models:
If unsure which provider has a model, check with:
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()]"
Rules:
Send the prompt to all models in parallel. The script handles this
automatically via concurrent.futures.ThreadPoolExecutor — no need for
delegate_task or manual parallelism.
One-shot chat completion per model. All calls fired concurrently by the script.
Multi-turn loop per model (also concurrent across models):
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)
Real tool execution — the script executes web_search and web_extract
for real:
web_search → SearXNG (self-hosted, via SEARXNG_URL) with DDGS fallbackweb_extract → direct HTTP fetch with HTML-to-text conversion (3000 chars/page)No mock tools, no fake results. Models must formulate good queries, pick the right URLs, and synthesize from real content. A model that generates a bad search query gets bad results and must recover.
Tool definitions passed via the OpenAI tools parameter:
web_search(query, limit) — returns titles, URLs, snippetsweb_extract(urls) — returns page content as textNo terminal tool — we don't have a sandbox. Terminal is not exposed to comparison models for safety reasons.
For each response:
Shuffle the responses and assign neutral labels. Do NOT reveal which model is which.
Shuffle rule: Use a random permutation. Do not always put the same model first. If the user is comparing 3 models, randomly assign A/B/C.
Present as:
🧪 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".
Formatting rules:
Wait for the user to vote. Accept:
After the vote, reveal the mapping:
🎭 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>
If the user wants the best possible answer, synthesize across all responses:
"Want me to synthesize the best parts of all responses into one?"
If yes, take the strongest elements from each response and produce a unified answer. Note which model contributed each part:
## Synthesized Answer
[merged response]
## Contributions
- Section X: primarily from <model_name>
- Section Y: primarily from <model_name>
For recurring comparisons, log results to a file:
~/.hermes/data/model_compare_history.jsonl
Format:
{"timestamp": "2026-06-27T12:00:00", "prompt": "...", "models": ["model_a", "model_b"], "winner": "model_a", "is_blind": true, "feedback": "..."}
This builds up a picture of which models win for which task types over time.
Use --test <ID> to run a pre-built test prompt. The mode is auto-set based on the test domain.
| ID | Domain | Prompt summary | Tools? |
|---|---|---|---|
| A | tool_calling | Latest Python version + top 2 features | 🔧 |
| B | tool_calling | Find Odysseus GitHub repo star count | 🔧 |
| C | tool_calling | Best reverse proxy for homelab, then find key feature | 🔧 |
| E | tool_calling | Search LRU cache implementations, then write a better one | 🔧 |
| H1 | tool_calling | Python 3.14 free-threaded status — find 3 sources, identify authoritative | 🔧 |
| H2 | tool_calling | Node.js stable version + EOL date, verify against official source | 🔧 |
| S1 | tool_calling | Write IPv4 validator, run with test cases, report pass/fail | 🔧 📦 |
| S2 | tool_calling | Write CSV to file, analyze averages, run script, report results | 🔧 📦 |
| S3 | tool_calling | Generate Fibonacci, save as JSON, read back and verify | 🔧 📦 |
| S4 | tool_calling | Reverse a linked list, run test, verify output, debug if wrong | 🔧 📦 |
| S5 | tool_calling | Caesar cipher encrypt/decrypt, run and verify round-trip | 🔧 📦 |
| J | coding | Implement LRU cache, O(1), type hints + docstring | |
| K | coding | Concurrent URL fetch with per-URL timeout, preserve order | |
| L | coding | Fix buggy merge sort (off-by-one in merge step) | |
| M | coding | Retry decorator, 3x, 1s delay, preserve metadata | |
| H3 | coding | Thread-safe cache with TTL + LRU eviction | |
| H4 | coding | Token bucket rate limiter, thread-safe, injectable clock | |
| O | code_review | SQL injection + unreliable rowcount loop | |
| P | code_review | Clean code (no bugs) — test false positive rate | |
| Q | code_review | Thread-unsafe cache in production service | |
| R | code_review | Float for money + missing transfer validation | |
| H5 | code_review | Asyncio connection pool — inflight leak, missing lock, no timeout | |
| H6 | code_review | Auth service — MD5, timing-unsafe, forgeable token, no expiry check | |
| H7 | code_review | Logging service — fetchone() called twice per loop iteration |
🔧 = uses web_search/web_extract tools. 📦 = uses sandbox tools (run_python/read_file/write_file).
Each test includes evaluation criteria used by the judge. Tool-calling tests also include a max_turns field (default 10) that controls the turn cap for that specific test — edit the TEST_BANK entry in scripts/compare.py to change it for an individual test. Code review tests include planted issues for objective scoring.
The --mode tools flag enables multi-turn tool calling with real tools (not mocks):
web_search, web_extract, run_python, read_file, write_filetool_calls, the script executes the real call:
web_search → SearXNG (self-hosted, via SEARXNG_URL) with DDGS fallbackweb_extract → direct HTTP fetch, HTML stripped to text, truncated to 3000 chars/pagerun_python → executes Python code in a per-model sandbox (temp dir, 10s timeout, no network)read_file → reads a file from the sandbox directory (path traversal blocked)write_file → writes a file to the sandbox directory (path traversal blocked)tool role messagemax_turns in TEST_BANK)Sandbox security: Each model gets its own temp directory (tempfile.mkdtemp). Path traversal (../) and absolute paths are rejected. Python execution has a 10-second timeout. No network access from within the sandbox subprocess. Sandbox is cleaned up after each model's run (in a finally block).
Tools exposed: web_search, web_extract, run_python, read_file, write_file. See references/provider-tool-support.md for which models support tool calling.
Judge sees the full tool call trace — what was searched, what was extracted, what code was run and its output, how many turns, whether it converged. This lets the judge evaluate tool selection strategy, not just the final answer.
The --efficiency flag (auto-enabled for tools mode) prints a token comparison table:
📊 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
Key metrics: turns, tool calls, tokens in (context consumed), tokens out (generated), efficiency ratio (out/in), time. Efficiency without accuracy is waste — a model that uses few tokens but gets the wrong answer is not efficient, it's just wrong fast.
"I need a model for summarizing legal documents. Compare claude-sonnet-4.6, gpt-4o, and gemini-2.5-flash on this prompt: [legal text]"
"Compare glm-5.2 (free) vs claude-sonnet-4.6 (paid) on this coding prompt. Is the paid one worth it?"
"Test this prompt on 3 models — I want to see which ones follow my formatting instructions"
"Compare the same model (llama-4-maverick) on OpenRouter vs NVIDIA — is there a difference?"
The scripts/provider_health.py module tracks provider endpoint health and
implements dead-host cooldown — when a provider fails consecutively, it's
marked dead for a cooldown period and subsequent calls skip it automatically.
~/.hermes/data/provider_health.json across runs# 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
Both call_model_simple and call_model_with_tools check provider health
before making API calls. If a provider is in cooldown, the call is skipped
with a [Provider X in cooldown (Ns remaining) — skipping] message instead
of waiting for a timeout. Successes and failures are recorded automatically.
The compare script only supports API-based providers (OpenRouter, Ollama Cloud, NVIDIA). When the user wants to include models only accessible via CLI tools (Codex CLI, Cursor CLI), use this hybrid pattern:
cursor-grok-4.5-high) are
only available through Cursor CLI, not on any API provider.scripts/compare.py as normal (background)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| CLI | Binary | Model flag | Auth | Cost |
|---|---|---|---|---|
| Codex | codex | -m gpt-5.6-sol | OAuth (hermes auth) | $20/mo included |
| Cursor | agent | --model "cursor-grok-4.5-high" | CURSOR_API_KEY in .env | $60/mo included |
Always run CLI models in background (
background=true+notify_on_complete=true) — they can take 1-5 minutes. Run them in the same tool batch as the API script launch for true parallelism.
Cursor Grok 4.5 High is the heaviest internal tier. For lighter tasks use
cursor-grok-4.5-medium. See thecursor-cliskill for full model selection guidance.
:free suffix) are especially prone to HTTP 429 rate-limiting after just 1-2 calls.:free suffix) and the cost gate — the script conservatively treats ALL OpenRouter models as paid, even :free suffix models that cost $0. Set COMPARE_CONFIRM_PAID=1 env var to bypass the cost confirmation gate. Example: COMPARE_CONFIRM_PAID=1 python3 scripts/compare.py --models "openrouter:tencent/hy3:free" .... No additional cost confirmation needed since the user has already chosen free-tier models.nvidia/ prefix — when using NIM via compare.py, pass the full model ID including the org prefix: nvidia:nvidia/nemotron-3.5-lightning-30b-a3b (provider colon, then full model ID). Passing nvidia:nemotron-3.5-lightning-30b-a3b (without the nvidia/ prefix) returns HTTP 404 "page not found" — NIM requires the full nvidia/... model ID in the API payload.:free suffix and NIM direct support tools. The OpenRouter paid tier (nvidia/nemotron-3.5-lightning without :free, CoreWeave-hosted) returns HTTP 404 on tools. Use nvidia:nvidia/nemotron-3.5-lightning-30b-a3b (NIM, free, stable) or openrouter:nvidia/nemotron-3.5-lightning:free (free, but prone to 502s)./v1/models endpoint lists many models but most return 404/410 when called. Only meta/llama-3.1-70b-instruct, meta/llama-3.3-70b-instruct, and mistralai/mixtral-8x7b-instruct-v0.1 were alive as of June 2026. Always verify a model is alive with a simple chat completion before using it in a comparison. See references/provider-tool-support.md for the current alive list.tools API parameter. Test with a simple tool-call request first. Models that mention "search" in text but don't emit tool_calls do NOT support tool calling. See references/provider-tool-support.md for the tested matrix.deepseek-v3.2 (Ollama Cloud) mentions "search" in text but does NOT emit tool_calls. mistralai/mixtral-8x7b-instruct-v0.1 (NVIDIA) returns HTTP 400 on the tools parameter. Test tool support per model before running --mode tools. See references/provider-tool-support.md.max_turns in TEST_BANK) prevents infinite loops, but the result is marked "did not converge." Check the converged field in the trace. Increasing max_turns can help models that need more turns to synthesize, but watch for models that loop on the same URLs without converging — more turns won't fix a model that can't synthesize.--max-turns CLI override (fixed 2026-07-17) — the script used to only support per-test max_turns in the TEST_BANK dict, requiring source edits to change the turn cap. This forced killing background runs to patch source. Now --max-turns N overrides at runtime. If the flag doesn't work, check that compare.py has the --max-turns argument parser entry.codex exec -m gpt-5.6-sol fails with "requires a newer version of Codex" on v0.135. Test with a trivial prompt first (codex exec --skip-git-repo-check -m <model> "say hello"). Fall back to gpt-5.5 if the newer model is unsupported.\n- Codex CLI needs --skip-git-repo-check — without it, Codex refuses to run outside a git repo. Always include this flag.\n- Cursor CLI --force required for web access — --trust --sandbox disabled alone does NOT enable web search in headless mode. Web requests are still blocked. Use --force (which implies --trust) to enable web access. Confirmed across 3 attempts: --trust → blocked, --trust --sandbox disabled → blocked, --force → works.\n- OpenRouter geofenced models — some models (e.g. meta/muse-spark-1.1) return HTTP 403 "This model is only available in the United States" when called from outside the US. No workaround without a US proxy. Exclude from comparisons run from non-US locations.execute_web_search now passes &engines=bing,yandex,duckduckgo,google explicitly. If search returns 43-char {"results": [], "note": "No results found"} on every query, check SearXNG engine health with curl -s "http://$SEARXNG_URL/search?q=test&format=json&engines=bing" and update the engines list in scripts/compare.py.ddgs --json -q ... -m ... syntax no longer works. The new CLI uses ddgs text -q ... -m ... -o <file> (outputs to file, not stdout). The script's DDGS fallback has been updated to use the new syntax. Verify with ddgs text --help if fallback fails.~/.hermes/.env by the script's load_env() function, but if you pass --mode tools to a background process (e.g. via terminal(background=true)), make sure to export SEARXNG_URL=http://... explicitly in the command. The load_env() function only sets vars that are NOT already in os.environ, but background shells start with a minimal environment.moonshotai/kimi-k3 hits HTTP 429 on the shared OpenRouter pool, especially when running multiple tests in parallel. Wait 15-30s and retry, or add a Moonshot API key to OpenRouter (BYOK) for dedicated rate limits.run_python tool runs subprocess.run([sys.executable, script]) which can make network calls if the code imports urllib or socket. The 10-second timeout limits damage but is not a true sandbox. For production hardening, consider running in a container or seccomp filter. For model comparison purposes, the timeout is sufficient.run_tool_loop function creates a temp dir per model and cleans it up in a finally block. If a model writes a file and then needs to read it back in a later turn, that works (same sandbox dir persists across turns). But if the script crashes mid-run, the finally block still cleans up.run_python returns stdout and stderr truncated to 2000 chars each. If a model generates a lot of output (e.g. printing a large list), the truncated output may confuse it. Models that format output concisely will perform better on sandbox tests.Odysseus — PewDiePie's self-hosted AI workspace — includes a "Compare" feature for blind side-by-side model testing with conceptually similar goals (anonymous presentation, evaluation, reveal). This skill takes a different approach: pure-prompt + stdlib scripts with no UI, designed to run inside any agent's tool loop rather than as a standalone web app. Odysseus also reported a fine-tuned Qwen 32B model scoring 39% on the Aider Polyglot benchmark — a useful data point for model comparison calibration.
Frequently asked questions
Send one prompt to multiple models simultaneously, present responses anonymously, let the user pick a winner, then reveal which model is which.
The source record exposes this install command: npx skills add https://github.com/moonlight-lupin/agent-skills --skill "mlops/model-compare". Inspect the command and pinned source before running it.
Static rules flagged write-files, exec-script, network in the source; the page lists the matching lines and excerpts.
Alternatives
VincentChuWaiChow/vanguard-frontier-agentic
Retrieves and analyzes Apex debug logs from a connected Salesforce org to identify governor-limit hits, SOQL N+1 patterns, unhandled exceptions, and async job failures. T1 read-only runtime — retrieves logs only, never executes code or mutates data. TRIGGER when: user asks to analyze an Apex log, debug a trigger failure, diagnose a governor limit hit, interpret a stack trace from a Salesforce org, or review a DEBUG log for performance issues. Trigger phrases: analyze apex log, debug this trigger
dotnet/skills
Grades a specified set of test methods individually and produces a concise table mapping each test (fully-qualified name) to a letter grade (A–F), a score band, and a one-line note — designed to be posted as a PR comment. Use when the caller wants per-test feedback on a curated list of methods (for example, the new or modified tests in a pull request), not a suite-wide audit. Polyglot: .NET, Python, TS/JS, Java, Go, Ruby, Rust, Swift, Kotlin, PowerShell, C++. Input is a list of test methods (or
johnqtcg/awesome-skills
Review Go code with a defect-first approach using repository policy (constitution.md first, then AGENTS.md fallback). Use for code review, PR review, quality checks, risk analysis, and regression detection.
NVIDIA/skills
Autonomous NeMo-RL research agent workflow for directed hypothesis testing and open-ended discovery. Guides agents through the full experiment lifecycle: understanding recipes and environments, wiring RL or NeMo-gym runs, launching reproducible baselines and iterations, analyzing results, preserving human oversight, and using git plus TSV logs as the research ledger. Do NOT use for: bug fixes, code review, documentation, refactoring, dependency updates, or single-file changes.