第四開発事業部の西田です。

生成AIを利用したアプリケーション開発のデファクトになりつつあるLangChainを使って、Gemini Pro Visionを使ってみます。

実行環境にはGoogle Colaboratoryを使っています。

必要なライブラリのインストール

!pip install -U --quiet langchain-google-genai  langchain

APIキーの設定

モデルの利用のために環境変数にGeminiのAPIキーをセットします。
APIキーはGoogle AI Studioから発行できます。

import os

os.environ["GOOGLE_API_KEY"] = "***************************************"

テキスト問い合わせ

まずは単純にテキストで問い合わせてみます。

from langchain_core.messages import HumanMessage
from langchain_google_genai import ChatGoogleGenerativeAI

llm = ChatGoogleGenerativeAI(model="gemini-pro")
result = llm.invoke("LangChainについて教えて")
print(result.content)

LangChainとは、自然言語を理解し、生成することができる人工知能モデルの開発を目指したプロジェクトです。〜

なんか違う気もしますがこんな感じで返答が返ってきました。

画像を使ったマルチモーダル問い合わせ

こっちが本題。
Gemini Pro Visionの真骨頂は画像を使ったマルチモーダルな問い合わせができることなのでいらすとやさんの画像で試してみます。
Colabでローカルのファイルを参照するためにアップロードしておきます。

from PIL import Image
from IPython.display import display

file_path = './kaigi_sagyouin_smile.png'

image = Image.open(file_path)
display(image)

llm = ChatGoogleGenerativeAI(model="gemini-pro-vision")

message = HumanMessage(
    content=[
        {
            "type": "text",
            "text": "何人の人がいますか?",
        },
        {"type": "image_url", "image_url": file_path},
    ]
)

result = llm.invoke([message])
print(result.content)

5人です。

しっかり正解です。素晴らしい。

レシートを読み取ってJSON形式にする

もうちょっと高度なことも試してみます。
OCRのようにレシートの画像データを読み込んで扱いやすいデータで返すことはできるでしょうか。

from langchain_core.output_parsers import JsonOutputParser
import requests
import json
import io

parser = JsonOutputParser()

llm = ChatGoogleGenerativeAI(model="gemini-pro-vision")
chain =  llm | parser

url = "https://free-icons.net/wp-content/uploads/2021/03/money030.png"
image = Image.open(io.BytesIO(requests.get(url).content))
display(image)

message = HumanMessage(
    content=[
        {
            "type": "text",
            "text": "画像内のデータに適切な構造を与えてJSON文字列にしてください。",
        },
        {"type": "image_url", "image_url": url},
    ]
)

receipt_json = chain.invoke([message])

print(json.dumps(receipt_json, indent=2, ensure_ascii=False))
{
  "store": "スーパーマーケット",
  "business_hours": "10:00-21:00",
  "tel": "000-0000-0000",
  "items": [
    {
      "name": "ニンジン",
      "price": 100
    },
    {
      "name": "たまねぎ",
      "price": 500
    },
    {
      "name": "牛肉",
      "price": 150
    },
    {
      "name": "レタス",
      "price": 200
    },
    {
      "name": "牛乳",
      "price": 1000
    }
  ],
  "total": 1050,
  "tax": 50
}

手書き文字や複雑なレシートではないですがバッチリ解析できてますね!

感想

OCR以外にも大量の情報がある画像から必要な情報だけをピックアップしたり、情報のラベル付や分類、説明にも使えそうです。
マルチモーダルに対応することで一気にLLMの利用幅が広がりますね。

おまけ

実行結果をGistにしたものも載せておきます。