$train_id = array_keys($similarities, max($similarities))[0];
$train = Train::findOrFail($train_id);
$train->answerが質問に対する回答
上記のコードを下記に変更する。
つまり、ユーザーからの質問と類似性の高いQ(質問)とそのA(回答)の3つをLLMに渡して違和感のない回答を作ってもらう。
$question <---- ユーザーからの質問
$train_id = array_keys($similarities, max($similarities))[0];
$train = Train::findOrFail($train_id);
$train_question = $train->question;
$train_answer = $train->answer;
// ユーザーからの質問、一番近かった用意した質問、用意した回答をLLMに渡して回答を整えてもらう
$answer = $this->_formatting_answer($question, $train_question, $train_answer);
// ユーザーからの質問、一番近かった用意した質問、用意した回答からLLMに回答を整えてもらう
private function _formatting_answer($question, $train_question, $train_answer)
{
// プロンプト作成
$prompts = [];
$question =
"
OpenAIのAPIであるembeddingsを利用して企業のチャットボットを運用しています。
あらかじめ質問と回答のセットを登録しており
ユーザーからの質問と最も近い登録された質問をembeddingsで算出し
その登録された質問の回答をユーザーに返すようにしています。
それで、ユーザーからの質問、登録された質問、登録された回答から適切な回答に整えてください。
整える必要がない場合は登録された回答をそのまま出力してください。
出力内容の説明などはせず、出力をそのままユーザーへの回答に使えるように出力してください。
ここで提示した情報以外は使用しないでください。
もし、ユーザーからの質問と登録された質問の内容がかけ離れている場合には
「お答えすることができません」と出力してください。
#ユーザーの質問:
$question
#最も近い登録された質問:
$train_question
#最も近い登録された質問の回答:
$train_answer
"
;
$prompts[] = ["role" => "user", "content" => $question];
$formatting_answer = $this->_api_formatting_answer($prompts);
return $formatting_answer;
}
private function _api_formatting_answer($prompts)
{
$api_key = 'xxxxxxxxxxxxxxxxx'; // OpenAIのAPIキーをセット
if(count($prompts) == 0) return '';
$url = 'https://api.openai.com/v1/chat/completions';
$data = array(
'model' => 'gpt-4o-mini',
'max_tokens' => 1000,
"messages" => $prompts,
);
$headers = array(
'Content-Type: application/json',
'Authorization: Bearer ' . $api_key
);
$ch = curl_init();
curl_setopt($ch, CURLOPT_URL, $url);
curl_setopt($ch, CURLOPT_POST, true);
curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data));
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
$response = curl_exec($ch);
$result = json_decode($response, true);
return $result['choices'][0]['message']['content'];
}