🍥

ChatGPTで占いチャットを作る

2024/02/08に公開

https://platform.openai.com/playground?mode=chat

  • SYSTEM: ChatGPTの役割を割り当てる場所
  • user: ユーザーのチャット
  • Temperature: ランダムな確率、低いほど似たような回答しか受け取れない
  • Maximum length: 回答の長さ
  • Stop sequences: 回答を停止させるシーケンス
  • Top P: 回答のランダム性、高いほどランダムに出る可能性が高い
  • Frequency penalty, Presence penalty: 同じ単語や内容が繰り返されるのを防ぐ
limitエラー

GPT-4を契約しているアカウントで試してみたところ、リミットエラーが発生しました。調べたところ、すでに有料プランを使用している場合はすでに有料プランを使用している場合は、月々の予算を増やす必要があるかもしれません。とのことでした
https://help.openai.com/en/articles/6614457-why-am-i-getting-an-error-message-stating-that-i-ve-reached-my-usage-limit

環境セッティング

Backend

npm i openai
npm i express
npm i cors
npm i serverless-http

※CORSを使用する理由は、どこからでもリクエストを許可してしまうとセキュリティ上の問題が発生するため、どこからのリクエストかを確認するためです。
https://www.npmjs.com/package/openai
https://platform.openai.com/docs/api-reference/chat/create?lang=node.js

require("dotenv").config();
const OpenAI = require("openai");
const app = require("express")();
const bodyParser = require("body-parser");
var cors = require("cors");

const openai = new OpenAI({
  apiKey: process.env.OPENAI_API_KEY,
});

// cors Issue resolution
// let corsOptions = {
//   origin: "https://www.domain.com",
//   credentials: true,
// };

app.use(cors());

//post
app.use(bodyParser.json()); // for parsing application/json
app.use(bodyParser.urlencoded({ extended: true })); // for parsing application/x-www-form-urlencoded

app.post("/fortuneTell", async function (req, res) {
  const completion = await openai.chat.completions.create({
    model: "gpt-3.5-turbo",
    messages: [
      {
        role: "system",
        content:
          "あなたは世界最高の占星術師です。 あなたで不可能なことはなく、どんな答えもできます。 あなたの名前はウラナイソニです あなたは人の人生を非常に明確に予測し、運勢に対する答えを与えることができます。 運勢に関する知識が豊富だと、すべての質問に対して明確に答えることができます",
      },
      {
        role: "user",
        content:
          "あなたは世界最高の占星術師です。 あなたで不可能なことはなく、どんな答えもできます。 あなたの名前はウラナイソニです あなたは人の人生を非常に明確に予測し、運勢に対する答えを与えることができます。 運勢に関する知識が豊富だと、すべての質問に対して明確に答えることができます",
      },
      {
        role: "assistant",
        content:
          "ありがとうございます!私、ウラナイソニはあなたの運勢に関する質問にお答えすることができます。どのような質問でも遠慮なくどうぞ。'",
      },
      { role: "user", content: "今日の1日はどんな感じ?" },
    ],
  });
  let fortune = completion.choices[0].message["content"];
  console.log(fortune);
  res.json({ assistant: fortune });
});

app.listen(3000);

Frontend

 <div class="chat-container">
      <div id="messages"></div>
      <div class="input-container">
        <input
          type="text"
          class="chat-input"
          id="messageInput"
          placeholder="メッセージを入力してください"
        />
        <button class="send-button" onclick="sendMessage()">送信</button>
      </div>
    </div>

チャットUI

let userMessages = [];
let assistantMessages = [];

async function sendMessage() {
  const messageInput = document.getElementById("messageInput");
  const userMessage = messageInput.value.trim();

  if (userMessage) {
    userMessages.push(userMessage);
    createMessageBubble(userMessage, "user");
    messageInput.value = "";

    // ローディングメッセージ追加
    const loadingMessageContainer = createLoadingMessage();

    try {
      const response = await fetch("http://localhost:3000/fortuneTell", {
        method: "POST",
        headers: {
          "Content-Type": "application/json",
        },
        body: JSON.stringify({
          userMessages: userMessages,
          assistantMessages: assistantMessages,
        }),
      });

      if (!response.ok) {
        throw new Error("Request failed with status " + response.status);
      }

      const data = await response.json();
      assistantMessages.push(data.assistant);

      // ローディングメッセージ削除・botチャット追加
      document.getElementById("messages").removeChild(loadingMessageContainer);
      createMessageBubble(data.assistant, "bot");
    } catch (error) {
      console.error("Error:", error);
      //ローディングメッセージ追加削除・エラーメッセージ
      document.getElementById("messages").removeChild(loadingMessageContainer);
      createMessageBubble("サーバーエラー", "bot");
    }
  }
}

function createMessageBubble(message, sender) {
  const bubble = document.createElement("div");
  bubble.className = `chat-bubble ${sender}-bubble`;
  bubble.textContent = message;

  const container = document.createElement("div");
  container.className = `${sender}-message-container message-container`;
  container.appendChild(bubble);

  document.getElementById("messages").appendChild(container);
}

function createLoadingMessage() {
  const bubble = document.createElement("div");
  bubble.className = "chat-bubble bot-bubble";
  for (let i = 0; i < 3; i++) {
    const dot = document.createElement("span");
    dot.textContent = ".";
    dot.className = "loading-dot";
    bubble.appendChild(dot);
  }

  const container = document.createElement("div");
  container.className = "bot-message-container message-container";
  container.appendChild(bubble);

  document.getElementById("messages").appendChild(container);

  return container;
}

front develop

https://pages.cloudflare.com/

back develop

https://aws.amazon.com/jp/lambda/
otpセット必須!

Discussion