2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

AIエージェントへの指示書の書き方

2
Posted at

はじめに

こんにちは。直近でAIエージェントを使ったサポートシステムの開発に取り組んだのですが、その際に意外と困ったのがAIにどうコンテキストを渡して、期待通りに動作を制御するかという部分で悩んだのでそれに対して考えたことを記事として残します!

Agentic Workflowでは、各エージェントに役割を与え、その振る舞いをシステムプロンプトで定義するのが基本的なアプローチです。最初のうちはシンプルで管理しやすいのですが、機能を詳細化・追加するにつれて問題が積み重なっていきます。

従来アプローチの課題

課題 内容
運用コスト システムプロンプトが肥大化し、毎リクエストのトークン消費が増加し続ける
制御性 長文化した指示から関係する部分をモデルが推論するため、解釈ゆらぎや読み落としが発生する
柔軟性 一部の手順を変更したくても、システムプロンプト全体を編集する必要があり、他の機能への影響リスクが生じる

これら3つは、エージェントを本番運用するうえで避けられない壁です。

本記事の目的

この課題に対する解決アプローチが Agent Skill です。

本記事では、

  1. Agent Skillとは何か(Anthropic公式ドキュメントをもとに解説)
  2. システムプロンプトのみで構成した場合と、Agent Skillを導入した場合の具体的な違い
  3. 何をシステムプロンプトに書き、何をAgent Skillに書くべきか(claude_agent_sdk の実装コード付き)

を整理します。


Agent Skillとは

Anthropic 公式ドキュメントでは、Agent Skill を次のように定義しています。

agent-skills/overview より

"Agent Skills are modular capabilities that extend Claude's functionality. Each Skill packages instructions, metadata, and optional resources (scripts, templates) that Claude uses automatically when relevant."

(日本語訳)Agent Skillは、Claudeの機能を拡張するモジュール型のケーパビリティです。各SkillはClaudeが自動的に使用する指示・メタデータ・オプションリソース(スクリプト、テンプレート)をパッケージ化します。

managed-agents/skills より

"Skills are reusable, filesystem-based resources that give your agent domain-specific expertise: workflows, context, and best practices that turn a general-purpose agent into a specialist. Unlike prompts (conversation-level instructions for one-off tasks), skills load on demand, only impacting the context window when needed."

(日本語訳)Skillはエージェントにドメイン固有の専門性を与えるための、再利用可能なファイルシステムベースのリソースです。汎用エージェントを専門家に変えるワークフロー・文脈・ベストプラクティスを提供します。プロンプト(1回限りのタスクに対する会話レベルの指示)とは異なり、Skillはオンデマンドで読み込まれ、必要なときだけコンテキストウィンドウに影響します。

キーポイント: Skillは「必要なときだけコンテキストに読み込まれる(on demand)」ことで、トークン消費を抑えながら専門知識を提供します。

Agent Skillの3段階読み込み構造(Progressive Disclosure)

レベル 読み込みタイミング トークン目安 内容
Level 1: メタデータ 常時(起動時) ~100 tokens/Skill YAMLフロントマターの namedescription
Level 2: 指示本文 Skill 呼び出し時 5k tokens 未満 SKILL.md 本文(手順・ガイダンス)
Level 3+: リソース 必要時のみ 実質無制限 bash 経由で実行するスクリプト・参照ファイル

結論

Agentic Workflowで

  • 全体方針や優先順位を与えるなら「システムプロンプト(system_prompt オプション)」
  • 再利用可能な手順やツール実行手続きを与えるなら「Agent Skill(SKILL.md)」

が基本です。

短く言うと、

  • システムプロンプト = 憲法
  • Agent Skill = 標準作業手順書(SOP)

です。


Agent Skill 導入前(システムプロンプトのみ)

システムプロンプトだけでエージェントを定義した場合の構成イメージです。

┌──────────────────────────────────────────────┐
│ system_prompt(システムプロンプト)               │
│  ├─ エージェントの役割・トーン                   │
│  ├─ 優先順位と禁止事項                          │
│  ├─ 【手順A】RAG検索の詳細フロー                 │
│  │   1. キーワード抽出                          │
│  │   2. FAQデータベース検索                     │
│  │   3. 結果がなければエスカレーション            │
│  ├─ 【手順B】TODOタスク管理フロー                │
│  │   1. 優先度判定                             │
│  │   2. タスク登録                             │
│  │   3. 通知                                  │
│  └─ 【手順C】日常会話フロー                     │
│      1. 挨拶への応答                            │
│      2. サポートへの誘導                        │
└──────────────────────────────────────────────┘

問題点:

  1. トークン消費大: 毎リクエスト全手順を読み込むため、コストが増大する
  2. 解釈ゆらぎ: 長文から関係部分を推論するため、読み落としが発生する
  3. 全体編集リスク: 1手順の変更でシステムプロンプト全体を触る必要がある
  4. 肥大化継続: 機能追加のたびに膨らむ一方で、縮小できない

Agent Skill 導入後

Agent Skillを導入した場合の構成イメージです。

┌──────────────────────────────────────────────┐
│ system_prompt(原則のみ)                      │
│  ├─ エージェントの役割・トーン                   │
│  ├─ 優先順位と禁止事項                          │
│  └─ Skillメタデータ(~100 tokens/Skill)        │
│      rag-search:    FAQを検索する              │
│      todo-manager:  タスクを登録する            │
│      conversation:  挨拶に応答する              │
└──────────────────────────────────────────────┘
          │ 呼び出し時のみ読み込み(on demand)
          ▼
┌──────────────────────────────────────────────┐
│ .claude/skills/(ファイルシステム上)             │
│  ├─ rag-search/SKILL.md    (< 5k tokens)     │
│  ├─ todo-manager/SKILL.md  (< 5k tokens)     │
│  └─ conversation/SKILL.md  (< 5k tokens)     │
└──────────────────────────────────────────────┘

変化した点:

  1. トークン削減: Skillメタデータのみ常時読み込み(約300 tokens)、手順は呼び出し時のみ
  2. 一意な呼び出し: Skill名で明示的に指定され、解釈ゆらぎがなくなる
  3. 変更範囲が限定: 手順変更は対象Skillファイルのみ
  4. 機能追加が容易: 新Skillを追加してもシステムプロンプトの変更は最小

トークン試算(サポートエージェントの例):

# 導入前(全手順をsystem_promptに)
sp_tokens = 1400  # 役割50 + 優先順位100 + 手順A400 + 手順B500 + 手順C350

# 導入後
sp_tokens = 350   # 役割50 + 優先順位100 + Skillメタデータ×3 (100×3)
# Skill本文は呼び出し時のみ(例: rag-searchだけ使う場合)
active_skill_tokens = 400  # rag-search/SKILL.md 1本分
total = 750  # 導入前より650 tokens削減(1,400 → 750)

導入前後の比較

観点 導入前(SPのみ) 導入後(Skill活用)
手順の管理場所 システムプロンプトにベタ書き 独立した SKILL.md ファイル
トークン消費 全手順を毎回読み込む メタデータのみ、手順は on demand
手順の特定 モデルが長文から推論 Skill名で明示的に呼び出し
変更の影響範囲 システムプロンプト全体 該当 Skill ファイルのみ
新機能の追加 システムプロンプト全体を再編集 新 Skill を追加するだけ
デバッグ 長文の中から問題箇所を探す 対象 Skill を単独でテスト可能

システムプロンプトとAgent Skillの役割分担

実務では「どちらを使うか」ではなく「どちらに何を書くか」を分けると安定します。

観点 システムプロンプト Agent Skill(SKILL.md)
目的 エージェントの人格・優先順位・安全境界を固定する 特定タスクの実行手順を部品化する
粒度 抽象的・原則的 具体的・手順的
変更頻度 低い(めったに変えない) 中〜高(業務変更で更新)
再利用性 低い(そのエージェント固有) 高い(他エージェントへ移植可能)
失敗時の影響 全タスクに波及 そのSkill利用時に限定
向いている記述 優先順位、禁止事項、回答トーン、判断基準 API呼び出し順、入力バリデーション、リトライ方針

システムプロンプトに書くべきもの

1. 優先順位

例:

  1. 安全性
  2. 正確性
  3. 速度

この順序は全タスクで一貫して効かせたいので、Skillではなくシステムプロンプト側に置きます。

2. 絶対に超えてはいけない境界

  • 秘匿情報の扱い
  • 破壊的操作の事前確認
  • 許可されたツール範囲

これはエージェント全体のガードレールであり、Skillごとに重複定義すると抜け漏れが起きます。

3. 判断スタイル

  • 不確実なときは明示する
  • 代替案を出す
  • 先に結論を示す

こうした「思考の癖」は横断的なためシステムプロンプトに寄せます。


Agent Skillに書くべきもの

1. ワークフロー手順

例:

  1. ログイン状態確認
  2. 対象一覧取得
  3. 下書き作成
  4. 本文反映
  5. 公開切り替え

このような処理順はSkillとして切り出すと再利用しやすくなります。

2. ツール入出力の契約

  • 必須パラメータ
  • 失敗時の分岐
  • タイムアウト時の再試行

運用知識はSkillに閉じ込めると、システムプロンプトを肥大化させずに済みます。

3. ドメイン固有の品質チェック

  • 記事投稿前チェックリスト
  • 命名規約
  • レビュー観点

タスク依存ルールはSkill側に置くほうが保守しやすいです。


使い分け判断フローチャート

次の質問で置き場所を決めると迷いません。

  1. そのルールは全タスクで有効か?
  2. そのルールはドメイン手順か?
  3. 変更頻度は高いか?

判断:

  • 1がYesならシステムプロンプト
  • 2がYesならAgent Skill(SKILL.md)
  • 3が高いならAgent Skill寄り

実装例: サポートエージェント(claude_agent_sdk)

claude_agent_sdk を使い、system_prompt オプションで役割・制約を定義しつつ、Agent Skill で手順を部品化する実装例です。

claude_agent_sdk の Skills は「APIアップロード不要」のファイルシステムベース。
.claude/skills/ ディレクトリに SKILL.md を置くだけで、SDK が自動検出します。

プロジェクト構成

support-agent/
├── .claude/
│   └── skills/
│       ├── rag-search/
│       │   └── SKILL.md
│       ├── todo-manager/
│       │   └── SKILL.md
│       └── conversation/
│           └── SKILL.md
└── main.py

ステップ1: SKILL.md ファイルを作成する

YAMLフロントマターの description が Level 1 メタデータとして常時読み込まれ、Claude がスキルを選ぶ判断基準になります。

.claude/skills/rag-search/SKILL.md

---
name: rag-search
description: FAQデータベースを検索して既存の回答を取得する。パスワードリセット、ログインエラー、機能の使い方など製品サポートの質問に使う。
---

# RAG検索

## 手順

1. ユーザーの質問からキーワードを抽出する
2. `search_faq(query)` でFAQデータベースを検索する
3. 検索結果がある場合: その内容をもとに回答する
4. 検索結果がない場合: todo-manager スキルでエスカレーションする

## 失敗時の対応

- 検索結果0件: 「担当者へ引き継ぎます」と伝え todo-manager へ委譲する
- タイムアウト: 1回再試行後、エスカレーションする

.claude/skills/todo-manager/SKILL.md

---
name: todo-manager
description: 未解決のサポートケースをTODOリストに登録して人間のオペレーターへエスカレーションする。rag-search で回答できなかった問い合わせに使う。
---

# TODOタスク管理

## タスク追加

1. 問い合わせ内容・ユーザーID・優先度(high/medium/low)を整理する
2. `create_todo(title, description, priority)` でタスクを登録する
3. 登録完了をユーザーに通知する

## 制約

- 優先度は high / medium / low の3段階
- 1リクエストにつき登録は1件まで

.claude/skills/conversation/SKILL.md

---
name: conversation
description: 日常的な挨拶・雑談・感謝の言葉に対応する。製品サポートに関係しない会話に使う。
---

# 日常会話

## 対応方針

- 自然で親しみやすいトーンで、1〜2文で簡潔に応答する
- 会話が落ち着いたらサポートの質問がないか一言添える

## 誘導例

「何かお困りのことがあれば、いつでもどうぞ!」

ステップ2: Python コードでシステムプロンプトと Skill を定義する

# main.py
import asyncio
from claude_agent_sdk import query, ClaudeAgentOptions

# システムプロンプト: エージェント全体の役割・優先順位・制約を定義する
SYSTEM_PROMPT = """
あなたはサポートエージェントです。

## 優先順位
1. 安全性(個人情報・パスワードは扱わない)
2. 正確性(不明なことは推測せず明示する)
3. 速度

## スコープ
- 対応: 製品サポート・技術的な質問
- 対応しない: 価格交渉・契約変更
"""


async def main():
    options = ClaudeAgentOptions(
        cwd="./support-agent",           # .claude/skills/ があるプロジェクトルート
        system_prompt=SYSTEM_PROMPT,     # システムプロンプトを直接指定
        setting_sources=["project"],     # .claude/skills/ を読み込む
        skills=["rag-search", "todo-manager", "conversation"],  # 有効にする Skill を指定
        allowed_tools=["Bash", "Read"],  # Claude が使えるツール
    )

    async for message in query(
        prompt="パスワードリセットの方法を教えてください",
        options=options,
    ):
        if hasattr(message, "result"):
            print(message.result)


asyncio.run(main())

すべての Skills を有効にする場合は skills="all" を使います。

options = ClaudeAgentOptions(
    cwd="./support-agent",
    system_prompt=SYSTEM_PROMPT,
    setting_sources=["project"],
    skills="all",            # 検出された全 Skill を有効化
    allowed_tools=["Bash", "Read"],
)

Skill が呼び出されるしくみ(参考)

SDK 起動時、setting_sources=["project"] によって .claude/skills/ 以下が走査され、各 Skill の description がシステムプロンプトのメタデータとして付加されます(Level 1 読み込み)。

[Claude が保持するメタデータ(~100 tokens/Skill)]
rag-search      - FAQデータベースを検索して既存の回答を取得する。...
todo-manager    - 未解決のサポートケースをTODOリストに登録して...
conversation    - 日常的な挨拶・雑談・感謝の言葉に対応する。...

「パスワードリセットの方法を教えてください」という質問が来ると、Claude は rag-search の description がマッチすると判断し、Bash ツールで .claude/skills/rag-search/SKILL.md を読み込みます(Level 2 読み込み)。手順を取得して初めて実行に移ります。


まとめ

Agent Skill は、肥大化するシステムプロンプトの「手順の詰め込み」問題を解消するために設計された仕組みです。

  • ファイルシステムベース: .claude/skills/*/SKILL.md に置くだけで SDK が自動検出
  • on demand 読み込み: 必要な Skill の手順だけがそのタスクのときに限りコンテキストへ入る
  • モジュール単位で変更・追加・削除: 他の Skill や本体のコードに影響しない

これにより、はじめに挙げた3つの課題が次のように解消されます。

課題 Agent Skill による解消
運用コスト Skillメタデータ(~100 tokens)のみ常時読み込み。手順は呼び出し時のみ
制御性 SKILL.md の description でマッチし Skill 名で一意に呼び出される。解釈ゆらぎがなくなる
柔軟性 手順の変更は該当 Skill ファイルだけを編集すればよい。他タスクへの影響ゼロ

結局、何をどこに書くか

書く場所 何を書くか 判断基準
システムプロンプト 役割・優先順位・禁止事項・回答スタイル 全タスクで一貫して効かせたいルール
Agent Skill(SKILL.md) タスク固有の手順・ツール呼び出し・品質チェック タスクが変われば変わる、再利用したい手順

機能が増えるたびにシステムプロンプトが膨らんでいくサイクルから抜け出せるのが、Agent Skill 最大のメリットです。

2
2
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
2
2

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?