はじめに
「社内マニュアルやドキュメントの内容をもとに、LLMに正確な回答をさせたい」——そう思ってRAG(Retrieval-Augmented Generation、検索拡張生成)の仕組みをゼロから実装しようとすると、テキストの分割、埋め込みベクトルの生成、検索、プロンプトへの埋め込みと、意外とやることが多いことに気づきます。
LlamaIndexTSは、このRAGパイプラインをTypeScript/JavaScriptの世界で驚くほど少ないコードで組み上げられるデータフレームワークです。今回は基本的な使い方から、ツール呼び出しを使ったエージェント実装まで、実際に手を動かしながら紹介していきます。
LlamaIndexTSとは
LlamaIndexTSは、人気のPython版LlamaIndexをルーツに持つ、LLMアプリケーション向けのデータフレームワークです。ドキュメントの読み込みからインデックス化、検索、回答生成までを一貫したAPIで扱えるようにしてくれます。
主な特徴
- 豊富な実行環境対応 - Node.js、Deno、Bun、Cloudflare Workers、Vercel Edge Runtimeなど、モダンなJavaScript実行環境で動作します
- マルチLLM対応 - OpenAI、Anthropic、MistralAI、Groqなど主要なLLMプロバイダーをパッケージ単位で切り替えられます
- RAGの基本機能一式 -
Documentによるデータの取り込みからVectorStoreIndexによるベクトル検索、QueryEngineによる回答生成までを標準で提供します - エージェント・ツール呼び出し - LLMに外部関数を実行させる仕組みが組み込まれており、単なる質問応答を超えた自動化処理も書けます
なお、GitHubリポジトリ(run-llama/LlamaIndexTS)は現在アーカイブ済みで、新規の機能開発は止まっています。とはいえnpmパッケージは引き続き利用可能で、3,000以上のスターを集めた実績のあるコードベースです。学習用途や既存プロジェクトの保守で使う分には問題ありませんが、新規に長期運用するプロダクトへ採用する際は、後継ツールの動向もあわせて確認しておくと安心です。
インストール
まずは本体パッケージと、利用したいLLMプロバイダーのパッケージをインストールします。ここではOpenAIを例にします。
npm install llamaindex @llamaindex/openai
APIキーは環境変数として設定しておきます。
export OPENAI_API_KEY=your-api-key
TypeScriptで利用する場合はtsconfig.jsonに以下の設定を追加しておくとスムーズです。
{
"compilerOptions": {
"moduleResolution": "bundler",
"target": "es2020",
"module": "esnext"
}
}
基本的な使い方
まずは、テキストファイルを読み込んでインデックス化し、質問に答えてもらう最小構成のコードです。
import fs from "node:fs/promises";
import { openai, OpenAIEmbedding } from "@llamaindex/openai";
import { Document, Settings, VectorStoreIndex } from "llamaindex";
// 使用するLLMと埋め込みモデルを設定
Settings.llm = openai({ model: "gpt-4o-mini" });
Settings.embedModel = new OpenAIEmbedding();
async function main() {
// テキストファイルを読み込んでDocumentを作成
const text = await fs.readFile("./data/notes.txt", "utf-8");
const document = new Document({ text, id_: "notes.txt" });
// ベクトルインデックスを構築(内部でチャンク分割・埋め込み生成が行われる)
const index = await VectorStoreIndex.fromDocuments([document]);
// 質問応答用のクエリエンジンを取得
const queryEngine = index.asQueryEngine();
const response = await queryEngine.query({
query: "このドキュメントの要点を3つ教えてください",
});
console.log(response.message.content);
}
main().catch(console.error);
VectorStoreIndex.fromDocumentsが、テキストの分割・埋め込みベクトルの生成・インデックス構築をまとめて面倒を見てくれるのがポイントです。自前で実装すると数百行になりかねない処理が、この数行に収まっています。
ストリーミングでチャットさせる
一問一答だけでなく、会話履歴を踏まえたチャット形式にもできます。回答をストリーミングで受け取る例です。
import { ContextChatEngine, Document, Settings, VectorStoreIndex } from "llamaindex";
import { openai, OpenAIEmbedding } from "@llamaindex/openai";
import fs from "node:fs/promises";
Settings.llm = openai({ model: "gpt-4o-mini" });
Settings.embedModel = new OpenAIEmbedding();
Settings.chunkSize = 512;
async function main() {
const text = await fs.readFile("./data/notes.txt", "utf-8");
const document = new Document({ text });
const index = await VectorStoreIndex.fromDocuments([document]);
const retriever = index.asRetriever({ similarityTopK: 5 });
const chatEngine = new ContextChatEngine({ retriever });
const stream = await chatEngine.chat({
message: "このドキュメントについて教えてください",
stream: true,
});
for await (const chunk of stream) {
process.stdout.write(chunk.response);
}
}
main().catch(console.error);
実践的なユースケース
RAGだけでなく、LLMに関数(ツール)を呼び出させて外部の処理と連携させることもできます。以下は、LLMが必要に応じてget_weatherツールを呼び出す簡単なエージェントの例です。
import { openai } from "@llamaindex/openai";
import { ChatMessage, tool } from "llamaindex";
import z from "zod";
async function main() {
const llm = openai({ model: "gpt-4.1-mini" });
const messages: ChatMessage[] = [
{ role: "user", content: "東京の天気を教えてください" },
];
const weatherTool = tool({
name: "get_weather",
description: "指定した地域の現在の天気を取得する",
parameters: z.object({
address: z.string().describe("天気を調べたい地域名"),
}),
execute: ({ address }) => {
// 実際にはここで気象APIなどを呼び出す
return `${address}は現在晴れです`;
},
});
let exit = false;
do {
const { newMessages, toolCalls } = await llm.exec({
messages,
tools: [weatherTool],
});
messages.push(...newMessages);
exit = toolCalls.length === 0;
} while (!exit);
console.log(messages.at(-1)?.content);
}
main().catch(console.error);
このように、社内ドキュメント検索チャットボットや、FAQ自動応答、さらにはツール呼び出しを組み合わせた業務自動化エージェントまで、同じフレームワークの上で段階的に機能を拡張していけるのがLlamaIndexTSの強みです。
まとめ
LlamaIndexTSを使うと、RAGパイプラインの構築やLLMのツール呼び出しといった、本来なら実装が煩雑になりがちな処理を、シンプルなAPIでまとめて扱えることが分かりました。VectorStoreIndexやContextChatEngineといった部品を組み合わせるだけで、ドキュメントに基づいた回答生成やエージェント的な振る舞いまで実現できます。
現在リポジトリはアーカイブされ活発な開発は止まっていますが、パッケージ自体は引き続き利用でき、RAGやエージェントの仕組みを学ぶ題材としては十分に価値があります。まずは手元のテキストファイル1つから、VectorStoreIndex.fromDocumentsを試してみてはいかがでしょうか。
