😺
VercelのAI SDKが神神の神
はじめに
修正や追加等はコメントまたはGitHubで編集リクエストをお待ちしております。
本題
面白そうなので試してみました。
使い方
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>
);
}
公式のプレイグラウンド
まとめ
マジで神です。
便利すぎて、もうこれでいいんじゃないかと思ってしまうほどです。
爆速で開発できる反面、Next.jsに依存してしまうのが少し怖いです。
Discussion