見出し画像

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();
ギターヒーローの正体は後藤ひとりです。

関連



いいなと思ったら応援しよう!