- 公開日:
Difyでの自前APIとの連携方法と注意点
- Authors
- Name
- 代表取締役 宮永邦彦
- @miyanaga
画像軽量化とWebフロントエンドのスピード改善の専門家です。Web系のIT技術大好き。
このサイトではスピード改善のリアルや、日々の技術的な気づきを共有します。
Difyには外部サービスと連携するツール機能があり、カスタムツールとして自前のAPIを連携対象に追加できる。
この記事では 「ふたつの数字の掛け算を行うという非常にシンプルな独自API」 を例にして、Difyにおけるカスタムツールの利用手順や、注意点を紹介する。
独自APIの用意
APIの作成と公開
実装方法はなんでも良いが、ここではNode.js + Fastify + ngrokでさくっとAPIサーバーを立ち上げる。
mkdir multiply-api
cd multiply-api
npm init -y
npm i fastify --add
index.js
を作成する。
const fastify = require("fastify")();
fastify.post("/multiply", async (request, reply) => {
const { a, b } = request.body;
const result = a * b;
reply.send({ result });
});
fastify.listen({ port: 3000 });
APIサーバーを起動する。
node index.js
ngrokで外部公開する。
ngrok http 3000
https://7217-*-*-*-*.ngrok-free.app
といった形式の外部公開URLが得られただろう。
もちろんVPSでもよいし、AWS Lambda関数でもよい。Difyのコンテナ(api
やworker
)からアクセスさえできればローカル環境でもよい。
OpenAPI-Swaggerによるスキーマを用意
この簡易APIをDifyに登録するのだが、OpenAPI-Swagger仕様によるスキーマが必要となる。
URLの変更
一箇所だけ、servers[0].url
は外部公開されたURL(ngrokであればhttps://7217-*-*-*-*.ngrok-free.app
)を指定すること。
openapi: 3.0.0
info:
title: 掛け算API
version: 1.0.0
description: このAPIはふたつの数字の掛け算をします。
servers:
- url: https://7217-*-*-*-*.ngrok-free.app # あなたの環境に合わせて変更
description: ngrokによる一時的な公開URL
paths:
/multiply:
post:
summary: 掛け算を行う
operationId: multiply
requestBody:
required: true
content:
application/json:
schema:
type: object
properties:
a:
type: number
description: かけられる数
example: 5
b:
type: number
description: かける数
example: 3
required:
- a
- b
responses:
"200":
description: 掛け算の成功
content:
application/json:
schema:
type: object
properties:
result:
type: number
description: かけ算の答え
example: 15
あらかじめスキーマが完備されたAPIならよいが、実際のところはそうでないAPIが多いだろう。
ひと手間かかって面倒な感じだが、DifyにおいてAIとAPIをスムーズに連携させるためのプロンプトの一種と考えて前向きに対処しよう。
PythonのFastAPIや、Node.jsのNextJSなどAPIフレームワークによっては、APIの実装とスキーマを同期して管理できる機能がある。本格利用の段階ではそのような工夫も考えたい。
Difyのカスタムツールに登録
Difyのメニューから、ツール
- カスタム
- カスタムツールを作成する
を選ぶとポップアップが表示される。
ここにカスタムツールの名前と、先ほど用意したOpenAPI-Swagger仕様のスキーマを登録しよう。
テスト
ボタンを押すとテストができる。a
に2
、b
に3
を入力し、テストボタンを押すと、{"result":6}
という期待した結果が得られた。
最後に保存ボタンを押すと、カスタムツールの登録は完了である。
チャットフローでカスタムツールを使う
次はスタジオ機能に移動し、チャットフローでカスタムツールを試してみよう。
ここでは「掛け算チャット」を作る。「2かける3は?」などの自然言語を解釈してAPIにより掛け算を行うチャットボットだ。
INFO
もちろん簡単な掛け算はLLM単体で実行できるが、ここでは外部APIとの連携を実証するための作例である。
パラメータ抽出の追加
まずは開始
ブロックにパラメーター抽出
ブロックを接続する。
自然言語による入力から、掛け算APIに渡すべき値が何かを抽出する。
ツールからインポート
ボタンを押して作成したカスタムツールのmultiply
APIを選択すると、スキーマに記述したパラメータa
とb
が自動で展開される。
カスタムツールの追加
続いてパラメーター抽出
ブロックからカスタムツール
- multiply
に接続する。
入力変数a
は、Variable
- パラメーター抽出/a
を選択する。b
についても同様にVariable
- パラメーター/b
を選択する。
これでユーザーの入力から掛け算の意図を汲み取り、APIに渡す処理を実現できる。
回答
一旦ここで回答ブロックをつなげて動作確認をする。a
、b
、そしてカスタムツールの出力text
を簡単に整形して表示するようにしてみた。
プレビュー機能で 「二かける三は?」 と尋ねてみると、
2 * 3 = {"result": 6}
という回答が得られた。
出力フォーマットはさておき、ユーザーの自然言語をLLMで適切に解釈し、独自に用意した掛け算APIを実行する流れを実現できた。
カスタムツールの注意点
カスタムツールの注意点は、出力スキーマは自動で解釈してくれないところである。
入力スキーマはパラメーター抽出やツールブロックの入力に活用できるが、出力はフラットな文字列text
としてしか扱うことができなかった。
今回のresult
のように必要な要素を抜き出すに、コードブロックなどでJSONを解析する必要がある。
Difyのバージョン
Difyのバージョンは 0.8.2
で検証した。
今後のバージョンで出力スキーマも解釈し、要素を個別に利用できるようになる可能性はある。しかし、もしかしたらLLMの入力としてはJSONやXMLなどの構造化データでもおおよそ問題ないので、設計思想としてこのままかもしれない。
代替案 - 出力スキーマをフラットテキストにする
構造化された出力は直接解析できないので、Dify向けのAPIの出力はそもそもシンプルなテキスト(text/plain
)にするという手も考えられる。
OpenAPI-Swagger仕様のスキーマの、responses
を以下のように変更して、APIの出力をtext/plain
にしても連携には問題がなかった。
responses:
"200":
description: 掛け算の成功
content:
plain/text:
schema:
type: string
example: "15"
代替案2 - HTTPリクエストブロック
実はスタジオ機能(ワークフロー編集)にも似たような機能があり、HTTPリクエスト
ブロックが用意されている。
こちらは比較的柔軟なHTTPリクエストを任意のWebサーバーに投げることができる。
カスタムツールに比べるとOpenAPI-Swaggerのスキーマを用意するのは面倒だけど、ちょっと連携を試してみたいといった用途にはこちらの方がよいかもしれない。
APIの認証について
カスタムツールによるAPI連携では当然、アクセス認証も設定できる。
設定による挙動は以下のようになっている。
APIリクエストヘッダAuthorization
(キーとして変更可能)に、指定した値を渡すシンプルな設定である。
- 認証タイプ
- なし 特に認証情報は渡さない
- APIキー
Authorization
ヘッダに指定の認証情報を渡す- ベーシック 値の前に
Basic
が付く - ベアラー 値の前に
Bearer
が付く - カスタム 値をそのまま渡す
- ベーシック 値の前に
ベーシック
文字通りベーシック認証だ。もしAPIがベーシック認証で保護されているなら、次のようにユーザ名とパスワードをBase64エンコードした値を設定すればDifyと連携できる。
echo "user:password" | base64
値は特にBase64である必要はなかった。
ベアラー
OAuth2などでアクセストークンを指定する場合にお馴染みの修飾子Bearer
であるが、これもtoken68である必要はなかった。
もしOAuth2で認証・認可を行っているAPIがあって、アクセストークンの有効期限が十分に長ければ、そのアクセストークンを値に指定することですぐに連携できるだろう。
まとめ
OpenAPI-Swaggerスキーマが必要という敷居はあるが、Difyと既存システムとのAPI連携は非常に夢が広がる機能である。
しかし、DifyからプリミティブなREST APIを呼び出すことは少ないと予想される。Dify側で複雑なプログラムロジックを組むのはあまり効率がよくないからだ。
おそらくもう少し複雑な処理を行うAI向け・Dify向けのAPIを新設することにはなる。だから既存のAPIにスキーマが用意されていなくても心配ない。それらの新設APIにのみ用意すれば実用上は問題ない。
また、エージェントアプリケーションで更新系のAPIとの連携も考えられる。ユーザーの自然言語入力に応じて既存システムに影響を及ぼすユースケースも今後は増えると思われる。
業務での本格的なAI利用に向けて、カスタムツールは避けて通れないテーマである。