😃
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