Agile育成ブログ
未来を変える喜びを
未分類

Next.js13とSupabaseでAIチャットアプリ構築(GPT-3)


Warning: count(): Parameter must be an array or an object that implements Countable in /home/xs638785/agile-software.site/public_html/wp-content/plugins/rich-table-of-content/functions.php on line 490
npx create-next-app@latest .

✔ Would you like to use TypeScript? … No / Yes
✔ Would you like to use ESLint? … No / Yes
✔ Would you like to use Tailwind CSS? … No / Yes
✔ Would you like to use src/ directory? … No / Yes
✔ Would you like to use App Router? (recommended) … No / Yes
✔ Would you like to customize the default import alias? … No / Yes

npx supabase login
npx supabase init
npx supabase init
npm i @supabase/auth-helpers-nextjs @supabase/supabase-js date-fns supabase openai
npm i -D encoding

ページ作成

ローディング画面

エラー画面

404 ページは頻繁にアクセスされます。アクセスのたびにエラーページをサーバーサイドレンダリングすると、Next.js サーバーの負荷が高くなってしまいます。その結果、コストが増加したり、体験が遅くなったりすることがあります。
これを避けるためにpages/404.jsファイルを作成することで、カスタマイズされた 404 ページを作ることができます。このファイルはビルド時に静的に生成されます。

'use client'

// エラー画面
const Error = () => {
  return (
    <div>
      <div className="text-center text-5xl font-bold mb-3 text-white">500</div>
      <div className="text-center text-xl font-bold text-white">Server Error</div>
    </div>
  )
}

export default Error

データが存在しないときの画面

supabase-server.tsファイル作成

サーバー側のクライアントを作成

import { headers, cookies } from 'next/headers'
import { createServerComponentClient } from '@supabase/auth-helpers-nextjs'
import type { Database } from '../utils/database.types'

export const createClient = () =>
  createServerComponentClient<Database>({
    headers,
    cookies,
  })

supabase-browser.tsファイル作成

ブラウザ側のクライアントを作成

入力画面

OpenAI API で提供されている GPT-3モデル GPT-3 「GPT-3」は、自然言語を理解し生成することができるモデルです。性能の異なる4つの主要モデルを提供しています。Da...

App Directoryではapiを使用するときのみpagesフォルダを使用する。

  • model:GPT-3のモデルを選択します。
  • prompt:
  • max_tokens:AIが生成する文章の最大数
  • temperature:テキストの創造性を制御する。低いと保守的で高いと多様な出力になる。
  • frequency_penalty:多様性と品質バランスを制御
  • presence_penalty:プロンプト

入力画面

KeyboardEvent オブジェクトは、キーボードによるユーザーの操作を示します。

  • insertData
  • insertError:

supabaseのpostテーブルにプロンプトを追加

        const { data: insertData, error: insertError } = await supabase
          .from('posts')
          .insert({
            prompt,
          })
          .select()

        if (insertError) {
          alert(insertError.message)
          return
        }

テキストプロンプトをAPIに送信

JSON.stringify()メソッドは、JavaScriptオブジェクトをJSON形式の文字列に変換します。これにより、データをサーバーに送信する前にデータを整形することができます。

const body = JSON.stringify({ prompt })

Content-Typeを指定しないと推測してContent-Typeを決めてしまう。
なので意図した形式でデータをやりとりできるようにContent-Typeを定めた方が良い。
‘application/json’とはjsonフォーマットでデータが送信されるようにしている。

        const response = await fetch('/api/openai', {
          method: 'POST',
          headers: {
            'Content-Type': 'application/json',
          },
          body,
        })

Postテーブル更新

投稿画面

キャッシュをクリアすることで最新の情報が取得される。

入力

送信

router.refresh()

データ取得

サーバー側のクライアントをインポートします。

import { createClient } from '../../../utils/supabase-server'

supabaseのpostsテーブルからデータを取得します。

  // 投稿リスト取得
  const { data: postsData } = await supabase
    .from('posts')
    .select()
    .order('created_at', { ascending: true })

データ表示

HTML要素の高さを取得します。

AIが生成した文章を表示させます。

{post.content && (
        <div className="mb-5">
          <div className="flex items-center space-x-2 mb-2">
            <div className="w-8 h-8 rounded-full object-cover bg-yellow-500 flex justify-center items-center text-white text-xs font-bold">
              A
            </div>
            <div className="text-white">AI</div>
          </div>

          <div className="flex items-end space-x-2">
            <div className="bg-white p-3 rounded-xl drop-shadow-md max-w-lg">
              {post.content.trim()}
            </div>
            <div className="text-sm text-white">{format(new Date(post.updated_at), 'HH:mm')}</div>
          </div>
        </div>
      )}

You cannot copy content of this page