0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

LlamaIndex.tsをVercelで使う

Last updated at Posted at 2025-02-21

はじめに

LlamaIndexはLLMとデータを扱うのに便利なオープンソースのデータフレームワークで、pythonで書かれています。これをJavaScript/TypeScript環境で使えるようにしたのがLlamaIndex.tsです。Node.jsやDeno、Vercel Edge Runtimeなど複数のJavaScriptランタイムで動作します​。サーバサイドでの利用に焦点を当てており、ブラウザからの直接利用は一部APIの不足により制限があります。

Typescript版はPython版の完全な移植というわけではなく、一部使えない機能があります。また、Vercelにデプロイする場合にはサーバーレス環境特有の課題に注意する必要があるなど、導入に難しいところもありますが、レイテンシが低く軽量に動作するのは大きな利点です。また、VercelはAI SDKを提供しており、LlamaIndexといっしょに使うことが出来ます。

この記事では、Vercelで使う上での基本的な手順と注意点のメモをご紹介します。私自身初心者なので、色々間違いがあるかもしれません。何かありましたらコメントいただければ幸いです。

基礎資料

LlamaIndex.tsを使うなら以下の資料は押さえておきたいです。

基本的なセットアップ

まずはnext.js, Vercelなどを準備します。ルートになるディレクトリにて以下のコマンドを入力します

#Next.jsの準備
npx create-next-app@latest .

#Vercelプロジェクトの準備
vercel

# Node.js 22 のインストールと使用
nvm install 22
nvm use 22

# 必要なパッケージのインストール
npm install llamaindex

上の手順のあとなら既に設定済みと思いますが、tsconfig.jsonの以下のパラメーターを確認して下さい。

tsconfig.json
{
  compilerOptions: {
    ...
    moduleResolution: "bundler"
    ...
  },
}

これは TypeScript が 最新のパッケージ配布方法(ESM + CJS + サーバーレス環境向けの conditional exports)に対応するため に必要な設定とのことです(参照)。

次に、公式の指示に従い、next.config.tsは削除して、代わりにnext.config.mjsを作ります。

next.config.mjs
import withLlamaIndex from "llamaindex/next";
 
/** @type {import('next').NextConfig} */
const nextConfig = {};
 
export default withLlamaIndex(nextConfig);

Next.js の ESM (ECMAScript Modules) 化に適応し、最新の依存関係の問題を避けるために有用とのことです(資料)。

OpenAIのChatモデルを使ってみる

公式サンプルを更に簡略した例を使って、OpenAIのgpt-4o-miniと質疑応答します。

まず、OpenAI API呼び出しの抽象化と設定の管理を行うヘルパーモジュールと作ります。これは、本質的には公式サンプルと同じです。

lib/openai.ts
import { OpenAI } from "@llamaindex/openai";

export async function getChatResponse(message: string) {
  const llm = new OpenAI({ model: "gpt-4o-mini", temperature: 0.1 });
  const response = await llm.chat({
    messages: [{ content: message, role: "user" }],
  });
  return response.message.content;
}

次に、バックエンドAPIエンドポイントを作ります。これがクライアントからのリクエスト処理、エラーハンドリング、openai.tsでのOpenAI関連の処理の橋渡しをします

app/api/openai/route.ts
import { NextResponse } from 'next/server';
import { getChatResponse } from '@/lib/openai';

export async function POST(request: Request) {
  try {
    const { content } = await request.json();
    const response = await getChatResponse(content);
    return NextResponse.json({ response });
  } catch (error) {
    console.error('API Error:', error);
    return NextResponse.json({ error: 'Error occurred' }, { status: 500 });
  }
} 

最後に、フロントエンドのUIコンポーネントを作ります。

app/page.tsx
'use client';

import { useState } from 'react';

export default function Home() {
  const [input, setInput] = useState('');
  const [response, setResponse] = useState('');

  const handleSubmit = async (e: React.FormEvent) => {
    e.preventDefault();
    try {
      const res = await fetch('/api/openai', {
        method: 'POST',
        headers: { 'Content-Type': 'application/json' },
        body: JSON.stringify({ type: 'chat', content: input }),
      });
      const data = await res.json();
      setResponse(data.response);
    } catch (error) {
      console.error('Client Error:', error);
      setResponse('エラーが発生しました。');
    }
  };

  return (
    <div className="p-8">
      <form onSubmit={handleSubmit}>
        <textarea
          value={input}
          onChange={(e) => setInput(e.target.value)}
          className="w-full p-2 border rounded"
        />
        <button type="submit" className="mt-2 px-4 py-2 bg-blue-500 text-white rounded">
          送信
        </button>
      </form>

      {response && (
        <div className="mt-4 p-4 bg-gray-100 rounded">
          {response}
        </div>
      )}
    </div>
  );
}

ローカルのテスト用に、.env.localにAPIキーを登録してください。

.env.local
OPENAI_API_KEY=sk-xQoeXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXQY0u

ついでに、vercelのサイトのsettingsのenvironment variableのところでも同じように設定しておいてください。こちらはデプロイしたときに使います。

準備ができたら

npm run dev

を実行し、http://localhost:3000 で動作確認してください。

上手く行ったら、Vercelプロジェクトにデプロイしてみましょう。

vercel deploy

Vercel AI SDKを使ってみる。

次は、Vercelが提供しているAI SDKを使う例を紹介します。最初に、パッケージをインストールします。

npm install ai

次に、公式サンプルのモジュールを、ほぼコピーしてきます(console.logは区別のために追加)。

app/api/aisdk/route.ts
import { OpenAI, SimpleChatEngine } from 'llamaindex';
import { LlamaIndexAdapter } from 'ai';

export const maxDuration = 60;

export async function POST(req: Request) {

  console.log('ai sdk route');
    
  const { prompt } = await req.json();

  const llm = new OpenAI({ model: 'gpt-4o-mini' });
  const chatEngine = new SimpleChatEngine({ llm });

  const stream = await chatEngine.chat({
    message: prompt,
    stream: true,
  });

  return LlamaIndexAdapter.toDataStreamResponse(stream);
}

page.tsxも、公式に従って修正します。useCompletionを使うことで、大幅に簡略になることがわかります。また、テキストはストリームされます。

app/page.tsx
'use client';

import { useCompletion } from 'ai/react';

export default function Home() {
  const { completion, input, handleInputChange, handleSubmit } = useCompletion({
    api: '/api/aisdk',
  });

  return (
    <div className="p-8">
      <form onSubmit={handleSubmit}>
        <textarea
          value={input}
          onChange={handleInputChange}
          className="w-full p-2 border rounded"
        />
        <button type="submit" className="mt-2 px-4 py-2 bg-blue-500 text-white rounded">
          送信
        </button>
      </form>

      {completion && (
        <div className="mt-4 p-4 bg-gray-100 rounded">
          {completion}
        </div>
      )}
    </div>
  );
}

最後に

LlamaIndex.tsは、Python版に比べると情報が少なくて勉強しづらいですが、ビルド時間は短く動作もサクサクで快適なので、積極的に使っていきたいですね。

0
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?