PDF ファイルとチャットする

この Codelab では、ユーザーが自然言語を使用して PDF ドキュメントから情報を抽出できる会話型アプリケーションを作成する方法について説明します。

  1. プロジェクトを設定する
  2. 必要な依存関係をインポートする
  3. Genkit とデフォルト モデルを構成する
  4. PDF ファイルを読み込んで解析する
  5. プロンプトを設定する
  6. UI を実装する
  7. チャットループを実装する
  8. アプリを実行する

前提条件

作業を開始する前に、次の前提条件を設定する必要があります。

設定の手順

依存関係を設定したら、プロジェクトをビルドできます。

1. プロジェクトを設定する

  1. ディレクトリ構造と、ソースコードを格納するファイルを作成します。

    $ mkdir -p chat-with-a-pdf/src && \
    cd chat-with-a-pdf && \
    touch src/index.ts
    
  2. 新しい TypeScript プロジェクトを初期化します。

    $ npm init -y
    
  3. pdf-parse モジュールをインストールします。

    $ npm i pdf-parse && npm i -D @types/pdf-parse
    
  4. プロジェクトで Genkit を使用するには、次の Genkit 依存関係をインストールします。

    $ npm i genkit @genkit-ai/googleai
    
    • genkit は、Genkit のコア機能を提供します。
    • @genkit-ai/googleai は、Google AI Gemini モデルへのアクセス権を提供します。
  5. モデル API キーを取得して構成する

    この Codelab で使用する Gemini API を使用するには、まず API キーを構成する必要があります。キーがない場合は、Google AI Studio でキーを作成します。

    Gemini API は無料枠が充実しており、利用を開始する際にクレジット カードは必要ありません。

    API キーを作成したら、次のコマンドを使用して GOOGLE_GENAI_API_KEY 環境変数をキーに設定します。

    $ export GOOGLE_GENAI_API_KEY=<your API key>
    

2. 必要な依存関係をインポートする

作成した index.ts ファイルに次の行を追加して、このプロジェクトに必要な依存関係をインポートします。

import { gemini20Flash, googleAI } from '@genkit-ai/googleai';
import { genkit } from 'genkit/beta'; // chat is a beta feature
import pdf from 'pdf-parse';
import fs from 'fs';
import { createInterface } from "node:readline/promises";
  • 最初の行は、@genkit-ai/googleai パッケージから gemini20Flash モデルと googleAI プラグインをインポートし、Google の Gemini モデルにアクセスできるようにします。
  • 次の 2 行は、PDF ファイルの解析用の pdf-parse ライブラリと、ファイル システム オペレーション用の fs モジュールをインポートします。
  • 最後の行は、node:readline/promises モジュールから createInterface 関数をインポートします。この関数は、ユーザー操作用のコマンドライン インターフェースの作成に使用されます。

3. Genkit とデフォルト モデルを構成する

次の行を追加して Genkit を構成し、Gemini 2.0 Flash をデフォルト モデルとして設定します。

const ai = genkit({
  plugins: [googleAI()],
  model: gemini20Flash,
});

次に、コードとエラー処理の骨組みを追加します。

(async () => {
  try {
    // Step 1: get command line arguments

    // Step 2: load PDF file

    // Step 3: construct prompt

    // Step 4: start chat

    // Step 5: chat loop

  } catch (error) {
    console.error("Error parsing PDF or interacting with Genkit:", error);
  }
})(); // <-- don't forget the trailing parentheses to call the function!

4. PDF を読み込んで解析する

  1. コマンドラインから渡された PDF ファイル名を読み取るコードを追加します。

        // Step 1: get command line arguments
        const filename = process.argv[2];
        if (!filename) {
          console.error("Please provide a filename as a command line argument.");
          process.exit(1);
        }
    
  2. PDF ファイルの内容を読み込むコードを追加します。

        // Step 2: load PDF file
        let dataBuffer = fs.readFileSync(filename);
        const { text } = await pdf(dataBuffer);
    

5. プロンプトを設定する

プロンプトを設定するコードを追加します。

    // Step 3: construct prompt
    const prefix = process.argv[3] || "Sample prompt: Answer the user's questions about the contents of this PDF file.";
    const prompt = `
      ${prefix}
      Context:
      ${text}
    `;
  • 最初の const 宣言は、ユーザーがコマンドラインからプロンプトを渡さない場合にデフォルトのプロンプトを定義します。
  • 2 番目の const 宣言は、プロンプトの接頭辞と PDF ファイルの全テキストをモデルのプロンプトに補間します。

6. UI を実装する

次のコードを追加してチャットを開始し、UI を実装します。

    // Step 4: start chat
    const chat = ai.chat({ system: prompt });
    const readline = createInterface(process.stdin, process.stdout);
    console.log("You're chatting with Gemini. Ctrl-C to quit.\n");

最初の const 宣言は、chat メソッドを呼び出してプロンプト(PDF ファイルの全文を含む)を渡すことで、モデルとのチャットを開始します。残りのコードは、テキスト入力をインスタンス化し、ユーザーにメッセージを表示します。

7. チャット ループを実装する

ステップ 5 で、ユーザー入力を受け取るコードを追加し、chat.send を使用してその入力をモデルに送信します。アプリのこの部分は、ユーザーが Ctrl+C キーを押すまでループします。

    // Step 5: chat loop
    while (true) {
      const userInput = await readline.question("> ");
      const { text } = await chat.send(userInput);
      console.log(text);
    }

8. アプリを実行する

アプリを実行するには、プロジェクトのルートフォルダでターミナルを開き、次のコマンドを実行します。

npx tsx src/index.ts path/to/some.pdf

これで、PDF ファイルとのチャットを開始できます。