はじめに
2025年9月、AnthropicのエンジニアリングブログにWriting effective tools for AI agents -- using AI agentsが公開された。AIエージェントに与えるツールをどう設計すべきか、Anthropic社内の実践知見をまとめた記事だ。
本記事では、この原文の要点を日本語で整理する。対象読者と得られる内容は以下の通り。
対象読者
- MCPサーバーを自作している、またはこれから作る方
- AIエージェント向けのツール設計に課題を感じている方
- Claude CodeやClaude Desktopを業務で組み込んでいる方
この記事で得られること
- Anthropicが提唱する5つのツール設計原則の具体的な理解
- 良いツール定義と悪いツール定義の違い
- MCPサーバー設計にすぐ活かせる実践的な指針
ツール設計がエージェントの能力を決める
原文は冒頭で、根本的な前提を示している。
Agents are only as effective as the tools we give them.
(エージェントは、与えられたツールの質でしか仕事ができない)
従来のソフトウェア開発では、関数やAPIは決定的(deterministic)なシステム同士の契約だった。getWeather("NYC")は何度呼んでも同じ手順でNYCの天気を取得する。
しかしエージェントは非決定的(non-deterministic)だ。「今日傘いる?」と聞かれたとき、天気ツールを呼ぶかもしれないし、一般知識から答えるかもしれない。場所を聞き返す可能性もある。時にはハルシネーションを起こし、ツールの使い方を間違えることすらある。
つまりツールとは、決定的システムと非決定的エージェントの間に結ぶ新しい種類の契約だ。
この前提を踏まえると、ツール設計に必要な姿勢が変わる。
| 従来のAPI設計 | エージェント向けツール設計 |
|---|---|
| 開発者が仕様書を読んで使う | エージェントが説明文だけで使う |
| 型と引数名で意図を伝える | 名前・説明・パラメータすべてがプロンプト |
| エラーはスタックトレースで調査 | エラーはエージェントの推論を狂わせる |
| 冗長なレスポンスも許容 | トークン消費が直接コストと性能に影響 |
原文はこの考え方をACI(Agent-Computer Interface)と表現している。HCI(Human-Computer Interface)に匹敵する設計努力をツールにも注ぐべきだ、という主張だ。
原文の表現を借りれば、「エージェントにとって使いやすいツールは、人間にとっても直感的に理解しやすい」。ACI設計は結果として開発者体験の向上にもつながる。
5つの設計原則
原文が示す5つの原則を順に解説する。
原則1: 高レバレッジなツールを選ぶ
ツールは多ければ良いわけではない。原文が指摘する典型的な失敗は、既存のAPI機能をそのまま薄いラッパーとしてツール化するパターンだ。
エージェントには固有の「アフォーダンス」がある。従来のソフトウェアとは異なる方法でアクションを認識し実行する。ツール設計では、エージェントの能力を意味のある形で拡張するものを選ぶ。
選定の判断基準
- そのツールがないとエージェントが達成できないタスクがあるか
- 複数のAPI呼び出しを1つのツールに統合して認知負荷を下げられるか
- エージェントが頻繁に必要とする操作か
CRUDの全操作を機械的にツール化するのは避ける。エージェントが実際に使うパターンを観察し、高頻度・高価値の操作に絞ること。
原則2: 名前空間で境界を明確にする
ツール名にはサービスやリソースの名前空間を含める。MCPクライアントはデフォルトでこれを行う場合もあるが、意識的に設計すべきだ。
# サービスで分類する例
asana_search
jira_search
slack_search
# リソースで分類する例
asana_projects_search
asana_users_search
名前空間を適切に設計すると、2つの効果がある。
- エージェントのコンテキストに読み込まれるツール数と説明文を削減できる
- エージェントのタスク判断の一部をツール名自体に委譲できる
プレフィックス型(slack_search_messages)とサフィックス型(search_slack_messages)の選択は、ツール利用の評価結果に無視できない影響を与える。効果はLLMごとに異なるため、自分の環境で評価して決めること。
原則3: 意味のあるコンテキストを返す
ツールのレスポンスは、エージェントが次のアクションを判断するための「高シグナル」な情報だけに絞る。
| 避けるべきフィールド | 望ましいフィールド |
|---|---|
uuid |
name |
256px_image_url |
image_url |
mime_type |
file_type |
created_at_epoch |
created_at(ISO 8601形式) |
低レベルの技術的識別子よりも、自然言語に近い識別子のほうがエージェントの下流の判断に直接役立つ。
ツール説明を書くときは、チームの新入社員にツールを説明する場面を想像する。自分が暗黙的に持っている知識を明示的にするのがポイントだ。
- クエリの書式
- 専門用語の定義
- リソース間の関係
原則4: トークン効率を最適化する
レスポンスの肥大化はコスト増と性能低下に直結する。原文は以下の手法を推奨している。
ページネーション・フィルタリング・トランケーション
デフォルト値を適切に設定し、必要に応じて絞り込めるようにする。
レスポンスフォーマットのenum化
response_formatパラメータを用意し、DETAILEDとCONCISEを切り替えられるようにする。
{
"name": "search_messages",
"parameters": {
"query": "プロジェクト進捗",
"response_format": "CONCISE"
}
}
原文のSlackツールの例では、DETAILEDが206トークン、CONCISEが72トークンと報告されている。約3分の1までトークンを削減できた計算だ。
DETAILEDレスポンスにはthread_ts、channel_id、user_idなどの技術的IDが含まれる。これらは後続のツール呼び出し(スレッド返信の取得など)に必要な場合がある。CONCISEはスレッドの内容のみを返し、IDは省略する。
レスポンスは25,000トークン以下に抑えることが推奨されている。これを超えるとエージェントの推論性能が低下する。
原則5: ツール説明をプロンプトエンジニアリングする
ツール定義のname、description、パラメータのdescriptionはすべてプロンプトだ。エージェントはこれらのテキストを手がかりにツールを選び、パラメータを構成する。
原文で報告されている2つの事例を紹介する。
事例1: SWE-benchでのSOTA達成
Claude Sonnet 3.5がSWE-bench Verifiedで49%を達成し、当時のSOTA(45%)を更新した。モデルの変更ではなく、ツール説明の精緻な改善がこの結果をもたらした。エラー率が大幅に減少し、タスク完了率が向上した。
事例2: Web検索ツールの「2025」問題
ClaudeのWeb検索ツールをリリースした際、Claudeがqueryパラメータに不要な「2025」を付加し続ける問題が発生した。検索結果に偏りが生じ、性能が低下した。ツール説明の改善だけでこの問題を解決できた。
ツール説明で意識すべきポイントは以下の通り。
- いつそのツールを使うべきかを明示する
- 必須パラメータと任意パラメータを区別する
- 期待される出力の形式を記述する
- 使用例やエッジケースを含める
- 他のツールとの境界を明確にする
良いツール定義と悪いツール定義の比較
原文の考え方に基づき、具体的な比較を示す。
ツール名と説明
// 悪い例
{
"name": "query_db_orders",
"description": "Execute order query"
}
// 良い例
{
"name": "search_customer_orders",
"description": "Search for customer orders by date range, status, or total amount. Returns order details including items, shipping, and payment info."
}
悪い例は内部実装(db)が名前に漏れている。説明も短すぎて、何ができるか判断できない。良い例は検索条件と返却内容が明確だ。
パラメータ定義
// 悪い例
{
"parameters": {
"user": { "type": "string" }
}
}
// 良い例
{
"parameters": {
"user_id": {
"type": "string",
"description": "The unique user identifier (e.g., 'usr_abc123'). Required."
}
}
}
userという名前は、ユーザー名なのかIDなのかオブジェクトなのか曖昧だ。user_idと明示し、フォーマット例を添えることで誤用を防ぐ。
レスポンス設計
// 悪い例: 生データをすべて返す
{
"id": "550e8400-e29b-41d4-a716-446655440000",
"256px_image_url": "https://cdn.example.com/img/550e8400.png",
"mime_type": "image/png",
"created_at_epoch": 1694448000,
"internal_flags": ["FLAG_A", "FLAG_B"]
}
// 良い例: エージェントが必要な情報に絞る
{
"name": "Project Alpha Logo",
"image_url": "https://cdn.example.com/img/project-alpha-logo.png",
"file_type": "png",
"created_at": "2025-09-11"
}
UUIDや内部フラグはエージェントの判断に寄与しない。トークンを消費するだけだ。
MCPサーバー設計への応用
Anthropicの5原則をMCPサーバー自作に適用する際の指針を整理する。
ツール数を絞る
MCPサーバーは数十のツールを公開できる。しかし、すべてを公開するとエージェントのコンテキストを圧迫する。
実践的なアプローチは以下の通り。
- まず3〜5個の核となるツールで始める
- 評価を回して不足を特定する
- 不足が確認できたツールだけを追加する
説明文にllms.txtを活用する
Claude Codeでツールを実装する際、関連するAPIやSDKのllms.txtファイルを読み込ませると、適切なツール説明を生成しやすい。多くの公式ドキュメントサイトがLLM向けのllms.txtを提供し始めている。
レスポンスにフォーマット切替を実装する
MCPツールのinputSchemaにresponse_formatパラメータを追加する。
{
"name": "search_issues",
"description": "Search project issues by keyword, status, or assignee.",
"inputSchema": {
"type": "object",
"properties": {
"query": {
"type": "string",
"description": "Search keyword for issue title or body."
},
"response_format": {
"type": "string",
"enum": ["DETAILED", "CONCISE"],
"description": "CONCISE returns title and status only. DETAILED includes assignee, labels, and full description.",
"default": "CONCISE"
}
},
"required": ["query"]
}
}
デフォルトをCONCISEにしておけば、通常の操作ではトークンを節約できる。詳細が必要な場面ではエージェントがDETAILEDに切り替える。
トランケーションとページネーション
大量のデータを返すツールには、必ず上限とページネーションを設ける。
{
"name": "list_documents",
"inputSchema": {
"type": "object",
"properties": {
"limit": {
"type": "integer",
"description": "Maximum number of results. Default: 20, Max: 100.",
"default": 20
},
"offset": {
"type": "integer",
"description": "Number of results to skip for pagination.",
"default": 0
}
}
}
}
上限を超えた場合は、件数と取得方法を示すメッセージを含める。
[Results truncated. 150 total matches. Use offset parameter to access remaining results.]
名前空間の一貫性
1つのMCPサーバー内でも、ツール名のプレフィックスを統一する。
# 一貫した命名
github_search_issues
github_get_pull_request
github_list_repositories
# 一貫していない命名(避ける)
search_github_issues
github_get_pull_request
listRepos
よくある失敗パターン
原文の知見を踏まえて、ツール設計のアンチパターンを整理する。
1. CRUDの全自動ツール化
REST APIのエンドポイントを1対1でツール化するパターンだ。20個のエンドポイントが20個のツールになり、エージェントのコンテキストを圧迫する。エージェントが実際に使う操作は3〜5個であることが多い。
2. 説明なしパラメータ
{
"parameters": {
"q": { "type": "string" },
"t": { "type": "integer" },
"f": { "type": "boolean" }
}
}
省略形のパラメータ名は人間でも読みにくい。エージェントにとっては致命的だ。名前と説明の両方で意図を伝える。
3. 巨大レスポンスの垂れ流し
フィルタリングやページネーションなしに数百件のレコードを一括で返す。25,000トークンを超えるレスポンスはエージェントの推論を劣化させる。
4. エラーメッセージの軽視
// 悪い例
{ "error": "400" }
// 良い例
{
"error": "Invalid date format for 'start_date'. Expected ISO 8601 (YYYY-MM-DD). Received: '2025/09/11'."
}
エージェントが自力でリカバリできる情報をエラーに含める。ステータスコードだけでは次の行動を判断できない。
5. 暗黙知への依存
「このAPIは先にauth_tokenを取得してから呼ぶ」「日付はUTC前提」といった暗黙の前提は、ツール説明に明記する。新入社員に説明するつもりで書く。
6. レスポンス構造の不統一
同じMCPサーバー内で、あるツールはJSONを返し、別のツールはMarkdownを返す。エージェントの処理パターンが安定しなくなる。レスポンスの構造は統一すべきだ。
評価駆動でツールを改善する
原文が強調するのは「Prototype → Evaluate → Collaborate」の反復プロセスだ。
ステップ1: プロトタイプ
ローカルのMCPサーバーやDesktop Extensionで素早くプロトタイプを立ち上げる。Claude Codeを使えば、llms.txtを読み込ませてワンショットでツールを実装できる。
ステップ2: 評価
実世界のユースケースに基づく評価タスクを作成する。
良い評価タスクの特徴
- 複数のツール呼び出しが必要(場合によっては数十回)
- 現実のデータソースやサービスに基づいている
- プログラムで検証可能な期待結果がある
悪い評価タスクの特徴
- 単一のツール呼び出しで完了する
- サンドボックス環境で複雑さが不足している
- 手動でしか検証できない
| 評価タスクの例 | 判定 |
|---|---|
| 「顧客ID 9182が3回請求されたと報告。調査して解決策を提示せよ」 | 良い。複数ツール・推論・判断が必要 |
「payment_logsでpurchase_completeを検索せよ」 |
悪い。単一操作で推論不要 |
収集すべきメトリクスは以下の通り。
- タスク全体の正解率
- 個別ツール呼び出しの実行時間
- ツール呼び出しの総回数
- 合計トークン消費量
- ツールエラーの発生回数と種類
冗長なツール呼び出しが多い場合は、ページネーションやトークン上限の調整が有効だ。無効なパラメータによるエラーが多い場合は、ツール説明の改善や使用例の追加を検討する。
ステップ3: エージェントとの協働
評価結果の分析にもClaude Codeを活用する。評価エージェントのトランスクリプト(ツール呼び出しとレスポンスを含む生ログ)をClaude Codeに渡すと、複数ツールの一括リファクタリングを実行できる。
原文によれば、記事中のアドバイスの大部分が、Claude Codeを使って社内ツール実装を繰り返し最適化する中から生まれた。
まとめ
Anthropicの原文から得られる要点を整理する。
根本的な前提
- ツールは決定的システムと非決定的エージェントの契約だ
- 従来のAPI設計のベストプラクティスはそのまま適用できない
5つの設計原則
| 原則 | 要約 |
|---|---|
| 高レバレッジなツール選定 | 数より質。エージェントの能力を意味ある形で拡張する |
| 名前空間の設計 | サービスやリソースで分類し、ツール選択精度を上げる |
| 意味のあるコンテキスト | 高シグナルな情報だけ返す。技術的IDは最小限に |
| トークン効率の最適化 | ページネーション、フォーマット切替、25,000トークン上限 |
| ツール説明のプロンプトエンジニアリング | 名前・説明・パラメータすべてがプロンプト。反復改善する |
改善プロセス
- Prototype → Evaluate → Collaborateを繰り返す
- 評価タスクは実世界の複雑さを反映させる
- Claude Code自体をツール改善のパートナーとして使う
ツール設計にどれだけの労力を注ぐべきか。原文の一節を引用して締めくくる。
Think about how much effort goes into human-computer interfaces (HCI), and plan to invest just as much effort in creating good agent-computer interfaces (ACI).
HCIにかける労力と同じだけACIにもかける。ツール設計はエージェントの性能を決定する最も直接的な介入手段だ。