embeddingsでベクトル化して類似性検索のみでチャットボットを実装する方法。
■前準備
Q&Aを集める
問い合わせが予想されるQ&Aを用意する。Q&Aの質問部分をベクトル化
Qの部分をベクトル化する。ベクトル化したものをDBに格納
Qに対し1,536次元のベクトル情報をDBに格納する。QAテーブル Qをベクトル化したテーブル
trains embeddings
・id --------- ┐ ・id
・question └----- ・train_id
・answer ・vector
■チャットボット側の実装
質問内容をベクトル化
質問内容をベクトル化する。質問内容とそれぞれのQとの距離を抽出
$query_embeddings ←質問内容をベクトル化したもの
// Qのレコードを取得
$trains = Train::get();
// 類似値を格納する変数
$similarities = [];
// 質問内容と各Qの類似値を算出
foreach ($trains as $train) {
$dot = $this->_dot_product($query_embeddings, $train->embeddings);
$normProduct = $this->_vector_norm_query($query_embeddings) * $this->_vector_norm_question($train->embeddings);
$similarities[$train->id] = $dot / $normProduct;
}
最も類似性の高いAの部分を抽出して回答とする
$train_id = array_keys($similarities, max($similarities))[0];
$train = Train::findOrFail($train_id);
$train->answerが質問に対する回答
類似度の閾値を設定しておいて、その値を下回る場合は、”お答えすることができません”的な回答をするような処理を入れておいた方がよい
■このチャットボットのメリット
- 運用コストが非常にリーズナブル
- 必ず用意したAしか回答しないのでハルシネーションなし
改善点
- 質問のされ方に限らず用意したAをそのまま回答する
- 以前の会話を考慮した回答ができない
(会話のキャッチボールができない)
1件のコメント