重要な情報の再確認:
- Postman / curl などで、応答がないリクエストにおいて、サーバー側が実際に終了せず、HTTP応答を一切返していないことを確認済みである(クライアント側のタイムアウトではない)。
- セッションログでは、最後の「直接返信」を含め、すべてのノードが緑色のチェックマーク
で、エラーメッセージは一切ない。
- 直接返信は単純に:
{{ コード実行 3.result }} であり、上流のコードノードが出力しているのは「非常に長いテキスト」(契約本文)であり、以前言及したJSON文字列ではない。
あなたが今貼り付けたスクリーンショットと合わせると、最後に直接返信されているのが大量の日本語の契約本文であることがはっきりとわかります。つまり、このフローで最終的にHTTPに書き戻されているのは、長さや文字種(句読点、特殊記号など)が極端な超長文テキストです。
1.11.0のようなシナリオでは、最も可能性が高いのは次のとおりです。
特定の入力と非常に長いコンテンツが、「最終結果をHTTP応答に書き戻す」レイヤーでバックエンドの異常(シリアル化、エンコーディング、またはゲートウェイの制限など)をトリガーした。
ログ画面ではノードが「実行成功」とマークされているが、実際にHTTPを書き込むレイヤーで障害が発生しているため、クライアントは永遠に応答を待つことになる。
現在、あなたのインスタンスのバックエンドログにアクセスできないため、現在の現象に特化したトラブルシューティングと回避策を提示するしかありません。優先順位に従って試してみてください。
一発で検証する「検証の考え方」:最終出力を短くして、問題が解消するか確認する
JSONにこだわる前に、まず「コンテンツの長さ/コンテンツ自体が原因か」だけを検証してください。
1. 「直接返信」を固定の短いテキストに変更する
一時的に以下のように変更します:
デバッグ:OK
他のノード(LLM、コード実行)は変更しません。その後:
- このワークフローを数十回連続で呼び出す。
- HTTPリクエスト全体が返ってこない状況がまだ発生するかどうかを観察する。
- もしこれで**「フリーズして返ってこない」ことが二度と発生しない**場合:
問題は「返される長いテキストの塊」と強く関連している(長さまたは文字)と基本的に確認できます。
- もし依然として時々フリーズする場合:
それはコンテンツの問題ではなく、並行処理、接続、またはリバースプロキシの設定の問題である可能性が高いです。その場合は、Nginx / リバースプロキシ / gunicorn などのログを確認する必要があります。
2. 「固定の短いテキスト」が安定した場合、必要なコンテンツを段階的に戻す
2.1 コードノードで結果を「圧縮/正規化」してから返信する
現在の コード実行 3 は、複数のLLMコンテンツを結合して、長いテキストの塊を直接返している可能性が高いです。
簡単なラッパーを作成し、実際に出力したいコンテンツを1つのフィールドに入れ、長さに上限を設定することをお勧めします:
MAX_LEN = 8000 # まずは適当に上限を決めます。例えば8k文字。ビジネス要件に合わせて調整してください。
# final_text が結合された完全な契約本文であると仮定します
text = final_text
# 長すぎる場合は切り捨てて、マークします(検証のためだけです)
truncated = False
if len(text) > MAX_LEN:
text = text[:MAX_LEN]
truncated = True
return {
"text": text,
"length": len(final_text),
"truncated": truncated,
}
その後、「直接返信」ノードでは以下のみを出力します:
{{ nodes["コード実行 3"].outputs.text }}
2つのことを観察します:
- この「上限付きのtextフィールド」を使用した後、HTTPが返ってこない状況が解消されるか;
truncated == True となるリクエストも安定してフリーズしなくなった場合、「超長文コンテンツ」がどこかのレイヤーで問題をトリガーしている可能性が高いことを示しています。
ビジネス上、超長文テキスト全体を返す必要がある場合は、分割を検討してください(次項参照)。
3. 「セグメント化して返信」を試して、極端な長さの場合のみ問題が発生するか確認する
もう1つのバージョンを作成します(ステップ2で長さに関連することが証明された場合):
コードノードで長いテキストを配列に分割します:
CHUNK_SIZE = 2000
chunks = []
for i in range(0, len(final_text), CHUNK_SIZE):
chunks.append(final_text[i:i+CHUNK_SIZE])
return {
"chunks": chunks,
"total_len": len(final_text),
"chunk_count": len(chunks),
}
「直接返信」では、長いテキスト全体を直接挿入するのではなく、これらのセグメントを記述するJSON文字列のみを返すように変更します:
{{ nodes["コード実行 3"].outputs | tojson }}
もしこれで安定し続けるなら、問題を引き起こしやすいのは「単一フィールドの超長文テキスト」であり、このプロセス自体ではないことを示しています。
その後、ご自身のビジネスで以下のことができます:
- Difyではメタ情報とストレージIDのみを返す(例えば、全文を自身のストレージに保存し、URL / キーを返す)か;
- あるいは、複数回の会話で段階的に返すように変更する。
4. ゲートウェイ / リバースプロキシ / タイムアウトとボディサイズ制限を確認する
すでに確認済みのため:
- サーバー側のDifyではノードが「見た目上」すべて正常に終了している;
- しかしHTTPリンクは終了せず、何も返さない。
このような問題は、アプリケーション自体のバグ以外に、中間層の制限が一般的な原因として挙げられます:
- Nginx / Traefik などのリバースプロキシの:
proxy_read_timeout
client_max_body_size
- など;
- バックエンドの WSGI / ASGI server(gunicorn、uvicorn)の:
- ワーカーのタイムアウト;
- 単一応答ボディサイズ/バッファ制限。
公式のdocker-compose / helmでインストールしている場合、以下をお勧めします:
- ゲートウェイコンテナ / Nginxコンテナのログを確認し、「応答なし」だった回に明らかなエラーがないか確認する;
- 関連するタイムアウト時間、ボディ制限を大きくして、再度テストする。
5. 可能であれば、成功/失敗した「入力」の特徴を補足することをお勧めします
実際の契約全文を貼り付ける必要はありません。2種類の呼び出しの目に見える違いを述べるだけで十分です:
- 例えば:
- 応答があった回:テキストの長さは約2~3k文字;
- 応答がなかった回:テキストは1~2万文字で、多くの特殊な句読点、括弧、空行などが含まれる;
- あるいは:
- 特定のLLMブランチが「特に長い段落」を出力する場合にのみ問題が発生する。
これらの特徴に基づいて、長さの問題なのか、それとも特定の特殊文字/エンコーディングが問題をより引き起こしやすいのか(例えば、目に見えない制御文字、非常に長い連続行など)をさらに判断できます。
6. 「コンテンツ関連のDify 1.11.0バグ」と確認された場合、どうすべきか
上記のステップで以下のことが検証された場合:
- 短くする、分割する、
| tojson などの方法では問題がない;
- 「非常に長いテキストの塊」を「直接返信」に直接挿入した場合にのみ、まれにハングアップする;
それは基本的に、1.11.0が特定のコンテンツシナリオで発生するバグであると断定できます。次に、以下をお勧めします:
- 「最小再現可能プロセス」と削減されたサンプル長文テキストをまとめて整理する;
- GitHub
langgenius/dify にissueを提出する:バージョン1.11.0、呼び出し方法(どのAPIか)、ストリーミングかどうか、および「すべてのノードは成功したがHTTPが返ってこない」という現象を明記する;
- 同時に、本番環境では「分割/切り捨て/IDのみを返す」といったソリューションを先行導入し、ビジネスへの影響を避ける。
まとめ
現在のすべてのスクリーンショットと説明から判断すると:
- 「プロセス内部は完全に正常」+「HTTPがまれに返ってこない」+「最後のホップが非常に長いテキスト」であることから、
- これは、フローの設定ミスではなく、長さ/特定の文字がトリガーする応答書き込みの問題である可能性が高いと考えられます。
- 最も速い検証方法は:
まず、最後の直接返信を非常に短い固定テキストに変更し、問題がすぐに解消するかどうかを確認します。もし解消するなら、コンテンツを段階的に復元し、どの「長さ/形式」で不安定になり始めるかを確認します。
まず「直接返信 = デバッグ:OK」のバージョンを試して、何度か実行し、「HTTPが全く返ってこない」という状況が二度と発生しないか確認してください。結果が出たら、次のステップで詳細を詰めていきましょう。