コンテンツへスキップ

サポートチャットボットは「答える」だけでなく「答えない」設計も必要だった

サポートチャットボットは「答える」だけでなく「答えない」設計も必要だった

経緯

LP に設置しているサポートチャットボットは、製品の機能・料金・トラブルシューティングに答えるという素直な役割を持っている。だが、質問に答えるように作られた対話型 AI には、そのままでは共通の弱点がある。システムプロンプトの中身をそのまま見せるよう仕向ける聞き方や、権限を偽って特別な回答を引き出そうとする言い回しに、素直に応じてしまいやすいという性質だ。

チャットボットの実体は、ナレッジベースのファイルをシステムプロンプトとして LLM に渡し、ユーザーの質問に答えさせる仕組みになっている。この弱点への対策は、アプリのコード側にキーワードフィルターを実装するのではなく、システムプロンプトそのものの中に、防御の方針を明文化して埋め込むという形で設計した。

「何を守るか」をキーワードでなくカテゴリで考える

最初に決めたのは、ソースコードや認証情報のような機密情報を「守るべき情報のカテゴリ」として言語化し、個別の禁止ワードの列挙に頼らないことだった。

「〇〇という単語を含む質問はブロックする」という実装は、言い回しを少し変えられるだけですり抜けられてしまう。一方、「このカテゴリに触れているか」という基準を LLM 自身に判断させれば、想定していなかった聞き方にもある程度対応できる。静的なキーワードフィルターと違い、モデルが持つ言語理解の力を借りて、表現の揺れそのものに汎化して対応できるのが利点だ。

拒否そのものを設計対象にする

禁止事項に該当する要求への応答についても、あらかじめ方針を持たせてある。ポイントは、拒否の理由を詳しく説明しないという原則だ。

一見、不親切に思えるかもしれない。だが、拒否理由を丁寧に説明すればするほど、その説明自体が「どこまでなら答えてもらえるか」を探る手がかりになってしまう。境界線の説明が、その境界線を回避するためのヒントになるという逆説がここにはある。短く・淡々と断ることのほうが、結果として安全に働く場面が多い。

なぜアプリ側のフィルターでなく、システムプロンプト側の方針にしたか

こうした防御は、アプリケーションのコード側(例えば入力メッセージを正規表現でチェックする仕組み)で実装することもできる。だが今回はあえて、LLM に渡すシステムプロンプトの中に「方針」として書き込む形を選んだ。

理由は、キーワードベースのフィルターが表現の揺れに弱いためだ。同じ意図を持つ要求でも、言葉を変えられれば静的なフィルターは片方しか拾えないかもしれない。LLM 自身に「こういう性質の要求だ」という判断基準を渡しておけば、学習済みの言語理解能力を使って、事前に想定していなかった言い回しにもある程度対応できる。もちろん万能ではないが、静的なフィルターよりも汎化性能で優位に立てる場面が多いというのが、この設計判断の理由だ。

まとめ

サポートチャットボットの「的確さ」は、答えられる質問に正しく答える能力だけで測られるものではない。答えてはいけない質問を、どんな聞かれ方をされても正しく見分けて断ることも、同じくらい重要な設計対象だ。情報をカテゴリで線引きする判断基準を持たせること、拒否の仕方そのものを設計すること——この 2 つを、アプリのコードではなく LLM に渡す方針として組み込むことで、単純な「頑張って答えるアシスタント」から一歩進んだ、実運用に耐えるサポートボットに近づけた。