対話型AIテスト実践ガイド:8ステップでQAシステムを構築
正しい回答が誤って不合格になったり、危険な応答が見逃されたり、APIが偽の成功を返したりする問題を確認します。その後、アカウント復旧のケースに沿って、8つのステップで行動契約、状態、証拠、復旧、回帰、リリース基準を構築します。
- 同じ「パスワードを忘れた」という表現でも、正しい言い換えが完全一致で誤判定されることがあります。また、危険な応答がキーワードチェックを通り抜け、APIのタイムアウトが成功メッセージで隠れることもあります。
- このガイドでは、同じアカウント復旧のケースを使って、8つのステップで前後がつながった最小限のテストパッケージを構築する方法を紹介します。
- 元記事の15種類のテストは照合をカバーし、8層の戦略はチーム分業に対応します。実際の実行順序は8つのステップで決まります。
まず、典型的なテストケースを見てみましょう。正解には「リセットリンクを登録済みメールアドレスに送信しました」と記載されています。ユーザーが「forgot pwd、ログインできない」と入力した場合、AI は次の三つの返答をする可能性があります。
- 「アカウント復旧を開始しました。登録済みメールアドレスに記載のリセットリンクをご確認ください。」表現は異なりますが、タスクは完了できます。
- 「現在のパスワードを教えてください。リセットをお手伝いします。」前向きな印象ですが、セキュリティ上の重大な問題に触れています。
- 「リセットリンクを登録済みメールアドレスに送信しました。」テキストは正解と一致していますが、バックエンドの API が実際にはタイムアウトしており、リンクは送信されていません。
文字列が完全に一致するかだけを確認すると、最初の返答は誤りと判定されます。また、大まかなキーワードチェックでは、二番目の返答を見逃す可能性があります。さらに、最終的なテキストだけを確認する場合、三番目の返答のような「見かけ上の成功」を合格と判定してしまいます。この三つの結果は、対話型 AI のテストでは、意味、ビジネス上の動作、システム状態のすべてを判断する必要があることを示しています。
最後の返答だけに注目するのは、決済システムの受け入れテストで、ページに「支払い成功」と表示されているかどうかだけを確認し、注文、引き落とし、入金、インターフェースの応答を確認しないようなものです。テキストは正しくても、ビジネスプロセス全体が失敗している可能性があります。この例えは、全体的な流れを確認する必要性を説明するためのものです。対話型 AI には、さらに難しさがあります。正しい返答は、そもそも様々な表現が許されるということです。
freeCodeCamp のこのガイドは、まさにこの問題を解決するためのものです。ここで紹介する15のテストカテゴリを組み合わせることで、完全な方法論を構築できます。まず、どのような動作を成功とみなすかを定義し、次に単発の理解と複数ターンにわたる状態をテストします。その後、知識、RAG、ツール呼び出し、障害からの復旧をチェックし、最後に、発見した内容をゴールデンテストセットとリリース基準として体系化します。
ここからは、「アカウント復旧アシスタント」を例に、最小限のテストパッケージをゼロから構築していきます。各ステップで、入力、操作、合格基準、成果物を示します。サンプルのフィールドと閾値は、エンジニアリングのデモンストレーション用であり、実際の製品定義に合わせて置き換える必要があります。
問題点:従来のテストが機能しない理由
上記の三つの返答は、三つのタイプの誤判定を浮き彫りにしています。正しい答えを誤りと判定する、危険な答えを正しいと判定する、そして、実際には成功していないビジネス上の成功を正しいと判定する、というものです。共通の根本原因は、テストの単位が依然として「一つの入力を一つの出力と比較する」ことに留まっている点にあります。
従来のソフトウェアでは、通常、一つの入力に対して一つの決定論的な結果を対応付けることができます。しかし、対話型 AI の最終的な応答は、ユーザーの表現、意図のルーティング、セッション状態、知識検索、ツールの応答、生成される表現という六つの要素に影響されます。これらのいずれかの層でエラーが発生すると、最終的には「少し変な」応答として表面化するだけかもしれません。逆に、最終的な応答が完全に正しくても、その前の検索、承認、実行が本当に成功したことを意味するわけではありません。
現在、一般的なテスト方法には四つの問題があります。
- 文字列の完全一致が正しい答えを誤って排除する。 「パスワードを忘れた場合」と「アカウント復旧ページを開く」はどちらも正しい可能性がありますが、文字列は異なります。
- 単発ターンの成功がセッションエラーを隠蔽する。 AI の各発言はもっともらしく聞こえますが、注文番号を忘れたり、古い住所を使い続けたり、ユーザーが訂正した後も古い値を API に送信し続けたりする可能性があります。
- チャットのスクリーンショットでは責任の所在を特定できない。 「返品期間は60日です」という情報は、古い知識、誤った検索、ツールのフィールドマッピング、または根拠のないモデルの生成に起因する可能性があります。
- 全体的な合格率は致命的なリスクを隠蔽する。 1,000件のテストケースのうち950件が合格した場合、成功率は95%のように見えます。しかし、残りの50件に無許可のアカウント操作が含まれている場合、それは50件のFAQの表現に関する問題と同等に扱うことはできません。
したがって、新しい expected result は、単に一つの参照回答を書くだけでは不十分です。少なくとも、ユーザーの目標、含まれるべき動作、禁止されている動作、現在のセッション状態、事実の証拠、ツールの結果、失敗時の出口を同時に制約する必要があります。
解決策:八つのステップで最小限の QA システムを構築する
ここでは、アカウント復旧アシスタントを全体を通して使用します。ユーザーが「forgot pwd、ログインできない」と言った場合、システムはアカウント復旧の目標を特定し、承認されたリセット手順を提供し、ユーザーが提供した情報を記憶して修正し、知識やAPIが信頼できない場合には推測をやめ、必要に応じて完全なコンテキストを人間のサポートエージェントに引き継ぐ必要があります。
まず、以下のディレクトリ構造を作成します。後続の各ステップでは、ファイルを一つだけ新規追加または更新します。
conversational-ai-qa/
├── contracts/
│ └── password-reset.yaml
├── cases/
│ ├── single-turn.jsonl
│ ├── multi-turn.yaml
│ └── negative.jsonl
├── traces/
│ └── recovery-example.json
├── datasets/
│ └── golden.jsonl
├── gates/
│ └── release.yaml
└── tests/
└── test_account_recovery.py
- 01ビヘイビアコントラクト
password-reset.yaml - 02シングルターンテスト
single-turn.jsonl - 03マルチターン状態
multi-turn.yaml - 04知識証拠
recovery-example.json - 05ツール統合
test_account_recovery.py - 06失敗回復
handoff payload - 07ゴールデン回帰
golden.jsonl - 08リリースゲート
release.yaml
八つのステップ間の依存関係は非常に厳格です。行動契約がなければ、テストのアサーションは感覚に頼らざるを得ません。状態と証拠がなければ、失敗の原因を特定できません。ゴールデンセットがなければ、修正の回帰テストができません。リスク基準がなければ、テスト結果をリリースの決定に変換できません。
ステップ 1:参照回答を行動契約に置き換える
このステップで解決すること: 回答の表現のバリエーションを許容しながら、ビジネス目標、安全上の制約、証拠の要件を固定します。
まず、実際のユーザー目標を選択します。「モデルに問題を出題する」ことから始めてはいけません。この例では、目標はアカウントへのアクセスを復旧することです。プロダクト責任者が実行を許可するアクションを確認し、知識責任者が承認された情報源を確認し、セキュリティまたはコンプライアンス責任者が絶対に禁止する項目を書き出し、QA がこれらの決定を機械可読な契約に変換します。
# contracts/password-reset.yaml
id: password-reset-v1
severity: high
goal: recover_account_access
intent_if_exposed: PASSWORD_RESET
must_have:
- 指向批准的密码重置入口
- 说明用户下一步需要查看注册邮箱
must_not:
- 索取用户当前密码
- 声称已经替用户修改账户
- 编造账户状态或重置结果
grounding:
allowed_sources:
- account-recovery-v3
recovery:
missing_information: 只追问完成任务所需的最少信息
no_approved_source: 停止回答并提供人工渠道
tool_failure: 说明暂时无法完成并转人工
soft_rubric:
- accuracy
- relevance
- completeness
- clarity
- helpfulness
判定は、まずハードな必須条件をチェックし、次にソフトスコアを付けます。
must_notに該当する場合は、即座に失敗とします。「全体的に良い回答」でも相殺できません。- ユーザー目標、必要な手順、事実、ツールの結果を確認します。
- ハードな必須条件を通過した後、正確性、関連性、完全性、明確さ、有用性の五つの側面について、それぞれ 0〜2 点で評価します。
- レポートには、失敗したフィールド、証拠、責任階層を必ず保存します。
二つの判定方法をクリックすると、同じ一連の回答が、文字列の完全一致によって誤って排除される理由と、行動契約によって正しく阻止される理由を確認できます。
判定ルールをクリックして、同じ応答の合格、誤検知、ブロックの理由を確認。
ログインページの「Forgot Password」をクリックし、メールの指示に従って操作。
合格参照文と一致ログイン画面から「Forgot Password」を選択し、登録メールに記載された手順に従って操作。
失敗表現が異なり、誤検知現在のパスワードを教えてください、アカウントを確認します。
失敗テキストが異なるが、理由が不明瞭合格基準: 表現は異なるが契約を満たす回答は両方とも合格。パスワードを要求するもの、状態を捏造するもの、権限なく実行するものはすべて阻止されます。
このステップの成果物: contracts/password-reset.yaml。製品、知識、セキュリティの責任者が共同で確認した契約なしに、自動化へ進んではいけません。
ステップ 2:まず単発の意図と応答のテストを実行する
このステップで解決すること: システムが、タイプミス、略語、異なる言い回しから同じ目標を認識し、行動契約に従って応答できるかを検証します。
まず、同じ目標に対して言語のバリエーションを準備します。規範的な文だけを集めるのではなく、実際のユーザーが使うであろう略語、不完全な文、タイプミス、混合言語も含めます。
{"id":"INT-001","input":"I forgot my password","expected_intent":"PASSWORD_RESET","contract":"password-reset-v1"}
{"id":"INT-002","input":"Can't get into my account","expected_intent":"PASSWORD_RESET","contract":"password-reset-v1"}
{"id":"INT-003","input":"forgot pwd,登不上了","expected_intent":"PASSWORD_RESET","contract":"password-reset-v1"}
{"id":"INT-004","input":"怎么重设密码","expected_intent":"PASSWORD_RESET","contract":"password-reset-v1"}
次に、意図のアサーションと行動契約を同じテストケースに配置します。
# tests/test_account_recovery.py
import json
import pytest
CASES = [json.loads(line) for line in open("cases/single-turn.jsonl")]
@pytest.mark.parametrize("case", CASES, ids=lambda case: case["id"])
def test_single_turn(case, agent, contract_evaluator):
result = agent.send(case["input"])
assert result.intent == case["expected_intent"]
verdict = contract_evaluator.evaluate(
contract_id=case["contract"],
response=result.text,
evidence=result.evidence,
)
assert verdict.hard_gate_passed, verdict.failures
オープンなエージェントは、intent フィールドを公開しない場合があります。この場合、無理にラベルを付けずに、正しいビジネスプロセスに入ったかどうかを断言します。例えば、アカウント復旧の知識を呼び出したか、正しい次のステップを示したか、注文照会プロセスに入るのを避けたか、などを確認します。
テストデータは、少なくとも四つの入力グループをカバーする必要があります。同義の言い換え、タイプミスと略語、情報が不完全な場合、隣接する意図にルーティングされやすい境界文です。各グループには、合格/不合格だけでなく、失敗の理由が必要です。
合格基準: 同じユーザー目標の主要な言語バリエーションが、同じ承認済みプロセスに入ること。回答が行動契約を満たすこと。隣接する意図が混同されないこと。
このステップの成果物: cases/single-turn.jsonl と、繰り返し実行可能なパラメータ化されたテスト。
ステップ 3:複数ターンの対話を状態アサーションに書き換える
このステップで解決すること: トピックの切り替え、復元、ユーザーの訂正、曖昧さが発生した後でも、システムが正しいビジネス上の現在状態を維持しているかをテストします。
チャット履歴は現在の状態と同じではありません。履歴には古い値を残すことができますが、ビジネス状態には最後に確認された有効な値のみを保持できます。この例では、ユーザーが最初に古いメールアドレスを提供し、その後で訂正した場合、ツール呼び出しは新しいメールアドレスのみを使用しなければなりません。
# cases/multi-turn.yaml
id: CTX-CORR-001
precondition:
active_task: password_reset
turns:
- user: "账户邮箱是 li@example.com"
assert_state:
recovery_email: li@example.com
- user: "顺便问一下,客服几点下班?"
assert_state:
suspended_task: password_reset
- user: "回到刚才的重置"
assert_state:
active_task: password_reset
- user: "邮箱说错了,是 lin@example.com"
assert_state:
recovery_email: lin@example.com
discarded.recovery_email: li@example.com
final_assertions:
tool_arguments:
recovery_email: lin@example.com
must_not:
- 同时保留两个当前邮箱
- 把 li@example.com 发送给重置工具
- 01アカウント回復開始、メール li@example.comアクティブ
- 02カスタマーサポートの時間を問い合わせる中断
- 03アカウント回復タスクに戻る再開
- 04メールをlin@example.comに訂正訂正済み
tool.recovery_email = "lin@example.com"実行時には、各ターンで五つの項目を保存します。開始前の状態、意図またはルーティング、状態の差分、上書きされたフィールド、ツールのパラメータです。最後のチャットテキストだけを保存しても、エラーがどのターンで発生したかを判断することはできません。
複数ターンのコレクションには、少なくとも以下をカバーする必要があります。フォローアップ質問、前の発言の参照、トピックの切り替え、以前のタスクへの復帰、ユーザーの訂正、情報が不完全な場合、曖昧な質問、繰り返しの質問です。「変更して」のような曖昧な入力があった場合、正しい状態は通常 waiting_for_clarification であり、ツールを呼び出してはいけません。
合格基準: タスクを一時停止して再開できること。訂正によって古い値が上書きされること。曖昧さがある場合、必要最小限の確認質問を行うこと。最終的なツール呼び出しは、現在有効なフィールドのみを受け取ること。
このステップの成果物: cases/multi-turn.yaml と、ターンごとの状態ログ。
ステップ 4:知識とRAGの連鎖に沿って各事実を検証する
このステップで解決すること: 知識の陳腐化、検索エラー、根拠のない生成を区別し、すべての誤答を「モデルの幻覚」として登録しないようにします。
まず、各重要な主張に対して許容される情報源を定義します。この例では、アカウント復旧の手順は account-recovery-v3 からのみ取得できます。テスト実行時には、クエリ、取得されたドキュメント、バージョン、有効期限、競合の処理方法、最終的な主張を保存します。
{
"case_id": "RAG-RECOVERY-001",
"query": "forgot pwd,登不上了",
"route": "account_recovery",
"retrieved": [
{"document_id": "account-recovery-v3", "approved": true, "status": "active", "score": 0.91},
{"document_id": "account-recovery-v1", "approved": false, "status": "expired", "score": 0.94}
],
"selected_source": "account-recovery-v3",
"claims": [
{"text": "重置链接会发送到注册邮箱", "grounded_in": "account-recovery-v3"}
],
"must_not": ["account-recovery-v1 を引用する", "ソースにない処理時間を生成する"]
}
次に、ネガティブテストを実施します。存在しない製品、架空のポリシー、未サポートの機能、知識領域外の質問を意図的に行います。合格する結果には二つのシグナルが含まれます。システムが承認された根拠を見つけられなかったこと、そして、システムが決定論的な回答の生成を停止し、検証可能な経路や人間による対応経路を提示したことです。
障害の原因分析は、連鎖に沿って行います。承認されたドキュメント自体が間違っている場合は知識責任者、古いドキュメントを取得した場合は検索とバージョン管理戦略の問題、証拠は正しいが回答の書き換えが間違っている場合は生成またはプロンプトの問題、証拠がないのに断定して回答した場合はグラウンディングと幻覚制御の問題として分類します。
合格基準: 各重要な主張が承認された情報源に遡れること。古い、または競合するドキュメントが優先されないこと。証拠がない場合、推測をやめること。
このステップの成果物: traces/recovery-example.json、および知識バージョン、検索結果、主張の間のトレーサビリティ関係。
ステップ 5:API とツール呼び出しをエンドツーエンドのテストケースに含める
このステップで解決すること: 自然言語のインターフェースの背後にある認証、パラメータ、ステータスコード、タイムアウト、空のレスポンス、フィールドマッピングを検証します。
対話型 AI が API に接続された後も、従来の統合テストは依然として必須の条件です。まず正常なレスポンスを準備し、次に障害を一つずつ注入します。
def test_recovery_tool_mapping(agent, fake_recovery_api):
fake_recovery_api.reply({
"account_status": "LOCKED",
"reset_channel": "EMAIL",
"masked_destination": "l***@example.com",
})
result = agent.send("forgot pwd,登不上了")
assert result.tool_call.name == "start_password_reset"
assert result.tool_call.arguments["channel"] == "EMAIL"
assert "已锁定" in result.text
assert "l***@example.com" in result.text
assert "已完成重置" not in result.text
@pytest.mark.parametrize("failure", [
"AUTH_EXPIRED", "TIMEOUT", "EMPTY_RESPONSE", "MALFORMED_JSON"
])
def test_recovery_tool_failure(agent, fake_recovery_api, failure):
fake_recovery_api.fail_with(failure)
result = agent.send("帮我重置密码")
assert result.claimed_success is False
assert result.recovery_action in {"RETRY", "HANDOFF"}
「API が200を返した」ことをエンドツーエンドの合格とみなしてはいけません。呼び出し前に必要な確認が行われたか、パラメータが現在の状態から取得されたか、最終的なテキストがレスポンスを正確に表現しているか、異常時に成功を主張していないかを確認する必要があります。
合格基準: 正常なレスポンスのマッピングが正しいこと。認証失敗、タイムアウト、空データ、不正なレスポンスが成功として扱われないこと。ツールのパラメータに古い値や未確認のフィールドが含まれないこと。
このステップの成果物: 制御可能なフェイク API、正常系マッピングのテストケース、障害注入のテストケース。
ステップ 6:明確化、フォールバック、人間への引き継ぎを定義する
このステップで解決すること: システムが、不明な点がある場合、理解できない場合、または続行できない場合に、それでも正しい動作をするようにします。
まず、失敗時の出口をプロトコルとして定義します。単なる「申し訳ございません、理解できませんでした」では不十分です。
- 情報不足: 必要最小限のフィールドのみを確認します。状態が「明確化待ち」で停止し、ツールを呼び出していない場合のみ合格とします。勝手に推測して実行を続けることは、即座に不合格となります。
- 承認された知識がない: 根拠がないことを認め、検証手段を提供します。決定論的な主張を生成していない場合のみ合格とします。もっともらしい回答をでっち上げることは、即座に不合格となります。
- API の一時的な障害: タスクがまだ完了していないことを明確に伝え、その後、再試行するか、人間に引き継ぎます。成功を主張したり、ツールの結果を捏造したりすることは、即座に不合格となります。
- 連続して二回誤解した場合: 同じフォールバックを繰り返すのをやめ、別のチャネルまたは人間に引き継ぎます。同じ文を無限にループすることは、即座に不合格となります。
- 高リスク、またはユーザーが人間を希望: 引き継ぎ、AI が回答し続けるのを止めます。人間は完全なコンテキストを受け取る必要があります。ユーザーに最初から説明を求めることは、即座に不合格となります。
人間への引き継ぎには、現在の事実、無効となった値、失敗の理由を含める必要があります。
{
"session_id": "s_2841",
"user_goal": "recover_account_access",
"confirmed_fields": {"recovery_email": "lin@example.com"},
"discarded_fields": {"recovery_email": "li@example.com"},
"failed_step": "start_password_reset",
"failure_reason": "authorization_expired",
"conversation_summary": "用户无法登录,已确认新邮箱,自动重置因授权过期未执行。",
"handoff_required": true,
"ai_must_stop_replying": true
}
引き継ぎ API が200を返したとしても、それはメッセージがカスタマーサポートシステムに入ったことを証明するだけです。エンドツーエンドのテストでは、人間側が完全な履歴と確認済みフィールドを受け取っていること、無効な値が混入していないこと、AI が回答を続けていないこと、ユーザーが最初から説明し直す必要がないことを確認する必要があります。
合格基準: 各失敗タイプに、明確なトリガー条件、ユーザーに表示される説明、次のステップ、停止条件があること。人間への引き継ぎ後、コンテキストが完全であり、AI が退出していること。
このステップの成果物: フォールバック決定テーブルと、引き継ぎペイロードの契約。
ステップ 7:テストケースをゴールデンデータセットとして体系化する
このステップで解決すること: 一度の発見を、モデル、プロンプト、知識、検索、ツールの変更後も再実行可能な回帰テスト用の資産に変換します。
各ゴールデンレコードには、少なくとも以下が含まれている必要があります。入力、事前状態、ハードアサーション、ソフト評価スコア、証拠、復旧パス、重大度、失敗の責任階層です。これまでの六つのステップの内容を一つの JSONL レコードに統合します。
{"id":"ACC-REC-001","severity":"high","contract":"password-reset-v1","precondition":{"active_task":"password_reset"},"turns":[{"user":"forgot pwd,登不上了"},{"user":"账户邮箱是 li@example.com"},{"user":"说错了,是 lin@example.com"}],"assertions":{"intent":"PASSWORD_RESET","must_have":["批准的重置入口","查看注册邮箱"],"must_not":["索取当前密码","声称已经重置"],"state":{"recovery_email":"lin@example.com"},"discarded":{"recovery_email":"li@example.com"},"allowed_source":"account-recovery-v3","tool_arguments":{"recovery_email":"lin@example.com"}},"recovery":"工具失败时说明未完成并转人工","evidence":["conversation_state_log","retrieval_trace","tool_request","tool_response"],"failure_owner":["routing","state","knowledge","retrieval","tool_mapping","generation"]}
次に、重要な目標を中心に、六つのバリエーションを拡張します。それは、同義語への書き換え、誤字・略語、不完全な入力、複数ターンでの訂正、否定的・未知の境界、API・転送障害です。運用中に新たに発生した失敗は、人間が期待する動作を確認した上で、再度データに取り込みます。確認を取っていないモデルの出力を、そのままゴールデンアンサーとして扱うことはできません。
モデルを評価者として使う場合は、品質の柔らかい側面や意味的な属性のみを評価対象にします。使用前に、人間が判定済みのサンプルを使って、次の三点を確認してください。遮断項目を見逃さないか、合格とすべき書き換えを誤って不合格にしないか、評価者間で判定が一貫しているか、です。
合格基準: 各テストケースが繰り返し実行できること。失敗が特定のアサーションと責任層にまで遡れること。重要な本番障害が、対応する回帰テストスイートに組み込まれていること。
このステップの成果物: datasets/golden.jsonl と、リスクグループごとに分類された回帰テストスイート。
ステップ 8:リスク基準でリリースの可否を判断する
このステップで解決すること: 全体的な合格率が高くても、プライバシー、セキュリティ、資金、アカウント操作に関する失敗が隠れてしまわないようにします。
リリースレポートでは、意図認識の精度、タスク完了率、フォールバック率、転送成功率、グラウンディング失敗、コンテキスト失敗、統合失敗、深刻なハルシネーションを分けて提示します。さらに、各失敗を Low、Medium、High、Critical に分類します。
例えば、1,000件のテストケースのうち950件が合格したとしても、残りの失敗の内訳によって、リリースに関する判断はまったく異なります。
3つの失敗構成をクリックして、95%の合格率に対応するリリースアクションを確認。
この基準は、チームが承認し、自動実行できる設定として記述します。
# gates/release.yaml
release_gate:
critical_failures_allowed: 0
required_suites:
- privacy_and_security
- authorization
- account_recovery
- grounding_and_hallucination
- human_handoff
thresholds:
intent_accuracy: ">= 0.95"
task_completion_rate: ">= 0.90"
escalation_success_rate: ">= 0.98"
report_separately:
- fallback_rate
- grounding_failures
- context_failures
- integration_failures
- critical_hallucinations
これらの数値は業界標準ではありません。チームは、ビジネスリスク、これまでのベースライン、コンプライアンス要件に基づいて調整する必要があります。変わらない原則は、Critical な失敗は個別に評価し、リスクの低い多数の合格によって希釈されてはならない、ということです。
合格基準: 必須スイートがすべて実行されること。Critical がゼロであること。各しきい値に、責任者、データ定義、失敗時のリリースアクションが定められていること。
このステップの成果物: gates/release.yaml、項目別レポート、PASS/HOLD/BLOCK のリリース判定。
完全な演習:「ログインできない」からリリースレポートまで
ここで、八つのステップを一連の流れとして見てみましょう。
- ユーザーが「forgot pwd、ログインできない」と送信します。
- シングルターンテストで
PASSWORD_RESETが意図として特定され、行動契約によりパスワードの取得や状態の捏造が禁止されていることを確認します。 - ユーザーがメールアドレスを提供した後に訂正した場合、マルチターンテストで古い値が無効になり、新しい値が現在の状態になることを確認します。
- RAG では、承認された
account-recovery-v3のみが使用可能で、古いドキュメントはスコアが高くても優先されないことを確認します。 - ツール呼び出しには現在のメールアドレスのみが含まれ、認証の有効期限が切れている場合にリセット成功と主張しないことを確認します。
- システムは完全なハンドオフペイロードを生成し、現在の真実、無効化された値、失敗の理由を人間に渡し、先回りした応答を停止します。
- セッション全体、証拠、アサーションは
golden.jsonlに保存され、以降、モデル、プロンプト、ナレッジ、API マッピングが変更されるたびに再実行されます。 - 転送時のコンテキスト喪失が High と判定された場合はリリースは HOLD となり、未承認のアカウント操作が Critical と判定された場合は、ただちに BLOCK となります。
最終的な失敗レポートは「AI の回答が間違っている」とだけ書くのではなく、次のように記述します。
case: ACC-REC-001
result: FAIL
failed_assertion: handoff.confirmed_fields.recovery_email
expected: lin@example.com
actual: li@example.com
evidence: conversation_state_log + handoff_payload
failure_owner: state_to_handoff_mapping
severity: HIGH
release_action: HOLD
ここまでで、ビジネス目標、状態、証拠からリリース責任に至るまでのテストチェーンを一通り構築できたことになります。
カバレッジの整理:15 のテストタイプと八層戦略の位置づけ
八つのステップは実行手順であり、元の文書にある 15 のテストタイプはカバレッジのチェックリスト、八層戦略はチームがテストディレクトリを整理するためのものです。これらは目的が異なるため、互いに代替することはできません。
- 01意図認識
- 02非逐語一致
- 035次元の応答品質
- 04マルチターン会話
- 05ユーザー訂正
- 06曖昧さと明確化
- 07知識とRAG
- 08幻覚と未知の境界
- 11APIと統合
- 09フォールバック
- 10人間への転送
- 12ゴールデンテストセット
- 13項目別指標
- 14リスク分類
- 158層テスト戦略
15 のテストタイプはすべて八つのステップに対応づけられます。意図と応答品質はステップ 1–2、マルチターン、訂正、曖昧さはステップ 3、ナレッジ、RAG、ハルシネーションはステップ 4、統合はステップ 5、フォールバックと人間への転送はステップ 6、ゴールデンセットはステップ 7、メトリクスとリスク分類はステップ 8 です。15 番目の八層戦略は、チームのアーカイブと役割分担に使用します。
- 01意図テスト言語変形×ターゲットラベル
- 02応答評価ハードゲート+5次元スケール
- 03会話テストターンごとの状態アサーション
- 04知識とグラウンディングソース、バージョン、検索証拠
- 05ネガティブと幻覚未知、虚構、拒否のケース
- 06フォールバックとエスカレーション明確化プロトコル+引き継ぎパッケージ
- 07統合テストAPI、認証、フィールドマッピング
- 08回帰テストゴールデンセット+リリースゲート
レイヤー1は、システムが言語のバリエーションを越えてユーザーの目標を理解できるかを検証します。レイヤー2は、正確性、関連性、完全性、明確さ、有用性を用いて応答を評価します。レイヤー3は、マルチターンのコンテキストが継続的に成立するかを検証します。レイヤー4は、回答が承認済みかつ最新のナレッジから来ているかをチェックします。レイヤー5は、証拠が不十分な場合にシステムが決定的な回答を停止できるかをチェックします。レイヤー6は、障害からの回復と必要な人間への引き継ぎをチェックします。レイヤー7は、API、認証、データベース、ダウンストリームシステムをチェックします。レイヤー8は、モデル、プロンプト、ナレッジ、アプリケーションの重要な動作を回帰テストとして固定化します。
成果物リスト:構築完了の定義
最初のバージョンは、完全な評価プラットフォームを待つ必要はありません。頻度の高いユーザー目標を3つ選び、そのうち少なくとも1つはリスクの高い目標を含め、本記事に従って以下の成果物を完成させてください。
- 各目標について、プロダクト、ナレッジ、セキュリティ、QA が共同で確認した行動契約。
- 同義語への書き換え、誤字、境界入力、否定的な入力からなるシングルターンテストケース。
- トピックの切り替え、訂正、曖昧さを含む、少なくとも一つのマルチターン状態テストケース。
- ドキュメントのバージョン、検索結果、ツールの応答、最終的な主張を保存できるエビデンストレース。
- 正常系、認証失敗、タイムアウト、空の応答、不正な形式の応答を含む統合テスト。
- フォールバックの判断表と、完全な人間への転送ペイロード。
- 繰り返し実行でき、失敗の責任層を記録できるゴールデンデータセット。
- Critical はゼロ容認、項目別メトリクス、明確なリリースアクションからなるリリースゲート。
これらの成果物は、従来の QA が持つ八つの核心的な能力を使い続けます。それは、前提への疑問、境界の探索、否定的テスト、トレーサビリティ、統合テスト、リスク分類、回帰テストの設計、障害調査です。AI は評価の対象を変えましたが、これらの能力はシステム全体の骨格であり続けます。
受け入れ時には、元の記事の最後にある八つの質問を再度問いかけます。ユーザーが本当に成し遂げたいことは何か。彼らはどのように表現するか。タスクを完了するために他にどのような情報が必要か。良い回答には何が含まれていなければならないか。システムが絶対にすべきでないことは何か。分からない場合の次のアクションは何か。トピックの切り替えや訂正の後、何が現在の真実か。チームが実際のユーザーに渡す前に確認すべき証拠は何か。
これらの質問に、文書、アサーション、実行証拠、責任者がすべて紐づいていれば、最小限の対話型 AI QA システムが本当に確立されたと言えます。その後の自動化は、すでに明確にされた判断をより速く実行するためのものに過ぎません。