[Typescript] LangchainでGeminiを使ってみる

2023.12.18

Introduction

先日NodeでGeminiを動かしてみましたが、
Langchainも速攻で対応してました。
Typescript版のLangchainで試してみましょう。

Environment

  • MacBook Pro (13-inch, M1, 2020)
  • OS : MacOS 13.5.2
  • node : v20.8.1

Setup

ここでやっているのと同じく、 API Keyを取得しておきます。
GOOGLE_API_KEYという環境変数に設定するか、
あとで.envファイルに設定します。

% export GOOGLE_API_KEY=XXXXXXXXXXXXXXX

必要なライブラリをインストールしましょう。

% npm install @types/node ts-node typescript --save-dev
% npm install langchain openai dotenv --save
% npm install @google/generative-ai --save
% npm install @langchain/google-genai --save

環境変数を設定しない場合、ディレクトリに.envファイルを作成して
GOOGLE_API_KEY変数にKeyを設定します。

# .env
GOOGLE_API_KEY=XXXXXXXXXXXXXXX

まずはテキストチャットのサンプルです。
dotenvを設定してChatGoogleGenerativeAIのモデル名にgemini-proを指定します。
あとは普通に実行すればOK。
バッチ実行もstreamもサポートしてます。

//chat.ts
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import { HarmBlockThreshold, HarmCategory } from "@google/generative-ai";


// 環境変数設定
require("dotenv").config();

export const run = async () => {
// Text
const model = new ChatGoogleGenerativeAI({
    modelName: "gemini-pro",
    maxOutputTokens: 2048,
    safetySettings: [
      {
        category: HarmCategory.HARM_CATEGORY_HARASSMENT,
        threshold: HarmBlockThreshold.BLOCK_LOW_AND_ABOVE,
      },
    ],
  });

  // Batch and stream are also supported
  const res = await model.invoke([
    [
      "human",
      "コンピュータゲームを作る日本語の新会社名をを1つ提案してください",
    ],
  ]);

  console.log(res);

};
run();
% npx ts-node ./chat.ts

AIMessage {
  lc_serializable: true,
  lc_kwargs: { content: '**アトモスフィアワークス**', name: 'model', additional_kwargs: {} },
  lc_namespace: [ 'langchain_core', 'messages' ],
  content: '**アトモスフィアワークス**',
  name: 'model',
  additional_kwargs: {}
}

multimodalも試してみます。
下記画像を用意して、Geminiに投げてみます。

example

モデル名はgemini-pro-visionを指定します。

//vision.ts
import fs from "fs";
import { ChatGoogleGenerativeAI } from "@langchain/google-genai";
import { HumanMessage } from "@langchain/core/messages";

// 環境変数設定
require("dotenv").config();

async function main() {

const vision = new ChatGoogleGenerativeAI({
  modelName: "gemini-pro-vision",
  maxOutputTokens: 2048,
});

//画像のパスを指定
const image = fs.readFileSync("./example.jpg").toString("base64");

const input = [
  new HumanMessage({
    content: [
      {
        type: "text",
        text: "この画像にある物は何に使用するか、その名前を教えてください。また、それは何人で行うものか教えてください。",
      },
      {
        type: "image_url",
        image_url: `data:image/png;base64,${image}`,
      },
    ],
  }),
];

// Multi-modal streaming
const res = await vision.stream(input);

for await (const chunk of res) {
  console.log(chunk);
}

}

main()
    .then(() => {
        console.log('ok');
    })
    .catch((e: Error) => {
        console.error(e.message);
        throw e;
    });

実行すると、画像を解析して答えてくれます。
満点の回答とはいえませんが、ちゃんと答えてくれます。
このあたりは聞き方を工夫すればもっと正確な回答をもらえるかもしれません。

% npx ts-node ./vision.ts
AIMessageChunk {
  lc_serializable: true,
  lc_kwargs: {
    content: ' この牌は麻雀牌といい、四人で行うゲームです。',
    name: 'model',
    additional_kwargs: {}
  },
  lc_namespace: [ 'langchain_core', 'messages' ],
  content: ' この牌は麻雀牌といい、四人で行うゲームです。',
  name: 'model',
  additional_kwargs: {}
}
ok

References