公司动态

5 分钟写出第一个 ComfyUI 自定义节点:新手从零到发布的完整指南

📅 2026/8/24 20:14:57
5 分钟写出第一个 ComfyUI 自定义节点:新手从零到发布的完整指南
5 分钟写出第一个 ComfyUI 自定义节点新手从零到发布的完整指南【免费下载链接】ComfyUIThe most powerful and modular diffusion model GUI, api and backend with a graph/nodes interface.项目地址: https://gitcode.com/GitHub_Trending/co/ComfyUIComfyUI 把一整套 AI 工作流拆成一个个能互相连接的节点你在界面上拖来拖去的每个方块背后都只是几行 Python。所以当你觉得这个功能怎么没有现成节点的时候与其干等官方排期不如自己动手造一个。这篇文章带你把整条路走一遍装好项目、写出第一个能跑的节点、让它跑得快最后变成一个能发给别人直接装的插件。为什么等官方更新通常是最慢的路做工作流的时候经常遇到这种事某个环节差一个小转换比如把图反个色、压一下亮度、拼个水印。你去社区问了一圈要么没人接要么回复是排期里。但说句实话ComfyUI 里一个节点并没有你想象的神秘。它本质就是一段逻辑外加一句我吃什么、我吐什么的声明。仓库里甚至留了一份现成的骨架文件你复制出来改几行重启一下它就直接出现在节点菜单里了。等你把第一个跑通后面就全是熟练工种。先把环境搭起来节点文件该放在哪动手前先拿到代码。仓库地址是https://gitcode.com/GitHub_Trending/co/ComfyUIclone 下来就能跑。自定义节点统一放在 custom_nodes/ 目录里。这里有个可以直接抄的示例文件里面把一个节点到底长什么样写得明明白白照着改就行。启动时 ComfyUI 会扫描这个目录挨个调用你文件里的入口函数问它你提供哪些节点类。所以发布一个节点这件事说穿了就是把文件放进对的地方然后让入口把它交出去。定义第一个节点声明 执行两件事一个节点就是一个继承自io.ComfyNode的类你只需要写两个方法define_schema向 ComfyUI 声明我是谁、叫什么、在哪个分类、吃什么输入、吐什么输出。execute真正的处理逻辑参数名要和你声明的输入字段一一对应。from comfy_api.latest import ComfyExtension, io class SoftInvert(io.ComfyNode): 按强度反色strength1 时完全反转。 classmethod def define_schema(cls) - io.Schema: return io.Schema( node_idSoftInvert, display_name柔性反色, categoryimage/filter, inputs[ io.Image.Input(photo), io.Float.Input(strength, default1.0, min0.0, max1.0, step0.05, display_modeio.NumberDisplay.slider), io.String.Input(tag, defaultinvert), ], outputs[io.Image.Output()], ) classmethod def execute(cls, photo, strength, tag) - io.NodeOutput: inverted 1.0 - photo blended photo * (1.0 - strength) inverted * strength return io.NodeOutput(blended)注意execute里那三个参数photo / strength / tag必须和inputs里每个输入声明的第一个字段名对得上。返回值用io.NodeOutput包一下结果就顺着线传给下一个节点了。就这么简单。输入输出怎么选常用类型和控件类型是节点之间的共同语言。输入和输出用的是同一套类型画布上只有同类型的端口才接得上线——所以把类型声明对了一个节点就已经成功了一大半。按用途分几档基础数据io.Image、io.String、io.Int、io.Float日常 90% 的场景用这些就够。模型相关io.Latent、io.Model、io.Vae、io.Conditioning做生成类节点时绕不开。控件io.Combo是下拉框io.Bool是开关用来让用户选模式、切功能。每个数值输入还能再细调给默认值、设min/max范围、定step步进再决定它显示成数字框还是滑杆display_mode。字符串输入可以开成多行。下面这张图就是输入配置项的展开面板你能看到default、min、max、lazy、multiline这些都是能配的。拿不准某个输入该怎么声明时去翻 comfy_extras/ 里的官方节点实现它们怎么写的就是最靠谱的参考答案。节点什么时候会被重新执行ComfyUI 不会无脑地把整张图从头算到尾。一个节点的输入没变它就沿用缓存、直接跳过这也是为什么你改一个参数只有下游那一段会重跑而不是全图重算。但偶尔你会希望看起来没变的东西其实变了也强制重跑。典型例子是读图节点它用文件名指代一张图文件名没改文件内容却被你替换了。这时候实现一个fingerprint_inputs方法返回一个指纹数字或字符串都行ComfyUI 拿它跟上次比较不一样就重新执行。核心仓库里的 LoadImage 节点用的就是图片哈希当指纹。不想每次都算把输入标记成懒加载反过来也有一招某些输入取值很贵而节点很多时候根本用不到它们那就别每次都去取。做法是把某个输入声明成lazyTrue再实现一个check_lazy_status方法。节点要跑之前会先问它你到底需要哪些字段你返回一个真正要评估的字段名列表就行返回空列表那批懒字段对应的上游就压根不用算。图一大会能省掉不少白花花的计算。一次处理一批图还不用把显存撑爆图像进来通常是个带 batch 维的张量第一维就是图片数量。所以你写处理一张图的逻辑很多时候只要不破坏这个形状对一整批也照样成立——批量处理很多时候是免费的。真正要留神的是内存尤其是大图和视频帧。三个习惯能救你的显存重计算放进不记录梯度的上下文里跑别搭无用的计算图中间产生的大张量用完就del掉别一直攥在手里批次实在太大就分块循环处理而不是一把全读进内存。想接外部 AI 服务先看现成的 API 节点如果你的节点不是本地推理而是要去调远端服务图像生成、3D 建模、视频、语音合成这类完全不用从零造轮子。comfy_api_nodes/ 里已经铺了一整套现成的 API 节点看名字就知道哪个调的是哪家服务。它们的骨架高度一致照着抄就行API 密钥要安全地存、网络请求走异步免得把界面卡死、异常要有兜底和重试、进度要实时反馈回前端。你的execute可以写成async里面直接await那个网络调用结果拿到手再io.NodeOutput返回。发布与维护把节点变成别人能装的插件节点写完只是开始想让它变成别人拉下来就能用的插件还有几件小事要顾上前端自定义脚本如果定义了WEB_DIRECTORY这个目录里的.js会被前端自动加载适合做界面增强。自定义后端路由需要自己开接口时可以用PromptServer注册路由示例文件里就有现成的写法。版本与文档用语义化版本号管理改动配一份说人话的 README 和一两个示例工作流别人接手的门槛会低一大截。测试仓库里有 tests-unit/ 这类测试目录发布前跑一下相关用例睡得更踏实。写第一个节点最快的办法就是现在打开 custom_nodes/把那个示例文件复制一份、改个名。它跑起来的那一刻你就已经是 ComfyUI 的开发者了。【免费下载链接】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),仅供参考