GoogleChatでGoogleのLLM(PaLM2)が動くように作ってみた~VertexAI APIを利用~
ChatGPTが一気に広まり、生成系AIの話題がニュースにならない日がありませんね。私も生成系AIの凄さに魅了され、ChatGPTやそのプラグインを使ったり、TalkToGPTで英会話の練習をしたり、GPTのAPIを使って開発したりしていましたが、GoogleのLLMってどうなんだろう、、と周囲でちょっと話題にあがったので、GoogleのPaLM2をGoogleChatで動かせるように作ってみたくなり、超素人開発をしてみました。
以下は、GCP初めて触る&Pythonも簡単なものしか書いたことのない素人の私が、上記開発の為にお盆休みの数日で取り組んだことを順に記載した、超素人備忘録です。また、自分でとりあえず動くものを作りたい、ということで作ったもので、セキュリティ・精度・正確性は考慮しておりませんのでご容赦ください。
尚、コーディングやエラー解決、Pythonの構文やテクニカルドキュメントの理解に当たっては、ChatGPTに全面的にサポート頂きました(笑)
1.全体の流れ
GoogleChatを使った開発を行うにはGoogleWorkSpace(GWS)のアカウントが必要で、GWSアカウント取得には、ドメイン保有が必要になる。
また、GoogleLLMのPaLM2を動かす方法の一つにGoogleCloudPlatform(GCP)のCluod Functionsを利用する方法がある。
そこで事前の環境準備として、①ドメイン取得②GWS無料トライアル契約と設定③GCPの無料トライアル契約と設定を行ったうえ、プログラム開発として①CloudFunctionsでのGoogleChatAPIの使い方の練習 した後、②VertexAI APIを利用 してGoogleChat内でPaLM2を利用できるようにした。
2.事前準備
①ドメインの取得
格安・無料でドメインが取得できる「お名前.com」に会員登録して、無料の「.com」ドメイン(+付属でもらえる「.site」ドメイン)を契約。
尚、後述②のGWSのでドメイン関連のDNS設定が必要となるが、これは、「お名前.com」の中(ネームサーバーの設定⇒DNS設定/転送設定)で実施。(以下ご参考)
②GoogleWorkSpace(GWS)の無料トライアル契約と設定
GWSは14日間の無料トライアルがあるので、トライアル契約を実施。
Admin画面でチュートリアルに従い
各種ドメインの設定(これは①のDNS設定画面で基本行い、それによりGWSでドメインが確認・承認される)
ユーザーの追加(当該ドメインのメールアドレス作成、10個まで可能)
G-Mailアドレスの有効化
を実施。①のお名前.comでのDNS設定が結構複雑だった。そして、最後のG-Mailのアドレス有効化で何度も失敗、セカンダリードメインでもうまくいかず、GoogleWorkSpaceのヘルプに問い合わせたが、実際にはうまくいっているのでそのままで問題なしとのこと。それならそのままでいっか、ということで次に進む。
③GoogleCloudPlatform(GCP)の無料トライアル契約と設定
GCPも以下無料トライアルと無料枠があるので、これを利用。尚、契約は上記②で取得したドメインのメールアドレスで実施。
3.プログラム開発
①Cloud FunctionsでのGoogleChatAPIの使い方の練習
以下のドキュメントに従って、Chatアプリの作り方を練習。
「Prerequisites」のところは、上記2の事前準備の通り。
「Cloud 関数を作成してデプロイする」のところは、最初Node.jsで行っていたが(タブに分かれているのに気づかず)うまくいかず、Pythonに変更して実施(HTTPで、未認証の呼出を許可とか、セキュリティ的には甘いのかな、、、と思いつつそのまま実施)。尚、ここに記載がなかったが、7の「main.py」以外に、gitHubサンプル通り「requirement.txt」の修正も必要(同僚に教えてもらった)。
「Google Chat にアプリを公開する」のところは、手順5の「管理」や手順6の「設定」というのはなかったが、「構成」タブにある内容だったでそのまま進める。手順6のfのメールアドレスには、②で作成したドメイン内の管理メールアドレスを追加。
これで、この「Quickstart App」は完成。GoogleChatの「チャット」や「スペース」でアプリを検索とすると、このアプリが見つかるのでそれを組み込むと、ちゃんとその中で応答が返ってきた。
②VertexAI APIの利用
次に、VertexAIのPaLM APIを用いてPaLM2をGoogleChatで利用できるようにする。以下がVertex AI APIのクイックスタートのサイト。
気持ち的には、上記①のGoogleChatで応答するサンプルコードと、上記クイックスタートのTry chat promptsのシェルスクリプトコードをあわせた感じのコードをPythonで書けばいいはず。
そこで、以下のステップで試行錯誤しながらプログラムを完成させた。
まずは上記をマージしたPythonコードの作成をそのままChatGPTにお願い。⇒2つのコードをそのままコピーしてお願いしただけにもかかわらず、さすがGPT、大体それっぽいコードを返してくれた。
上記マージコードにPROJECT_IDとACCESS_TOKENの記述があったが、PROJECT_IDはGCPの画面の中ですぐに見つけられたので、自分のPROJECT_ID変更。
次にACCESS_TOKEN。こちらは、どう取得していいかわからないので、ChatGPTに聞いてみると、1つの方法として「IAMと管理」 > 「サービスアカウント」からサービスアカウントのJSONキーファイルを取得し、それを使ってACCESS_TOKENを取得するプログラムを書いてくれたので、そのプログラムを実行して一旦はACCESS_TOKEN取得。
だが、ACCESS_TOKENは有効期限が過ぎると変わってしまい、この方法では実用できない。それを回避する方法をまたGPTに聞いたところ、ランタイム環境変数を作成しそこにJSONキーファイルの中身をセットする方法(環境変数はGOOGLE_APPLICATION_CREDENTIALSとした)、セットした環境変数を利用してTOKENを取得する方法を教えてくれたので、その方法に変更し、必要なモジュール(os、google.oauth2、json)をインポート。
また、トリガーURLをクリックしてもアクセス拒否になってしまっていたので、権限を上記①と同じになるようにAllUserを追加(セキュリティ的な懸念はあるも)
その後、デプロイ・GoogleChatでトライ&エラー試行を繰り返す中で、ログエクスプローラーの見方、Curlコマンドでのコンソール実行など、エラーを突き止める方法もGPTに教えてもらいつつ、都度出るエラーと実行元ソースコードをChatGPTに渡し、コードの返信&解説で内容を理解しながらコードを再修正。(例えば、Curlコマンドで色々試しす中で、examplesの中のoutputの文字列が空白の場合や「!」が入るとエラーなることが判明。また、response_dataのJSONのリスト構造を確認して適切に値が取れるように修正を行った)
そしてGoogleChatに組み込みこんだチャットアプリ(Vertex AI Test)で、英語の質問に英語で返ってくるところまで完成。(現状Vertex AI APIはパブリックには日本語対応していないので)
最終的に動いたコードはこちら(デバッグの為のPrintとか、使っていない変数とか色々残っているが一旦そのまま)
<main.py> ※PROJECT_IDのところは、自分自身のものに置き換え
from typing import Any, Mapping
import flask
import functions_framework
import requests
import os
from google.oauth2 import service_account
import json
from google.auth.transport.requests import Request
@functions_framework.http
def vertex_chat(req: flask.Request) -> Mapping[str, Any]:
# Get service account credentials from environment variable
credentials_json_str = os.environ.get('GOOGLE_APPLICATION_CREDENTIALS')
if not credentials_json_str:
raise Exception("Service account credentials not found in environment variable.")
# Parse the JSON string to get the actual credentials dictionary
credentials_json = json.loads(credentials_json_str)
# Specify the desired scopes for the credentials
scopes = [
'https://www.googleapis.com/auth/cloud-platform',
'https://www.googleapis.com/auth/dialogflow',
# Add any other necessary scopes here
]
# Create credentials object with the specified scopes
credentials = service_account.Credentials.from_service_account_info(
credentials_json, scopes=scopes)
# Make a request to set up the credentials
credentials.refresh(Request())
# Now you can use the credentials to get the access token
access_token = credentials.token
print("ACCESS_TOKEN:",access_token)
if req.method == "GET":
return "Hello! This function must be called from Google Chat."
request_json = req.get_json(silent=True)
print(request_json["message"]["text"])
# Extract sender's display name and avatar URL
display_name = request_json["message"]["sender"]["displayName"]
avatar = request_json["message"]["sender"]["avatarUrl"]
# Create the input data for AI model prediction
input_data = {
"instances": {
"context": "My name is Ned. You are my personal assistant. My favorite movies are Lord of the Rings and Hobbit.",
"examples": [
{
"input": {"content": request_json["message"]["text"]},
"output": {"content": "welcome"}
}
],
"messages": [
{
"author": "user",
"content": request_json["message"]["text"]
}
]
},
"parameters": {
"temperature": 0.3,
"maxOutputTokens": 200,
"topP": 0.8,
"topK": 40
}
}
print("INPUT_DATA:",input_data)
# Make a POST request to AI model prediction API
response = requests.post(
"https://us-central1-aiplatform.googleapis.com/v1/pbrojects/PROJECT_ID/locations/us-central1/publishers/google/models/chat-bison:predict",
json=input_data,
headers={
"Authorization": f"Bearer {access_token}", # Replace with actual access token
"Content-Type": "application/json"
}
)
print("RESPONSE:",response.json())
# Process the response from the AI model and generate a message
if response.status_code == 200:
response_data = response.json()
generated_output = response_data["predictions"][0]["candidates"][0]["content"]
response_message = {
"text": generated_output # Use the generated output as the reply
}
else:
response_message = {
"text": "An error occurred while processing your request." # Handle error case
}
print("API error response:", response.content)
# Return the generated response message
return response_message
<requirement.txt>
Flask>=2.3.2
functions-framework>=3.*
requests>=2.31.0
google-auth
4.今後
以上で、目標であった、PaLM2をGoogleChatで動かせるように自分で作ってみたい、というところは一旦は実現したが、本格的に利用しようと思った場合には、以下のようなことを検討していく必要がある。(職場の同僚情報含む)
セキュリティ・認証の考慮⇒とりあえず動くことだけを考えたので、ほぼ考慮できていないが本格的な利用の場合は必須。
応答の精度向上⇒現在ソースコード中のinstancesの中のexamples等の記載や、parametersも適当なのでその修正要。
日本語対応⇒以下の通り、現在Vertex IAI APIの日本語対応は公にはサポートされていないが(以下リンクの通り)、個別サポートの確認や、ない場合には内部に言語変換を組み込む等が必要。
ベクターデータベースの対応⇒以下はChatGPTでの記事ではあるが、どのLLMでも共通な仕組みのようなので、勉強してみたい。
この記事が気に入ったらサポートをしてみませんか?