M8 Nodes
M8 节点包:按货架分类的 ComfyUI 自定义节点 —— 大模型推理(远程 / 本地)、skill 装载、相机机位、多角色提示词,另带一个独立网页工作台
ComfyUI-M8nodes
English | 中文
按货架分类的 ComfyUI 自定义节点包。
三个货架、五个节点,外加一个独立网页工作台:
| 货架 | 节点 | 做什么 |
| --- | --- | --- |
| 大模型 | M8LLMInference | 靠 API 调外部大模型做提示词 / 文本处理 |
| 大模型 | M8SkillLoader | 把文本文件变成知识包,喂给推理节点 |
| 大模型 | M8LLMLocal | 本地跑 GGUF,不联网;配 mmproj 就能识图 |
| 相机 | M8CameraControl | 把「相机在哪、朝哪、拍多近」翻译成提示词 |
| 提示词 | M8MultiCharacter | 多角色分块与区域权重 |
除本地推理节点外,零第三方依赖。后端只用 Python 标准库和 ComfyUI 自带的东西,装完不用 pip 装任何包。
M8LLMLocal要跑起来得另外装llama-cpp-python—— 那是它自己的事,不装不影响别的节点,它会自己报一句缺什么。
M8 工作台(网页)
插件自带一个独立网页。它和节点是两条线:节点管工作流,网页管那些不适合塞进节点的工具。
界面的视觉取自参考站 azusa.nyacraft.cn —— 色值、布局、动效都照着它的 CSS 实现,
逐项对照见 docs/M8WEB-DESIGN.md;功能是本插件自己的。
两个门都能进,看到的是同一份数据:
| 怎么进 | 什么时候用 |
| --- | --- |
| ComfyUI 顶栏的 M8 按钮 | ComfyUI 开着的时候,顺手进去 |
| 双击 M8web/start-workbench.bat(或者它的桌面快捷方式) | ComfyUI 不用开也能用 |
第二个门是独立的小服务(M8web/m8-serve.py,只用 Python 标准库)。它和 ComfyUI
读写的是同一份文件,所以两边看到的内容始终一致。
数据存在哪:<ComfyUI>/models/M8data/webapp/*.json
- 不在插件目录里 —— 插件更新、ComfyUI 重装都不会带走它
- 不在浏览器里 —— 换浏览器、换机器、清缓存都不影响
- 就是几个普通 json 文件,备份直接复制文件夹
- 想换个地方就设环境变量
M8_DATA_DIR - 装到别人机器上时,路径由 ComfyUI 自己的
folder_paths算出来,所以装在哪个盘都对
从旧版本升上来的话:第一次打开会在顶上出现一条横幅问你要不要搬旧数据 (以前存在浏览器里的那些),点一下就行,搬完横幅就没了。
四套主题,右上角切换,选择会记住:
| 主题 | 样子 | | --- | --- | | 白天 | 干净的白底 | | 黑夜 | 深色,默认 | | 樱花粉 | 粉色调 + 飘落的粉色花瓣 | | 海蓝 | 蓝色调 + 缓缓起伏的水波 |
动效是纯 CSS,不引第三方库;系统开了「减少动态效果」时会自动停掉。
布局:左侧是返回首页 + 功能列表(一条条列表,不是宫格),右侧是功能区。 首页是 3 列的圆角卡片,行数随功能增加而变多。
功能:
| 功能 | 干什么 | | --- | --- | | 图片工坊 | 分段裁剪 / 分段遮挡 / 贴纸遮挡(带抠图和贴纸库)/ 宫格拼图(最多 25 张)/ 文字与画笔 | | OC 工坊 | 每个原创角色一条:例图和特征词存在一起,随时一键复制去出图 | | 提示词归纳 | 一张卡一条概念提示词(构图、光影、画风这种),配一张效果例图,归到分类里存着 | | 图片元数据 | 拖一张图进来,读出生成参数、工作流和 EXIF | | LoRA 解析 | 拖一个 safetensors 进来,读出训练参数和训练标签 | | 混淆图 | 三种打法:小番茄(默认,无密钥)/ 置乱(带密钥)/ 嵌套(藏另一张图),都能原样解回去 | | 像素风转化 | 用卷积把图压成像素画:抗锯齿、面积平均、锐化、减色抖动、最近邻放大 |
图片工坊和图片元数据全部在本机处理,图片不会上传。 LoRA 解析只读文件开头那一段 header(几 KB 到几百 KB),张量数据一个字节都不读, 几百 MB 的模型也是一瞬间 —— 文件不上传、不落盘,读完就把引用清掉。 混淆图两种模式都是可逆的纯本地运算:置乱是像素置换,嵌套改的是每个像素的最低位, 解回来逐像素一致。混淆出来的图要存成 PNG,转 JPEG 会压掉低位,那就解不回来了。
OC 工坊、提示词归纳、贴纸库这三处的内容存在浏览器里(IndexedDB)。
更新插件不会动它们,但换成 localhost 打开、清浏览器数据、换台机器就看不见了 ——
所以每一处都有「导出备份 / 导入备份」,导出的 json 里连例图一起带着,出事灌回去就行。
首页上有个「创建桌面快捷方式」—— 浏览器自己建不了(网页没有文件系统权限),
所以由后端代劳,往桌面写一个很小的 .bat:双击它会先把本地服务拉起来,再开浏览器,
所以 ComfyUI 关着也能用。
写的是纯文本脚本,不是 .lnk —— Windows 的二进制快捷方式只能借 PowerShell 生成,
而这里是网页请求触发的。让一个网络请求在本机创建进程是安全红线(审核也是这么要求的),
所以宁可按功能换安全。代价是图标用系统默认的,换不成插件那张。
网页源码在 M8web/,以后新功能加在 M8web/pages/ 下,
并在 M8web/assets/js/app.js 的 FEATURES 里登记一条 —— 首页卡片和左侧菜单会同时出现。
节点
M8 · 大模型推理
靠 API 调外部大模型。默认指向 DeepSeek,base_url 填别的就能换成任何 OpenAI 兼容端点(OpenAI / OpenRouter / 硅基流动 / Ollama / 自建中转都行)。
- 两个提示词框:系统提示词(定人格和输出格式)+ 对话提示词(这次要问的事)
- 模型下拉:填好地址和密钥后点「刷新模型」,从接口拉回模型列表自动填进下拉;也可以手动输入模型名
- 思考强度:关 / 低 / 中 / 高。供应商不支持该参数时会自动去掉重试一次,不会因此整个跑不起来
- 思考内容:可显示在节点面板上(只读框,点按钮展开/收起)
/引用 skill:在对话提示词框里打一个/,弹出已上传的 skill 列表;继续输入会收缩范围,和输入重合的部分高亮;上下键选、回车确认、Esc 取消。选中后写进框里的是/名字,后端认得这个写法,会把那份 skill 一起带上- skill 自动模式:
skill_auto默认关。打开后服务端已上传的 skill 会被一起注入,由模型自己判断该用哪个。默认关是因为库里内容一多,每轮都会带上几份用不上的,白烧 token —— 要哪份在提示词里打/引用更准。份数和长度上限在设置里可调 - 输入:skill(知识包)、图片、音频。图片和音频是给多模态模型用的,不接就是纯文本对话
- 输出:只有一栏文本
温度、最大长度、超时都能调;还有一个 extra_params 可以手填 JSON 传那些本插件没覆盖的供应商专有参数。
M8 · 相机控制
把「相机在哪、朝哪、拍多近」翻译成能直接进正向提示词的文字。
节点上是一块三维球面视图:中间是主体,相机绕着它转,轨道上标着前/后/左/右。
左键拖画布转视角、滚轮调远近、Shift+滚轮调翻滚,四个滑块和视图双向同步。
下方实时显示这段机位会输出什么提示词。
(from front:10.00), (eye-level:3.00), (medium shot:1.00),
机位配置可以存成多份(「保存」按钮 / 右侧下拉「加载配置」),
存在 m8/data/camera-configs/,一个配置一个 json 文件。
M8 · Skill 装载
把一个 skill 包装成可以连线的知识包,喂给大模型推理节点。
skill 是目录,不是单个文件:
m8/data/skills/
└── aigc-prompt/
├── SKILL.md 主文件,必需
└── references/ 资源,可选(会被一起带上)
这样带参考资料的 skill 才能真正用起来 ——「照着 references/style.md 里的风格写」 之所以有意义,是因为那个文件的内容在请求发出前就被内联进正文了。 单文件上限 64 KB、整包 256 KB;超出的不内联,但会在末尾列出清单, 让模型知道自己缺什么,不至于编一个「我已按参考文件写」的答案。
- 点「上传 Skill」传一个 md 文件(自动包成目录式,主文件叫
SKILL.md) - 点「上传整个包」选一个目录,连带
references/scripts/一起搬过来 - 下拉选一个,接给推理节点的 skill 输入
- 点「资源清单」看这个包带了哪些附属文件、本次会内联几个(走通知,不占节点的地方)
- 一个 skill 可以同时喂给多个推理节点,改一次全都变
M8 · 多角色编辑
把多个角色的提示词分块组装成一段提示词,每个角色带自己的画面区域。
每个角色一张卡片(提示词 / 位置 / 混合权重 / 羽化),上面一块画布把各角色的区域 画成可拖拽的框 —— 位置这种事,拖比填四个数字快得多。
- 在画布空白处拖一下就能画出一个角色,松手即成,卡片自动多一张
- 画布按
width/height输入的比例显示,改尺寸框的相对位置不变(存的是百分比) - 框和卡片是一一对应的,不存在「有角色没框」的状态
- 每张卡片上直接标出这个角色会生成的那段语法,不用去预览框里找
- 语义体检:区域重叠、多处 FILL、羽化相对画面过大这类「语法没错但画面会不对」的问题会列在预览下面
- 预设:整套角色配置可以存成多份,存在
m8/data/prompt-presets/,一个预设一个 json - 反向解析:从别处抄来的一段区域提示词,粘进去就能拆回角色块接着改
三种输出格式,按下游用什么选。默认是 Regional Prompts(换成别的在工具栏上切就行):
| 格式 | 输出 | 配什么用 |
| --- | --- | --- |
| Attention Couple | COUPLE(x1 x2, y1 y2, weight) prompt | comfyui-prompt-control |
| Regional Prompts | prompt MASK(...) 用 AND 相连 | comfyui-prompt-control |
| 纯文本 | 逗号分隔的提示词 | 任何节点,不依赖第三方 |
fantasy forest COUPLE(0.00 0.25, 0.00 1.00, 1.00) elf archer COUPLE(0.25 0.50, 0.00 1.00, 1.00) dwarf warrior
安装
手动安装
cd ComfyUI/custom_nodes
git clone https://github.com/chenr5934-tech/ComfyUI-M8nodes.git
重启 ComfyUI 即可。不需要 pip 安装任何依赖。
节点会出现在右键菜单的 M8/ 下面,按货架分成三组:大模型、相机、提示词。
更新
cd ComfyUI/custom_nodes/ComfyUI-M8nodes
git pull
配置 API Key
密钥有两种给法:
推荐:存在服务端。 在节点上填入密钥,点「保存密钥到服务端」。密钥存进 m8/data/credentials.json,输入框会被自动清空。这样工作流文件里不会带明文,分享出去不会泄漏。以后这个节点留空就会自动用服务端那份。
临时用:直接填在节点上。 只对当前节点生效,并且会写进工作流文件。给别人传工作流时会一起传出去。
m8/data/ 不会被提交到仓库(在 .gitignore 里)。
常见问题
节点上点「刷新模型」没反应 / 报错?
多半是地址或密钥的问题。节点上会把错误显示成一条带错误码的通知,形如 M8-LLM-004,拿这个码去 docs/ERROR-PLAYBOOK.md 查表,里面有原因和修法。
模型不支持图片 / 音频输入?
接口会返回 400,报错里会说清。断开那两个输入,或者换成多模态模型。
想把密钥留在自己机器上、不写进工作流?
用「保存密钥到服务端」,别直接填在节点上。
打了 / 没弹出列表?
服务端还没有 skill。先用 M8 · Skill 装载 节点的「上传 Skill」传一个进去。下拉显示的是服务端的列表(存在 m8/data/skills/),不是本地某个文件夹。
写了 /名字 但好像没生效?
后端只在能唯一对上的时候才注入。对不上或对上多个候选,就一个都不带(猜错会把错的资料塞给模型,比不带糟得多)。把名字写全一点即可。另外 URL、盘符路径、3/4 这类斜杠不会被当成引用。
用的是别的服务商,提示词格式不一样?
provider 选「自定义」,base_url 填对方的地址。对方有专有参数就用 extra_params 手填 JSON。
更多排查手段见 docs/ERROR-PLAYBOOK.md(里面有装好之后的四步自检)。
小鲸鱼(界面扩展)
侧边栏的「小鲸鱼」入口 + 右下角常驻挂件。
挂件形象与整体设计移植自 MeteorNOX/DeepSeek-Balance-Whale-Widget,
MIT 协议,版权归原作者所有,原许可证副本见 js/ui/whale/assets/LICENSE.txt。
这一版按「核心优先」只搬了余额 + 对话这条主线,音效、随机台词、四边吸附、
今日已用记账、每轮消耗统计都没有移植。
- 挂件:白底深蓝描边的思考气泡,显示余额和今日已用。左键刷新、右键呼出对话、拖动换位置(位置会记住)
- 对话窗口:非模态,开着照样能操作画布。标题栏拖动、右下角缩放,尺寸和位置都记住。输入框打
/能引用 skill。对话记录存在服务端(m8/data/whale-history.json),关掉再开还在 - 快捷选项:输入框上方三个按钮 —— 跑一张图(它自己写提示词、填进画布、提交排队)、选 LoRA(挑几个并说明理由)、查报错(翻失败记录并给修法)
- 它能操作画布:读队列、改节点参数、提交排队、中断任务、清空队列。工具在前端执行,每一步都留痕在对话里
- 带图对话:对话框左下角的 + 能贴图给多模态模型(data URL 直传,不落盘)
- 用量与消耗:挂件显示余额;「今日已用」按余额差值记账;每轮对话后报本次消耗金额(按 DeepSeek 的峰谷价换算)
- 快捷菜单:鼠标滑到鲸鱼身上,右侧出现汉堡按钮;点开是常用项(大小 / 音效 / 音量 / 用量 / 峰谷 / 气泡 / 每轮消耗 / 避让滚动条),位置和说话方式都照原版
- 设置面板(侧边栏里):挂件开关与大小、音效与音量、气泡开关、避让滚动条、API Key、模型列表、系统提示词、思考强度、温度 / 长度 / 超时、余额刷新间隔、用量重置、每轮消耗提示
密钥只存在服务端,浏览器拿到的永远只是掩码。
它是怎么组织的
节点按在工作流里干的活分成货架,一个货架一个目录、一段错误码:
| 货架 | 目录 | 错误码段 |
| --- | --- | --- |
| 地基 | m8/core/ | M8-CORE-### |
| 接口 | m8/server/ | M8-SRV-### |
| 大模型 | m8/nodes/llm/ | M8-LLM-### |
| 加载器 | m8/nodes/loaders/ | M8-LOAD-### |
| 采样 | m8/nodes/samplers/ | M8-SAMP-### |
| 判断 | m8/nodes/logic/ | M8-LOGIC-### |
| 图像 | m8/nodes/image/ | M8-IMG-### |
| 文本 | m8/nodes/text/ | M8-TXT-### |
目录是两层的:一个货架一个文件夹,货架里一个功能一个文件夹。
m8/nodes/llm/ 货架:大模型
├── __init__.py 货架收集器(不含节点代码)
├── llm_inference/ 功能:一个节点一个文件夹
│ ├── __init__.py
│ └── node.py
└── skill_loader/
├── __init__.py
└── node.py
js/nodes/llm/llm_inference.js 前端:文件名和功能文件夹逐字一致
js/nodes/llm/skill_loader.js
这么分只有一个目的:改一个功能只翻一个文件夹。往货架根目录丢一个散落的 .py、
或者让功能包的注册表里混进别人的节点,都会被测试拦下来。
每个失败路径都带一个错误码,报错长这样:
[M8-LLM-004] 接口返回 401
修复:API Key 不对或没权限。检查密钥,或确认它属于这个 base_url 对应的服务商
详情:{"error":{"message":"Authentication Fails"}}
抓这个码去 docs/ERROR-PLAYBOOK.md 就能直接定位到文件和函数。
开发
| 文件 | 内容 | | --- | --- | | AGENTS.md | 作业规程:环境、货架地图、加节点的固定流程、验证标准 | | docs/ROADMAP.md | 货架规划与节点清单 | | docs/ARCHITECTURE.md | 前后端分工、路由表、数据存放、视觉语言 | | docs/CONVENTIONS.md | 代码规范 | | docs/TESTING.md | 测试分工与实机自检清单 | | docs/ERROR-PLAYBOOK.md | 报错查表 | | docs/RELEASING.md | 发布流程 |
静态验证(可脱离 ComfyUI 运行,不联网):
python tests/smoke_import.py
许可
第三方素材:小鲸鱼的挂件形象与整体设计移植自
MeteorNOX/DeepSeek-Balance-Whale-Widget(MIT,版权归原作者,
原许可证副本见 js/ui/whale/assets/LICENSE.txt);M8 工作台的界面视觉取自参考站 azusa.nyacraft.cn。