Workflowの実行成功と、利用者へ必要な値が返ったことは、別々に確認します。 上流ノードの出力、Outputノードの参照、最終結果のキー、呼び出した公開版の順にたどりましょう。プロンプトを長くする前に、同じ実行のどこまで値が届いているかを見ます。
対象は、DifyのWorkflowで内部の処理結果は見えるのに、画面や呼び出し元へ期待した値が返らない人です。ノードの入力・出力と変数選択の基本を前提にします。本稿はWorkflowのOutput(出力)ノードを扱います。ChatflowのAnswer(回答)ノードは別の仕組みです。
公式資料の確認日は2026年11月6日です。現行のOutput資料は2026年9月17日、Version Control資料は10月28日の更新表示を確認しました。以下のデータとPythonは、出力の対応を考えるための架空教材です。Dify Cloud・LLM・外部APIで実行したログではありません。 画面名や利用できる操作は、自分の版とアプリ種別で照合してください。
内部の処理結果と、Workflowから返す出力を分ける
まずWorkflowかChatflowかを確認する
ノードを探す前に、作ったアプリの種類を確認します。現行のOutput公式資料では、OutputはWorkflow向けです。Chatflowで利用者へ返す内容はAnswerの公式資料を参照します。
Workflowで、上流のLLMが文章を作っただけでは、その全てが呼び出し元の欲しい名前で返るとは限りません。どの値を外へ出すかをOutputで指定し、その名前を利用側の処理とそろえます。線でノードをつないだことと、出力項目を定義したことを混同しないようにします。
一方、Chatflowの回答文を編集する課題で、WorkflowのOutput設定を探しても、同じ操作にはなりません。「画面に回答がない」という症状だけで記事を選ばず、アプリの種類と、利用者がどの画面や呼び出し方法で結果を見るのかを確認してください。
本稿の架空課題は、研修用の短いメモを整理し、確認が必要な文章と件数を返すWorkflowです。実在の議事録や個人情報は使いません。AIが処理した内容をそのまま自動送信する仕組みではなく、返ってきた項目を検収するところまでを考えます。
| 確認したいもの | 見る対象 | 本稿の扱い |
|---|---|---|
| 上流でできた文章 | 対象ノードの実行結果 | Outputが参照する元の値 |
| Workflowから返す項目 | Outputと最終結果 | 中心となる確認対象 |
| Chatflowの回答文 | Answerの設定と結果 | アプリ種別を分ける |
| 呼び出し元の画面表示 | 受け取ったキーと画面側の参照 | 最終値を受け取った後も確認 |
上流の変数名と、最終出力のキーは同じでなくてよい
例えば上流のLLMノードがtextという変数へ文章を返し、Output側ではそれをdraft_textという名前で公開できます。上流のノード名、上流のフィールド名、外へ出す名前の三つを書き分けると、どこを直すかが分かります。
「ノードの表示名をdraft_textにしたから、その名前の値が返る」と考えないようにします。現行資料では、Outputで割り当てた変数名がAPI応答のキーになります。参照する値を選ぶ設定も、その名前とは別に必要です。
教材の対応表なら「下書き作成ノードのtextを、最終draft_textへ渡す」と書けます。この一文があれば、上流を別のノードへ置き換えた後に、参照元も更新したかを確認できます。見出しや表示ラベルを変えただけで終わらないようにしましょう。
利用側で以前からanswerを探しているのに、公開したWorkflowがdraft_textを返すようになった場合は、値が存在しても画面に表示されない可能性があります。結果が空なのか、読む名前が違うのかを、受け取ったデータで分けて確認します。
出力名の変更は、呼び出す側にとって仕様の変更です。読みやすい名前へ変える場合も、その値を使う表・アプリ・後続処理を確認し、同じ版の名前にそろえます。値を作る側だけを直しても、受け取り側の参照は自動では説明できません。
対応表の参照元には、似た表示名のノードを区別できる情報も残します。例えば「下書き」と「下書き修正」が両方あるなら、最初の文章か、修正後の文章かで目的が違います。型が同じ文字列でも、利用者に見せたい内容が違うためです。
ノードを複製して試した後も、Outputが元のノードを参照したままになっていないかを見ます。新しいノードのテスト結果が良くなっても、外へ返す参照先が変わらなければ、利用側では以前の内容を見る場合があります。編集した場所と、実際に出力している場所を、一つの実行でたどってください。
現行Outputは、旧Endの説明をそのまま当てはめない
現行公式は、Outputが以前Endという名前であり、現在は省略可能だと説明しています。OutputがないWorkflowや経路は実行できても、呼び出し元へ返すデータがない場合があります。「成功したから、欲しい出力もあるはず」と決めない理由の一つです。
また、Outputを通ったことと、他の並列経路も全て止まったことは同じではありません。古い記事の「終了」という名前だけを根拠に、実行全体の停止を想定しないようにします。自分の環境で使える接続や画面の制約は、その版の動作で確認してください。
ここで確認するのは、現行資料の意味と、自分が実行した経路です。過去のEndの画面写真を見て、設定項目が少し違うから不具合だと決める必要はありません。版・アプリ種別・ノード名を記録し、同じ条件の説明を探します。
最終結果の{}、文章項目が""、項目そのものがない状態も区別します。{}は空のオブジェクト、空文字は名前のある項目へ空の文章が入った状態です。原因を調べるときは、この形の違いを消さずに残してください。
特に、後から「見えないので全部空」とまとめると、上流が文章を作らなかったのか、Outputで指定しなかったのか、利用側が違う名前を読んだのかが分かりません。症状を短い言葉にする前に、値の形を一段だけ具体化しておくと役立ちます。
| 観察した形 | 分かること | まだ分からないこと |
|---|---|---|
| outputsが空オブジェクト | その部分に項目がない | どの段階で項目がなくなったか |
| draft_textが空文字 | 名前のある項目は存在する | 参照元も空だったか |
| draft_textがnull | 空文字とは別の値 | 変換や参照のどこで生じたか |
| review_requiredがfalse | booleanの値がある | その判断内容が妥当か |
| 画面だけ何も見えない | 表示としては空 | 受け取った最終データが空か |
これは観察用の分類表です。各状態をDifyが特定の設定で返すと再現確認した表ではありません。自分が見た値を分類して、次に見る段階を決めるために使います。nullを見たら、この表だけで特定のノードの不具合だと決めないようにします。
複数のOutputを使うなら、名前の重複を先に点検する
一つのWorkflowに複数のOutputを配置する構成では、実行された出力が最終結果へまとめられます。現行公式は、同じ名前があると後に追加された値が先の値を上書きすると説明しています。必要な二つの結果を、同じresultへ割り当てないようにします。
例えば「研修メモの下書き」と「確認事項の説明」を別の経路で作ったのに、両方の出力名をresultにすると、二つの文章を別々の項目として受け取る設計にはなりません。順番の違いでどちらが残るかを当てにせず、draft_textとreview_noteのように役割を分けます。
並列経路の完了順を、キャンバスの左右や見た目から推測しないでください。本稿では実際の並列実行を検証していません。独立した名前で返すと、受け取った側が名前を使って両方の存在を確認できる、という設計の練習です。
一つの出力値へまとめたい場合は、その値の内容を決める別の処理が必要です。二つの文章を結合するのか、片方だけを採用するのか、オブジェクトで分けるのかを明示します。名前を重複させることを、結合の代わりにはしません。
なお、Workflowをツールとして公開する場合には、公式に組み込み出力用の予約名への注意があります。通常のWorkflowの全ての項目で同じ制約だと広げず、ツール化する段階でtext・files・jsonなどの扱いを資料へ照合してください。
四つの項目の名前・参照元・型・意味を決める
教材では、受付ID、下書き、確認要否、件数を返すと決めます。利用者が読む文章だけでなく、どの入力に対する結果かも含めます。これはDifyが自動で追加する項目ではなく、この架空Workflowで決めた出力の仕様です。
| 外へ返す名前 | 想定する参照元 | 型 | 意味 |
|---|---|---|---|
| request_id | 入力の受付ID | string | DEMO-03の入力に対する結果 |
| draft_text | 下書き作成ノードのtext | string | 人が確認する下書き |
| review_required | 確認判定用の値 | boolean | 確認が必要かを表す値 |
| item_count | 件数の計算結果 | number | 教材では整数の2 |
# 対応表をPythonで表した架空教材。Difyへの登録・API実行はしません。
bindings = [
("request_id", "input.request_id", "DEMO-03"),
("draft_text", "draft_node.text", "研修メモを2件に整理しました。"),
("review_required", "check_node.review_required", True),
("item_count", "count_node.item_count", 2),
]
assert len(bindings) == 4
assert len({name for name, source, value in bindings}) == 4
input.request_idなどは、対応を説明するための教材内の表記です。その文字列をDifyの変数欄へ直接入力する指示ではありません。実際の画面では、参照したい上流ノードの出力を、利用版の変数選択機能で指定します。
同じ名前でも参照元を間違えることがあります。別の文章ノードのtextを選べば、型としては文字列なので、型だけでは取り違えを見つけられません。名前・参照元・型・値の意味を一緒に確認するために、この表を用意しています。
項目を増やすときも、名前だけ追加して終わらせません。例えばレビュー用の説明文をreview_noteとして加えるなら、どのノードの何を使うか、説明文がない場合に空文字を許すか、その項目を利用側が必要とするかを決めます。最初の4項目を確認できてから、一つずつ増やすと差を追いやすくなります。
逆に、入力の受付IDを外へ返す必要がない設計もあります。その場合も、検証中に結果と入力を照合する手段は用意します。本稿では架空IDを返す方法を選びましたが、実在の個人識別情報を出力項目へ増やすことを勧める例ではありません。
架空の出力を検収し、空欄・重複・実行版を確認する
重複する名前を、結果の辞書にする前に見つける
結果が一つのオブジェクトになった後では、上書き前の値が残っていない場合があります。そこで、設定の対応表の段階で名前を数えます。以下の関数は、本稿のPython教材の検査用です。Dify内部の処理を再現した実装ではありません。
def make_example_outputs(rows):
seen = set()
result = {}
for name, source, value in rows:
if name in seen:
raise ValueError("duplicate output name: " + name)
seen.add(name)
result[name] = value
return result
outputs = make_example_outputs(bindings)
assert set(outputs) == {"request_id", "draft_text", "review_required", "item_count"}
assert outputs["item_count"] == 2
try:
make_example_outputs(bindings + [("draft_text", "other_node.text", "別の下書き")])
except ValueError as error:
assert "duplicate output name" in str(error)
else:
raise AssertionError("教材の重複検査が通ってしまいました")
この検査を通したから、実際のDifyの参照が正しいと証明できるわけではありません。あくまで、対応表に同じ出力名が2回書かれた状態を見つける練習です。実際の画面の全Outputと見比べ、名前の一覧が一致するかを確かめます。
項目の順番だけを変えた場合も、この教材の一意な名前と値の対応は変わりません。最終結果を読む側が、オブジェクトの何番目という位置に頼らず、draft_textなどの名前で読む設計になっているかも確認しましょう。
名前を分けた後は、両方を使う側へ変更を伝えます。上書きの問題だけを直しても、古いresultを読んでいる側が残っていれば、結果が消えたように見えます。出力の変更と、受け取り側の変更を一組にします。
教材の対応表を逆順にしても、名前と値の組が同じなら、同じ項目を取り出せることを確認できます。表の並び順と、項目名で読む操作を区別するための小さな練習です。
reordered_outputs = make_example_outputs(list(reversed(bindings)))
assert reordered_outputs == outputs
assert reordered_outputs["request_id"] == "DEMO-03"
assert reordered_outputs["draft_text"] == "研修メモを2件に整理しました。"
これは、実際のWorkflowの実行順が自由に変えられるという意味ではありません。処理には入力の依存関係があります。本稿のPythonは、すでに対応する値が用意された教材の表を読み直しているだけです。設定表の順序と、ノードの実行依存を混ぜないようにします。
空文字・false・型の違いを、六つの保留例で分ける
「空ではないか」を値の真偽だけで調べると、正しいFalseまで空欄として扱ってしまう場合があります。今回のreview_requiredはbooleanなので、Falseも仕様上の値です。項目があるか、型が合うか、文章が入っているかを順に確認します。
def inspect_outputs(value):
if type(value) is not dict:
return ["outputs_type"]
expected = {
"request_id": str, "draft_text": str,
"review_required": bool, "item_count": int,
}
problems = []
for name, kind in expected.items():
if name not in value:
problems.append("missing:" + name)
elif type(value[name]) is not kind:
problems.append("type:" + name)
if problems:
return problems
if value["request_id"] != "DEMO-03":
problems.append("request_id_mismatch")
if not value["draft_text"].strip():
problems.append("empty_draft")
if value["item_count"] < 0:
problems.append("negative_count")
return problems
assert inspect_outputs(outputs) == []
assert inspect_outputs({**outputs, "review_required": False}) == []
cases = [
({}, "missing:request_id"),
({**outputs, "draft_text": " "}, "empty_draft"),
({**outputs, "review_required": "false"}, "type:review_required"),
({**outputs, "item_count": "2"}, "type:item_count"),
({**outputs, "request_id": "DEMO-02"}, "request_id_mismatch"),
([], "outputs_type"),
]
for value, expected_problem in cases:
assert expected_problem in inspect_outputs(value)
| 教材の結果 | 見つけたい差 | 次に見る場所 |
|---|---|---|
| 空のオブジェクト | 必要な4項目がない | 実行経路とOutput設定 |
| draft_textが空白 | 項目はあるが文章がない | 同じ実行の参照元の値 |
| review_requiredが文字列false | booleanではない | 変換前後の型 |
| item_countが文字列2 | 数値ではない | 件数を返す処理と参照 |
| 受付IDがDEMO-02 | 別の入力の結果 | 実行ID・入力・公開版 |
| 結果が配列 | 想定したオブジェクトではない | どの段階の値を読んだか |
この関数が受け付ける整数は、教材の件数のための約束です。Difyのnumberが常にPythonのintとして返る、という意味ではありません。実際に利用側へ届くJSONの型と、その側で必要な型へ合わせて検査を設計します。
検査を通った文章でも、内容が正確とは限りません。ここで確認できるのは、決めた項目・型・受付ID・空白などの形です。下書きの根拠や、2件という件数が元の入力に対応するかは、別に内容を見て照合してください。
例えばitem_countが2で、下書きの文章にも「2件」と書いてあっても、元のメモが3項目なら内容の照合は終わっていません。二つの出力が一致することと、入力の情報を正しく整理できたことは別です。教材では架空の2項目という期待を先に置き、形を確認した後で、元の項目との対応を人が見ます。
また、review_requiredがFalseなら、その値が空ではないことは分かりますが、人の確認が本当に不要かまでは、この型検査では分かりません。自動処理の可否を型だけで決めず、想定した入力と出力内容を確認する工程を残します。本稿の例は、外部へ自動送信する判断を実行しません。
最終出力の値と、受け取り側が読む場所を照合する
内部ノード、最終出力、API応答全体、イベント、画面表示は、それぞれ値の入れ物が異なります。draft_textという名前を探すときも、どの段階を読んでいるのかを先に確認します。
現行のOutput資料は、API利用時の出力がoutputsの中へ入り、ストリーミングでは最終のworkflow_finishedイベントに出力が現れると説明しています。応答全体の構造は使うAPIや呼び出し方法の資料へ照合し、途中の本文断片だけを最終結果と扱わないようにします。
# 最終outputsの部分を取り出した後、という想定の架空教材です。
# HTTP応答全体や、本物のイベントログではありません。
example_blocking_outputs = dict(outputs)
example_finished_event = {
"event": "workflow_finished",
"data": {"outputs": dict(outputs)},
}
assert inspect_outputs(example_blocking_outputs) == []
assert inspect_outputs(example_finished_event["data"]["outputs"]) == []
assert example_blocking_outputs["draft_text"] == example_finished_event["data"]["outputs"]["draft_text"]
この例は、通信を送るコードではありません。すでに取り出した同じ値を、二つの教材上の入れ物へ置いて比較しています。実際のAPIの認証情報、エンドポイント、送信処理は含めていません。
利用側のログを確認するときは、必要な項目名と安全な架空入力で再現します。共有する確認票へ、実在の文章や認証情報をそのまま貼る必要はありません。出力名と型、どの段階で空になったかを残せば、質問を小さくできます。
画面だけが空なら、受け取った最終値にdraft_textがあるかを見ます。ある場合は利用側の表示や参照を確認する段階です。ない場合はWorkflowの出力へ戻ります。どちらでも、最初にLLMの指示文を変更する必要があるとは限りません。
利用側に以前の結果を保存する仕組みがある場合は、新しい実行の受付IDや時点とも照合します。DEMO-03を送ったのにDEMO-02の表示を見ていれば、文章の内容が似ていても同じ検証ではありません。Workflow内の出力だけでなく、利用側がどの結果を表示しているかを確認します。
ただし、前の結果が見えたという観察だけで、Difyの会話変数が原因だと決めません。アプリの種類、呼び出し元の保存処理、実行版など、異なる段階があり得ます。まず同じ実行の最終出力を取り出し、その後に表示との対応を調べる順序を保ちましょう。
編集中の結果と、利用者が呼ぶ公開版を混ぜない
編集画面で出力名を直しても、利用者が以前の公開版を呼んでいれば、同じ結果にはなりません。公式のVersion Controlでは、Current Draftが作業中、Latest Versionが利用者向けの公開版として分けられています。
まず、自分が見た成功結果がどの版のものかを確認します。編集中のテストだけか、実際の公開版かを記録し、同じ架空のDEMO-03入力で、必要な4項目が返るかを照合します。結果の値だけを見て、最新版を呼んだと決めないようにします。
公開へ反映する前には、使っている側の名前が変わる影響を確認します。例えばanswerからdraft_textへ変えた場合は、その変更を前提に利用側を合わせる必要があります。公開操作をした事実だけで、受け取り側まで整ったとは考えません。
版の名前や公開時刻を確認票に残すと、翌日の再現でも比較しやすくなります。版の復元や指定実行などの詳細機能には利用環境・プラン差があるため、利用できる範囲を公式で確認してください。本稿は、それらの操作や有料機能を実行していません。
公開後の確認では、同じ入力、同じ利用方法、同じ期待項目を使います。テストのたびに入力や呼び出し元を変えると、版の差なのか入力の差なのかが分からなくなります。まず一つの再現例で出力の対応を確かめてください。
確認票には、期待と観測を別の欄にします。「期待:draft_textが文字列」「観測:まだ未記入」のように、実行前は観測欄を空けておきます。Python教材で予定した値を、そのままDifyの実測欄へコピーしないようにします。
同じ確認を公開版でも実行して初めて、観測欄を埋めます。利用側の画面だけでなく、その実行の最終項目を確認できたかも記録してください。編集中で通った確認と、公開された経路で通った確認を、一つの成功欄へまとめないことが目的です。
質問先へは、経路・対応表・実際の値を一組で渡す
確認票は「アプリ種別」「利用版」「入力の架空ID」「実行された経路」「上流の値」「Outputの名前と参照」「最終結果」「利用側が読む名前」の順にします。長いプロンプト全文より、値が通った順序が分かる記録を先にそろえます。
今回なら、期待はDEMO-03の下書き文字列、確認要否boolean、件数2です。上流に文章があり、最終結果にdraft_textがなければ、その間の参照と出力を見ます。最終結果に値があるのに画面だけ空なら、その後の利用側を確認します。
再現を小さくする際には、複数のOutputを一つへまとめた検証用コピーを考える方法もあります。ただし、その変更だけで原因が確定したとはせず、元の対応表で何が異なったかを記録します。使われている本番Workflowを、確認前に大きく組み替えないようにします。
学習の到達点は、四つの項目について「どこで作り、何という名前で外へ返し、誰が読むか」を説明できることです。次に、六つの保留例を自分で分類し、欠けた項目と空文字、falseと文字列falseを区別します。Difyの画面を開く前に、紙の対応表でも練習できます。
講座や個別支援を検討する場合は、基本操作だけか、出力仕様の設計や公開後の検収まで扱うかを確認します。Difyを扱う講座でも、自分の版・持ち込みWorkflow・API利用側まで相談できるとは限りません。質問期間、支援の範囲、費用を申込前に照合してください。
Difyを申請フローや顧客管理などの業務に使う練習をしたい人は、バイテックAIスクールのDifyマスターコースも比較できます。公式ページでは、申請・顧客管理・レポートの自動化を題材にしています(2026年11月6日確認)。自作ワークフローの出力設定や質問対応が学べる範囲は、受講前に確認してください。
よくある質問
Q. Workflowが成功なら、最終出力も返っていますか?
必要な値が返ったかは別に確認します。現行公式ではOutputがない経路も実行できますが、呼び出し元へ返すデータがない場合があります。上流の値と最終の出力項目を照合してください。
Q. 旧記事のEndノードと、今のOutputは同じ説明でよいですか?
現行公式は旧Endからの名称と役割の変更を説明しています。Outputの任意性や、他の並列経路を停止するものではない点を、自分の版の画面と合わせて確認します。旧画面の説明だけで動作を決めないようにします。
Q. LLMのtextは、最終結果でもtextという名前ですか?
Outputで別の名前を割り当てられます。本稿では上流のtextをdraft_textへ対応させます。参照元ノード、参照するフィールド、外へ返す名前を分けて記録してください。
Q. 複数のOutputで同じresultを使ってよいですか?
現行公式は、同じ名前があると後の値が先の値を上書きすると説明しています。必要な複数の結果は一意の名前へ分け、結合したい場合は結合の内容を別に設計します。
Q. review_requiredがfalseなら、出力が空という意味ですか?
今回の仕様ではfalseもbooleanの値です。項目がない、空文字、文字列false、booleanのfalseを区別します。形の検査と、文章内容や確認要否の妥当性を判断する工程も別です。
Q. 編集画面では直ったのに、利用側の結果が変わりません。
同じ入力と利用方法で、作業中のDraftと利用者が呼ぶ公開版を照合します。出力名を変更した場合は、利用側の参照も確認してください。本稿の例は実際のCloudやAPIでの実行結果ではありません。