「Difyソースコードリーディング #11 - Dify v0.11.0のアップデートのコードを読む」を開催しました #もくもくDify

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

もくもくDifyで「Difyソースコードリーディング #11 - Dify v0.11.0のアップデートのコードを読む」という勉強会を開催しました。

dify-mokumoku.connpass.com

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

youtube.com

Difyのソースコードはこちらです。

github.com

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

今回のポイント

今回はDify v0.11.0以降のリリースノートを見て、気になった機能のソースコードを見ていきました。

Difyのリリースノートはこちらです。

github.com

IterationノードのParallelモード

Dify v0.11.0での最も大きな新機能は、Iterationノードに「Parallelモード」が追加されたことです。

Iterationノードはプログラミングでいうforループのようなノードで、それを並列実行する設定ができるようになりました。

ソースコードとしては、api/core/workflow/nodes/iteration/entities.pyを参照すると、Iterationノードの設定値などを持つIterationNodeDataクラスに、is_parallelとparallel_numsというインスタンス変数が追加されていることを確認できます。

class IterationNodeData(BaseIterationNodeData):
        :
    is_parallel: bool = False  # open the parallel mode or not
    parallel_nums: int = 10  # the numbers of parallel

実際の並列化の処理は、api/core/workflow/nodes/iteration/iteration_node.pyに実装されています。

以下のように、ワーカースレッドを使って処理を実行し、Queueを介してワーカースレッドからイベントを受け取るという実装でした。

            if self.node_data.is_parallel:
                futures: list[Future] = []
                q = Queue()
                thread_pool = GraphEngineThreadPool(max_workers=self.node_data.parallel_nums, max_submit_count=100)
                for index, item in enumerate(iterator_list_value):
                    future: Future = thread_pool.submit(
                        self._run_single_iter_parallel,
                            :
                while True:
                    try:
                        event = q.get(timeout=1)
                            :
                # wait all threads
                wait(futures)

コードの引用元:https://github.com/langgenius/dify/blob/317ae9233ec25896dbf2c2d05a8e085953a4b222/api/core/workflow/nodes/iteration/iteration_node.py#L162

OpenRouter

Dify v0.11.1のリリースには、OpenRouter経由のAnthropic Claude-3-5-Haikuのサポートが含まれていました。

OpenRouterは最近ときどき耳にして気になっていたので、OpenRouterについて少し調べてみました。

openrouter.ai

OpenRouterは、OpenAIのChat Completions APIの形式でさまざまなLLMを使うことができるサービスでした。

公式ドキュメントのQuick Startを見ると、OpenAIのクライアントのbase_urlをOpenRouterのURLに変更して使うのが分かります。

client = OpenAI(
  base_url="https://openrouter.ai/api/v1",
  api_key="$OPENROUTER_API_KEY",
)

さまざまなLLMを統一的なインターフェースで扱うことができるパッケージとしてはLangChainやLiteLLMがありますが、OpenRouterはPythonなどのパッケージではなくクラウドサービスという違いになります。

github.com

Difyではapi/core/model_runtime/model_providers/openrouter/llm/llm.pyにOpenRouterを使うコードが書かれていました。

Vanna.AI

Dify v0.11.1には、Vanna.AIのURLが設定できるようになったというアップデートもありました。

Vanna.AIについても知らなかったので、少しだけ調べてみました。

少し調べた自分の理解としては、Text-to-SQLOSSWebサービスのようでした。

github.com

vanna.ai

OpenRouterやVanna.AIのように、Difyのアップデートを追ったりすることでLLMのエコシステムを知ることができるのはよかったです。

その他

その他、ちょっとした気になった点もいくつかソースコードを読んでみました。

  • ナレッジAPIのURL変更について#10102
    • ナレッジAPIのURLが一部変更(追加)されたようでした
  • PodcastAudioGeneratorというツールは何なのか podcast_audio_generator.py
    • 単にOpenAIのTTSでした
  • ビルトインツールの読み込みを別スレッドにすることによる高速化について #9146
    • ちょっとした変更で起動時間が大幅に短縮されたようでした

次回のご案内

以上、今回はDify v0.11.0以降のアップデートについてソースコードを見ていきました。

次回の開催日は未定ですが、またv0.12がリリースされたといったタイミングで新機能のソースコードリーディングなどをしていくつもりです!

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

dify-mokumoku.connpass.com