ジェネラティブエージェンツの大嶋です。
もくもくDifyで「Difyソースコードリーディング #8 - Difyのコード実行環境「dify-sandbox」」という勉強会を開催しました。
アーカイブ動画はこちらです。
dify-sandboxのソースコードは以下です。
今回も 戸塚さん と一緒に話しながらコードを読んでいきました!
今回のポイント
今回はdify-sandboxを理解するべく、コードを読んでいきました。
dify-sandboxの概要
dify-sandboxの概要については、READMEに添付されている画像によく書かれていました。
画像引用元:https://github.com/langgenius/dify-sandbox
概要としては以下のようになります。
- ビルド時:python.soというファイルが作成され、DifySeccompというchrootによるルートディレクトリの変更やSeccompによるシステムコールの制限のための関数が提供される
- サーバー起動時:設定ファイルや環境変数が読み込まれ、pip installによりdependencies/python-requirements.txtに記載のパッケージがインストールされる
- API呼び出し時:APIキーやリクエストの最大値などのチェックを経て、リクエストのコードがファイルに保存され、DifySeccomp関数を使用して実行される
Pythonコードの実行
HTTPリクエストで送られてきたPythonのコードは、internal/core/runner/python/python.go で以下のようにコマンドとして実行する準備がされていました。
cmd := exec.Command( configuration.PythonPath, untrusted_code_path, LIB_PATH, key, )
configuration.PythonPathは、conf/config.yaml で「/usr/local/bin/python3」が設定されています。
untrusted_code_pathというのは prescript.py の一部を置換した内容のファイルです。
prescript.py
prescript.py は、最終的に実行されるPythonスクリプトです。
以下の箇所でpython.soを読み込んでDifySeccompを実行しています。
lib = ctypes.CDLL("./python.so")
:
lib.DifySeccomp({{uid}}, {{gid}}, {{enable_network}})
その後、以下のようにPythonコードが実行されます。
code = b64decode("{{code}}") : code = decrypt(code, key) exec(code)
{{code}}
の箇所は、暗号化したうえでBASE64エンコードされたPythonコードが置換されます。
おそらくGo言語の標準ライブラリではforkとexecの間でDifySeccompを実行するのが大変なので、Go言語で実行した子プロセスのPythonスクリプト内でDifySeccompを実行してexecしているのではないかと思います。(想像なので違ったらすみません)
Pythonパッケージのインストール
よくdify-sandboxに追加のPythonパッケージをインストールしたいという要望があると思いますが、サーバー起動時に dependencies/python-requirements.txt の内容がpip installされるため、ここに必要なパッケージを記述したファイルを配置すればよさそうです。
おそらく、そのためにコンテナイメージをビルドしなおす必要もありません。
また、internal/controller/router.go を参照すると依存関係を更新・リフレッシュするAPIも用意されているため、dependencies/python-requirements.txtを編集してこのどちらかのAPIを実行すれば、サーバー実行中に動的にPythonパッケージを追加したりすることもできるかもしれません。(updateとrefreshのAPIの違いまでは読み解いていません)
dependencyRouter.POST("update", UpdateDependencies) dependencyRouter.GET("refresh", RefreshDependencies)
次回のご案内
以上、dify-sandboxを読み解いてみました。 考えてみれば当然ですが、機能はかなり少なく、1時間ほどで気になるコードのほとんどに目を通すことができました。
次回は「Difyのワーカーは何をしているのか」を読み解いていきます! ご興味ある方はぜひ気軽にご参加ください!
また、水曜日にもDifyの活用についてのもくもく会があります。 こちらもご興味ある方はぜひ気軽にご参加ください!