「Difyで生成AIにデータ分析をさせたいけれど、グラフ描画ライブラリが使えない…」
「標準のコードブロックだとPythonの標準モジュールしか動かない」
Difyのセルフホスト版を使っていると、こうした課題に直面することがあります。
そこで今回は、Difyの隣に「コード実行専用のサーバー(FastAPI)」を構築し、生成AIが書いた高度なPythonコードを実行させる方法を解説します。
なぜ外部実行環境が必要なのか?
Difyには標準で「コードブロック」という機能がありますが、セキュリティや環境の制約上、以下のような制限があります。
- 標準モジュールしか使えない:
matplotlibやpandasなどの外部ライブラリがインポートできません。 - 動作が不安定: Difyのコンテナ内に無理やりライブラリを入れても、アップデート等で環境が壊れるリスクがあります。
そこで、Difyとは別に「コードを受け取って実行し、結果(画像など)を返すAPIサーバー」を立てることで、安全かつ柔軟な実行環境を実現します。
実行環境の構築(FastAPI + Docker)
今回は、Dockerを使って簡単にPython実行環境(APIサーバー)を立ち上げます。
1. リポジトリの準備
まずは以下のコマンドで、構築用のコード一式をダウンロードします。
git clone https://github.com/tom160313/code_executor.git
cd code_executor
2. コンテナの起動
Docker Composeを使ってサーバーを起動します。
docker compose up -d
起動後、ブラウザで http://localhost:8501/docs (または設定したポート)にアクセスし、FastAPIのドキュメント画面が表示されれば成功です。

- コードの中身
コード自体はいたってシンプルで、受け取ったコードを実行→画像ファイルを保存→そのファイルをレスポンスとして返却といった感じです。
from fastapi import FastAPI, Request, UploadFile, File
from pydantic import BaseModel
import uuid
import os
import traceback
import matplotlib.pyplot as plt
from fastapi.staticfiles import StaticFiles
from fastapi.responses import FileResponse
from starlette.middleware.cors import CORSMiddleware
import codecs
app = FastAPI()
# CORS対応
app.add_middleware(
CORSMiddleware,
allow_origins=["*"],
allow_credentials=True,
allow_methods=["*"],
allow_headers=["*"]
)
# static ディレクトリ作成
STATIC_DIR = "static"
os.makedirs(STATIC_DIR, exist_ok=True)
app.mount("/static", StaticFiles(directory=STATIC_DIR), name="static")
class CodeInput(BaseModel):
code: str
@app.post("/execute")
async def execute_code(payload: CodeInput):
code = codecs.decode(payload.code, "unicode_escape")
local_vars = {}
try:
exec(code, local_vars, local_vars)
for val in local_vars.values():
if hasattr(val, "savefig"):
filename = f"{uuid.uuid4().hex}.png"
filepath = os.path.join(STATIC_DIR, filename)
val.savefig(filepath)
plt.close("all")
# ファイルをそのままレスポンスとして返す(ダウンロード対応)
return FileResponse(
path=filepath,
filename="graph.png",
media_type="image/png",
headers={
"Access-Control-Allow-Origin": "*",
"Access-Control-Expose-Headers": "Content-Disposition"
}
)
return {
"status_code": 200,
"body": "コードは実行されましたが、画像は生成されませんでした。",
"files": []
}
except Exception as e:
return {
"status_code": 500,
"body": f"エラーが発生しました: {str(e)}",
"traceback": traceback.format_exc(),
"files": []
}
Difyワークフローの設定
立ち上げた実行環境を、Difyのワークフローから呼び出せるように設定します。
ワークフローの全体像
処理の流れは以下のようになります。
- LLMノード: ユーザーの要望に基づき、Pythonコード(グラフ描画など)を生成させる。
- コード抽出ノード: 生成されたテキストから、Pythonコード部分だけを抜き出す。
- HTTPリクエストノード: 抜き出したコードを、先ほど立てたFastAPIサーバーに送信する。
- 回答ノード: サーバーから返ってきた結果(画像ファイルや実行ログ)を表示する。
HTTPリクエストノードの設定例
Difyの「HTTPリクエスト」ノードを以下のように設定します。
- URL:
http://{実行サーバーのIP}:8501/execute※Docker環境の場合、host.docker.internalやローカルIPを指定する必要があります。 - メソッド:
POST - ヘッダー:
Content-Type: application/json - ボディ: JSON形式で以下のように記述します。
{ "code": "{{#直前のノードで抽出したコード#}}" }
まとめ:Difyの可能性を広げよう
この仕組みを使えば、Dify上で「売上データをグラフ化して」「複雑な計算処理を行って」といった高度なタスクを自動化できるようになります。
外部サーバーとの連携は少しハードルが高く感じるかもしれませんが、一度構築してしまえば、どんなライブラリでも自由に使える最強のAIエージェント基盤となります。
ぜひチャレンジしてみてください。


コメント