TestSpriteはバックエンドテストでハルシネーションされたアサーションをどのように削減するか?
ハルシネーションは通常チャットボットの問題として議論されます。AIが事実でないもっともらしいことを述べるというものです。バックエンドのテスト生成では、同じ障害パターンがより静かでより高コストな形で現れます。APIが実際には決して返さないものをチェックするアサーションです。
AIがハンドラーコードを読み込み、レスポンスに user_id が含まれることを表明するテストを生成する。しかし実際のAPIは userId を返す。テストは200を表明するが、エンドポイントは201を返す。テストは created_at をISO文字列として期待するが、シリアライザーはUnixタイムスタンプを出力する。これらのアサーションはどれもランダムに生まれたものではない。すべて、もっともらしいものだった。そして、すべてが「幻覚」だった——AIが一度も確認していない現実を断言したという、まさにその意味において。
TestSpriteがこの問題に対して取るアプローチは、表面的な改善ではなく構造的な解決です。その理由を理解するには、まずこれらの幻覚がどこから生まれるのかを理解する必要があります。
幻覚されたアサーションの発生源
幻覚されたアサーションには主に3つの発生源があり、そのいずれもプロンプトの改善では解決できません。
学習済みの事前確率。何百万ものAPIを学習したモデルは、強固な期待値を持つようになります。たとえば「RESTのcreateは201を返す」「タイムスタンプはISO 8601形式だ」「リストエンドポイントは結果を data 配列で包む」といった期待です。あなたのAPIが統計的な標準から外れている場合——そして、すべての実際のAPIはどこかで外れています——修正を強制するものがなければ、モデルの事前確率があなたの現実に勝ってしまいます。
コードと実行時の乖離。ソースコードは、稼働中のAPIを不完全にしか表していません。シリアライゼーション層はフィールド名を変更し、ミドルウェアはヘッダーを挿入または削除し、フレームワークの規約はケーシングを変換します。ハンドラーからレスポンスを推測するAIは、真実から一段変換を経た証拠に基づいて推論しているに過ぎません。
もっともらしい補完。情報が欠落している場合、生成モデルは整合性のある内容でギャップを埋めます。ページネーションの形式がコードから明確でなければ、モデルはよくある形式を選びます。補完されたアサーションはレビューで問題なく見えます——まさに「もっともらしい」からです。「もっともらしさ」こそが問題なのです。
2種類の失敗モード、そしてより深刻なのはどちらか
幻覚されたアサーションは、2つの方向で悪影響を及ぼします。
目に見えるものは偽陰性(false failure)です。テストが user_id を表明し、APIが userId を返してテストが失敗する。エンジニアが20分かけて調べた結果、プロダクトは正常でテストが間違っていたと判明する。これがテストスイート全体に広がると、チームは「赤」を信頼しなくなり、テストそのものの意義が損なわれます。
より危険なのは偽陽性(false pass)です。幻覚されたアサーションが偶然に緩い内容——フィールドの存在のみを確認してその型を検証しない、またはステータスコードではなくステータス範囲を表明する——になっていると、APIが実際に壊れていてもテストが通過してしまいます。スイートはグリーンを示します。その信頼感は本物です。しかし、その裏にある検証は本物ではありません。チームはこのカテゴリの問題をダッシュボードからは発見できません。ユーザーから発見することになります。
幻覚を減らすことは、テストをより多く通過させることではありません。「通過」と「失敗」が、主張する通りの意味を持つようにすることです。
構造的な解決策としての「観察」
TestSpriteのBackend Testing 2.0は、幻覚が生まれる推論のステップを取り除きます。アサーションを生成する前に、エージェントがエンドポイントを実際に呼び出し、本物のレスポンスを記録します。実際のフィールド名、実際のステータスコード、実際のレスポンス形状です。
他の検証ツールはコードを読んで推測します。TestSpriteはアプリを開いて実際に使用します。
生成処理はその観察結果に基づいて行われます。事前確率に基づくものでも、コードからの推論でも、もっともらしい補完でもありません。createエンドポイントが camelCase の userId とUnixタイムスタンプを含む201を返すなら、それがアサーションで確認される内容です。なぜなら、それが実際に観察されたものだからです。モデルの学習済み事前確率が上書きできるものは何もありません。グラウンドトゥルースがコンテキスト内に存在しているからです。
この規律は、マルチステップフローにも及びます。動的な変数は実際のレスポンスから取得され、後続のステップに引き渡されます。実際のcreate呼び出しから得られた実際のIDが、read・update・deleteに渡されます。「ステップ3がステップ1で生成されなかったフィールドを参照する」という幻覚の連鎖は組み立てることができません。なぜなら、チェーンは実際に存在することが証明された値から構築されるからです。
そして、観察されたコントラクトがリグレッションのベースラインになります。後のClaude Codeセッションがエンドポイントの返す内容を変更した場合、その発見は2つの観察結果の比較——以前に返された内容と現在の内容——であり、現実と推測の比較ではありません。
AI生成バックエンドに特有のリスク
Claude CodeやCursorでバックエンドを構築しているチームは、両面から幻覚リスクに直面します。AIがコードを書き、次にAIがテストを書く。テスト生成器がコード生成器と同じソースから推論する場合、エラーは相関します。テストがコードの誤った前提を引き継ぎ、それを確認してしまう可能性があります。これが、バグが検出される代わりに「認定」される仕組みです。
観察はその相関を断ち切ります。テスト生成器の入力はコードではありません。稼働中のシステムの実際の動作であり、コード生成器の前提がフレームワーク・シリアライザー・データベースと出会って生み出したすべてのものを含んでいます。AI生成のハンドラーが status を文字列で返すつもりでも、共通シリアライザーがそれをオブジェクト内にネストしていれば、推論ベースのテストは「そうであるはず」の内容を表明し、観察ベースのテストは「実際にある」内容をキャプチャします。
AIのスピードで開発するチームにとって、グリーンを信頼できるものにするのはこの特性です。アサーションとコードが、共通の推測ではなく現実を通じて互いに照合されています。
シナリオ:間違えることすらなかったアサーション
4人のチームが、Claude Codeでイベントチケット販売プラットフォームを構築しています。あるセッションでグループ予約エンドポイントを追加します。1回の呼び出しで複数の席を予約し、座席ごとの詳細を含む予約情報を受け取るものです。
ハンドラーを読んだ推論ベースの生成器は、もっともらしいアサーションを生成したでしょう。成功時は200、seats 配列、各座席には seat_number。もっともらしい、しかし3箇所で間違いです。エンドポイントは201を返します。配列はシリアライザーデコレータによって reservations にリネームされています。そして座席番号は「B-14」のような seatLabel 文字列として返ってきます。ハンドラーコードにはその情報が見えません。ラベルはモデル層で生成されるからです。
TestSpriteのエージェントはまずエンドポイントを呼び出します。観察結果には 201、reservations、seatLabel が記録されます。生成されたテストはまさにそれを表明し、実際の bookingId をキャンセルフローに渡して、座席が解放されることを検証します。
実行結果から1件の本物の問題が見つかります。グループ予約をキャンセルすると、最初の座席を除くすべての座席が解放されるのですが、最初の座席がロックされたまま残ってしまいます。キャンセルのループがインデックス1から始まっているためです。これは本物のバグです。テストを先にデバッグする必要なく発見されました。アサーションのどれも推測ではなかったからです。
発見はClaude Codeのターミナルに表示され、コーディングエージェントがオフバイワンを修正し、再実行で解放が確認されます。誰も「テストがAPIについて間違っていた」ことを調べる時間を費やしていません。テストはAPIについて間違えることがありませんでした。APIを「見て」いたのですから。
まとめ
幻覚されたアサーションは推論から生まれます。学習済みの事前確率、コードと実行時の乖離、そしてギャップを埋めるもっともらしい補完から。これらはチームに、時間を浪費する偽陰性と、バグを認定してしまう偽陽性のコストをもたらします。後者の方が深刻です。ユーザーが発見するまで見えないからです。
TestSpriteは推論をループから取り除くことで、構造的に幻覚を減らします。Backend Testing 2.0は何かを表明する前に実際のAPIを観察し、実際の値をマルチステップフローに通し、リグレッションを観察結果間の比較に変えます。AIが生成したバックエンドでは、コードとテストが同じ誤った推測を共有する可能性があります。観察こそが、両者が互いに正直であり続けるための手段です。
今すぐAI IDEの中からTestSpriteで、あなたのAPIを現実と照合してテストしてください。