anthropics / anthropics/skills

`claude-api` skill eagerly injects ~156k tokens, exhausting the context window in a single tool call

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

説明

# `claude-api` skill eagerly injects ~156k tokens, exhausting the context window in a single tool call

## Environment

| | |
|---|---|
| Claude Code | 2.1.220 |
| Skill | `claude-api` (bundled at `%LOCALAPPDATA%\Temp\claude\bundled-skills\2.1.220\\claude-api`; also published via `anthropic-agent-skills` → `github.com/anthropics/skills`) |
| Model | `claude-opus-5` (default context) |
| OS | Windows 11 (10.0.22631), Git Bash |
| Node | v24.14.0 |

## Summary

Invoking `Skill(claude-api)` injects a single message of **624,401 characters (~156k tokens)** — the concatenation of `SKILL.md` plus **31 reference documents**. On a default-context model this consumes the entire window, and the very next API call fails with `Prompt is too long`. The session is unrecoverable.

This is not a slow degradation. It is one tool call from a fresh session to a dead session.

## Reproduction

1. Start a new session on `claude-opus-5` (default context).
2. Prompt with a request to edit a Markdown file that mentions model names in prose, e.g.:

> Opus 5 is now available and is more capable than Fable 5. Please update the model list in our global CLAUDE.md accordingly.

3. The model reads `~/.claude/CLAUDE.md` (~1 KB), then invokes `Skill(claude-api)` per the skill's trigger.
4. Next assistant turn: `Prompt is too long`.

The task is editing a Markdown table in a config file. No code, no API calls, no SDK usage anywhere in scope.

*(The prompt above is minimized from the one that produced the transcript below; it retains the tokens that match the trigger — `Opus`, `Fable`, `CLAUDE.md`.)*

### Transcript evidence

| Entry | Type | Size |
|---|---|---|
| 6 | user prompt | 683 B |
| 13 | `Read` of a ~1 KB Markdown file | ~1 KB |
| 14 | `tool_use` / `Skill` | 1.2 KB |
| **17** | **skill payload** | **624,401 chars (~156k tokens)** |
| 19 | assistant | `Prompt is too long` |

## Expected vs. actual

**Expected:** the skill loads its entry document and reads references on demand, as the progressive-disclosure model for skills implies.

**Actual:** 32 documents arrive at once, before the model knows which — if any — are relevant.

## Analysis

### 1. Over half the payload is provably irrelevant to any given task

Composition of the 624,401 characters:

| Segment | Chars | Share |
|---|---|---|
| `shared/model-migration.md` | 143,685 | 23% |
| Managed Agents suite (14 files) | 202,069 | 32% |
| `SKILL.md` | 68,375 | 11% |
| Everything else (17 files) | 210,272 | 34% |

**`shared/model-migration.md` is the single largest file at 23% of the payload — and `SKILL.md`'s own subcommand table says to load it conditionally:**

> | `migrate` | … **Read `shared/model-migration.md` immediately** … |

It is gated behind an explicit subcommand, then loaded eagerly regardless. The Managed Agents suite (another 32%) is likewise a distinct feature area that a config-file edit never touches. **55% of the payload is two on-demand feature areas.**

Language detection does work — only TypeScript variants were included, not all nine languages. The eager loading of `shared/` defeats the savings.

### 2. No lighter invocation exists

The skill exposes exactly one subcommand, `migrate`. It cannot reduce the payload, because the dispatch instruction operates on already-loaded text:

> If the User Request at the bottom of this prompt is a bare subcommand string (no prose), **search every Subcommands table in this document** …

The document must be fully injected before the subcommand is read. There is no argument that loads less.

### 3. The trigger is far too broad for the payload size

From the skill description:

> TRIGGER — read BEFORE opening the target file; don't skip because it "looks like a one-liner" — whenever: the prompt names Claude/Anthropic in any form (Claude, Anthropic, Fable, Opus, Sonnet, Haiku, `anthropic`, `@anthropic-ai`, `claude-*`, `us.anthropic.*`, `[1m]`) …

Any prompt containing the bare string "Opus", "Sonnet", or "Claude" matches — including editing a file *named* `CLAUDE.md`. Coupled with a 156k-token payload and language that explicitly preempts the model's judgement (*"don't skip because it looks like a one-liner"*), the failure mode is systematic rather than incidental.

### 4. The payload was stale for the task that summoned it

The bundled content is stamped `## Current Models (cached: 2026-06-24)` and describes **Fable 5** as *"most capable widely released model"*. It contains no knowledge of Opus 5 — the exact fact being added to the file. The skill exhausted the session to supply information it did not have.

## Suggested fixes

Roughly in order of impact:

1. **Make `shared/` progressive.** Ship `SKILL.md` with an index of references and let the model `Read` what it needs. This alone cuts ~89% of the payload.
2. **Honour the existing conditional gates.** `model-migration.md` and the Managed Agents suite are already documented as on-demand; load them that way.
3. **Narrow the trigger.** Require an API/SDK signal (an `anthropic` import, an API call site, a model-id string in code) rather than any mention of a model name in prose. Editing a `.md` file should not match.
4. **Soften the anti-judgement language.** *"Don't skip because it looks like a one-liner"* suppresses exactly the check that would have avoided this.
5. **Budget-aware loading.** A skill about to consume ~78% of a 200k window should degrade to its index rather than fail the session.

## Impact

Any user on a default-context model who mentions a Claude model name loses their session. It is most likely to fire on trivial tasks — config edits, doc updates, casual questions about model choice — where the cost is least justified and the user has least warning.

**Workaround:** `"permissions": { "deny": ["Skill(claude-api)"] }` in `settings.json`, or run in a 1M-context session.

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

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

評価

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

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

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