🤯

AIエージェント開発における対話テスト(自問自答させる)

に公開

AIエージェント開発の時に、自然言語による対話システムの品質保証は、従来のソフトウェアテストとは根本的に異なっているので良い方法が無いかなぁと考えていました。
入力パターンが無限に存在し、文脈に依存した適切な応答が求められるためです。

テストを考えてみて、LLMが自分自身でテストケースを生成する手法が割と有効だったので、実際の取り組みを通じて詳しく解説します。

※本記事は、私自身のメモ的な意味合いが強く、確実性が保証されていないし、テスト駆動開発のように、しっかりと確立されて体系化されたものではないのでご了承ください。

従来のテスト手法との違い

一般的なWebアプリケーションやAPIのテストでは、明確な入力に対して予測可能な出力を検証できます。

// 従来のAPIテスト例
test('ユーザー情報取得', async () => {
  const response = await fetch('/api/users/123');
  expect(response.status).toBe(200);
  expect(response.data.name).toBeDefined();
});

しかし、AIエージェントの対話では同じようにテストはできないです。

文脈依存性

  • 前の会話内容によって適切な回答が変化
  • ユーザーの知識レベルに応じた説明が必要
  • 感情や緊急度を考慮した対応

表現の多様性

  • 同じ意図でも無数の表現方法が存在
  • 誤字脱字や略語への対応
  • 複数の質問が混在する複雑な問い合わせ

これらの特性により、開発者が手動ですべてのテストケースを網羅することは現実的ではありません。

AI自己生成テストの方法

要件からパターン抽出

社内ヘルプデスクAIエージェントの開発を例に、実際の手順を見てみましょう。

要件定義の例

・パスワードリセット
・アカウント設定
・システムトラブルの対応
・情報が足りない場合は質問する
・解決できない場合は、Agentから管理部門に通知するかを確認できる

まず、基本的な動作確認(モンキーテスト)は済ませておきます。

  • あいまいな質問に対して適切に聞き返すか
  • 基本的な礼儀作法ができているか etc...

AIによるテストケース生成

次に、テスト対象のAIエージェント自身に以下のような指示を与えます
※違うエージェントに聞かないように。

1. 想定される問答を要件定義された内容からパターン分けしてください
{$要件を書いた資料}
2. パターンごとの想定会話をそれぞれ4ラリー分作ってください。
3. 想定会話は以下の2つの場合で用意してください
   - 無事解決したパターン
   - 情報不足で解決しなかったパターン

生成されたテストケース例

以下は例ですが、要件はパターンが多いほどこの例も多く出てきます。

パターン例:パスワードリセット(解決ケース)

ユーザー:「パスワードを忘れました」
AI:「承知いたしました。どちらのシステムのパスワードでしょうか?」

ユーザー:「社内メールシステムです」
AI:「社内メールシステムのパスワードリセットですね。お使いのユーザーIDを教えてください」

ユーザー:「yamada.taroです」
AI:「確認いたします。リセット用メールを登録済みの個人用メールアドレスに送信いたします。10分以内に届かない場合はお声がけください」

ユーザー:「ありがとうございます」
AI:「他にご不明な点はございませんか?何かありましたらいつでもお声がけください」

判断の例

パターン例':パスワードリセット(未解決ケース)

ユーザー:「パスワードを忘れました」
AI:「どちらのシステムのパスワードでしょうか?」

ユーザー:「何のシステムかもわからないです」
AI:「どのような作業をしようとしていましたか?」

ユーザー:「パソコンを開いたら何かログイン画面が出てきました」
AI:「申し訳ございません。詳細が不明なため、ITサポート担当にご相談ください。内線番号は1234です」

ユーザー:「わかりました」
AI:「ご不便をおかけして申し訳ございません。ITサポートがお手伝いいたします」

判断の例

応用パターン:クレーム対応のテスト

別なパターンとして想定される質問の方向性を詳しく書くと、より特定のパターンに対してのテストになる。

クレーム対応をテストする場合の指示の例

感情的になっているユーザーからのクレーム対応を想定して
エスカレーションが必要になっている想定でテストケースを作成してください

生成例

ユーザー:「ITサポートの対応が最悪だ!責任者を出せ!」
AI:「ご迷惑をおかけして大変申し訳ございません。どのような対応で問題がございましたでしょうか?」

ユーザー:「担当者の態度が悪い!名前も覚えてない!もういい加減にしろ!」
AI:「担当者の対応でご不快な思いをおさせして、心よりお詫び申し上げます。詳しい状況をお聞かせください」

ユーザー:「説明してもわかってもらえないし、上から目線で最悪だった!」
AI:「そのようなご対応をしてしまい、本当に申し訳ございませんでした。責任者に報告し、改善いたします」

ユーザー:「改善って何をするんだ!口だけじゃないのか!」
AI:「申し訳ございません。このような重要な件はITサポート責任者が直接対応させていただきます。責任者の田中から直接ご連絡差し上げますので、お時間をいただけますでしょうか?」

ユーザー:「いつ連絡くるんだ!」
AI:「本日中に責任者の田中からお電話いたします。今回は本当に申し訳ございませんでした」

判断の例

メリット

テストケース作るのが楽

シンプルに、目的に沿ったテストケースを作ってくれるのが楽

会話の例が一気に見れる

自分で何度かラリー形式で質問するよりも、効率的で、会話したときのパターンを確認できるから楽。

※AIが生成した会話パターンを実際に入力してみて、想定通り答えが返ってくるかを見るとより確実になる

網羅性の向上

AIが自分の能力範囲を理解した上でテストケースを生成するため、開発者が見落としがちなエッジケースも含められます。思いつかない複雑な問い合わせパターンや、微妙なニュアンスの違いも自動的に検出できます。

自然な対話パターンの生成

実際の人間の質問パターンに近い、より自然な対話を生成できます。定型的なテストケースではなく、実際のユーザーが使いそうな表現や言い回しを含んだテストが可能になります。

開発効率の向上

AIが会話パターンを自動生成するため工数削減がちょっとだけできる。要件変更があった場合も、新しい要件に基づいてテストケースを再生成できる。
当たり前ですが、プロンプトに渡す要件の情報が詳しければ詳しいほどよくなる。

テストのサイクル

テストケース生成 → 自問自答 → 結果確認 → プロンプト調整 → 再テスト

このサイクルで、AIエージェントの対話の品質をあげるみたいなことをやってみていました。

再テストを自動化するともっといいかも

質問1つに対して、チェックする項目が複数あるとして

再テスト時の質問をコード化する → 回答させる → 回答結果を、別のLLMにチェックさせる

みたいなことで自動化できるはず。

感想

もっといい方法があるかもしれない。って言うのもこの方法で確認したから絶対大丈夫とも限らないわけで。
AIってテストが課題で、テスト駆動開発みたいな体系化されたテストってないよなと。

Discussion