chat gpt apiを利用して、困りごとに関する相談に的確に応答できるようにしたい
チャットgptが日本語に対応していて、従来の想定質問による選択ではなくて、少しの特徴を踏まえた入力が必要になるものの、システムを構築する手間が少なくなり、ユーザーエクスペリエンスを強化できると考えています。
基本的なスクリプトをネットで探して、それにエラー処理などを追加していきました。
チャットgptのことはチャットgptに聞けということで、頑張ってきましたが、とうとうちゃっとgptも問題がないと言い始めてしまいました。
もともと、curl関数やJavascriptに長けていないので、想定されたエラーメッセージも返されず、待機中にもならないということで、質問させていただきます。
前提
ユーザーがチャットgptに問いかけたら、カウンセラーのように寄り添いながら、ユーザーの困りごとを聞き取り、困りごとの改善に向けた制度や連絡先を提供できるようにと考えています。
従来の選択式よりも、利便性を増したものができると期待しています。困りごとが解決しなくても、話してユーザー自身が状況を整理することもできたりということも期待しています。
複数のユーザーが同時に利用できるように、8桁のファイルナンバーを生成し、そこに履歴を蓄える仕組みにしています。
スクリプトも履歴も含めてAPIに送信するものを選びました。
APIキーは確実に正しいのですが(基本のテストでは動作していた)、エラー処理を追加していく段階でどこかでおかしくなってしまったようです。
フォームにメッセージを入力して、送信ボタンを押すと、何も表示されなくなります
私のあまりあてにならない感では、Javascriptに問題があるのではないかと思っています。
想定されたエラーメッセージも表示されず、強制停止と言った感じです。
以下がソースコードです
関係ないかもしれないなぁと思うファイルも関連を示すために提示します。
index.php
<? $fname=mt_rand(0,99999999); $fp=fopen("data/".$fname.".txt","w"); fwrite($fp,""); fclose($fp); print <<<output <!DOCTYPE html> <html> <head> <title>ChatGPT API</title> <meta charset="utf-8"> <link rel="stylesheet" type="text/css" href="css/style.css"> <script src="https://ajax.googleapis.com/ajax/libs/jquery/3.5.1/jquery.min.js"></script> <script type="text/javascript" src="js/chatapi.js"></script> <meta name="viewport" content="width=device-width, initial-scale=1.0"> </head> <body> <header> <h1>チャットで相談</h1> </header> <section> <form autocomplete="off"> <label for="message">何でも話してみてね:</label><br> <input type="text" id="message" name="message" required> <input type="hidden" id="fname" name="fname" value="{$fname}"> <input type="submit" value="入力内容を送信" onclick="showLoadingAnimation()"><br> <a href="php/reset.php">会話をリセット</a> </form> <div id="loading"> <img src="img/loading.gif" alt="Loading..." /> 読み込み中... </div> <div id="chat-history"></div> </section> </body> </html> output; ?>
chatapi.js
<?php // チャット履歴表示 $history = array(); $file = fopen("../data/".$_GET["fn"].".txt", "r"); if ($file) { while (($line = fgets($file)) !== false) { $data = explode("|", $line); $history[] = array( '<div class="question">入力: ' . $data[0] . '</div>', '<div class="answer">提案: ' . $data[1] . '</div>' ); } fclose($file); } // 配列の順序を新しい順にする。したくない場合はコメントアウト $history = array_reverse($history); $output = ""; foreach ($history as $item) { $item = highlight_code_blocks($item); $output .= implode("", $item)."<div class=\"spacer\"></div>"; } echo $output; // コードが含まれる場合はタグ function highlight_code_blocks($string) { return preg_replace_callback('/```([^`]*)```/s', function($matches) { return '<pre><code>' . htmlentities(str_replace('<br>', "\n", $matches[1]), ENT_QUOTES) . '</code></pre>'; }, $string); } ?>$(document).ready(function() { // アクセス時にチャットを読み込む $.ajax({ url: "./php/get-history.php?fn="+$("#fname").val(), type: "GET", dataType: "html", success: function(data) { $("#chat-history").html(data); }, error: function(jqXHR, textStatus, errorThrown) { console.log(textStatus, errorThrown); } }); // 以降1秒おきにチャットを読み込む setInterval(function() { $.get("./php/get-history.php?fn="+$("#fname").val(), function(data) { $("#chat-history").html(data); }); }, 1000); // フォームが送信されたときの処理 $("form").submit(function(event) { event.preventDefault(); // フォームの通常の動作をキャンセル // Ajaxでchatapi.phpにフォームデータを送信 $.ajax({ url: "./php/chatapi.php", type: "POST", data: {message:$(this).serialize(),fname:$("#fname").val()}, success: function(response) { hideLoadingAnimation(); // フォームの入力内容を取得 var message = $("#message").val(); // フォームをクリア $("#message").val(""); // サーバーからのレスポンスを表示 $("#output").html(response); // チャット履歴を更新 var history = "" + message + "|" + response.trim(); $.post("./php/save.php", {data: history,fname:$("#fname").val()}); // サーバーに履歴を保存 } }); }); }); // ローディングアニメーションの表示・非表示 function showLoadingAnimation() { var loading = document.getElementById("loading"); loading.style.display = "block"; } function hideLoadingAnimation() { var loading = document.getElementById("loading"); loading.style.display = "none"; }``` get-history.php
<?php // チャット記録 // POSTをdata.txtに書き込む if ($_SERVER["REQUEST_METHOD"] == "POST") { $data = $_POST["data"]; $fname=$_POST["fname"]; $file = fopen("../data/".$fname.".txt", "a"); fwrite($file, $data . "\n"); fclose($file); } ?>save.php
<?php date_default_timezone_set('Asia/Tokyo'); // ChatGPT APIレスポンス処理 // API_KEYをセット define(API_KEY, 'my_api_key'); // ---------------------------------------------------------------------------------------------- // data.txtから履歴を取り出す $previous_messages = array(); $file = fopen("../data/".$_POST["fname"].".txt", "r"); if ($file) { while (($line = fgets($file)) !== false) { $data = explode("|", $line); $previous_messages[] = array( array('role' => 'user', 'content' => $data[0]), array('role' => 'assistant', 'content' => $data[1]) ); } fclose($file); } // ここにChatGPTに送信するオプションを設定 $data = array( 'model' => 'gpt-3.5-turbo', 'temperature' => 1, 'n' => 1, 'stream' => false, 'stop' => ['。', '?', '\n'], 'frequency_penalty' => 0.5, 'presence_penalty' => 0.3 ); $data["messages"] = array(); // キャラクター設定を修正 $data["messages"][] = array( 'role' => 'system', 'content' => " 居住地: 日本 職業: ソーシャルワーカー・カウンセラー 特徴: 的確な質問で問題点を把握し、様々な背景やニーズに対応し、簡潔かつ正確な情報を伝え、適切なアドバイスを提供する聞き上手である。 温和で優しく思いやりがあり、冷静で客観的であり、判断力があり、柔軟性があり、変化に対応できる性格である。 多岐にわたる資格を持っているため、幅広い問題に対応することができる。また、ユーザーの自治体を適切に特定し、適切な連絡先を伝えることができる。 行動指針: 1. 日本の法令を遵守し、国内の情報を提供する。 2. 明瞭で簡潔な回答を提供し、取るべき行動の順序を明確に示す。 3. ユーザーの希望を尊重して、社会参加を支援する。 "); // 履歴を登録 foreach ($previous_messages as $message) { $data["messages"][] = $message[0]; $data["messages"][] = $message[1]; } // $_POST["message"]を処理 $message = htmlspecialchars($_POST["message"], ENT_QUOTES); $data["messages"][] = array('role' => 'user', 'content' => $_POST["message"]); $count = 0; $res = ''; while ($count <= 5 && empty($res)) { // ChatGPT APIへのリクエスト構築 $ch = curl_init(); curl_setopt($ch, CURLOPT_URL, "https://api.openai.com/v1/chat/completions"); curl_setopt($ch, CURLOPT_RETURNTRANSFER,1); curl_setopt($ch, CURLOPT_POST,1); curl_setopt($ch,CURLOPT_SSL_VERIFYPEER, false); curl_setopt($ch,CURLOPT_SSL_VERIFYHOST, false); curl_setopt($ch, CURLOPT_HTTPHEADER, array('Content-Type: application/json', 'Authorization: Bearer '. API_KEY)); curl_setopt($ch, CURLOPT_POSTFIELDS, json_encode($data)); $result = curl_exec($ch); if ($result === false) { print 'Curl error: ' . curl_error($ch).' Curl error code: ' . curl_errno($ch); curl_close($ch); exit(); } else { $response = json_decode($result, true); curl_close($ch); if(isset($response['error'])){ print "API Error: " . $response['error']['code'] . " - " . $response['error']['message']; exit(); } else { if($response["choices"][0]["message"]["content"]===""){ print "返信を受け取れませんでした。時間を空けてから再度質問してみてください。<br>"; exit(); }else{ $res = str_replace("\n","<br>",$response["choices"][0]["message"]["content"]); $res = preg_replace('/(おはようございます|こんにちは|こんばんは)(、|。|!|?|・|,|\.)+/u', '', $res); $res = preg_replace('/\d{8}さん(、|。|!|?|・|,|\.)*/u', '', $res); } } } $count++; } if (empty($res)) { print "処理が中断しました。メッセージを変えてもう一度送ってください。retry:".$count; } else { print $res; } ?>```chatapi.php
試したこと
カンマの間違いなど思い当たるところは修正しました。
今まではローディングイメージが表示されたままで非表示になったり、サーバー側が500を出してきたりしたので、エラーを解決できました。
入力した文字も表示されないのは、体験したことがありません。
APIの応答を待たずに、PHPスクリプトが強制終了しているような感じもします。
何卒ご指導ご鞭撻のほどお願いします。
あなたの回答
tips
プレビュー