公開日:

Difyでの自前APIとの連携方法と注意点

Authors
  • author image
    Name
    代表取締役 宮永邦彦
    Twitter
    @miyanaga
  • 画像軽量化とWebフロントエンドのスピード改善の専門家です。Web系のIT技術大好き。

    このサイトではスピード改善のリアルや、日々の技術的な気づきを共有します。

Difyには外部サービスと連携するツール機能があり、カスタムツールとして自前のAPIを連携対象に追加できる。

この記事では 「ふたつの数字の掛け算を行うという非常にシンプルな独自API」 を例にして、Difyにおけるカスタムツールの利用手順や、注意点を紹介する。


独自APIの用意

APIの作成と公開

実装方法はなんでも良いが、ここではNode.js + Fastify + ngrokでさくっとAPIサーバーを立ち上げる。

bash
mkdir multiply-api
cd multiply-api
npm init -y
npm i fastify --add

index.jsを作成する。

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サーバーを起動する。

bash
node index.js

ngrokで外部公開する。

bash
ngrok http 3000

https://7217-*-*-*-*.ngrok-free.appといった形式の外部公開URLが得られただろう。

もちろんVPSでもよいし、AWS Lambda関数でもよい。Difyのコンテナ(apiworker)からアクセスさえできればローカル環境でもよい。

OpenAPI-Swaggerによるスキーマを用意

この簡易APIをDifyに登録するのだが、OpenAPI-Swagger仕様によるスキーマが必要となる。

URLの変更

一箇所だけ、servers[0].urlは外部公開されたURL(ngrokであればhttps://7217-*-*-*-*.ngrok-free.app)を指定すること。

yaml
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仕様のスキーマを登録しよう。

掛け算を行うAPI

テストボタンを押すとテストができる。a2b3を入力し、テストボタンを押すと、{"result":6}という期待した結果が得られた。

パラメータと値を入力し、テストボタンを押す

最後に保存ボタンを押すと、カスタムツールの登録は完了である。

チャットフローでカスタムツールを使う

次はスタジオ機能に移動し、チャットフローでカスタムツールを試してみよう。

ここでは「掛け算チャット」を作る。「2かける3は?」などの自然言語を解釈してAPIにより掛け算を行うチャットボットだ。

INFO

もちろん簡単な掛け算はLLM単体で実行できるが、ここでは外部APIとの連携を実証するための作例である。

パラメータ抽出の追加

まずは開始ブロックにパラメーター抽出ブロックを接続する。

自然言語による入力から、掛け算APIに渡すべき値が何かを抽出する。

ツールからインポートボタンを押して作成したカスタムツールのmultiplyAPIを選択すると、スキーマに記述したパラメータabが自動で展開される。

パラメーターを抽出

カスタムツールの追加

続いてパラメーター抽出ブロックからカスタムツール - multiplyに接続する。

入力変数aは、Variable - パラメーター抽出/aを選択する。bについても同様にVariable - パラメーター/bを選択する。

これでユーザーの入力から掛け算の意図を汲み取り、APIに渡す処理を実現できる。

2つの数値の積を計算する

回答

一旦ここで回答ブロックをつなげて動作確認をする。ab、そしてカスタムツールの出力textを簡単に整形して表示するようにしてみた。

2つの数値を掛け合わせる

プレビュー機能で 「二かける三は?」 と尋ねてみると、

ノードが2つ接続されている
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にしても連携には問題がなかった。

yaml
      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と連携できる。

bash
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利用に向けて、カスタムツールは避けて通れないテーマである。