anthropics / anthropics/skills

skill-creator: description-optimization loop burned 100% of a Max subscription in ~3 minutes — false-negative eval bug + no cost guardrails

オープン
#1,412 コメント 2 件 リアクション 0 件 担当者 0 名 GitHub で見る
主要言語
Python
スター
176k
フォーク
20.8k
平均マージ
7時間 21分
マージ済み PR(30日)
5

説明

The description-optimization loop in skill-creator (scripts/run_loop.py → scripts/run_eval.py) consumed 100% of a Claude Max subscription's quota in roughly 3 minutes (121 claude -p invocations before crashing in iteration 2). Two independent problems compounded:

1. A correctness bug in run_eval.py produces false negatives (0% recall), which makes the loop believe the description never triggers, so it keeps iterating and burning quota on a problem that doesn't exist.
2. The optimization flow has no cost guardrails: SKILL.md instructs the agent to run the eval with the session's model, and the defaults multiply into hundreds of potential invocations with no warning or confirmation.

Bug 1: early returns in run_eval.py cause false negatives

run_single_query() decides "not triggered" far too early, in three places (scripts/run_eval.py (https://github.com/anthropics/skills/blob/main/skills/skill-creator/scripts/run_eval.py)):

- Lines 140–141: if the first tool_use block is anything other than Skill/Read (e.g. Claude runs a Grep, Glob, or TodoWrite before loading the skill), it hits else: return False and the run is scored as not-triggered — even though the skill loads one block later.
- Lines 150–154: message_stop returns False if no Skill/Read block was pending, so any first assistant message that ends without touching the skill fails the run, even when a later turn would invoke it.
- Line 168: the fallback branch returns after inspecting only the first tool_use item in the message.

In practice, models frequently do a quick search/read or write a todo list before invoking a skill, so should-trigger queries systematically score 0/3. Observed effect: precision=100% recall=0% on every iteration, which the improvement loop then "fixes" by rewriting a description that was never broken.

Suggested fix: only return early on a positive match; on non-matching blocks or message_stop, clear the pending state and keep consuming the stream. Score "not triggered" only at the result event or timeout. (Applied locally, works as expected.)

Bug 2: no cost guardrails on the optimization loop

- SKILL.md (line ~390) says: "Use the model ID from your system prompt (the one powering the current session)". When the session runs on a large reasoning model, every eval call generates thousands of thinking tokens that count against the user's subscription quota.
- Defaults multiply aggressively: --num-workers 10, --runs-per-query 3, --max-iterations 5, ~20-query eval set → up to ~300 claude -p invocations per optimization run. 10 parallel workers also produced a wave of 429s.
- Neither SKILL.md nor the scripts mention cost, quota, or ask for confirmation before launching. The words "cost"/"quota" don't appear in the optimization section at all.
- These subprocess invocations don't appear in the user's web history, so the quota drain looks inexplicable from the user's side.

Suggested fixes:
- Print an estimated invocation count (queries × runs × iterations) and require explicit confirmation before starting.
- Instruct/default the eval calls to a small model (haiku), or at minimum warn loudly when the chosen model is a reasoning-class model, and document the fidelity trade-off.
- Lower --num-workers default (10 concurrent sessions against one subscription trips rate limits anyway).

Environment

- skill-creator from this repo, installed via plugin marketplace (June 2026 snapshot; bugs verified present at current main)
- Claude Code CLI on macOS, Claude Max subscription
- Loop invoked as documented in SKILL.md § "Description Optimization", Step 3

コントリビューションガイド

このリポジトリのコントリビューションガイドは索引されていません

評価

この issue はまだ評価されていません。

新しい issue をメールで受け取る

初心者向けの GitHub issue を短くまとめたダイジェスト。