AI活用

ComfyUIのGUI用JSONとAPI用JSONの違い|変換できない原因を解説

ComfyUIのworkflow JSONはGUI用とAPI用で構造が違い、GUI用をそのまま/promptへ送っても動きません。同一workflowの並置で差を示し、File → Export Workflow (API)での正式な出力、Node IDの逆引き、parse後の最小差分書き換えを解説します。

この記事の目次
  1. 結論:API形式はUIから書き出し、書き換えはparse後に構造で行う
  2. 2種類のJSONを見比べる
  3. GUI JSONに含まれる情報
  4. API形式に必要な情報
  5. API形式を出力・変換する
  6. Node IDと入力参照の関係
  7. 自分のworkflowで目的のIDを見つける
  8. 最小差分だけを書き換える
  9. 2形式でdiffを取り、必要・不要を自分の表にする
  10. よくある質問
  11. まとめ

ComfyUIのworkflow JSONには、画面を復元するためのGUI用と、実行だけに必要な情報を持つAPI用の2種類があり、GUI用をそのまま/promptへ送っても動きません。変換に失敗する原因の多くは、この構造差と、Node IDが「表示順」ではなく「識別子」であることを知らずに手で書き換えることです。同じworkflowを2形式で並べ、正式な出力方法と最小差分の書き換え方を整理します。

情報確認日:2026年8月22日(日本時間)

結論:API形式はUIから書き出し、書き換えはparse後に構造で行う

責任範囲

  • GUI用JSONとAPI用JSONの構造差を、同一workflowの並置で示す
  • API形式に必要なclass_typeinputs[node_id, output_index]参照を説明する
  • 現行UI(2026年8月時点)での正式な書き出し方法を確認する
  • Node IDと入力参照の関係、文字列置換ではなくparse後に書き換える理由を扱う
  • workflowの共有・読み込み・依存確認はComfyUIのworkflow JSONを読み込む方法、送信先の経路はComfyUI APIの使い方に任せる
スポンサーリンク

2種類のJSONを見比べる

同じ「Checkpointを読み、Promptをエンコードし、KSamplerで生成して保存する」workflowの、正のPromptノードだけを2形式で並べます。上がGUI用(File → Saveで得られるもの)、下がAPI用です。どちらも公式ドキュメントで確認できる形式を最小に切り詰めています。

// GUI用(抜粋)。画面復元のための情報が中心
{
  "version": 1,
  "state": { "lastNodeId": 9, "lastLinkId": 9 },
  "nodes": [
    {
      "id": 6,
      "type": "CLIPTextEncode",
      "pos": [415, 186],
      "size": [422, 164],
      "flags": {},
      "order": 2,
      "mode": 0,
      "inputs": [{ "name": "clip", "type": "CLIP", "link": 3 }],
      "outputs": [{ "name": "CONDITIONING", "type": "CONDITIONING", "links": [4] }],
      "properties": { "Node name for S&R": "CLIPTextEncode" },
      "widgets_values": ["a quiet harbor at dawn, watercolor"]
    }
  ],
  "links": [[3, 4, 1, 6, 0, "CLIP"], [4, 6, 0, 3, 0, "CONDITIONING"]],
  "groups": [],
  "config": {},
  "extra": {}
}
// API用(同じノード)。実行に必要な情報だけ
{
  "6": {
    "class_type": "CLIPTextEncode",
    "inputs": {
      "clip": ["4", 1],
      "text": "a quiet harbor at dawn, watercolor"
    },
    "_meta": { "title": "CLIP Text Encode (Prompt)" }
  }
}

GUI用ではPromptの文字列がwidgets_valuesという配列の中に名前なしで入り、接続はlinksという別の配列で管理されています。API用では同じ文字列がinputs.textという名前付きの場所にあり、接続もinputs.clip["4", 1]として直接書かれています。変換とは、この「名前のない値と別管理の接続」を「名前付きの入力」へ組み直す作業です。

GUI JSONに含まれる情報

GUI用JSONは、公式のworkflow JSON仕様(2026年8月確認)ではversionstatenodeslinksgroupsconfigextraなどを持ちます。ノード一つをとっても、実行に関係ない項目が大半です。

フィールド 役割 実行に必要か
possize キャンバス上の座標と大きさ 不要
flagsmode 折りたたみ・ピン留め、バイパスやミュートの状態 modeはバイパスの判定に使われるが、API形式には含まれない
order キャンバス上の並び順 不要。実行順は接続から決まる
colorbgcolor ノードの配色 不要
inputs[].linkoutputs[].links links配列への参照番号 接続情報として必要だが、形が違う
widgets_values ウィジェットの値を並べた配列 値としては必要だが、名前がない
groupsextra グループ枠、表示設定、メモ 不要

widgets_valuesは「ウィジェットが画面に並ぶ順」で値が入るため、何番目がseedで何番目がstepsかはノード定義を見ないと分かりません。推測で対応づけると、seedの位置にstepsを書くような変換ミスが起こります。

バイパスしたノードの扱い:GUIでバイパス(modeによる無効化)したノードは、API形式への書き出し時にフロントエンド側で解決され、API用JSONには解決後の接続だけが残ります。この挙動は公式仕様書に明記されていないため、自分のworkflowで書き出し前後を比べて確認してください。GUI用JSONだけを見て手で変換すると、この解決が抜けて「無効化したはずのノードが動く」状態になります。

API形式に必要な情報

API形式は、公式ドキュメントの説明どおり「ノードIDをキーにしたオブジェクト」で、各ノードはclass_typeinputs_metaだけを持ちます。

キー 中身 省略できるか
最上位のキー(例:"6" ノードID。文字列 不可。他ノードからの参照先になる
class_type ノードの種類。/object_infoのキーと一致する名前 不可
inputs ウィジェット値と接続をまとめた名前付きオブジェクト 不可。必須入力が欠けると送信時にエラー
inputs.<name>が配列のとき ["参照先ノードID", 出力インデックス]で接続を表す 接続する入力では必須
_meta.title 表示名。UIで付けたタイトル 可。実行には使われない

接続の表現が重要です。"clip": ["4", 1]は「ID 4のノードの1番目(0始まり)の出力をつなぐ」という意味で、GUI用のlinks配列にあった[link_id, origin_id, origin_slot, target_id, target_slot, type]から、origin_idorigin_slotだけを取り出して入力側へ埋め込んだ形です。link_idtypeはAPI形式には現れません。

ウィジェット値と接続が同じinputsに混ざるため、「値か参照か」は型で見分けます。文字列・数値・真偽値なら値、2要素の配列なら参照です。この規則を知っていれば、書き換えるときにseedへ誤って配列を入れるような事故を防げます。

API形式を出力・変換する

正式な方法は一つで、現行UI(2026年8月時点)のメニューからFile → Export Workflow (API)を選ぶことです。公式ドキュメントはこの操作に開発者モードが不要だと明記しており、.jsonファイルがダウンロードされます。

  1. 1
    GUIで1回実行する

    動かないworkflowを書き出しても、API側でも動かない。先に画面で通す

  2. 2
    File → Export Workflow (API)

    保存したファイルをworkflow_api.jsonのように、GUI用と区別できる名前にする

  3. 3
    GUI用も保存する

    File → Saveで通常のJSONも残す。API用は画面に戻せないため、編集元はGUI用になる

  4. 4
    2つを並べて確認する

    ノード数とclass_typeがGUI側のtypeと一致するか、バイパスしたノードが消えているかを見る

GUI用JSONをスクリプトで自動変換したくなりますが、公式SDKの現時点の範囲にworkflow管理は含まれず、変換APIも公式には提供されていません。widgets_valuesの順序とノード定義の対応、バイパスの解決など、UIが内部で持つ知識が必要なため、自前変換はズレやすい作業です。変換はUIに任せ、GUI用を編集元として管理します。

設定名は変わる:以前のフロントエンドでは「Enable dev mode options (API save, etc.)」を有効にして「Save (API Format)」を使う手順でした。現行では設定にこの項目が残っていても、書き出し自体はFileメニューから行えます。自分の版でメニュー名が違う場合は、公式ドキュメントで最新の名称を確認してください。

Node IDと入力参照の関係

Node IDは「画面で何番目に置いたか」ではなく、ノードを追加した時点で採番される識別子です。GUI用のstate.lastNodeId(旧形式ではlast_node_id)がこの採番の現在値で、ノードを消してもIDは詰められません。

同じ見た目のworkflowでも、作った順が違えばIDは変わります。公式サンプルで"6"が正のPromptでも、自分のworkflowで"6"とは限りません。

自分のworkflowで目的のIDを見つける

  • UIの設定にあるNode ID badge mode(公式設定一覧で「ノードのIDマーカー表示を制御」と説明されている項目)を有効にすると、キャンバス上の各ノードにIDが表示される
  • API用JSONをclass_type_meta.titleで検索する。正のPromptならCLIPTextEncodeが2つあるので、inputs.textの中身か、KSamplerのpositiveが参照しているIDで見分ける
  • 参照は一方向。KSamplerinputs.positive["6", 0]なら、ID 6がそのworkflowの正のPromptだと確定する

「KSamplerから逆にたどる」方法はタイトルに依存しません。_meta.titleは自由に変えられる表示名で、共有されたworkflowでは別の意味に付け替えられていることがあります。

最小差分だけを書き換える

書き換えで一番多い失敗は、テキストエディタの置換や文字列のreplaceで済ませることです。負のPromptや_meta.titleの同じ語句まで変わる、引用符の扱いでJSONが壊れる、といった事故が起きます。

parseして構造で触れば、変える場所を限定できます。正のPromptとseedだけを差し替える例です。

# 確認日: 2026-08-22 / 公式 script_examples/basic_api_example.py と同じ考え方
import json

with open("workflow_api.json", encoding="utf-8") as f:
    wf = json.load(f)

# KSampler から正の Prompt のノード ID を逆引きする
sampler_id = next(k for k, v in wf.items() if v["class_type"] == "KSampler")
positive_id = wf[sampler_id]["inputs"]["positive"][0]

wf[positive_id]["inputs"]["text"] = "a quiet harbor at dawn, watercolor"
wf[sampler_id]["inputs"]["seed"] = 12345

with open("workflow_api.modified.json", "w", encoding="utf-8") as f:
    json.dump(wf, f, ensure_ascii=False, indent=2)

差し替え前後のファイルをdiffにかけると、変わった行が2行だけであることを確認できます。変更点が想定より多ければ、置換が別の場所に及んでいる合図です。

diff workflow_api.json workflow_api.modified.json
# 期待する出力: "text" の行と "seed" の行だけが < > で表示される

2形式でdiffを取り、必要・不要を自分の表にする

自分のworkflowでGUI用とAPI用を書き出し、ノード一つを選んで項目を並べ、どちらに何があるかを記入します。

項目 GUI用にある API用にある 実行に必要 気づいたこと
pos
widgets_values / inputs.<name>
links / ["id", index]
mode(バイパス)
_meta.title

表を埋めると、「座標と配色は消え、ウィジェット値は名前付きで残り、接続は別配列から入力側へ移る」という構造差が自分のノードの実例として残ります。Gitでどちらを正本にするかは別記事で扱います。

よくある質問

API用JSONをComfyUIの画面に読み込めますか?

座標や接続配列がないため、GUI用として復元できません。編集元は必ずGUI用で保存し、API用は書き出し直して作ります。

書き出したAPI用JSONを送ると「必須入力がない」と言われます

custom nodeの更新で入力名が変わったか、GUI側でウィジェットを入力に変換したまま未接続になっている可能性があります。/object_infoでそのclass_typeの必須入力名を確認し、GUIで一度実行してから書き出し直してください。

Node IDを自分で「1, 2, 3」と振り直してもよいですか?

API用JSON内で参照と一緒に付け替えれば動きますが、GUI用との対応が取れなくなります。IDは識別子として触らず、差し替える値だけを変えるほうが安全です。

まとめ

GUI用JSONは画面復元のための座標・配色・links配列・名前なしのwidgets_valuesを持ち、API用JSONはノードIDをキーにclass_typeと名前付きのinputsだけを持ちます。変換はUIのFile → Export Workflow (API)に任せ、自前の変換は避けます。

書き換えるときはNode IDを表示順と混同せず、KSamplerの参照から逆引きして、parse後に構造で一か所だけ変えます。送信先の経路と最小実行はComfyUI APIの使い方を参照してください。

スポンサーリンク