😃
Next.js を使用して Vercel AI SDK と LangChain JS を実装してみた
はじめに
ChatGPTのAPIを使用してNext.jsで簡単なチャットページを実験的に実装してみます。
今回はVercel AI SDKを使用しますが、同時にLangChainも簡単に試してみようと思います。
※ 実装内容が古くなりましたので、新しく記事を書きました。(2024年7月19日)
読者対象
- Next.js開発の経験者
事前準備
- OpenAI プラットフォームから API キーを作成します。
コードを書く
ステップ
- Next.js + Typescript を作成する
- env.localにOPENAI_API_KEYを記述する
- /api/aiSdkChat.ts と /api/langChainChat.ts を作成し、index.tsx を編集する
Next.js + Typescript を作成
yarn create next-app sample-ai --typescript
cd sample-ai
yarn add ai openai-edge
yarn add langchain
SDKの実装
/api/aiSdkChat.ts
import { OpenAIStream, StreamingTextResponse } from "ai";
import { Configuration, OpenAIApi } from "openai-edge";
import { NextRequest } from "next/server";
export const runtime = "edge";
const config = new Configuration({
apiKey: process.env.OPENAI_API_KEY,
});
const openai = new OpenAIApi(config);
export default async function handler(req: NextRequest) {
const { messages } = await req.json();
const response = await openai.createChatCompletion({
model: "gpt-3.5-turbo",
stream: true,
temperature: 0.9,
messages: messages.map((message: any) => ({
content: message.content,
role: message.role,
})),
});
const stream = OpenAIStream(response);
return new StreamingTextResponse(stream);
}
/api/langChainChat.ts
import { StreamingTextResponse, LangChainStream, Message } from "ai";
import { ChatOpenAI } from "langchain/chat_models/openai";
import { AIMessage, HumanMessage } from "langchain/schema";
import { NextRequest } from "next/server";
export const runtime = "edge";
export default async function handler(req: NextRequest) {
const { messages } = await req.json();
const { stream, handlers } = LangChainStream();
const llm = new ChatOpenAI({
modelName: "gpt-3.5-turbo",
streaming: true,
temperature: 0.9,
});
llm
.call(
(messages as Message[]).map((m) =>
m.role == "user"
? new HumanMessage(m.content)
: new AIMessage(m.content)
),
{},
[handlers]
)
.catch(console.error);
return new StreamingTextResponse(stream);
}
index.tsx
useChatではVercel AI SDKまたはLangChainのどちらかを指定するようにしてみました。
(どちらを指定してもチャットページの動作は同じです)
import type { NextPage } from "next";
import { useChat } from "ai/react";
const Home: NextPage = () => {
const aiSdkChat = `/api/aiSdkChat`;
const langChainChat = `/api/langChainChat`;
const { messages, input, isLoading, stop, handleInputChange, handleSubmit } =
useChat({
api: aiSdkChat,
});
if (!isLoading) console.log(messages);
return (
<>
<div className="mx-auto w-full max-w-md py-24 flex flex-col">
<p className="font-bold text-lg">ChatGPT</p>
<br />
{messages.map((m) => (
<div key={m.id} className="w-96 mb-2 p-2">
{m.role === "user" ? "Human: " : "AI: "}
{m.content}
</div>
))}
<br />
<form onSubmit={handleSubmit}>
<input
name="box"
className="w-96 flex rounded bottom-0 border border-gray-300 text-gray-700 mb-2 p-2"
value={input}
onChange={handleInputChange}
/>
{isLoading ? (
<button
type="submit"
className="opacity-50 cursor-not-allowed w-96 rounded bg-sky-500 hover:bg-sky-700 mb-2 p-2"
disabled
>
Send
</button>
) : (
<button
type="submit"
className="w-96 rounded bg-sky-500 hover:bg-sky-700 mb-2 p-2"
>
Send
</button>
)}
</form>
<p className="w-96 text-slate-500 text-xs">
開発ツールのコンソールからメッセージ変数の値を確認して、値がどのように格納されているかを確認できます。
</p>
</div>
</>
);
};
export default Home;
動作確認
yarn dev
して、
起動させたURL(localhost:3000など)をPCブラウザで確認します。
会話をしてみます。
動作しているようです。
まとめ
Vercel AI SDKを使うと、このようなシンプルなチャットページを実装するのは非常に簡単でした。
さらにご自分でエラーハンドリングを追加してみると、より理解が深まる機会になると思います。
また、LangChain JSには、プロンプトテンプレートやエージェントなど機能がたくさんありますので、いろいろ試してみたいと思います。
参考サイト
Discussion