
I Looked Into How Skill Descriptions Get Truncated in Claude Code
This page has been translated by machine translation. View original
I'm Suenaga from the Retail App Co-creation Department.
Claude Code's Skills are handy, but a Skill's description and name are information passed to the AI, so I wondered whether they eat up context just like tool definitions do, and I looked into it.
The limit on description
A Skill is written in a file called SKILL.md, like this:
---
name: my-skill
description: 何をする Skill か、いつ使うか
when_to_use: 発火条件の追加情報 (省略可)
---
(本文)
The part enclosed by --- at the top is the metadata, and the name / description / when_to_use written there are passed to Claude. The description and when_to_use are combined and treated as a single explanation, but there is a default limit of 1,536 characters per skill. You can change this by setting maxSkillDescriptionChars.
There is also a limit on the total across all Skills, which by default is set to 1% of the model's context window. This can also be changed by setting skillListingBudgetFraction. If you want to specify a fixed number of characters, you can also use the environment variable SLASH_COMMAND_TOOL_CHAR_BUDGET.
As for the behavior when this is exceeded, the official documentation (Skill descriptions are cut short) says the following:
When it overflows, descriptions for the skills you invoke least are dropped first, so the skills you actually use keep their full text.
The name remains but the description is removed, so Claude ends up treating that Skill in a state where it "knows the name but doesn't know what it does."
With a 200K context model, the default 1% gives a total budget of about 2,000 characters. With one Skill, the full 1,536 characters fit, but with 10 Skills that works out to an average of 200 characters each, and with 50 Skills only an average of 40 characters each.
By the way, running /doctor tells you whether you are over budget and which Skills' descriptions have been dropped. Once your Skills start to increase, it may be a good idea to take a look.
Don't pass unnecessary Skills to Claude
Rather than waiting for descriptions to be truncated automatically, there is also a way to explicitly state that "this Skill should not be shown to Claude." With the skillOverrides setting, you can switch the state of each Skill among 4 levels.
| Value | Information passed to Claude | / menu |
|---|---|---|
on |
name + description | Shown |
name-only |
name only | Shown |
user-invocable-only |
Not passed | Shown |
off |
Not passed | Hidden |
Running /skills opens a Skill list UI, where you can cycle through states with Space and confirm with Enter, which writes to .claude/settings.local.json. If you write directly to the settings file, it looks like this:
{
"skillOverrides": {
"legacy-context": "name-only",
"deploy": "off"
}
}
name-only is a state where "Claude is told the Skill exists but isn't given the description," and suits Skills you only launch manually (/name). user-invocable-only is conversely a state where "it is completely hidden from Claude, but a human can still call it from /," and off is complete disablement. This way, Skills you don't normally use are no longer passed to Claude and no longer put pressure on context. Note that skillOverrides does not apply to Skills that come from plugins, so those are managed from the /plugin side.
Let's test whether they really get cut
The discussion so far was based on the documentation, so from here I'll deliberately set maxSkillDescriptionChars and skillListingBudgetFraction to small values locally and check whether it behaves as described.
For testing, I prepared 5 arbitrary dummy Skills. The combined length of description and when_to_use is varied between roughly 70 and 140 characters.
sandbox/.claude/skills/
├── greet-user/SKILL.md # description + when_to_use ~137字
├── format-date/SKILL.md # ~132字
├── convert-units/SKILL.md # ~110字
├── summarize-text/SKILL.md # ~109字
└── generate-uuid/SKILL.md # ~69字
The contents are dummies with no actual processing, and only the description / when_to_use in the metadata section enclosed by --- at the top of SKILL.md are meaningful.
Reducing the per-skill limit
First, with only maxSkillDescriptionChars: 80 written, I asked Claude to "paste, word for word, the descriptions currently visible in the system prompt." Except for generate-uuid (combined ~69 characters), the other 4 exceed 80 characters combined, so if the setting was effective they should have come back cut at 80 characters.
Here is the result.
- format-date: 日付を ISO 8601 や日本語表記など複数のフォーマットに整形する。「日付を整形して」「YYYY-MM-DD にして」「和暦に変換」のようなリクエストで発火する想定。検証用ダミー。 - 日付文字列が含まれていて、かつフォーマット変換の意図が明示されているとき。
- greet-user: ユーザーに挨拶を返す。朝・昼・夜で文面を変える。「挨拶して」「こんにちは」「hello」などの軽い挨拶リクエストで発火する想定。検証用のダミー Skill なので実際の処理はしない。 - ユーザーが挨拶っぽい一言を投げてきたとき。技術的な質問とセットで来た場合は発火しない。
- summarize-text: 長文を 3 行に要約する。「要約して」「サマリー」「短くまとめて」などのリクエストで発火する想定。検証用ダミーなので実際には要約処理はしない。 - 入力に長めの文章があり、要約・サマリー化が明示的に求められているとき。
- convert-units: 単位変換を行う。長さ・重さ・温度・通貨など。「メートルをフィートに」「摂氏を華氏に」のような明示的な変換指示で発火する。検証用ダミーなので実数値は適当。 - 入力に数値と単位が含まれ、別単位への変換が要求されているとき。
- generate-uuid: UUID v4 を生成する。「UUID 出して」「ID 作って」で発火。検証用ダミー。 - 一意な識別子を生成してほしいと明示されたとき。
The descriptions of all Skills were output at their original length (70–140 characters), and there was no sign of them being cut at 80 characters. I couldn't tell whether maxSkillDescriptionChars is not being read from the project-level settings.json, or whether it isn't taking effect for some other reason. Since there is also no way to directly peek at the contents of the system prompt from the CLI side, this is as far as I could trace it this time.
Reducing the overall budget
Next, I launch with skillListingBudgetFraction: 0.0005. With a 200K context model the overall budget is about 100 characters, so even just 5 Skills shouldn't fit at all.
Here is the output of /doctor.
Skill listing will be truncated
8 descriptions dropped (full descriptions kept for most-used skills) (0.1%/0.1% of context): greet-user, format-date,
convert-units, +5 more
run /skills to disable some, or raise skillListingBudgetFraction (currently 0.1%) in settings.json
Opting in would cost ~1k tokens for skills every session and uses rate limits faster
The ones whose descriptions were removed, leaving only the name, totaled 8: my 5 own Skills (format-date / greet-user / summarize-text / convert-units / generate-uuid) and 3 bundled Skills (init / review / security-review). The ones whose descriptions remained were the remaining bundled Skills (update-config, keybindings-help, simplify, fewer-permission-prompts, loop, schedule, claude-api). Also, as for the 3 that were dropped, init / review / security-review, as the official documentation (Restrict Claude's skill access) says
A few built-in commands are also available through the Skill tool, including /init, /review, and /security-review
they are originally built-in commands that have been made callable through the Skill tool as well. Their origin is different from the other bundled Skills whose descriptions remained, so that may be related to the drop behavior.
Just as the documentation's "descriptions are dropped first" states, the descriptions were not cut off partway but removed entirely. The name remained for all Skills, so Claude is left in a state of "knowing that a Skill called greet-user exists but not knowing what it does." Also, the fact that all 5 of my own Skills were among those removed is consistent with the documentation's statement that Skills that have never been invoked are treated as lowest priority.
By the way, the setting value was 0.0005 (= 0.05%), but it was displayed as 0.1%. I wonder whether there is a lower floor, or whether display rounding kicked in 🧐
In closing
Skill information is cached, so there isn't much difference in terms of cost. Even so, personally I don't want to put content I'll never use into context, so I set Skills I don't need to user-invocable-only and call them that way.
See you 👋
