必要に応じて読み込むスキルの作成
モデルが関連する際にのみ取得する機能をパッケージ化し、エージェントにアタッチします。
list_skillscreate_skillupdate_agenttest_skill_trigger原則 — スキルの数を少なく保つ。 エージェントの業務に必要なもののみをアタッチする(約5つ以下)。モデルは1行の
descriptionからスキルを選択します。アタッチする数が増えるほど、間違ったスキルやどのスキルも読み込まれる頻度が高くなります。 いつ 使用するかの重複がある場合は、スキルをマージしてください。詳細は 設計原則 を参照してください。
スキル はオンデマンドで読み込まれる機能パックです:システムプロンプトには description(「いつ使用するべきか」)のみが含まれ、モデルはスキルの関連性を判断した場合にのみ、完全な instructions を取得します。したがって、description は短く、いつ を示すものでなければなりません。さもないと、モデルはそれにアクセスすべきかどうかを知りません。
list_skills() # what already exists
create_skill(
name="refund-policy",
description="Use when the user asks about refunds, cancellations or chargebacks.",
instructions="The full procedure: eligibility windows, how to word the outcome, when to escalate …",
)
update_agent(name="Support", add_skills=["refund-policy"]) # attach it (incremental — keeps existing skills)手順はエージェントの soul(プロンプトの一部であり、すべてのターンで存在する)ではなく、instructions(読み込み時に取得される)に記述してください。いつ を示す1行の description が、スキルを発見可能にするものです。曖昧な description では、モデルはそれを取得しません。
ツールはスキルに同乗できる
スキルは独自のツールバインディングを保持できます — create_skill(tools=[…]) または
update_skill(name, add_tools=[…]) を使用することで、手順と必要なツールを1回の操作でアタッチし、自己完結型の機能として提供できます。
スキルのツールは、スキルが読み込まれた後にのみ利用可能になります。 開始時のツールセットには含まれておらず、スキルを読み込むことでそこに追加されます。したがって、順序は固定されています:手順を読み、次にツールを取得する — モデルはツールに飛び越えて即興で処理することはできません。
この順序はプロンプトで要求するのではなく、コードで強制されます。プロンプトで要求しても機能しなかったためです。2026-08-22 に測定したところ、「企業 X の競合他社を調査する」というタスクで、手順とツールを同時に渡した場合、モデルはウェブ検索を3回呼び出し、スキルを全く読み込みませんでした。モデルは記憶から競合他社の名前を捏造し、その捏造された名前で検索して何も見つからず(それらは存在しません)、捏造された名前を回答として記載しました — 手順のステップ1で「まず、この企業が実際に何を販売しているかを確立する」と書かれていたにもかかわらず、その手順は読みませんでした。任意の手順は読み込まれません。
これに依存する前に知っておくべき2つの事項:
- スキルのツールは、エージェント自身の
toolsリストには表示されません。get_agentはエージェントに直接アタッチされたツールのみを表示します。コンソールの [Tools] タブでは、スキルにバインドされたツールは「via skills」という別の読み取り専用行として表示されます。「ツール X が有効かどうか」を確認する場合は、両方の場所を確認するか、テストチャットでツールを呼び出すだけです。 - エージェントが既に持っているツールは影響を受けません。 エージェント自体が
web_searchを持っている場合、それはすべてのターンで利用可能であり続けます。スキルに起因して追加されるツールのみが、そのスキルの読み込みを待ちます。 - ツールを スキル にバインドするのは、その手順内でのみ意味をなす場合(返金スキルの内部での返金照会)です。 エージェント にバインドするのは、ターン全体で一般的に有用な場合(
save_contact、web_search)です。
ツールのバインディングは可用性であり、ポリシーではない — 呼び出すべきタイミングは手順に記述する
スキル(またはエージェント)でツールをチェックすることは、そのツールを 呼び出し可能 にするだけです。モデルはスキーマと1行の description をすべてのターンで確認するため、機会主義的に使用することがあります — 訪問者がメールアドレスを申し出ると、save_contact が実行されます。しかし、確実に発生する必要がある動作はすべて書き留める必要があり、その各部分には適切な配置場所が1つあります:
| 指定する内容 | 配置場所 |
|---|---|
| このスキルを読み込むタイミング | スキルの description (すべてのターンでプロンプトに含まれる) |
| 手順:どのステップでどのツールをどの引数で呼び出すか | スキルの instructions — ツール名を明示する(「発注者が興味を確認した後、メールと電話番号で save_contact を呼び出し、その後、1営業日後に schedule_followup を呼び出す」) |
| 会話全体を駆動する必要がある動作(リードを常に取得する、料金を決して引用しない) | エージェントの soul / task |
手順でツール名を指定しない場合の失敗モード:すべてが 設定されているように見える — ツールはチェックされ、スキルは読み込まれる — にもかかわらず、エージェントはそれを呼び出さないか、推測された引数で呼び出します。エラーは発生しません。新人に指示を出すかのように手順を記述してください:ステップ、ツール名、引数、そして「完了」がどのように見えるか。
必須のツール呼び出し:トリガーは instructions のみに存在せず、description に存在しなければならない
instructions は、モデルが load_skill を呼び出した 後にのみ モデルに表示されます — モデルは頻繁に、スキルを読み込まずに直接回答します。したがって、「ユーザーが電話番号を提供した場合、save_contact を呼び出さなければならない」というルールが instructions のみに記述されている場合、それが重要となる瞬間にそのルールは不可視になります:ツールは静かに呼び出されず、モデルは連絡先を保存したと主張することさえあります。これは本番環境で発生しました — エージェントは連続して連絡先を含むメッセージに回答し、詳細が記録されたことを「確認」しましたが、記録は存在しませんでした。
修正策は、description (これは すべてのターンでシステムプロンプトに含まれる)に1文を追加することです:
update_skill(
name="consultative-sales",
description="Consultative sales: understand the case, recommend products, arrange expert callbacks. "
"When the user provides a phone number or email, call save_contact BEFORE answering anything else.",
)詳細な手順は instructions に保持し、必須呼び出しの トリガー を description に配置してください。
2つの関連するルール:
- ツールが生成しない戻り値をスクリプトしないでください — 実際の値をそのまま中継してください。 組み込みの
save_contactとschedule_followupは、成功時に 実際の参照コード(形式AB2C-D3EF、サーバー側に保存され、エンドユーザーの詳細ページでテナントに表示可能)を返します。モデルに、ツール結果からのコード をそのまま中継するよう指示してください — 1つを捏造したり、#12345のようにフォーマットしたりしないでください。その他のツールについては、スクリプトする前に実際に ID を返すことを確認してください:約束されたが欠落している ID は捏造されます。 create_skill/update_skill/get_skillはwarningsリストを返すようになりました これにより、これら2つのパターン(trigger_hidden_in_instructions、promised_tool_return_id)が正確にフラグ付けされます。警告は advisory(助言)です — 保存は成功します — が、リンターのように扱ってください:修正し、無視しないでください。
instructions 内の実例はツール呼び出しの遵守率を計測可能に向上させる
これは本番バックエンドでベンチマークしました(難易度が異なる6件のリード取得メッセージ — 長い質問に埋め込まれた番号、スペース付きの数字グループ、修正 — 各条件ごとにサンプリング)。スキルが読み込まれた状態で、単純な「X を呼び出さなければならない」という指示では 3–4/6 でした。短い実例のブロックを追加すると、テストされた両方のモデルで 6/6 になりました。指示セクションの移動は何も変化させませんでした — 位置は重要ではなく、実例が重要 です。
効果的な実例ブロックには、4種類のエントリがあり、それぞれ1行です:
### Worked examples (follow exactly)
1. User: "I'd like to know about X, my phone is 13800138000"
→ call save_contact(phone="13800138000") first, then answer about X.
2. User: "email me the offer: li@example.com"
→ call save_contact(email="li@example.com").
3. COUNTER-EXAMPLE (forbidden): user gives a phone number and you reply
"I've noted it down" WITHOUT calling the tool — claiming success without
the call is the worst failure.
4. User: "sorry, wrong number — it's 13633334444"
→ call save_contact again with the corrected value.
5. Numbers may contain spaces ("138 0013 9000") — still a phone number;
strip the spaces and call save_contact(phone="13800139000").反例(3)とフォーマットの境界ケース(5)は、残りのミスの大部分を閉じます — モデルは 認識(「これは電話番号か?」)と 圧力下での誠実さ(豊富なドメインの質問に先に答え、保存が発生したと主張する)において、意欲よりも失敗します。エントリは約5件に保ち、実際の引数を使用して正確な呼び出し構文を使用してください。
出荷前にトリガーをテストする — 本番環境で死体を数えないでください
スキルが 実際に 発火するかどうかは計測可能なので、計測してください。test_skill_trigger は、本番 プロンプトアセンブリ、ツールスキーマ、モデルルーティングに対してメッセージをドライランし、モデルの判断を報告します — ツールは実行されず、何も保存されず、トークンカウントはクォータに含まれます(上限:5メッセージ × 5サンプル)。
test_skill_trigger(
agent="advisor",
messages=[
"My phone is 555 0123, call me back", # easy
"long question about the product … oh and my number is 555 0123", # buried
"555 0123 — that's me", # implicit
"sorry, wrong number, it's 555 9999", # correction
],
expect_tool="save_contact",
samples=3,
loaded=true, # simulate post-load_skill → tests instructions quality
) # loaded=false (default) → first turn, tests the description trigger結果は以下のように読み取ってください:
hit_rateが現実的なメッセージで ~90% 未満の場合 → トリガー(description)を強化するか、実例(instructions)を追加し、再テストしてください。claimed_without_call> 0 は最悪の失敗です — モデルはツールを呼び出さずにユーザーに「了解しました!」と伝えました。上記のブロックから反例を追加してください。- 両方のモード でテストしてください:
loaded=falseは、説明のみが最初のターンでトリガーされることを証明します。loaded=trueは、読み込まれた手順がそれを希釈しないことを証明します(長い手順は確かに希釈します — それが実例が補償するものです)。
結果には advice リストも含まれます:サンプルが外れるか嘘をつく場合、どの修正を適用するかを正確に伝えます(トリガーを description に追加、実例ブロックの追加、反例またはフォーマットの境界ケースの追加)と、各推奨事項の背後にあるベンチマーク数値 — 適用して再テストしてください。
完全なループ:create_skill → warnings(静的リンター)を修正 → test_skill_trigger(動的現実チェック)→ その advice を適用 → 遵守率が維持されるまで再テスト。