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 是目前最流行的开源扩散模型 GUI 与节点式 AI 工作流平台,而 ComfyUI 节点开发(也就是 ComfyUI 插件开发)是扩展它最直接的方式:几十行 Python 代码,就能把你自己的 AI 能力变成画布上一个可连接的节点。这是一篇 ComfyUI 自定义节点教程,全程按"亲手搭一个节点"的任务推进:先拿到模板,再一步步把节点写出来、调好参数、加上缓存,最后发布成插件。不用任何营销话术,只讲你真能跑起来的东西。
第 1 步:拿到一个能跑的 ComfyUI 节点模板
开发 ComfyUI 自定义节点,第一步不是写代码,而是看官方给的模板。克隆仓库后,custom_nodes/ 目录下就有一个现成的样例文件example_node.py.example,把它复制一份、去掉.example后缀改名,就是你插件的起点。
一个现代写法节点文件只需要两样东西:节点类和入口函数。模板的骨架长这样:
from comfy_api.latest import ComfyExtension, io async def comfy_entrypoint() -> MyExtension: return MyExtension() # ComfyUI 启动时会调用它来加载你的节点comfy_entrypoint()是插件的入口,ComfyUI 启动时扫描custom_nodes/目录,找到这个函数就把你声明的节点注册进系统。后面所有步骤都是往这个骨架里填肉。
第 2 步:用 Schema 定义你的第一个 ComfyUI 节点
节点的核心是define_schema——一份"自我介绍":我叫什么、放在哪个菜单、吃什么、吐什么。我们不用官方的图像反色例子,换一个更实用的场景:把 4 张图拼成 2x2 网格(工作流里批量对比效果时经常用到)。
class StitchGrid(io.ComfyNode): @classmethod def define_schema(cls) -> io.Schema: return io.Schema( node_id="StitchGrid", display_name="图片九宫格拼接", category="image/composite", inputs=[io.Image.Input("image")], outputs=[io.Image.Output()], ) @classmethod def execute(cls, image) -> io.NodeOutput: b, h, w, c = image.shape grid = image.view(2, 2, h, w, c).permute(0, 2, 1, 3, 4).reshape(2*h, 2*w, c) return io.NodeOutput(grid)三个关键点,记住就不容易踩坑:
node_id和display_name是两回事:前者写进工作流 JSON、决定节点身份,后者才是画布上显示的名字。category决定菜单位置:image/composite意味着它出现在"图像处理 → 合成"菜单下。execute的返回值用io.NodeOutput包一层,参数顺序和inputs声明顺序一致。
逻辑其实就一行:把[4, H, W, C]的批次张量重排成 2x2 的大图。ComfyUI 里几乎所有图像节点都是这个套路——吃张量、处理张量、吐张量。
第 3 步:给节点配置输入参数:滑条、下拉框与默认值
裸节点只有一个图输入,用起来像半成品。ComfyUI 的类型系统支持给每个参数加修饰,让前端自动生成对应的控件:
io.Float.Input("radius", default=2.0, min=0.0, max=50.0, step=0.5, display_mode=io.NumberDisplay.slider), # 前端渲染成滑条 io.Combo.Input("mode", options=["高斯", "均值"], default="高斯"), # 渲染成下拉框 io.String.Input("prompt", multiline=True, default=""), # 渲染成多行文本框min/max/step控制取值范围,display_mode决定显示成数字输入框还是滑条,default决定用户不改参数时的行为。默认值要给"大多数人都能用"的值,这是新手最容易偷懒的地方——一个 0 或 1 的默认值,往往让用户第一次用就以为节点坏了。
常用输入类型按使用频率排:Image、Latent、Model这类工作流数据流,Int/Float/String/Bool这类标量参数,以及Combo下拉框。comfy_extras/ 目录下的官方节点(音频、视频、超分等上百个)都是活的参考书,遇到不会定义的参数,先进去搜一个同类节点抄作业。
第 4 步:如何给节点加懒加载与指纹缓存提速
工作流一复杂,"节点明明没变却每次都重跑"就成了性能问题。ComfyUI 给了两个可选钩子,按需启用即可。
懒加载:某些输入只在特定条件下才需要真正求值,用check_lazy_status告诉系统哪些输入该算、哪些该跳过:
@classmethod def check_lazy_status(cls, image, enable_debug, debug_text): if enable_debug == "on": return ["debug_text"] # 只有开启调试时才去读取这段长文本 return []指纹缓存:系统默认"任何输入变化就重跑",但你可以用fingerprint_inputs定义自己的重跑条件——返回值和上次相同,节点就直接复用缓存结果:
@classmethod def fingerprint_inputs(cls, image, threshold): return f"{image.shape}_{threshold}"核心仓库的 LoadImage 节点就是这么干的:返回图片哈希,图没换就绝不重读磁盘。这两个钩子不写完全能跑,写了能让长工作流快一个档次。
第 5 步:发布插件,并扩展成完整能力
节点写完只是开始。把多个节点装进一个插件,靠的还是第 1 步的ComfyExtension:
class MyExtension(ComfyExtension): @override async def get_node_list(self): return [StitchGrid, Watermark, BatchRename] # 一个插件可装任意多个节点插件还可以顺手做两件进阶的事:
- 挂 API 路由:用 aiohttp 的 router 注册
/xxx接口,前端扩展就能和后端对话; - 调外部 AI 服务:参考 comfy_api_nodes/ 目录,它内置了 Gemini、OpenAI、Kling 等几十家服务的集成框架,
execute写成async就能发起非阻塞的网络请求——这也是 ComfyUI 工作流扩展中最常见的"接入外部模型"路径。
最后看一张节点真正跑起来的效果,一个节点的输出,最终会变成画布上这样可预览的作品:
小结
回顾这条 ComfyUI 开发入门路径,五步其实对应五件小事:
- 复制 custom_nodes/ 里的模板,认识
comfy_entrypoint入口; - 用
io.Schema声明输入输出,写execute逻辑; - 用
min/max/Combo/default把参数面板做漂亮; - 需要时用
check_lazy_status和fingerprint_inputs提速; - 用
ComfyExtension打包发布,想接外部服务就看 comfy_api_nodes/ 的现成框架。
每个环节都有官方代码可抄:comfy_extras/抄内部实现,comfy_api_nodes/抄 API 集成。剩下的事只有一件——把你的第一个节点拖进画布,连线,点"运行"。
【免费下载链接】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),仅供参考