ELYSAI
Development

「200 OK」を合格にしない、AIエージェントのツール契約テスト

ELYSAI編集部6分
「200 OK」を合格にしない、AIエージェントのツール契約テスト

AIエージェントへ社内APIを渡す開発責任者は、「呼べた」ではなく「正しい条件で、重複なく、完了を確認できた」まで試す必要があります。本稿では、一つの書き込みツールを本番へ出すための契約テンプレートとテストを作ります。

ツールの説明文を仕様にしない

説明文が丁寧でも、実行側は入力、権限、再試行、成功の証拠、回復方法を保証する必要があります。

HTTPの200 OKはリクエストが成功したことを示しますが、POSTの応答内容は処理結果または適用後の状態を表し得ます。[1] したがって、通信成功だけを「発注完了」や「返金完了」とみなさず、業務上の後条件を別に定義します。

OpenAIも、戻り値とエラー動作を定義し、可能なら冪等にし、引数・権限をアプリ側で確認するよう案内しています。[2] 冪等とは、同じ要求を再送しても副作用が重複しない性質です。

コピーできるツール契約

所有者はAPIと業務ルールを管理する開発者です。業務責任者が成功・禁止条件を確認します。

tool_contract:
  name: create_purchase_order
  owner: procurement-platform
  input:
    required: [supplier_id, item_id, quantity, request_id]
    additional_properties: false
  authorization:
    actor_scope: procurement-write
    supplier_must_be_approved: true
  side_effect: purchase_order_created
  idempotency_key: request_id
  success_evidence: [purchase_order_id, status]
  success_when: status == "created"
  ambiguous_failure: reconcile_then_stop
  approval_required_when: amount_exceeds_internal_limit

JSON Schemaでは、requiredで必須項目を指定し、additionalProperties: falseで宣言外の項目を拒否できます。[3]

契約には次の五点を必ず入れます。

  1. 前条件:誰が、どの対象へ、どの権限で実行できるか
  2. 入力境界:必須、型、列挙値、上限、追加項目の扱い
  3. 副作用:どの外部状態が変わるか
  4. 完了証拠:IDと状態をどこから取得するか
  5. 再試行規則:重複防止キーと、結果不明時の照合先

六つの契約テストを通す

実APIまたは副作用を再現する環境で、次を自動化します。

テスト入力・状況合格条件
正常系承認済み仕入先、正しい権限PO IDとcreatedを返す
余分な項目未定義のbank_accountを追加実行前に拒否する
権限違反読み取り専用主体APIを呼ばず拒否する
重複実行同じrequest_idを二回送るPOは一件、同じIDを返す
曖昧な失敗作成後に応答をtimeoutさせる照合してから停止し、再作成しない
後条件不成立HTTP 200、status: rejected成功扱いせず例外キューへ送る

OWASPは、高影響の操作で判断と実行を分け、承認を主体・ツール・対象・引数・時刻・期限へ結び付け、可能なら冪等にするよう推奨しています。[4] 実行側がこの制約を強制するかを試します。

発注ツールで試す

たとえば、エージェントが在庫不足を見て発注案を作る場面を考えます。モデルはquantity: 20とrequest_id: restock-481を提案し、人が金額と仕入先を承認します。実行側は承認済み仕入先、権限、数量上限を独立して検証してからAPIを呼びます。

APIが処理後にtimeoutした場合、同じ要求をすぐ作り直してはいけません。まずrequest_idで発注先を照会します。既存POがあればそのIDを採用し、なければ同じキーで再送します。結果を照合できないときはunknownとして止め、人へ渡します。

完了条件は、六テストが通り、失敗時にsuccess / rejected / unknownのいずれかへ必ず分類され、unknownが自動再試行されないことです。

よくある失敗と適用境界

  • 型検証だけで終える:正しいJSONでも、権限外の操作は防げません。
  • 例外を文章で返す:後段が成功と誤読します。エラーコードと再試行可否を固定します。
  • timeoutを失敗と決める:処理済みなら重複が起きます。先に業務状態を照合します。
  • approval済みだけを見る:対象や引数が承認時から変わっていないか照合します。

副作用がなく、公開情報を読むだけの低リスクツールすべてに同じ重い契約テストを課すという場合には向きません。その場合も入力schemaとエラー分類は残し、書き込み・外部送信・金銭・権限変更を伴うツールから厳格化します。

明日から使える実装チェックリスト

  • [ ] 一つの書き込みツールを選んだ
  • [ ] 前条件、入力、副作用、完了証拠を契約へ書いた
  • [ ] 宣言外の入力を拒否する
  • [ ] 実行側で権限と承認内容を再確認する
  • [ ] 重複防止キーがある
  • [ ] timeout後の照合APIがある
  • [ ] HTTP成功と業務成功を分けた
  • [ ] unknownを自動再試行しない
  • [ ] 六つのテストをリリース条件にした

まず最も危険なツール一つで契約を書き、timeout後の重複テストを実行してください。ここで二件作成されるなら、モデルを改善する前にツール境界を直す必要があります。

参考資料

  1. RFC 9110: HTTP Semantics
  2. OpenAI API: Programmatic Tool Calling
  3. JSON Schema: Object
  4. OWASP Cheat Sheet Series: AI Agent Security

本記事はAIを活用して作成し、公開前に自動レビューを実施しています。情報の確認日:2026-10-04。

Share this post

Author

ELYSAI編集部

Talk to us about your AI challenge

Talk to us about your AI challenge

Related Posts