🐶

Dify API と GASのカスタム関数を組み合わせてスプレッドシートからLLMを利用する

2024/07/14に公開
2

この記事では、LLMアプリケーション開発プラットフォームであるDifyとGoogle Apps Script(GAS)のカスタム関数を使って、スプシに記載した画像URLに写っているのがわんこかどうかをDifyを使って自動で判定してみました。

なぜDifyとGASカスタム関数の組み合わせなのか?

GASのカスタム関数から直接OpenAIなどのAPIを叩くのが実装としては一番早いのですが、RAGを使いたい、複数のGASから呼び出したい、GAS以外からも呼び出したい、LLMのモデルを柔軟に変えたい、などが発生することも多いです。
そのため実際にLLMアプリケーションを作っていく際は単純にAPIを叩くだけでは解決できないことがおおく、LLMに関わる処理をどこかにまとめておき、まとめておいたものをAPI経由で呼び出すという形にするのが好ましいです。

そこで登場するのがDifyです。
Difyはチャットボットなどを作るのにも使えますが、このLLM処理をまとめてAPI処理にすることも出来ます。

本記事では「gpt-4o」モデルを使用し、画像がわんこかどうかの判定する処理をサンプルとして作ってみました。

全体像

Difyでワークフロー作成: 画像URLを入力として受け取り、gpt-4oで画像を解析して「犬」か「犬ではない」かをスプレッドシートの準備: 画像URLと判定結果を記録するためのスプレッドシートを作成します。
判定するワークフローを作成します。
GASカスタム関数作成: DifyのAPIを呼び出し、画像URLを渡して判定結果を取得するカスタム関数を作成します。
スプレッドシートに関数入力: スプレッドシートの判定結果列に、GASカスタム関数を入力して結果を自動表示させます。

Step-by-Stepガイド

0. OpenAIのAPIキーを発行してDifyに設定しておく

こちらの記事などを参照にDifyに設定しておいてください
https://zenn.dev/acntechjp/articles/03d6e8fa2b58bd

1. Difyでワークフロー作成

Difyにログインし、新しいワークフローを作成します。

機能を選択し、画像アップロードを有効にします。

モデルにgpt-4oを選択し、プロンプトに犬画像ならtrue,そうでないならfalseを返してください。のように設定します。

Is that a dog in the image?
If it is a dog, set TRUE to.
If not, return FALSE.
Must not return anything other than TRUE or FALSE.

プロンプトは英語じゃなくてもよいのですが、英語のほうがデバッグがしやすい(日本語が返されると、\u306f\u3044\u3001\u6dfb\ のように表示されるのでUnicodeエスケープしないと読めないためです)ので日本語をそのまま出力しないのであれば英語のほうがラクだと思います。

出力ノードを追加し、gpt-4oの判定結果をそのまま出力するように設定します。

GASからDifyのAPIを叩くためのAPIシークレットキーを作っておきます。

2. スプレッドシートの準備

Googleスプレッドシートで新しいスプレッドシートを作成し、以下の列を作成します。

列名 説明
url 画像のURL -
image =image(A2) 画像表示するための関数
is_dog 後述 わんこ判定結果

3. GASカスタム関数作成

スプレッドシートの「拡張機能」メニューから「Apps Script」を開きます。
以下のGASコードを記述します。
※ DIFY_API_KEYはスクリプトプロパティに入れてください

function is_dog_image(image_url) {
  return postToDifyAPI(image_url);
}

function postToDifyAPI(image_url) {
  const scriptProperties = PropertiesService.getScriptProperties();
  const apiKey = scriptProperties.getProperty("DIFY_API_KEY"); // スクリプトプロパティから取得

  const url = "https://api.dify.ai/v1/workflows/run";
  const headers = {
    "Authorization": "Bearer " + apiKey,
    "Content-Type": "application/json"
  };

  const payload = {
    "inputs": {},
    "response_mode": "blocking",
    "user": "howdy39",
    "files": [{
        "type": "image",
        "transfer_method": "remote_url",
        "url": image_url, // ex "https://github.com/howdy39.png"
    }]
  };

  const options = {
    "method": "post",
    "headers": headers,
    "payload": JSON.stringify(payload),
    "muteHttpExceptions": true // HTTP エラー発生時にも例外をスローしないようにする
  };

  const response = UrlFetchApp.fetch(url, options);

  // レスポンスの処理
  const responseText = response.getContentText();
  if (response.getResponseCode() === 200) {
    Logger.log(responseText); // レスポンス内容をログに出力
    const responseJson = JSON.parse(responseText);
    return responseJson.data.outputs.text;
  } else {
    Logger.log("Error: " + response.getResponseCode()); // エラー発生時のログ出力
    return "Error: " + response.getResponseCode();
  }
}

4. スプレッドシートに関数入力

スプレッドシートの is_dog 列に、 =is_dog_image(A2) のように関数を入力します。(A2は画像URLが入力されているセルのアドレス)
すると、判定結果が自動的に表示されます。

まとめ

DifyとGASカスタム関数を組み合わせることで、画像わんこ判定を自動化するワークフローを簡単に作成できました。
慣れれば5分もあればこれぐらいなら作れてしまうと思います。

これぐらいのケースだとDifyを使うメリットがそこまで見えてこないと思いますが、Difyにはアナリティクス機能がついていたりと実際に運用をしていくとほしい機能が最初から揃っています。
ぜひDify使ってみてください。

Discussion

Naoki IwataNaoki Iwata

Difyでgpt-4oを使用するには「設定→モデルプロバイダー」で
OpenAIのAPI-KEYのセットアップが必要なので
この記事の手順だけではgpt-4oで実装はできないです🐶

howdy39howdy39

to Naoki Iwata さん
コメントありがとうございます!
APIキーの設定が必要な旨を追加しておきました🐶