Google GenAIのGeminiを使って画像の内容をテキストで説明させる

生成AIアプリを使っての画像の要約(画像の内容をテキスト化)はもはや珍しい話ではなくなったが、Google GenAIを使っても簡単に同様のことを実現できる。

“Google GenAIのGeminiを使って画像の内容をテキストで説明させる” の続きを読む

LLMにテーブルデータを渡す際はCSVを使用する

LLMを利用する際、入力するデータの「トークン数」は、処理速度と利用料金に直接的な影響を及ぼす重要な要素だ。テーブル形式のデータを渡す際には、そのフォーマットによって消費量が劇的に変化するので、適切なフォーマットで表現して渡すようにしたい。

“LLMにテーブルデータを渡す際はCSVを使用する” の続きを読む

Spreadsheetの内容からGoogle Slideを生成するプログラムをGeminiに書かせる

2025年5月6日にリリースされたGemini 2.5Pro Preview 05-06が良い。この一週間程度色々なプログラムを試しに書かせてみた。時々躓く部分はあるが、かなりの精度で期待通りのプログラムを作ることができている。

備忘録を兼ねて、Geminiを使ってSpreadsheetの内容からGoogle Slideを生成するプログラムを作る手順を残しておく。

“Spreadsheetの内容からGoogle Slideを生成するプログラムをGeminiに書かせる” の続きを読む

プログラムの中でLLMに任せられる部分はなるべく丸投げしたい

LLMの力を使ってコーディングの生産性をあげようという動きが活発だが、自分の中には「もはやコードは可能な限り書かない方が善だ」という感覚が生まれつつある。LLMができるタスクをわざわざ人の手を使って再生産したコードで動かすより、LLMに任せられる部分は可能な限りLLMに任せるようにしていきたい。LLMによって高速に書かれたコードであっても、コードとして存在する以上いつかは負債になるからだ。プロンプトももちろん負債にはなりうるが、自分が人間である限りコードよりはプロンプトの方がメンテナンスの難易度は低そうに思える。

まだまだ2025年現在ではLLMにはできないことも多いのでプログラムを自前で書かなければいけない部分もそこそこある。ただ、プログラムの一部分であってもLLMに頼れる部分は頼る、というスタイルは実験的にどんどん取り入れていきたいと思っている。

今回は、「与えられた数字が偶数かどうかを調べて返す」というあえてLLMにやらせなくても良いようなテーマを実際にGeminiを使って関数として実装してみる。

“プログラムの中でLLMに任せられる部分はなるべく丸投げしたい” の続きを読む

DockerコンテナとローカルでGCPの認証情報を共有する

ローカルマシンで認証をする

gcloud auth application-default login

ローカルマシンでgcloud auth application-default loginコマンドを実行してアカウント認証を行うと、下記の場所にクレデンシャルファイルが格納される。

Mac: $HOME/.config/gcloud/application_default_credentials.json

Windows: %APPDATA%\gcloud\application_default_credentials.json

How Application Default Credentials works

クレデンシャルファイルをバインドマウントする

上記のクレデンシャルファイルをdocker runのバインドマウント機能を使ってコンテナにバインドする。

docker run -v ~/.config/gcloud/application_default_credentials.json:/tmp/keys/adc.json:ro

上の書き方であれば、Dockerコンテナ内で /tmp/keys/adc.json というパスでローカルのGCPのApplication Defaultのクレデンシャルファイルを参照できるようになる。(Macの場合)

Docker Composeを使う場合は下記のように指定すればOK。

version: '3'
services:
  app:
    volumes:
      - ~/.config/gcloud/application_default_credentials.json:/tmp/keys/adc.json:ro

コンテナ内で参照するApplication Default認証のパスを指定する

GCPの各ライブラリは環境変数 GOOGLE_APPLICATION_CREDENTIALSで指定された場所にあるクレデンシャルファイルを使って認証を行う。Dockerコンテナにマウントしたクレデンシャルの保存先 /tmp/keys/adc.jsonGOOGLE_APPLICATION_CREDENTIALS にセットするように設定すれば、Dockerコンテナ内でローカル環境の認証情報を使ってGCPの各ライブラリを動かすことができるようになる。

version: '3'
services:
  app:
    environment:
      GOOGLE_APPLICATION_CREDENTIALS: /tmp/keys/adc.json
    volumes:
      - ~/.config/gcloud/application_default_credentials.json:/tmp/keys/adc.json:ro

Web AR開発用のJSライブラリ AR.js

これまでARアプリを作るときはARKitを使うことがほとんどだったが、マルチプラットフォームで動くライトウェイトなARアプリを作る機会があり、Web ARを試すことになった。Web ARを実現するためのライブラリは多数存在するが、2024年現在もっとも多く使われているライブラリは調べる限りAR.jsのようだ。サポートしているブラウザの種類や資料の数をみても、今の所AR.jsを使わない理由はなかったのでAR.jsを試してみることにした。

“Web AR開発用のJSライブラリ AR.js” の続きを読む

Google Slideのスライドをスクリプトで生成する

Google Apps Scriptに用意されているSlidesサービスを使うと、プログラムでスライドを新しく生成することができる。

https://developers.google.com/apps-script/reference/slides/slides-app

SlideAppクラスのcreate メソッドを使うと全く新しいスライドを新規で生成できるが、まっさらなスライドに要素を追加していく処理を全てスクリプトで書くのは結構大変なので、ベースとなるスライドをコピーするアプローチをとった方が何かと楽だ。

// srcFileId: コピー元のスライドのID
// filename: コピーして作られたファイルにつけるファイル名

const copy = DriveApp.getFileById(srcFileId).makeCopy(filename);

// 特定のフォルダに配置したければmoveToを呼び出す
// copy.moveTo(DriveApp.getFolderById(targetFolderId));


const newSlideId = copy.getId();

ファイルのコピーはSlidesサービスではなくDriveサービスのmakeCopyで行う。

const slide = SlidesApp.openById(newSlideId);

コピーしたスライドのIDをSlidesAppのopenByIdの引数に渡す形で、スライドを開き編集していくことができる。

const firstSlide = slide.getSlides()[0]
firstSlide.insertTextBox('Hello');

Google Apps ScriptのBigQuery Serviceのメソッドの引数の調べ方

Google Apps ScriptからBigQueryの機能を利用するにはAdvanced ServiceであるBigQuery Serviceを利用する。

https://developers.google.com/apps-script/reference#advanced_services

このAdvanced Serviceのメソッドを調べるには少し知識が必要になる。

“Google Apps ScriptのBigQuery Serviceのメソッドの引数の調べ方” の続きを読む

Google Apps Scriptでスプレッドシートの内容をオブジェクトの配列として取得する

Apps Scriptでスプレッドシートをテーブル的に使いたい時に、シートの内容をオブジェクトの配列として取得したいケースがよくある。

シート全体のセルの値はgetValues()もしくはgetDisplayValues()メソッドを使って取得することができる。

取得した値のうち、一行目をヘッダー行(keyの配列)として取り出し、残りの行を値として取り出すことで、オブジェクトの配列を作る。

function getRowsAsObjects(sheet) {
  var data = sheet.getDataRange().getDisplayValues();
  
  const header = data.shift();
  
  var rows = data.map(function(row) {
    var dic = {}
    header.forEach((h, idx) => {
      dic[h] = row[idx];
    });
    return dic;
  });

  return rows;
}

すると、このような結果が得られる。

[{name=Apple, date=2024/01/01}, {date=2024-03-13, name=Orange}]

よく書くコードなので、GASのライブラリとしてまとめた。

https://script.google.com/home/projects/1igMdPkdNu4Yg7u_rnBrXYTh7x15KotD0IpikNvrP52fCLV67ClXJ81ut

スクリプトID: 1igMdPkdNu4Yg7u_rnBrXYTh7x15KotD0IpikNvrP52fCLV67ClXJ81ut

使い方

var objects = SheetValues.getRowsAsObjects(SpreadsheetApp.getActiveSpreadsheet().getSheetByName("TestSheet"))