🤖

AIチャットアプリを作ってみよう (AI チャット実装編)

2023/12/14に公開

この記事は某有志アドベントカレンダー 2023の 14 日目の記事です。


「AIチャットアプリを作ってみよう」シリーズ


こんにちは。あべです。

前回に引き続き、AIチャットアプリのサーバーサイドの実装をしていこうと思います。

Open AI API を呼び出す

まずは、Open AI APIのAPI KEYを取得します。
Create new secret key から、API KEYを作成して、クリップボードにコピーします。

ターミナルにて、exportしておきましょう。

$ export OPENAI_API_KEY='<API KEY>'

まずはお試しで、以下のように固定の質問をするようコードを修正してみます。

// index.ts

import { Hono } from "hono";
import OpenAI from "openai";

const app = new Hono();

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

app.get("/chat", async (c) => {
  const message = "クリスマスのおすすめの予定を教えてください!";
  const completion = await openai.chat.completions.create({
    messages: [{
      role: "system",
      content: message,
    }],
    model: "gpt-3.5-turbo",
  });

  console.log(completion.choices[0].message.content);
  return c.text(completion.choices[0].message.content ?? '');
});

export default app;

curlしてみると、いい感じに回答が返ってきました。

$ curl http://localhost:3000/chat

クリスマスのおすすめの予定は以下のようなものです:

1. クリスマスマーケットに行く:クリスマスマーケットでは、美味しい食べ物や飲み物を楽しめるだけでなく、かわいいクリスマスの雑貨や手作り品も購入できます。冬の風物詩として定番のイベントです。

2. 家族や友人と一緒にクリスマスディナーを作る:家族や友人たちと一緒に料理を作るのは、特別な日の楽しみの一つです。クリスマスディナーには、トルコ料理やローストビーフなど、特別な料理を用意するのもいいでしょう。

3. クリスマス映画を観る:クリスマス映画は、心温まる物語やユーモアに溢れた作品が多くあります。家族や友人たちと一緒に映画館に行ったり、自宅で映画鑑賞パーティーをするのもおすすめです。

4. ボランティア活動に参加する:クリスマスは、愛と思いやりの季節です。地元のホームレスシェルターや老人ホームなどでボランティア活動に参加することで、他の人々のために何かをすることができます。

5. クリスマス風のアクティビティを楽しむ:スケートリンクでスケートをしたり、雪が降っている場合は雪だるまを作ったり、温泉に行ったりするなど、季節に合ったアクティビティを楽しむこともおすすめです。

これらの予定は、家族や友人と特別な時間を過ごすためのものです。自分の好みや家族や友人のスケジュールに合わせて、楽しいクリスマスを過ごしてください!%

任意の問い合わせをできるように修正する

少し修正して、任意の質問を投げられるようにしましょう。
せっかくなので、zodでリクエストボディのバリデーションなんかもしてみます

import { Hono } from "hono";
import OpenAI from "openai";
import { HTTPException } from 'hono/http-exception'
import { z } from 'zod';

const ChatRequest = z.object({
  message: z.string(),
});

const app = new Hono();

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

app.post("/chat", async (c) => {
  // check content-type
  const contentType = c.req.header('content-type');
  if (contentType !== 'application/json') {
    throw new HTTPException(400, { message: 'Content-Type must be application/json'});
  }

  // check body
  const body = await c.req.json();
  const validationResult = ChatRequest.safeParse(body);
  if (!validationResult.success) {
    throw new HTTPException(400, { message: validationResult.error.message });
  }

  // chat
  console.log(`質問: ${validationResult.data.message}`);
  const completion = await openai.chat.completions.create({
    messages: [{
      role: "system",
      content: validationResult.data.message,
    }],
    model: "gpt-3.5-turbo",
  });

  console.log(completion.choices[0].message.content);
  return c.text(completion.choices[0].message.content ?? '');
});


export default app;

honoではcontent-type: application/jsonの場合、.json()でbodyを取得できるようですね。
他のcontent-typeではそれぞれの方法でbodyを取得する必要があるようです。

では早速実行してみます。

$ curl -X POST http://localhost:3000/chat \
    -H "Content-Type: application/json" \
    -d '{"message":"お正月の料理といえば?"}'

おせち料理、餅、お雑煮、伊達巻、かまぼこ、鯛の煮付け、黒豆、お吸い物、なます、お餅のお焼きなどです。

心なしか淡白な回答が返ってきましたが、いい感じですね。

次回予告

今回はOpen AI APIを呼び出して任意の質問に回答する機能を実装してみました。
次回はアプリケーションをコンテナ化し、App Runnerにデプロイするところまでやりたいと思います!

それではー。

株式会社ガラパゴス(有志)

Discussion