4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

Dify の Agent node における token 制限の仕組み

Last updated at Posted at 2025-12-17

はじめに

Dify の Workflow におけるAgent nodeは、複数回の LLM 実行やツール呼び出しを自律的に行える強力な機能です。一方で、実際に運用し始めると「どこでどのように token 制限が効いているのか分かりにくい」という課題に直面します。

本記事では、Dify の Agent node における token 管理の仕組みについて、実装を追いながら整理します。
特に以下のような方を対象としています。

  • Agent node を使って長いコンテキストを扱っている
  • token 超過時の挙動を正しく理解したい
  • Dify の内部実装に興味がある

Agent node とは

公式ドキュメント では、Agent node は以下のように説明されています。

エージェントノードは、LLMにツールの自律的な制御権を与え、
どのツールをいつ使用するかを反復的に決定できるようにします。
すべてのステップを事前に計画する代わりに、
エージェントは問題を動的に推論し、
複雑なタスクを完了するために必要に応じてツールを呼び出します。

Agent node は、内部で LLM を複数回呼び出しながら推論とツール実行を繰り返す ことで、与えられた目的を達成するためのノードです。

Agent node 内部の処理フロー(token 観点)

実際には、実行前後で Graph の構築や状態更新なども行われますが、
本記事ではtoken 管理に関係する部分に絞って説明します。

token に関係する処理だけを抜き出すと、Agent node の流れは概ね以下のようになります。

※ Dify では Agent の実行戦略自体も Plugin として実装されており、Agent node は Plugin 経由で Model API を呼び出します。

Agent node における token 制限の全体像

Dify の Agent node では、主に以下 4 箇所 で token 制限が関係します。

  1. 会話履歴(history)の件数制限
  2. 会話履歴(history)の token 数制限
  3. LLM の出力 token 設定(option)
  4. LLM の最大 token 制限(context length)

特に重要なのは TokenBufferMemory と LLM 自体の制限 です。

以下で登場する valid_message_limit や valid_message_token_limit は、
説明用に簡略化した表現です(実際にその名前のメソッドが存在するわけではありません)。

1. 会話履歴(history)の件数制限

まず、取得する会話履歴の「件数」による制限があります。
UI 上では以下の設定に対応しています。

(※ UI 上では 0〜100 件まで設定可能)

内部実装では message_limit によって制御されており、最大 500 件で制限されています。

def get_history_prompt_messages(
        self, max_token_limit: int = 2000, message_limit: int | None = None
    ) -> Sequence[PromptMessage]:
        """
        Get history prompt messages.
        :param max_token_limit: max token limit
        :param message_limit: message limit
        """
        app_record = self.conversation.app

        stmt = (
            select(Message)
            .where(Message.conversation_id == self.conversation.id)
            .order_by(Message.created_at.desc())
        )

        if message_limit and message_limit > 0:
            message_limit = min(message_limit, 500)
        else:
            message_limit = 500

2. 会話履歴(history)の token 数制限

次に、取得した履歴を token に分解し、token 数がしきい値を超えていないかを確認します。

curr_message_tokens = self.model_instance.get_llm_num_tokens(prompt_messages)

if curr_message_tokens > max_token_limit:
    while curr_message_tokens > max_token_limit and len(prompt_messages) > 1:
        prompt_messages.pop(0)
        curr_message_tokens = self.model_instance.get_llm_num_tokens(prompt_messages)

  • max_token_limit はデフォルトで 2000 token
  • 超過した場合、古いメッセージから順に削除 されます
  • この挙動は環境変数によって有効 / 無効を切り替え可能です

初期コンテキストが非常に大きいユースケースでは、この制限が実用上問題になるケースもあります。

3. LLM の出力 token 設定(option)

LLM 側の option として、出力 token 数の上限 を指定できます。
この値を小さくすると、生成される文章の長さが制限されます。

※ GPT-5 系以降では設定方法が変更されているため、モデルによっては本 option が表示されない場合があります。

4. LLM の最大 token 制限(context length)

最後に、LLM 自体が持つ 最大 context length の制限です。
非常に長い入力を一度に与えると、この制限を超えてエラーになる可能性があります。
Agent node では複数回 LLM を呼び出すため、履歴・ツール結果・システムプロンプトの合計がこの上限を超えないよう注意が必要です。

おわりに

Agent node の token 管理は、表面的な設定項目だけでは挙動を理解しづらい部分がありますが、実装を追うことで 「どこで・何が・どの順番で制限されるのか」 が明確になります。

現状の Dify では、コンテキスト超過時は履歴の切り捨てやエラーで対応されていますが、今後は Claude Code のような コンテキスト圧縮(compaction)を前提とした設計 が主流になっていく可能性があります。
GPT-5.2 でも compact 機能が導入されており、Dify 側での対応にも期待したいところです。

本記事が、Agent node を使った設計や token 周りのトラブルシューティングの参考になれば幸いです。

※ 本記事の内容は執筆時点の Dify の実装に基づいており、将来的に変更される可能性があります。

4
0
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
4
0

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?