ノードの無線化とは
ノードベースツールの最大の特徴は、各機能を線で繋いでいくだけで複雑な処理ができることです。 その反面、ノードと線の数が増えれば増えるほど、画面がごちゃごちゃになり(スパゲッティ化し)、何をしているのかさっぱり分からなくなる問題も抱えています。
そんな中、「データをワイヤレスで飛ばせばいいんじゃない?」という発想が出るのは自然な流れでしょう。
カスタムノード
無線化を実現するカスタムノードはいくつか存在します。 chrisgoringe/cg-use-everywhere も有名ですが、最近ではよりシンプルで扱いやすい KJNodes のセットがよく使われています。
Set & Get ノード

{
"id": "6fc93157-d6f0-4252-82b5-617d576d6193",
"revision": 0,
"last_node_id": 29,
"last_link_id": 24,
"nodes": [
{
"id": 18,
"type": "PrimitiveString",
"pos": [
813.23974609375,
100
],
"size": [
270,
58
],
"flags": {},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "STRING",
"type": "STRING",
"links": [
18
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "PrimitiveString"
},
"widgets_values": [
"Hello!"
]
},
{
"id": 21,
"type": "GetNode",
"pos": [
1410,
100
],
"size": [
210,
58
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "STRING",
"type": "STRING",
"links": [
21
]
}
],
"title": "Get_A",
"properties": {},
"widgets_values": [
"A"
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 24,
"type": "PreviewAny",
"pos": [
1660.1823082011686,
101.86602952083894
],
"size": [
210,
88
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [
{
"name": "source",
"type": "*",
"link": 21
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.73",
"Node name for S&R": "PreviewAny"
},
"widgets_values": []
},
{
"id": 16,
"type": "SetNode",
"pos": [
1115.82763671875,
100
],
"size": [
210,
60
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [
{
"name": "STRING",
"type": "STRING",
"link": 18
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_A",
"properties": {
"previousName": "A"
},
"widgets_values": [
"A"
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 17,
"type": "GetNode",
"pos": [
1410,
269.8281322314048
],
"size": [
210,
60
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
24
]
}
],
"title": "Get_B",
"properties": {},
"widgets_values": [
"B"
],
"color": "#323",
"bgcolor": "#535"
},
{
"id": 28,
"type": "SetNode",
"pos": [
1115.82763671875,
269.8281322314048
],
"size": [
210,
60
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"link": 23
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_B",
"properties": {
"previousName": "B"
},
"widgets_values": [
"B"
],
"color": "#323",
"bgcolor": "#535"
},
{
"id": 26,
"type": "LoadImage",
"pos": [
825.15966796875,
269.8281322314048
],
"size": [
258.080078125,
369
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
23
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.73",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"e1525d66b933d4a87fc5d4ee612ee7f0.png",
"image"
]
},
{
"id": 29,
"type": "PreviewImage",
"pos": [
1660.1823082011686,
269.8281322314048
],
"size": [
280.5429999999999,
309.9090000000001
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 24
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.73",
"Node name for S&R": "PreviewImage"
},
"widgets_values": []
}
],
"links": [
[
18,
18,
0,
16,
0,
"*"
],
[
21,
21,
0,
24,
0,
"*"
],
[
23,
26,
0,
28,
0,
"*"
],
[
24,
17,
0,
29,
0,
"IMAGE"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 0.8264462809917354,
"offset": [
-486.46352687657804,
215.10827887439387
]
},
"frontendVersion": "1.33.9",
"ue_links": [],
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
使い方は非常にシンプルです。
-
- Setノード (送信側):
- データを入力し、
Constantに任意の名前(ID)を設定します。
-
- Getノード (受信側):
Constantに送信側と同じ名前を設定すると、離れた場所でもデータを受け取ることができます。
便利だけど多用は禁物

{
"id": "260a52ec-3239-43ea-a0c6-e442b71439c4",
"revision": 0,
"last_node_id": 26,
"last_link_id": 34,
"nodes": [
{
"id": 9,
"type": "SaveImage",
"pos": [
1630,
140
],
"size": [
334.228271484375,
383.0218200683594
],
"flags": {},
"order": 17,
"mode": 0,
"inputs": [
{
"name": "images",
"type": "IMAGE",
"link": 9
}
],
"outputs": [],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29"
},
"widgets_values": [
"ComfyUI"
]
},
{
"id": 6,
"type": "CLIPTextEncode",
"pos": [
534.1920166015625,
160
],
"size": [
422.84503173828125,
164.31304931640625
],
"flags": {},
"order": 11,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 27
}
],
"outputs": [
{
"name": "CONDITIONING",
"type": "CONDITIONING",
"slot_index": 0,
"links": [
19
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
"anime,flat illustration,simple illustration,portrait of a girl, red hair, wearing headset"
]
},
{
"id": 12,
"type": "VAELoader",
"pos": [
-394.3125915527344,
360.7410583496094
],
"size": [
315,
58
],
"flags": {
"collapsed": false
},
"order": 0,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "VAE",
"type": "VAE",
"slot_index": 0,
"links": [
26
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "VAELoader"
},
"widgets_values": [
"vae-ft-mse-840000-ema-pruned.safetensors"
]
},
{
"id": 15,
"type": "KSampler",
"pos": [
1020,
130
],
"size": [
315,
262
],
"flags": {},
"order": 15,
"mode": 0,
"inputs": [
{
"name": "model",
"type": "MODEL",
"link": 34
},
{
"name": "positive",
"type": "CONDITIONING",
"link": 19
},
{
"name": "negative",
"type": "CONDITIONING",
"link": 20
},
{
"name": "latent_image",
"type": "LATENT",
"link": 21
}
],
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"slot_index": 0,
"links": [
23
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "KSampler"
},
"widgets_values": [
1,
"fixed",
20,
8,
"dpmpp_2m",
"karras",
0.65
]
},
{
"id": 8,
"type": "VAEDecode",
"pos": [
1370,
140
],
"size": [
210,
46
],
"flags": {},
"order": 16,
"mode": 0,
"inputs": [
{
"name": "samples",
"type": "LATENT",
"link": 23
},
{
"name": "vae",
"type": "VAE",
"link": 32
}
],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"slot_index": 0,
"links": [
9
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "VAEDecode"
},
"widgets_values": []
},
{
"id": 4,
"type": "CheckpointLoaderSimple",
"pos": [
-394.3125915527344,
120.49484252929688
],
"size": [
315,
98
],
"flags": {},
"order": 1,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"slot_index": 0,
"links": [
29
]
},
{
"name": "CLIP",
"type": "CLIP",
"slot_index": 1,
"links": [
25
]
},
{
"name": "VAE",
"type": "VAE",
"slot_index": 2,
"links": []
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "CheckpointLoaderSimple"
},
"widgets_values": [
"😎-v1.x\\meinamix_meinaV11.safetensors"
]
},
{
"id": 17,
"type": "SetNode",
"pos": [
-40,
185.2870635986328
],
"size": [
210,
58
],
"flags": {},
"order": 10,
"mode": 0,
"inputs": [
{
"name": "CLIP",
"type": "CLIP",
"link": 25
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_clip",
"properties": {
"previousName": "clip"
},
"widgets_values": [
"clip"
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 18,
"type": "SetNode",
"pos": [
-40,
360.7410583496094
],
"size": [
210,
58
],
"flags": {},
"order": 8,
"mode": 0,
"inputs": [
{
"name": "VAE",
"type": "VAE",
"link": 26
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_vae",
"properties": {
"previousName": "vae"
},
"widgets_values": [
"vae"
],
"color": "#322",
"bgcolor": "#533"
},
{
"id": 16,
"type": "SetNode",
"pos": [
-40,
530
],
"size": [
210,
60
],
"flags": {},
"order": 14,
"mode": 0,
"inputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"link": 24
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_image",
"properties": {
"previousName": "image"
},
"widgets_values": [
"image"
],
"color": "#2a363b",
"bgcolor": "#3f5159"
},
{
"id": 21,
"type": "GetNode",
"pos": [
270,
270
],
"size": [
210,
60
],
"flags": {},
"order": 2,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "CLIP",
"type": "CLIP",
"links": [
27,
28
]
}
],
"title": "Get_clip",
"properties": {},
"widgets_values": [
"clip"
],
"color": "#432",
"bgcolor": "#653"
},
{
"id": 23,
"type": "GetNode",
"pos": [
520,
560
],
"size": [
210,
60
],
"flags": {},
"order": 3,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
33
]
}
],
"title": "Get_image",
"properties": {},
"widgets_values": [
"image"
],
"color": "#2a363b",
"bgcolor": "#3f5159"
},
{
"id": 25,
"type": "GetNode",
"pos": [
520,
690
],
"size": [
210,
58
],
"flags": {},
"order": 4,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "VAE",
"type": "VAE",
"links": [
31
]
}
],
"title": "Get_vae",
"properties": {},
"widgets_values": [
"vae"
],
"color": "#322",
"bgcolor": "#533"
},
{
"id": 24,
"type": "GetNode",
"pos": [
1370,
250
],
"size": [
210,
58
],
"flags": {},
"order": 5,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "VAE",
"type": "VAE",
"links": [
32
]
}
],
"title": "Get_vae",
"properties": {},
"widgets_values": [
"vae"
],
"color": "#322",
"bgcolor": "#533"
},
{
"id": 7,
"type": "CLIPTextEncode",
"pos": [
534.462890625,
370
],
"size": [
422.5741882324219,
120.74252319335938
],
"flags": {},
"order": 12,
"mode": 0,
"inputs": [
{
"name": "clip",
"type": "CLIP",
"link": 28
}
],
"outputs": [
{
"name": "CONDITIONING",
"type": "CONDITIONING",
"slot_index": 0,
"links": [
20
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "CLIPTextEncode"
},
"widgets_values": [
"text, watermark, worstquality,mouth"
]
},
{
"id": 26,
"type": "GetNode",
"pos": [
747.037109375,
37.25156784057617
],
"size": [
210,
60
],
"flags": {},
"order": 6,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "MODEL",
"type": "MODEL",
"links": [
34
]
}
],
"title": "Get_model",
"properties": {},
"widgets_values": [
"model"
],
"color": "#223",
"bgcolor": "#335"
},
{
"id": 22,
"type": "SetNode",
"pos": [
-40,
74.30988311767578
],
"size": [
210,
60
],
"flags": {},
"order": 9,
"mode": 0,
"inputs": [
{
"name": "MODEL",
"type": "MODEL",
"link": 29
}
],
"outputs": [
{
"name": "*",
"type": "*",
"links": null
}
],
"title": "Set_model",
"properties": {
"previousName": "model"
},
"widgets_values": [
"model"
],
"color": "#223",
"bgcolor": "#335"
},
{
"id": 14,
"type": "LoadImage",
"pos": [
-390,
530
],
"size": [
315,
375.9122009277344
],
"flags": {},
"order": 7,
"mode": 0,
"inputs": [],
"outputs": [
{
"name": "IMAGE",
"type": "IMAGE",
"links": [
24
]
},
{
"name": "MASK",
"type": "MASK",
"links": null
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "LoadImage"
},
"widgets_values": [
"Consistency VAE Decoder.png",
"image"
]
},
{
"id": 11,
"type": "VAEEncode",
"pos": [
800,
560
],
"size": [
157.03707885742188,
46
],
"flags": {},
"order": 13,
"mode": 0,
"inputs": [
{
"name": "pixels",
"type": "IMAGE",
"link": 33
},
{
"name": "vae",
"type": "VAE",
"link": 31
}
],
"outputs": [
{
"name": "LATENT",
"type": "LATENT",
"slot_index": 0,
"links": [
21
]
}
],
"properties": {
"cnr_id": "comfy-core",
"ver": "0.3.29",
"Node name for S&R": "VAEEncode"
},
"widgets_values": []
}
],
"links": [
[
9,
8,
0,
9,
0,
"IMAGE"
],
[
19,
6,
0,
15,
1,
"CONDITIONING"
],
[
20,
7,
0,
15,
2,
"CONDITIONING"
],
[
21,
11,
0,
15,
3,
"LATENT"
],
[
23,
15,
0,
8,
0,
"LATENT"
],
[
24,
14,
0,
16,
0,
"*"
],
[
25,
4,
1,
17,
0,
"*"
],
[
26,
12,
0,
18,
0,
"*"
],
[
27,
21,
0,
6,
0,
"CLIP"
],
[
28,
21,
0,
7,
0,
"CLIP"
],
[
29,
4,
0,
22,
0,
"*"
],
[
31,
25,
0,
11,
1,
"VAE"
],
[
32,
24,
0,
8,
1,
"VAE"
],
[
33,
23,
0,
11,
0,
"IMAGE"
],
[
34,
26,
0,
15,
0,
"MODEL"
]
],
"groups": [],
"config": {},
"extra": {
"ds": {
"scale": 1,
"offset": [
322.3125915527344,
60.74843215942383
]
},
"frontendVersion": "1.18.1",
"VHS_latentpreview": false,
"VHS_latentpreviewrate": 0,
"VHS_MetadataImage": true,
"VHS_KeepIntermediate": true
},
"version": 0.4
}
リーダブルノードのすゝめ でも触れましたが、ノードツールの最大の利点は「繋がった線を見るだけでデータの流れが掴める」ことです。 いたずらに無線化すると、「この画像データ、どこから飛んできたの?」と処理の流れを追うのが非常に困難になります。
一つのworkflowのあらゆる場所に何度も何度も同じ変数が出てくるような場合は、無線化が便利であったりしますが、そもそも、それほど大きいworkflowは小さく分割すべきかもしれませんね(;・∀・)