「Difyソースコードリーディング #4 - モデルやツールのYAMLファイルの扱いを読み解く」を開催しました #もくもくDify

ジェネラティブエージェンツの大嶋です。

もくもくDifyで「Difyソースコードリーディング #4 - モデルやツールのYAMLファイルの扱いを読み解く」というイベントを開催しました。

dify-mokumoku.connpass.com

アーカイブ動画はこちらです。

youtube.com

Difyのソースコードは以下です。

github.com

今回も 戸塚さん と一緒に話しながらコードを読んでいきました!

今回のポイント

Difyに組み込みのツールを追加する方法

今回まずは、Difyに組み込みのツールを追加する処理がどのように実装されているのかを探していきました。

Difyに組み込みのツールを追加する方法は、api/core/tools/README.mdapi/core/tools/docs ディレクトリのドキュメントに書かれていました。

現状は英語と中国語のドキュメントのみですが、戸塚さんが日本語版のプルリクエストを出してくれているそうです。

プルリクエスト:https://github.com/langgenius/dify/pull/8469

組み込みツールの追加の例

組み込みツールの追加の例として、Discordのツールを追加するプルリクエストも参考に見ていきました。

プルリクエスト:https://github.com/langgenius/dify/pull/7852

そのツール特有の処理を行うクラスを実装し、ツールの名前やパラメータをYAMLファイルに記述するだけで、組み込みのツールが追加されるようです。

YAMlファイルの構造の定義

ツールの名前やパラメータを記述するYAMLファイルの構造は、tool_entities.py というファイルに定義されていました。

たとえばToolParameterというクラスが以下のように定義されています。

class ToolParameter(BaseModel):
        :
    name: str = Field(..., description="The name of the parameter")
    label: I18nObject = Field(..., description="The label presented to the user")
    human_description: Optional[I18nObject] = Field(None, description="The description presented to the user")

ツールの読み込みの実装

ツールを追加する際、そのツール用のPythonファイルとYAMLファイルだけ記述すればいいということは、どこかでツールの実装を動的にimportしているはずです。

builtin_tool_provider.py を見ると、以下のようにツールのモジュール名からサブクラスをロードしている箇所がありました。

            assistant_tool_class = load_single_subclass_from_source(
                module_name=f"core.tools.provider.builtin.{provider}.tools.{tool_name}",
                script_path=path.join(
                    path.dirname(path.realpath(__file__)), "builtin", provider, "tools", f"{tool_name}.py"
                ),
                parent_type=BuiltinTool,
            )

load_single_subclass_from_sourceの実装は module_import_helper.py にあり、

以下のように動的にモジュールを読み込んでいることがわかりました。

        module = importlib.util.module_from_spec(spec)

importlib.util.module_from_specはPythonの標準ライブラリの関数で、モジュールの動的なimportなどに使えるようです。 この関数は知らなかったので勉強になりました。

参考:https://docs.python.org/ja/3/library/importlib.html#importlib.util.module_from_spec

組み込みのモデルについて

その後、組み込みのモデルについても見ていきました。

基本的に同じような構造になっていて、モデルを追加する際に記述するYAMLファイルの構造は model_entities.py で定義されており、組み込みモデルの動的なimportは model_provider.py で実装されているようでした。

モデルやツールを追加しやすいよう動的に読み込んでいるしくみは、なかなか面白かったです!

次回のご案内

次回は「ナレッジベース・RAGの実装を読み解く」というテーマです。 ご興味ある方はぜひ気軽にご参加ください!

dify-mokumoku.connpass.com

また、水曜日にもDifyの活用についてのもくもく会があります。 こちらもご興味ある方はぜひ気軽にご参加ください!

dify-mokumoku.connpass.com