devtu-fix-tool について
ToolUniverse ツールの障害を診断・修正する、設定や実装、テストを保守する開発者向けスキルです。CLI で再現を確認し、エラー種別に応じて根本原因を修正してから検証します。
主な機能
- 01CLI で障害の再現を先に確認
- 02エラー種別から設定・コード修正を特定
- 03API ドキュメントとパラメーター定義を確認
- 04ツール設定とテストの更新
- 05ツール再生成と検証の実行
活用シーン
- 01応答データとスキーマの不整合を調査
- 02パラメーター検証や API エンドポイントの修正
- 03修正後の統合テストと単体テストの確認
インストール
コマンドをコピーしてターミナルで実行します。
npx skills add https:/ / github.com/ mims-harvard/ tooluniverse --skill devtu-fix-toolインストール後、Claude Code で/devtu-fix-toolを入力して読み込まれたか確認します。
同梱ファイル
SKILL.md と一緒にインストールされる参考資料やスクリプト。
EXAMPLES.mdQUICK-REFERENCE.mdunit-tests-reference.md詳細
ToolUniverse ツールの修正
エラーの体系的な特定、的を絞った修正、検証を通じて、失敗する ToolUniverse ツールを診断し、修正します。
バグ修正の基本原則
修正を書く前に、次の点を確認してください。なぜユーザーはこの失敗状態に陥るのでしょうか?
- 復旧するのではなく、予防する — 失敗後にヒントを追加するのではなく、失敗が起きないよう根本原因を修正します
- 出力時ではなく入力時に検証する — 誤ったパラメーター、不明な疾患名、未対応の薬剤は、サイレントな API 呼び出しの後に判明させるのではなく、明確なガイダンスとともに早期に検出して拒否します
- サイレントな変更を隠さない — 入力が自動正規化される場合(融合表記、タイトルケース)、両方の形式をネイティブに受け入れるか、明確なガイダンスとともに拒否します。サイレントに変換して隠すことは避けてください
- 「データなし」と「クエリ不正」を区別する — フィルターが誤っているために結果がゼロ件になる場合と、データが存在しないためにゼロ件になる場合は異なります。レスポンスではこの違いを明確に示す必要があります
- 個々の事例ではなく、抽象化を修正する — パラメーター名に一貫性がない場合は、インターフェイスを修正します。増え続けるエイリアスのリストを追加するのではありません
避けるべきアンチパターン:
- 事前に検証せず、結果がゼロ件のメッセージにヒントを追加する
- 命名の一貫性を修正せず、パラメーターのエイリアスを追加する
- 事前検証する代わりに、クエリの失敗後に調査して救済しようとする
バグの検証(重要)
バグ報告に対応する前に、まず CLI で検証してください:
python3 -m tooluniverse.cli run <ToolName> '<json_args>'
エージェントから報告されるバグの多くは、MCP インターフェイスの混乱による誤検知です。修正を実装する前に、必ずバグが再現可能であることを確認してください。
手順
失敗するツールを修正する場合:
- 対象を絞ったテストを実行してエラーを特定します:
python scripts/test_new_tools.py <tool-pattern> -v
-
API が正しいことを確認します — 公式 API ドキュメントをオンラインで検索し、エンドポイント、パラメーター、使用パターンが正しいことを確認します
-
エラーの種類を特定します(「エラーの種類」セクションを参照)
-
エラーパターンに応じて適切な修正を適用します
-
JSON 設定またはツールクラスを変更した場合は、ツールを再生成します:
python -m tooluniverse.generate_tools
tests/tools/にツールテストが存在する場合は、確認して更新します:
ls tests/tools/test_<tool-name>_tool.py
-
統合テストとユニットテストを再実行して修正を検証します
-
問題、根本原因、解決策、テスト結果を含む修正概要を提示します
修正箇所
| 問題の種類 | 変更するファイル |
|---|---|
| バイナリレスポンス | src/tooluniverse/*_tool.py + src/tooluniverse/data/*_tools.json |
| スキーマの不一致 | src/tooluniverse/data/*_tools.json(return_schema) |
| データラッパーの欠落 | src/tooluniverse/*_tool.py(操作メソッド) |
| エンドポイント URL | src/tooluniverse/data/*_tools.json(endpoint フィールド) |
| 無効なテスト例 | src/tooluniverse/data/*_tools.json(test_examples) |
| ツールテストの更新 | tests/tools/test_*_tool.py(存在する場合) |
| パラメーターとしての API キー | src/tooluniverse/data/*_tools.json(パラメーターを削除)+ *_tool.py(環境変数を使用) |
| ツールが読み込まれない(任意キー) | src/tooluniverse/data/*_tools.json(required_api_keys ではなく optional_api_keys を使用) |
エラーの種類
1. JSON 解析エラー
症状:Expecting value: line 1 column 1 (char 0)
原因:ツールは JSON を想定していますが、バイナリデータ(画像、PDF、ファイル)を受け取っています
修正方法:Content-Type ヘッダーを確認します。バイナリレスポンスの場合は、JSON を解析する代わりに説明文字列を返します。return_schema を {"type": "string"} に更新します。
2. スキーマ検証エラー
症状:Schema Mismatch: At root: ... is not of type 'object' または Data: None
原因:data フィールドのラッパーがない、またはスキーマの型が誤っています
修正方法はエラーによって異なります:
Data: Noneの場合 → すべての操作メソッドにdataラッパーを追加します(下記の「複数操作パターン」を参照)- 型が一致しない場合 → JSON 設定の
return_schemaを更新します:- データが文字列の場合:
{"type": "string"} - データが配列の場合:
{"type": "array", "items": {...}} - データがオブジェクトの場合:
{"type": "object", "properties": {...}}
- データが文字列の場合:
重要な概念:スキーマはレスポンス全体ではなく、data フィールドの内容を検証します。
3. Null 許容フィールドのエラー
症状:Schema Mismatch: At N->fieldName: None is not of type 'integer'
原因:API がオプションフィールドに None/null を返します
修正方法:JSON 設定で {"type": ["<base_type>", "null"]} を使用して、null 許容型を指定します。オプションフィールドに使用し、必須の識別子には使用しないでください。
4. 相互排他的なパラメーターのエラー
症状:別のパラメーターを渡したときに、Parameter validation failed for 'param_name': None is not of type 'integer' が発生します
原因:ツールは paramA または paramB のどちらか一方を受け付けますが、両方が固定型で定義されています。一方だけを指定すると、もう一方が None になるため、検証に失敗します。
例:
{
"neuron_id": {"type": "integer"}, // ❌ Fails when neuron_name is used
"neuron_name": {"type": "string"} // ❌ Fails when neuron_id is used
}
修正方法:相互排他的なパラメーターを null 許容にします:
{
"neuron_id": {"type": ["integer", "null"]}, // ✅ Allows None
"neuron_name": {"type": ["string", "null"]} // ✅ Allows None
}
一般的なパターン:
idまたはnameパラメーター(ID または名前で取得)acronymまたはnameパラメーター(記号または正式名称で検索)- 指定されない場合があるオプションのフィルターパラメーター
重要:相互排他的でない場合でも、真にオプションのパラメーター(filter_field、filter_value など)も null 許容にしてください。
5. 混在型フィールドのエラー
症状:Schema Mismatch: At N->field: {object} is not of type 'string', 'null'
原因:コンテキストによってフィールドが異なる構造を返します
修正方法:複数の異なるスキーマを持つフィールドには、JSON 設定で oneOf を使用します。これは、同じ基本型と null を指定する null 許容型({"type": ["string", "null"]})とは異なります。
6. 無効なテスト例
症状:404 ERROR - Not found または 400 Bad Request
原因:テスト例で無効または古い ID を使用しています
修正方法:以下のリスト → 取得、または検索 → 詳細のパターンを使って、有効な例を見つけます。
7. API パラメーターのエラー
症状:400 Bad Request またはパラメーター検証エラー
修正方法:正しい型、必須フィールド、列挙値を指定して、JSON 設定のパラメータースキーマを更新します。
8. API キー設定のエラー
症状:API キーがオプションの場合にツールが読み込まれない、または api_key パラメーターが混乱を招く
原因:オプションにすべきキーに required_api_keys を使用している、または API キーをツールパラメーターとして公開している
主な違い:
required_api_keys:キーがない場合、ツールはスキップされますoptional_api_keys:キーがなくてもツールは読み込まれて動作します(パフォーマンスは低下します)
修正方法:匿名でも動作するものの、キーがあるとレート制限が緩和される API には、JSON 設定で optional_api_keys を使用します。API キーは環境変数からのみ読み込み(os.environ.get())、ツールパラメーターとしては使用しないでください。
9. API エンドポイントパターンのエラー
症状:有効なリソースで 404 が発生する、または予期しない結果が返される
修正方法:公式 API ドキュメントを確認し、値を URL パスとクエリパラメーターのどちらに含めるべきかを確かめます。
10. 一時的な API エラー
症状:タイムアウト/接続/5xx エラーにより、テストが断続的に失敗します
修正方法:単体テストでは、一時的なエラーに pytest.skip() を使用します。外部 API の停止によってテストを失敗させないでください。
よくある修正パターン
スキーマ検証パターン
スキーマが検証するのは応答全体ではなく、data フィールドの内容です。return_schema の型を、data の中身(配列、オブジェクト、文字列)に合わせてください。
複数操作ツールのパターン
すべての内部メソッドは {"status": "...", "data": {...}} を返す必要があります。トップレベルで別のフィールド名を使用しないでください。
有効なテスト例を見つける
テスト例が 400/404 で失敗した場合は、次の方法で有効な ID を見つけます:
- リスト → 取得:最初にリストエンドポイントを呼び出し、結果から ID を抽出します
- 検索 → 詳細:既知のエンティティを検索し、返された ID を使用します
- バージョンを順に試す:対応している場合は、異なるデータセットのバージョンを試します
単体テストの管理
単体テストの確認
ツールを修正した後、単体テストがあるか確認します:
ls tests/tools/test_<tool-name>_tool.py
ユニットテストを更新するタイミング
次の場合は、ユニットテストを更新してください。
- 戻り値の構造を変更する場合:
result["data"]の構造を確認するアサーションを更新します - 操作を追加/変更する場合:新しい操作のテストケースを追加します
- エラー処理を変更する場合:エラーに関するアサーションを更新します
- 必須パラメーターを変更する場合:パラメーター検証テストを更新します
- スキーマの問題を修正する場合:テストで正しいデータ構造を検証できるようにします
- バイナリ処理を追加する場合:バイナリ応答のテストを追加します
ユニットテストの実行
# Run specific tool tests
pytest tests/tools/test_<tool-name>_tool.py -v
# Run all unit tests
pytest tests/tools/ -v
ユニットテストのチェックリスト
-
tests/tools/test_<tool-name>_tool.pyが存在するか確認します - 修正の前後にユニットテストを実行します
- データ構造が変更された場合はアサーションを更新します
- 直接テストとインターフェーステストの両方が成功することを確認します
ユニットテストのパターンと例について詳しくは、unit-tests-reference.md を参照してください。
検証
統合テストの実行
python scripts/test_new_tools.py <pattern> -v
ユニットテストの実行(存在する場合)
pytest tests/tools/test_<tool-name>_tool.py -v
ツールの再生成
JSON 設定またはツールクラスを変更した後は、次を実行します。
python -m tooluniverse.generate_tools
次の場合は再生成してください。
src/tooluniverse/data/*_tools.jsonファイルを変更した場合- ツールクラスの実装を変更した場合
テストスクリプトの変更では再生成は不要です。
出力形式
修正後、次の概要を提示してください。
問題:[問題の簡単な説明]
根本原因:[失敗した理由]
解決策:[変更した内容]
変更内容:
- ファイル 1:[説明]
- ファイル 2:[説明]
- ファイル 3(該当する場合):[ユニットテストの更新]
統合テストの結果:
- 修正前:X 件のテスト、Y 件成功(Z%)、N 件失敗、M 件のスキーマが無効
- 修正後:X 件のテスト、X 件成功(100.0%)、0 件失敗、0 件のスキーマが無効
ユニットテストの結果(該当する場合):
- 修正前:X 件のテスト、Y 件成功、Z 件失敗
- 修正後:X 件のテスト、X 件成功、0 件失敗
テストのベストプラクティス
テスト前にパラメーター名を確認する
重要:正しいパラメーター名を確認するため、必ずツールの JSON 設定または生成されたラッパーを読んでください。パラメーター名を推測しないでください。
誤ったテストの例:
# ❌ WRONG - assumed parameter name
AllenBrain_search_genes(query='Gad1') # Fails: unexpected keyword 'query'
正しい方法:
# ✅ RIGHT - checked config first
# Config shows parameters: gene_acronym, gene_name
AllenBrain_search_genes(gene_acronym='Gad1') # Works!
正しいパラメーター名の確認方法:
- JSON 設定を読みます:
src/tooluniverse/data/*_tools.json - 生成されたラッパーを確認します:
src/tooluniverse/tools/<ToolName>.py - JSON 設定内の test_examples を確認します
系統的なテスト方法
複数のツールをテストする場合:
- まずサンプルをテストする:API ごとに 1~2 個のツールをテストし、パターンを特定します
- エラーを分類する:エラーの種類(パラメーター検証、API エラー、データ構造)ごとにまとめます
- 系統的に修正する:同じ種類の問題があるツールをまとめて修正します
- 一度だけ再生成する:すべての JSON の変更後に
python -m tooluniverse.generate_toolsを実行します - すべてを検証する:修正したすべてのツールを徹底的にテストします
データ構造を理解する
ツールが返すデータ構造はさまざまです。
- オブジェクト:
{"data": {"id": 1, "name": "..."}}- 単一の結果 - 配列:
{"data": [{"id": 1}, {"id": 2}]}- 複数の結果 - 文字列:
{"data": "description text"}- テキスト応答
データ構造に応じてテストしてください:
# For object data
result = tool()
data = result.get('data', {})
value = data.get('field_name') # ✅
# For array data
result = tool()
items = result.get('data', [])
count = len(items) # ✅
first = items[0] if items else {} # ✅
よくある落とし穴
- スキーマが検証するのは
dataフィールドであり、応答全体ではありません - すべてのメソッドで
{"status": "...", "data": {...}}のラッパーが必要です - JSON 設定の変更後は再生成が必要です
- キーなしで動作する API には
optional_api_keysを使用してください - 正しいエンドポイントの形式については、公式 API ドキュメントを確認してください
- 一時的な API 障害ではユニットテストを失敗させず、スキップしてください
- 相互排他的なパラメーターは null を許容する必要があります - 新しいツールで最もよくある問題です
- 設定からパラメーター名を確認してください - 推測や当て推量は避けてください
- 正しいデータ構造を想定してテストしてください - リスト、辞書、文字列を区別します
デバッグ
- API 応答を調べる:ステータスコード、Content-Type ヘッダー、本文のプレビューを確認します
- ツール設定を確認する:ToolUniverse を読み込み、ツールの設定を調べます
- デバッグ出力を追加する:run メソッドで URL、パラメーター、ステータス、Content-Type を記録します
クイックリファレンス
| タスク | コマンド |
|---|---|
| 統合テストを実行する | python scripts/test_new_tools.py <pattern> -v |
| 単体テストを実行する | pytest tests/tools/test_<tool-name>_tool.py -v |
| 単体テストが存在するか確認する | ls tests/tools/test_<tool-name>_tool.py |
| ツールを再生成する | python -m tooluniverse.generate_tools |
| ステータスを確認する | git status --short | grep -E "(data|tools|.*_tool.py|tests/tools)" |
| エラーの種類 | 修正箇所 |
|---|---|
| JSON 解析エラー | src/tooluniverse/*_tool.py の run() メソッド |
| スキーマの不一致 | src/tooluniverse/data/*_tools.json の return_schema |
| 404 エラー | src/tooluniverse/data/*_tools.json の test_examples または endpoint |
| パラメーターエラー | src/tooluniverse/data/*_tools.json の parameter スキーマ |
| 単体テストの失敗 | tests/tools/test_*_tool.py のアサーション |
| ツールがスキップされた(オプションのキー) | src/tooluniverse/data/*_tools.json で optional_api_keys を使用する |
| API キーをパラメーターとして指定している | JSON の params から削除し、Python で os.environ.get() を使用する |