😺

VercelのAI SDKが神神の神

2023/06/21に公開

はじめに

修正や追加等はコメントまたはGitHubで編集リクエストをお待ちしております。

本題

面白そうなので試してみました。

https://vercel.com/blog/introducing-the-vercel-ai-sdk

使い方

apiを実装します。

app/api/chat/route.ts
import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'

// OpenAI APIのクライアントを作成します。
const config = new Configuration({
  apiKey: process.env.OPENAI_API_KEY
})
const openai = new OpenAIApi(config)

// 重要!runtimeをedgeに設定します。
export const runtime = 'edge'

export async function POST(req: Request) {
  // リクエストの本文から`messages`を抽出します。
  const { messages } = await req.json()
  // プロンプトを指定してOpenAIにストリーミングチャット補完を要求します。
  const response = await openai.createChatCompletion({
    model: 'gpt-3.5-turbo',
    stream: true,
    messages
  })
  // 応答をフレンドリーなテキストストリームに変換します。
  const stream = OpenAIStream(response)
  // ストリームで応答します。
  return new StreamingTextResponse(stream)
}

Pageを作成します。

app/chat/page.tsx
'use client'

import { useChat } from 'ai/react'

export default function Chat() {
  const { messages, input, handleInputChange, handleSubmit } = useChat()
  // useChat({ api: `/api/chat` }) とすると、URLを指定できます。

  return (
    <div>
      {messages.map(m => (
        <div key={m.id}>
          {m.role}: {m.content}
        </div>
      ))}

      <form onSubmit={handleSubmit}>
        <label>
          Say something...
          <input
            value={input}
            onChange={handleInputChange}
          />
        </label>
      </form>
    </div>
  )
}

たったこれだけで動きます。
しかもストーリームで動いているので、リアルタイムに応答が返ってきます。

ちょっと改良する

モデルの種類を指定できるようにしてみます。

app/api/chat/[model]/route.ts
import { OpenAIStream, StreamingTextResponse } from 'ai'
import { Configuration, OpenAIApi } from 'openai-edge'

// OpenAI APIのクライアントを作成します。
const config = new Configuration({
  apiKey: process.env.OPENAI_API_KEY
})
const openai = new OpenAIApi(config)

// 重要!runtimeをedgeに設定します。
export const runtime = 'edge'

export async function POST(
  req: Request,
  { params }: { params: { model: string } },
) {
  const model = params.model;
  // リクエストの本文から`messages`を抽出します。
  const { messages } = await req.json()
  // プロンプトを指定してOpenAIにストリーミングチャット補完を要求します。
  const response = await openai.createChatCompletion({
    model,
    stream: true,
    messages
  })
  // 応答をフレンドリーなテキストストリームに変換します。
  const stream = OpenAIStream(response)
  // ストリームで応答します。
  return new StreamingTextResponse(stream)
}
app/chat/page.tsx
"use client";

import { useChat } from "ai/react";
import { useState } from "react";
export default function Chat() {
  const [model, setModel] = useState("gpt-3.5-turbo-16k");
  const { messages, input, handleInputChange, handleSubmit } = useChat({
    api: `/api/chat/${model}`,
  });

  return (
    <div>
      {messages.map((m) => (
        <div key={m.id}>
          {m.role}: {m.content}
        </div>
      ))}
      <select onChange={(e) => setModel(e.target.value)} value={model}>
        <option value="gpt-3.5-turbo">gpt-3.5-turbo</option>
        <option value="gpt-3.5-turbo-16k">gpt-3.5-turbo-16k</option>
        <option value="gpt-4">gpt-4</option>
      </select>
      <form onSubmit={handleSubmit}>
        <label>
          Say something...
          <input value={input} onChange={handleInputChange} />
        </label>
      </form>
    </div>
  );
}

公式のプレイグラウンド

https://sdk.vercel.ai/

まとめ

マジで神です。
便利すぎて、もうこれでいいんじゃないかと思ってしまうほどです。
爆速で開発できる反面、Next.jsに依存してしまうのが少し怖いです。

GitHubで編集を提案

Discussion