2026/8/24 1:38:24

ComfyUI插件开发实战:三步做出你的第一个自定义节点

ComfyUI插件开发实战:三步做出你的第一个自定义节点 ComfyUI插件开发实战三步做出你的第一个自定义节点【免费下载链接】ComfyUIThe most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface.项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI你搭的工作流里最后缺一步官方节点库里没有的后处理。与其改核心代码正解是 ComfyUI 插件开发在 custom_nodes 里放一个 Python 文件工作流就能多出一个新节点。 动手前的准备环境与扩展位置先弄清三件事项目怎么跑起来、扩展文件放在哪、系统怎么发现你的扩展。五分钟搭好环境把项目拉到本地装依赖然后启动执行git clone https://gitcode.com/GitHub_Trending/co/ComfyUI再用pip install -r requirements.txt装依赖运行python main.py浏览器打开 127.0.0.1:8188能看到节点面板就算就绪。扩展文件的落点扩展机制一句话启动时 ComfyUI 扫描custom_nodes目录逐个 .py 文件调用comfy_entrypoint()拿回它返回的节点列表。所以一个扩展就是一个普通的 .py 文件放进目录、完成注册即可。官方样例 custom_nodes/example_node.py.example 是现成骨架直接复制就能改。 核心机制速览两件事就够一个节点要做的事情只有两件声明长什么样、告诉系统怎么跑。整个机制就是下面两段代码。最小骨架Schema 三要素Schema相当于一张商品标签标签上写清规格前端就自动渲染出参数面板。class MyInvert(io.ComfyNode): classmethod def define_schema(cls) - io.Schema: return io.Schema( node_idMyInvert, # 唯一标识不可与其他节点重名 display_name图像反色, # 前端显示名 categoryimage/处理, # 节点搜索里的分类 inputs[ io.Image.Input(image), # 输入图像张量 io.Float.Input(strength, default1.0, min0.0, max2.0, step0.05), ], outputs[io.Image.Output()], # 输出类型必须与实际返回值一致 ) classmethod def execute(cls, image, strength): return io.NodeOutput(1.0 - image * strength) # 反色演示记住三点node_id是唯一标识category 决定搜索分类输入类型决定它能接哪些口。入口函数把节点报上名节点不注册系统看不见它。注册动作像新员工入职报到——名单上没名字就不算你的人。from comfy_api.latest import ComfyExtension, io # 引入官方节点 API class MyInvertExtension(ComfyExtension): async def get_node_list(self): return [MyInvert] # 返回要注册的节点列表 async def comfy_entrypoint(): # 系统扫描的入口函数名固定 return MyInvertExtension()comfy_entrypoint这个名字是写死的改名整个文件都不会被加载。上图是官方样例中参数选项的自动补全面板你写 Schema 时 IDE 里也有同样的提示。 十五分钟做出第一个可用插件不用从零写。复制官方样例改处理逻辑得到一个能跑的图像反色节点。建骨架、配参数、运行、验证四步走把样例另存为custom_nodes/my_invert.py类名同步改掉修改node_id与display_name顺手把 category 归到你常用的分类python main.py重启在节点面板搜索 MyInvert节点应当出现连线 LoadImage → MyInvert → SaveImage按 Queue Prompt 出图。结果落在 output 目录和输入图对比明暗正好反转。上图是项目 input 目录自带的示例图可以直接拿来验证节点。从能用到好用节点能用和好用差距通常在参数细节和计算调度上而不是算法本身。参数设计的关键取舍每个参数给一个安全默认值用户不动它也能出结果。用 min/max/step 限定范围用户常拖的参数设 display_modeslider总是小数字的参数就别给自由输入框。用延迟求值跳过无谓计算输入声明 lazyTrue再在check_lazy_status里决定本次真正要哪些字段# 输入定义时标 lazyTrue需要时才求值 classmethod def check_lazy_status(cls, image, prompt, save): if save enable: return [prompt] # 用户开启保存才索取该字段 return []没被点名的字段不求值上游图也不会跟着空跑。让错误会说话在 execute 开头校验输入类型和参数范围不合格就抛ValueError把原因和修改方式写进消息。一句明确的报错胜过五十行 traceback。⚠️ 避坑指南三个高频事故下面三个现象几乎人人踩过按现象 → 原因 → 解法走一遍。重启后节点没出现现象重启后搜索框里没有节点界面也没有报错原因入口函数名没写成comfy_entrypoint或文件没直接放在custom_nodes目录下解法看启动日志找 ImportError保持函数名与 async 定义不变文件放在目录根部。输入参数永远是 None现象前端改了参数执行结果却不变execute 里拿到的是 None原因它是lazy参数check_lazy_status 没返回这个字段名它就没被求值解法把字段名加进返回列表或干脆去掉 lazy 声明让它即时求值。输出口接不上下一节点现象输出端口连不上或连上后下游节点报错原因Schema 里声明的输出类型与 execute 实际返回值不一致解法图像就声明io.Image.Output()返回[B,H,W,C]张量类型对上才能互通。 下一步跑通一个节点之后剩下的是规模问题。行动清单从自己的工作流里挑一个小需求做成节点学 Combo 下拉、Bool 开关和 Mask 输入把参数面板做完整读一读 comfy_extras/ 里的节点实现感受官方参数写法给插件写上 README 和版本号整个 custom_nodes 目录可以发给同事复用。真实的生态资源官方样例 custom_nodes/example_node.py.example最小完整扩展结构一目了然comfy_api_nodes/ 目录Gemini、Luma 等外部服务 API 节点的成套模板含异步请求与进度上报tests-unit/ 目录官方测试写法你给节点写回归测试时可以照着来。工作流的上限不取决于模型而取决于你能拼出多少节点。【免费下载链接】ComfyUIThe most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface.项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUI创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考