AI が API の引数を間違える理由 — get() が 678 通り存在するという事実
生成 AI が実在しないメソッドを呼んだり引数名を間違えたりするのはなぜか。805 ライブラリ 126,529 個の API を静的解析した実測データから、その構造的な原因を説明します。
公開日: 2026-08-08 生成AI静的解析API設計ハルシネーション
生成 AI にコードを書かせると、動かないコードが返ってくることがあります。 構文は正しく、一見それらしいのに、実行すると TypeError: get() got an unexpected keyword argument で落ちる。
原因を「AI が賢くないから」で片付けると、対策を誤ります。 805 のライブラリを静的解析して分かったのは、もっと構造的な理由でした。
実測: get という名前の API は 678 個ある
126,529 個の公開 API を名前で集計したところ、上位はこうなりました。
| メソッド名 | 定義されている数 |
|---|---|
get | 678 |
close | 420 |
Operations | 396 |
delete | 391 |
run | 358 |
Serializer | 284 |
get という名前のメソッドが、678 通りの異なるシグネチャで存在します。 そして引数の数もバラバラです。
| 引数の数 | 該当する get の数 |
|---|---|
| 0 個 | 43 |
| 1 個 | 139 |
| 2 個 | 187 |
| 3 個 | 160 |
| 4 個 | 104 |
| 5 個以上 | 45 |
実際のシグネチャを並べると、共通点がないことが分かります。
# msal
HttpClient.get(url, params=None, headers=None, **kwargs)
# azure-mgmt-advisor
MetadataOperations.get(name: str, **kwargs: Any) -> MetadataEntity
ResiliencyReviewOperations.get(review_id: str, **kwargs: Any) -> ResiliencyReview
同じ get でも、第一引数が url のものと name のものと review_id の ものがあります。返す型も違います。
AI にとって何が起きているか
言語モデルは学習データの統計から次のトークンを予測します。 client.get( の続きとして何が来るかを考えるとき、モデルの中では 678 通りの get の記憶が混ざり合っています。
その結果、こういうことが起きます。
- 最も頻出のパターンに引きずられる ——
requests.get(url) は学習データに大量にあるので、 マイナーなライブラリの get(review_id=...) を書くべき場面でも get(url=...) と書いてしまう
- 別のライブラリの引数名が混入する ——
timeout を受け取るのは別の get なのに、こちらにも付けてしまう
- 存在しない引数を発明する ——
「たぶんこういう引数があるはず」という一般化が働く
これは推論の失敗ではありません。知識の解像度の問題です。 モデルは「get というメソッドがよくある」ことは知っていても、 「このクラスの get は review_id: str を取る」までは保持していません。
もう一つの要因: 型注釈の普及率
同じ解析で、型情報の有無も調べました。
| 項目 | 件数 | 割合 |
|---|---|---|
| 戻り値の型注釈あり | 48,704 | 38.5% |
| 引数に型注釈あり | 34,989 | 27.7% |
7 割以上の API には引数の型注釈がありません。 つまり多くのライブラリでは、シグネチャを見ても 「この引数に何を渡すべきか」がコードからは分かりません。
型注釈がないと、AI は docstring や使用例から推測するしかなくなります。 推測の精度は、そのライブラリが学習データにどれだけ含まれていたかに 依存します。マイナーなライブラリほど不利です。
学習データのカットオフという別問題
さらに厄介なのが、時間の問題です。
モデルの学習データには締め切りがあります。それ以降に追加された API、 変更されたシグネチャ、廃止された引数は、モデルの知識に存在しません。 そして API は変わります。引数名が変わり、デフォルト値が変わり、 非推奨になります。
モデルは「知らない」ことを知りません。学習時点の記憶に基づいて、 自信を持って古いシグネチャを出力します。
対策: 正確な情報を手元に置く
ここまでの原因は、いずれも知識の欠落です。推論能力の不足ではありません。 そして知識の欠落は、知識を渡せば埋まります。
具体的には、質問に関連する API のシグネチャを、 生成の前に検索して一緒に渡します。
RELEVANT APIS (verified to exist in current sources):
- [encode/httpx] httpx._api.request(method: str, url: URL | str,
*params: QueryParamTypes | None = None,
*timeout: TimeoutTypes = DEFAULT_TIMEOUT_CONFIG,
*follow_redirects: bool = False, ...) -> Response
Sends an HTTP request.
---
QUESTION: httpx で 5 秒タイムアウトの GET を書いて
渡している情報は、実際のソースコードを Python の ast モジュールで 解析して抽出したものです。記憶からの再生ではないので、 モデルの学習時期に関係なく正確です。
これで解決するのは、この記事で挙げた 3 つすべてです。
- 同名 API の混同 —— どの
getかが文脈で確定する - 型注釈の欠如 —— 注釈がある場合はそのまま渡る
- カットオフ —— 解析時点の最新シグネチャが渡る
解決しないこと
正直に書いておくと、これで直らない誤りもあります。
- 設計が悪い —— 要求に対して不適切なアプローチを選ぶ
- 要求の読み違い —— 曖昧な指示を別の意味に解釈する
- アルゴリズムの誤り —— ロジック自体が間違っている
これらは推論の領域であり、外から知識を足しても改善しません。 API の正確さと、設計の良し悪しは別の軸です。
言い換えると、知識で直る誤りと、推論でしか直らない誤りを 切り分けることが重要です。前者はコストの低い方法で確実に減らせます。 後者はモデルの能力そのものに依存します。
まとめ
AI が API を間違えるのは、get が 678 通りあり、7 割の API に型注釈がなく、 学習データには締め切りがあるからです。いずれも構造的な条件であり、 モデルが賢くなれば自動的に解決する類のものではありません。
生成の前に正確なシグネチャを渡すという対策は地味ですが、 原因に直接対応しています。当サイトの 収録ライブラリ一覧では、この方法で抽出した 805 ライブラリ分の API を公開しています。 仕組みの詳細は技術解説をご覧ください。