Claude Media
Agent Skillsにスクリプトを同梱する設計 — エラー処理と実行・参照の書き分け

Agent Skillsにスクリプトを同梱する設計 — エラー処理と実行・参照の書き分け

Skillにスクリプトを入れるなら、エラーはスクリプト内で処理し、SKILL.mdで「実行」か「参照」かを書き分けます。定数の根拠と検証つき中間ファイルまで、設計の要点を例つきで解説します。

Agent Skillsにスクリプトを同梱するときの設計判断は、4つに絞れます。エラーをスクリプトの中で処理すること、SKILL.mdで「実行する」か「参照する」かを書き分けること、定数に根拠を残すこと、実行前に検証できる中間ファイルを挟むことです。ベストプラクティスの「Advanced: Skills with executable code」節がこの4点を扱っており、本記事はそれぞれを例つきで掘り下げます。

命名・description・本文の分割はAgent Skillsの命名規則と段階的開示の設計原則にあります。ここでは、Markdownだけで済まないSkill、つまりスクリプトを抱えるSkillに話を絞ります。

スクリプトを同梱すると何が変わるか

Markdownだけのスキルは、Claudeが文章を読んで自分でコードを書き、実行します。スクリプトを同梱すると、その部分は書かれたコードをそのまま走らせる形に変わります。

同梱の利点は4つあります。

  • 生成したコードより信頼できる
  • コードをコンテキストに載せずに済み、トークンを節約できる
  • コード生成の時間が要らない
  • 使うたびに挙動がそろう

Claudeがスクリプトを書けるとしても、あらかじめ用意しておく価値があるという立場です。

仕組みの面では、実行環境にファイルシステムとbashがあることが前提になります。Skillのnameとdescriptionは起動時にシステムプロンプトへ読み込まれ、SKILL.mdや他のファイルは必要になったときに読まれます。スクリプトはbash経由で走り、中身を読み込まずに済むため、コンテキストを消費するのは出力だけです。

Claude Codeのドキュメントも同じ構成を示しています。scripts/helper.pyには「utility script - executed, not loaded」と注記が付いており、実行はされても、中身はコンテキストへ読み込まれません。

どこまでスクリプトに固定するか — 自由度の3段階

スクリプトにするかどうかは、作業の壊れやすさとばらつきで決まります。指示の具体性は作業に合わせて変えます。自由度は3段階です。

自由度向く場面SKILL.mdの書き方
高向く場面複数の方法が成り立つ、文脈で判断が変わるSKILL.mdの書き方文章の手順だけを書く(コードレビューの観点など)
中向く場面望ましい型はあるが、多少の変化は許せるSKILL.mdの書き方パラメータ付きの擬似コードやスクリプトの雛形を置く
低向く場面壊れやすい、一貫性が最優先、順序が決まっているSKILL.mdの書き方実行するコマンドを一字一句指定する

低自由度の例はデータベース移行です。python scripts/migrate.py --verify --backupを「そのまま実行し、コマンドを変えたりフラグを足したりしない」と書きます。

たとえるなら、両側が崖の細い橋では、安全な道が1本しかないので、手すりと正確な指示が要ります。何も危険のない野原なら、方向だけ示して任せられます。同梱スクリプトは、この橋の部分を固める道具です。何でもスクリプトにすると、判断が要る箇所まで硬直します。

モデルによっても、必要な具体性は変わります。Haikuでは指示が足りているか、Sonnetでは明快で無駄がないか、Opusでは説明しすぎていないかを見る、という観点があります。スクリプトに固めた部分は出力のぶれが小さくなるはずなので、小さいモデルで動かすSkillほど、橋の部分を固める価値が高いという推論が成り立ちます。これはドキュメントに書かれた効果ではないため、実際のモデルで試して確かめてください。

エラーは丸投げせず、スクリプトの中で処理する

「Solve, don't defer」は、エラー条件をClaudeに任せず、スクリプトが自分で扱うという原則です。

悪い例は、ファイルを開いて失敗したら落ちるだけのコードです。例外が出ればClaudeは原因を推測して作り直すことになり、同梱した意味が薄れます。良い例は、ファイルが無ければ既定の内容で作成し、権限が無ければ代替を使います。ベストプラクティスの例を、構造そのままに抜き出します。

def process_file(path):
    """Process a file, creating it if it doesn't exist."""
    try:
        with open(path) as f:
            return f.read()
    except FileNotFoundError:
        # Create file with default content instead of failing
        print(f"File {path} not found, creating default")
        with open(path, "w") as f:
            f.write("")
        return ""
    except PermissionError:
        # Provide alternative instead of failing
        print(f"Cannot access {path}, using default")
        return ""

押さえたいのは2点です。

1つ目は、処理した事実をprintで出力に残している点です。出力はClaudeの目に入る唯一の情報なので、黙って既定値に切り替えると、あとで結果の違和感を追えなくなります。

2つ目は、何でも握りつぶす書き方とは違う点です。この例が処理するのは、既定値で続けて問題ない2種類の失敗だけです。続行すると結果が壊れるケースは、原因が分かるメッセージを添えて失敗させるほうが筋に合います。この線引きは文面の例から読み取れる設計であり、ドキュメントが明示している規則ではありません。

定数には根拠を書く — voodoo constantsを避ける

同じ節に、設定値の書き方があります。理由の分からない定数は「voodoo constants」と呼ばれ、Ousterhoutの法則が引き合いに出されています。注意書きは「正しい値を自分が知らないなら、Claudeにどう決められるのか」という問いです。

# HTTP requests typically complete within 30 seconds
# Longer timeout accounts for slow connections
REQUEST_TIMEOUT = 30
 
# Three retries balances reliability versus speed
# Most intermittent failures resolve by the second retry
MAX_RETRIES = 3

悪い例は、TIMEOUT = 47やRETRIES = 5に理由のコメントが無いものです。47秒の根拠が書かれていなければ、Claudeは状況に合わせて変えてよいのか判断できません。

根拠を書くと、値を変える条件が決まります。「ほとんどの一時的な失敗は2回目の再試行までに解消する」と書いてあれば、再試行を増やす前に、失敗の原因を疑う理由ができます。

「実行」か「参照」かをSKILL.mdで書き分ける

ここは重要な区別です。同じスクリプトでも、Claudeに実行させる場合と、読んで理解させる場合があります。

くらべる

スクリプトの扱いを文面で指定する

最も一般的

実行させる

「analyze_form.pyを実行してフィールドを抽出する」と書きます。Claudeはbashで走らせ、出力だけをコンテキストに取り込みます。

複雑なロジック向け

参照させる

「フィールド抽出のアルゴリズムはanalyze_form.pyを参照」と書きます。Claudeはファイルを読み、中身を理解したうえで使います。

ほとんどの補助スクリプトは、実行させるほうが確実で効率もよくなります。読ませる場合はファイル全体がコンテキストに入るため、トークンを払うのは「読ませる価値のあるロジック」に限る、と考えると判断しやすくなります。

SKILL.mdの書き方の例です。次は簡略にした形で、スクリプトごとに用途・コマンド・結果を並べます。

## Utility scripts
 
**analyze_form.py**: Extract all form fields from PDF
実行: python scripts/analyze_form.py input.pdf > fields.json
 
**validate_boxes.py**: Check for overlapping bounding boxes
実行: python scripts/validate_boxes.py fields.json
結果: "OK" か、衝突の一覧

出力形式まで書いておくと、Claudeは次のスクリプトへ何を渡せばよいかが分かります。逆に動詞が曖昧な文面(「analyze_form.pyを使う」など)では、実行と参照のどちらなのかが決まりません。

Claude Codeでは、実行を許可の仕組みと対にする

Claude Codeには、同梱スクリプトを実行する側の仕組みがあります。frontmatterのallowed-toolsと、スキルの置き場所を指す${CLAUDE_SKILL_DIR}の組み合わせです。

---
name: render-chart
description: Render a chart from a CSV file
allowed-tools: Bash(${CLAUDE_SKILL_DIR}/scripts/render.sh *)
---
 
Run `${CLAUDE_SKILL_DIR}/scripts/render.sh <csv-file>` to render the chart.

${CLAUDE_SKILL_DIR}は本文とallowed-toolsのBashルールの両方で置換されます。同じ変数を両方に書くと、ルールが本文の指示するコマンドと一致し、許可の確認なしでスクリプトが走ります。本文で「実行する」と決めたスクリプトは、ここで許可の形にまで落とせます。

なおallowed-toolsの許可は、そのスキルを呼んだターンに限られ、次のメッセージを送ると消えます。組織がallowManagedPermissionRulesOnlyを設定している場合、プロジェクトと個人のスキルのallowed-toolsは無視されます。社内でスキルを配るなら、許可が効かない環境があることを見込んでおきます。

計画を検証してから実行する — 中間ファイルの作り方

複雑でひらめき任せになりやすい作業ほど、ミスが入りやすくなります。有効なのは、plan-validate-executeというパターンです。まず計画を構造化した形式で作らせ、実行の前にスクリプトで検証します。

たとえば、スプレッドシートの内容を基にPDFの50個のフィールドを更新する場面を考えます。検証が無ければ、存在しないフィールドを指したり、値が衝突したり、必須項目を落としたりしかねません。

手順

検証つきの更新フロー

  1. 1

    分析する

    元のPDFを調べてフィールドの一覧を出します。

  2. 2

    計画ファイルを作る

    変更内容をchanges.jsonのような中間ファイルに書きます。

  3. 3

    計画を検証する

    スクリプトでchanges.jsonを検査します。問題があれば、元のPDFには触れずに計画を直します。

  4. 4

    実行して確認する

    検証を通った計画だけを適用し、出力を確かめます。

この型が効く理由は4つあります。エラーを早期に拾える、機械的に検証できる、元ファイルに触れずに計画を直せる、エラーが具体的な問題を指す、です。バッチ処理、破壊的な変更、検証ルールが複雑な作業、失敗が許されない作業に向きます。

実装のコツは、検証スクリプトのメッセージを具体的にすることです。例えば「signature_dateが無い。使えるのはcustomer_name、order_total、signature_date_signed」のように、候補まで出します。次に示すのは、この考え方に沿って書いた検証スクリプトの例です。

import json, sys
 
def validate(plan_path, fields_path):
    plan = json.load(open(plan_path))
    fields = set(json.load(open(fields_path)))
    errors = []
    for name in plan:
        if name not in fields:
            errors.append(
                f"Field '{name}' not found. "
                f"Available fields: {', '.join(sorted(fields))}"
            )
    if errors:
        print("\n".join(errors))
        sys.exit(1)
    print("OK")
 
validate(sys.argv[1], sys.argv[2])

Claudeはメッセージに挙がった候補から正しい名前を選び、計画を直して再実行できます。

検証ループをSKILL.mdに書く

スクリプトで検証できる作業では、「実行→エラー→修正→再実行」の検証ループを、手順として本文に書いておきます。手順をチェックリストにし、検証が失敗したらステップ2へ戻ると明示する書き方です。OOXML編集の例がこの型にあたります。

## Document editing process
 
1. Make your edits to `word/document.xml`
2. **Validate immediately**: `python ooxml/scripts/validate.py unpacked_dir/`
3. If validation fails:
   - Review the error message carefully
   - Fix the issues in the XML
   - Run validation again
4. **Only proceed when validation passes**
5. Rebuild: `python ooxml/scripts/pack.py unpacked_dir/ output.docx`
6. Test the output document

「検証が通るまで次へ進まない」と明記している点が肝心です。検証に失敗したときの戻り先が書かれていないと、Claudeは失敗を報告して止まるか、検証を飛ばして先へ進むかの二択になりがちです。

スクリプトが無いSkillでも、同じ形は作れます。検証役をスタイルガイドの文書に置き換え、Claudeが文書を読んで内容を突き合わせる形です。スクリプトにできるなら機械的に、できないなら文書で、という使い分けです。

同梱前に確かめる実行環境の制約

スクリプトを入れる前に、動く環境を決めておく必要があります。パッケージの扱いが環境で違うためです。

環境パッケージの扱い
claude.aiパッケージの扱いnpmとPyPIからのインストール、GitHubからの取得が可能
Claude APIパッケージの扱いネットワークアクセスなし、実行時のパッケージインストール不可

APIで使うSkillが、依存を実行時に入れる前提だと動きません。必要なパッケージはSKILL.mdに書き、コード実行ツールのドキュメントで利用可能かを調べます。「pdfライブラリを使う」のような曖昧な書き方は避け、pip install pypdfと使用コードまで書きます。

APIでSkillを動かす手順はAgent Skills APIクイックスタートに、組織への配布と審査はAgent Skillsの企業導入にあります。

ほかに、スクリプト周りで見落としやすい項目があります。

  • パスは/区切りにする(Windows形式のバックスラッシュは避ける)
  • validate_form.pyのように、ファイル名が内容を表すようにする
  • 決まった処理は、Claudeに検証コードを書かせず、スクリプトとして置く
  • MCPツールを使うなら、BigQuery:bigquery_schemaのようにサーバー名:ツール名で書く

MCPツールを完全修飾名で書かないと、複数のサーバーがあるときにClaudeがツールを見つけられない場合があります。

同梱スクリプトの設計チェック

ベストプラクティスのチェックリストのうち、コードとスクリプトの項目は次のとおりです。

  • スクリプトが問題を解決している(Claudeに丸投げしない)
  • エラー処理が明示的で、役に立つ内容になっている
  • voodoo constantsがなく、値の根拠がある
  • 必要なパッケージが、手順に書かれ、利用可能と確認されている
  • スクリプトに明確なドキュメントがある
  • パスがすべてスラッシュ区切りになっている
  • 重要な操作に検証・確認のステップがある
  • 品質が重要な作業にフィードバックループがある

手元のSkillに当てるときの順番

既存のSkillを見直すなら、効果の大きい順に3つ見ます。

  1. SKILL.mdの各スクリプト言及が、「実行」と「参照」のどちらか読み取れるか
  2. 例外が出たとき、スクリプトが自分で続行か中断かを決めて出力しているか
  3. 破壊的な操作の前に、計画を検証する段があるか

1つ目は文面を直すだけで済み、コストが最も低い点検です。3つ目は設計の変更になるため、バッチ処理や書き換えを伴うSkillから着手するのが現実的です。

まとめ

スクリプトを同梱したSkillの出来は、コードの賢さより、失敗したときの振る舞いと文面の曖昧さで決まります。エラーはスクリプトが処理して出力に残し、定数は根拠を書き、SKILL.mdでは実行と参照を動詞で書き分けます。壊れると痛い作業には、計画を検証してから実行する段を挟みます。

Claude Codeで置く場合は、${CLAUDE_SKILL_DIR}を本文とallowed-toolsに同じ形で書いて、実行の意図を許可にまで通します。Skillの全体設計はClaude Code Skills完全ガイド、ツール側の設計はエージェント向けツール設計の原則も合わせて参照してください。

参照した一次ソース

この記事の記述は、次の一次ソースと照合しています。更新時に参照先が変わった場合は一覧も更新します。

  1. platform.claude.com/docs/en/agents-and-tools/agent-skills/best-practices
  2. code.claude.com/docs/en/skills
この記事を共有:XはてブLinkedIn