🤖
Google AppsScript から Gemini や PaLM を呼び出す
tl;dr
Vertex AI の大規模言語モデルを GAS から呼び出すことができます。appsscript.json の scopes の設定と ScriptApp ライブラリを使ってトークンを取得すれば簡単に cloud の API を呼び出すことができます。
事前準備
プロジェクトの設定から Show "appsscript.json" manifest file in editor にチェックしておくこと。
appsscript.json に oauthScopes を追加しておくこと。
appsscript.json
{
...,
"oauthScopes": [
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/cloud-platform.read-only",
"https://www.googleapis.com/auth/script.external_request"
],
...
}
token の取得
Vertex AI の API を呼び出すにはアカウント認証して、token を取得する必要があります。
Google が提供している、OAuth2.0ライブラリ "apps-script-oauth2" を使用する必要があると思っていましたが、もっと簡単な方法で取得できました。
ScriptApp.getOAuthToken();
なんとこれだけでトークンが取得できます。
実装
上記を踏まえて実装。
// 以下設定はそれぞれの環境によって変えてください。
// Vertex AI の Cloud Console からコードを表示で見ることができます。
const API_ENDPOINT = "{your API_ENDPOINT}"
const PROJECT_ID = "{your project id}"
const GEMINI_MODEL_ID = "gemini-pro"
const PALM_MODEL_ID = "text-unicorn@001" // ここは bison でも良い。
const LOCATION_ID = "{your location}"
// GEMINI と PALM の ENDPOINT
// streamGenerateContent と predict で response が変わることに注意
const GEMINI_ENDPOINT = `https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${GEMINI_MODEL_ID}:streamGenerateContent`;
const PALM_ENDPOINT = `https://${API_ENDPOINT}/v1/projects/${PROJECT_ID}/locations/${LOCATION_ID}/publishers/google/models/${PALM_MODEL_ID}:predict`;
function setPrompt(prompt) {
return {
"contents": [
{
"role": "user",
"parts": [
{
"text": prompt
}
]
}
],
"generation_config": {
"maxOutputTokens": 1024,
"temperature": 0,
"topP": 1
}
}
}
function setPalmPrompt(prompt) {
return {
"instances": [
{
"content": prompt
}
],
"parameters": {
"candidateCount": 1,
"maxOutputTokens": 256,
"temperature": 0,
"topK": 40
}
}
}
function getToken() {
return ScriptApp.getOAuthToken();
}
function callPalm(text, token) {
const headers = {
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
};
const payload = setPalmPrompt(text);
const options = {
"method": "POST",
"headers": headers,
"payload": JSON.stringify(payload)
};
// link: https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations.publishers.models/predict
const response = UrlFetchApp.fetch(PALM_ENDPOINT, options);
const responseData = JSON.parse(response.getContentText());
console.log(responseData);
return responseData.predictions[0].content;
}
function callGemini(text, token) {
const headers = {
"Authorization": "Bearer " + token,
"Content-Type": "application/json"
};
const payload = setPrompt(text);
const options = {
"method": "POST",
"headers": headers,
"payload": JSON.stringify(payload)
};
// link: https://cloud.google.com/vertex-ai/docs/reference/rest/v1beta1/projects.locations.publishers.models/streamGenerateContent
const response = UrlFetchApp.fetch(GEMINI_ENDPOINT, options);
const responseData = JSON.parse(response.getContentText());
// candidates で返ってきているテキストを全て繋ぎ合わせる
let returnText = "";
for(let data of responseData) {
returnText += data.candidates[0].content.parts[0].text;
}
console.log(returnText);
return returnText;
}
function run() {
const token = getToken();
const text = "ぷろんぷと";
console.log(callPalm(text, token));
console.log(callGemini(text, token));
}
おわりに
GAS に組み込んでちょっとしたタスクを Gemini で自動化していくの楽しいです。
みなさんも良い GAS Gemini ライフを!!
Discussion