
LlamaIndex.TS クイックスタートガイド
TypeScript版の「LlamaIndex.TS」のクイックスタートガイドをまとめました。
・LlamaIndex.TS v0.1.4
1. LlamaIndex.TS
「LlamaIndex」は、専門知識を必要とする質問応答チャットボットを簡単に作成できるライブラリです。「LlamaIndex.TS」は、TypeScriptに最適化されたシンプルなパッケージで基本機能のみ提供します。
コードサンプルは「LlamaIndexTS/examples」を参照。
2. ドキュメントの準備
今回は、マンガペディアの「ぼっち・ざ・ろっく!」のあらすじのドキュメントを使います。
・bocchi.txt

3. 質問応答
質問応答の実行手順は、次のとおりです。
(1) Node.js v18以降のインストール。
(2) 環境変数の設定。
以下のコードの <OpenAI_APIのAPIキー> にはOpenAI APIのAPIキーを指定します (有料)。毎回自動ロードしたい場合は、OSの環境変数に追加します。
$ export OPENAI_API_KEY="<OpenAI_APIのキー>"
(3) TypeScriptプロジェクトの作成。
$ mkdir helloworld
$ cd helloworld
$ npm init -y
$ npm install llamaindex
$ npm install typescript
$ npm install @types/node
$ npx tsc --init
(4) 「index.ts」を作成し、以下のように編集。
・index.ts
import fs from "fs/promises";
import {
Document,
SentenceSplitter,
SimpleNodeParser,
serviceContextFromDefaults,
VectorStoreIndex
} from "llamaindex";
async function main() {
// Documentの準備
const text = await fs.readFile(
"bocchi.txt",
"utf-8",
);
const document = new Document({ text: text });
// NodeParserの準備
const textSplitter = new SentenceSplitter({
chunkSize: 2000, // チャンクサイズ
paragraphSeparator: "\n\n" // セパレーター
});
const nodeParser = new SimpleNodeParser({
textSplitter: textSplitter
});
// ServiceContextの準備
const serviceContext = serviceContextFromDefaults({
nodeParser: nodeParser
})
// Indexの作成
const index = await VectorStoreIndex.fromDocuments(
[document],
{
serviceContext: serviceContext
}
);
// QueryEngineの準備
const retriever = index.asRetriever({ similarityTopK: 1 }); // チャンク取得数
const queryEngine = index.asQueryEngine({ retriever: retriever});
// 質問応答
const response = await queryEngine.query({
query: "ギターヒーローの正体は?",
});
// 出力の確認
console.log(response.toString());
}
main();
(5) index.tsの実行。
$ npx ts-node index.ts
ギターヒーローの正体は後藤ひとりです。
「ギターヒーローの正体は?」に対して、「ギターヒーローの正体は後藤ひとりです。」が返されました。正解です。
4. 取得したチャンクの確認
取得したチャンクは、response全て出力すると確認できます。
// 出力の確認
console.log(response);
Response {
response: 'ギターヒーローの正体は後藤ひとりです。',
sourceNodes: [
TextNode {
id_: 'f3111c0d-1c43-4b9d-a7dd-4c9152fb45a8',
metadata: {},
excludedEmbedMetadataKeys: [],
excludedLlmMetadataKeys: [],
relationships: [Object],
hash: 'qWX1cz3P2fUdVHKaixKWe8eSzs+WEsPKUUicbB8qgjY=',
text: '吉田銀次郎(よしだぎんじろう)\n' +
'ライブハウス「FOLT」の店長を務める男性。' +
:
'ギターヒーロー\n' +
'後藤ひとりが動画配信の際に用いるハンドルネーム。' +
:
textTemplate: '',
metadataSeparator: '\n',
type: 'TEXT'
}
]
}
5. インデックスの読み書き
(1) Indexの作成と保存。
「Index」に「StoreContext」を設定することで、自動的に保存されます。
import fs from "fs/promises";
import {
Document,
SentenceSplitter,
SimpleNodeParser,
serviceContextFromDefaults,
storageContextFromDefaults,
VectorStoreIndex
} from "llamaindex";
async function main() {
// Documentの準備
const text = await fs.readFile(
"bocchi.txt",
"utf-8",
);
const document = new Document({ text: text });
// NodeParserの準備
const textSplitter = new SentenceSplitter({
chunkSize: 2000, // チャンクサイズ
paragraphSeparator: "\n\n" // セパレーター
});
const nodeParser = new SimpleNodeParser({
textSplitter: textSplitter
});
// ServiceContextの準備
const serviceContext = serviceContextFromDefaults({
nodeParser: nodeParser
})
// Indexの作成と保存
const storageContext = await storageContextFromDefaults({
persistDir: "./storage", // storageフォルダにIndexを保存
});
const index = await VectorStoreIndex.fromDocuments(
[document],
{
serviceContext: serviceContext,
storageContext: storageContext,
}
);
console.log("Done")
}
main();
Done
・storage
・doc_store.json
・index_store.json
・vector_store.json
(2) Indexの読み込みと質問応答。
import {
SentenceSplitter,
SimpleNodeParser,
serviceContextFromDefaults,
storageContextFromDefaults,
VectorStoreIndex
} from "llamaindex";
async function main() {
// NodeParserの準備
const textSplitter = new SentenceSplitter({
chunkSize: 2000,
paragraphSeparator: "\n\n"
});
const nodeParser = new SimpleNodeParser({
textSplitter: textSplitter
});
// ServiceContextの準備
const serviceContext = serviceContextFromDefaults({
nodeParser: nodeParser
})
// Indexの読み込み
const storageContext = await storageContextFromDefaults({
persistDir: "./storage",
});
const index = await VectorStoreIndex.init({
serviceContext: serviceContext,
storageContext: storageContext,
});
// QueryEngineの準備
const retriever = index.asRetriever({ similarityTopK: 1 });
const queryEngine = index.asQueryEngine({ retriever: retriever});
// 質問応答
const response = await queryEngine.query({
query: "ギターヒーローの正体は?",
});
// 出力の確認
console.log(response.toString());
}
main();
ギターヒーローの正体は後藤ひとりです。
関連
LlamaIndexTS released new modules and restructured the documentation to help you better build LLM applications.
— Emanuel Ferreira (@manelferreira_) January 29, 2024
1️⃣ Ingestion Pipeline: now with transformations you can easily customize your nodes with a variety of modules such as parsers, extractors, and embeddings (s/o to… pic.twitter.com/odurHTlkXD