🦜

PromptyとLangChainを使ってGemini Flash(gemini-1.5-flash)から出力を得る

2024/08/31に公開

はじめに

この記事ではMicrosoftが提供するPromptyを使ってGeminiを操作する方法について説明します。

Promptyとは

GitHubの記載によると以下のように説明されています。

Prompty is an asset class and format for LLM prompts designed to enhance observability, understandability, and portability for developers. The primary goal is to accelerate the developer inner loop.

訳:PromptyはLLMプロンプトのためのアセットクラスとフォーマットで、開発者のための観測可能性、理解可能性、移植性を高めるように設計されています。主な目的は、開発者のインナーループを加速することです。

他にも「プロンプトとその実行を単一のアセットに標準化する」とあります。

Prompty standardizes prompts and their execution into a single asset.

引用:prompty - GitHub

ちょっとわかりにくいと思うので簡単に説明するとつまりは
「AIに関するもろもろの設定をコンフィグレーションファイルに書いておいて、それを使ってAIを操作するためのパッケージ」です。

Promptyを使うには

Promptyは以下のフレームワークおよびサービスを使って利用できます。

  • Prompt flow
    • Azure Machine Learningの機能として提供されています
  • LangChain
  • Semantic Kernel

今回はLangChainを使ってGeminiを操作してみます。

LangChainを使ってGeminiを操作する

LangChainを使ってGeminiを操作するためには以下の手順を踏みます。

  • パッケージをインストールする
  • Google CloudのプロジェクトIDを環境変数に設定する
  • Google Cloudのプロジェクトに認証を実行する
    • gcloud auth application-default loginの実行
  • ソースコードを準備する
  • 実行する

パッケージをインストールする

まずはGeminiを操作するためのパッケージをインストールします。

pip install -U langchain langchain-prompty  google-cloud-aiplatform langchain_google_vertexai

※Vertex AIを使っているため関連のパッケージもインストールしています。

Google Cloudのプロジェクトの名前を環境変数に設定する

次にGoogle CloudのプロジェクトIDを環境変数に設定します。

export PROJECT_ID=your_project_name

プロジェクトIDはGoogle Cloudのコンソールから確認できます。

Google Cloud welcome

Google Cloudのプロジェクトに認証を実行する

次にGoogle Cloudのプロジェクトに認証を実行します。

gcloud auth application-default login

ソースコードを準備する

今回は簡単に実行してもらえるようにサンプルコードを用意しました。
まずはGitHubからコードをクローンします。

git clone https://github.com/ymd65536/prompty_gemini_flash.git

GitHub CLIを使っている場合は以下のコマンドでクローンできます。

gh repo clone ymd65536/prompty_gemini_flash

実行する

準備ができたら実行します。

cd prompty_gemini_flash/src
python main.py

実行結果

result-gemini

実行してみたけど何がどう変わったのか

実行結果を見ても何がどう変わったのかわからないと思います。
(実際のところ、Promptyがなくても同じ実行結果が得られると思います。)

実際にどこらへんが変わったのかはコードを見てもらうとわかると思いますが、かなり簡潔になっていると思います。

import os
from langchain_google_vertexai import VertexAI
from langchain_prompty import create_chat_prompt


PROJECT_ID = os.environ.get("PROJECT_ID", "")
LOCATION = os.environ.get("LOCATION", "asia-northeast1")

USE_CHAT_MODEL_NAME = os.environ.get(
    "USE_CHAT_MODEL_NAME",
    "gemini-1.5-flash-001"
)


if __name__ == "__main__":

    cwd = os.getcwd()

    try:
        prompt = create_chat_prompt(f'{cwd}/basic.prompty')
        prompt_text = prompt.invoke(
            {
                'question': "LangChainとはなんですか?"
            }
        )
        chat = VertexAI(model_name=USE_CHAT_MODEL_NAME, temperature=0)
        answer = chat.invoke(prompt_text)
        print(answer)
    except Exception as e:
        print(str(e))

basic.promptyというファイルにプロンプトやAIの設定を書いておき、main.pyでそれを読み込んで実行しています。basic.promptyは以下のようにyaml形式になっています。

---
name: ExamplePrompt
description: A prompt that uses context to ground an incoming question
authors:
  - Kento.Yamada
model:
  api: chat
  parameters:
    max_tokens: 3000
sample:
  firstName: Kento
---

system:
あなたは LangChain の質問に答える AI アシスタントです。

user:
{{question}}

basic.promptyには質問を受け取ってAIに渡すための設定が書かれています。
main.pyを見ていただくとわかるとおり、max_tokensの設定はしていませんが、basic.promptyで設定されているため、その設定が使われています。
また、system:ではAIの役割が定義されており、Promptyによる設定が使われています。

他にもAIが実行するツールセットを設定できるようですが、今回は使っていません。
別の機会に試してみたいと思います。

まとめ

今回はPromptyを使ってGeminiを操作する方法について説明しました。
Promptyを使うことで設定とロジックを分離することができ、コードが簡潔になるので
Promptyはかなり便利だと思います。

可能であれば、Promptyでなしで書いた場合と比較してみたいと思います。

トラブルシューティング

TypeError: issubclass() arg 1 must be a classと出る場合

class PropertySettings(BaseModel)でTypeError: issubclass() arg 1 must be a classと出る場合は
以下のコマンドで解決します。具体的にはtyping_extensions==4.5.0をインストールします。

pip install typing-extensions==4.5.0

Token has been expired or revoked.と出る場合

以下のようなエラーが表示される場合は認証情報が切れている可能性があります。

Retrying langchain_google_vertexai.llms._completion_with_retry.<locals>._completion_with_retry_inner in 4.0 seconds as it raised ServiceUnavailable: 503 Getting metadata from plugin failed with error: ('invalid_grant: Token has been expired or revoked.', {'error': 'invalid_grant', 'error_description': 'Token has been expired or revoked.'}).

以下のコマンドで認証情報を更新します。

gcloud auth application-default login

Discussion