ComfyUI RollingArtist
两个 ComfyUI 节点,从 CSV 随机抽人生成提示文本:
- RollingArtist(滚动艺术家):抽艺术家 + 分配随机权重
- RollingCharacter(滚动角色):抽角色(不带权重),带作品标签与角色描述(源数据列
core_tags),支持按作品筛选
两者共用抽样、去重与记录机制:4 种去重模式下「判重 → 生成 → 记录」在同一 SQLite 事务内,多线程与多开 ComfyUI 都不重复出图。中英文界面自动切换。
安装
cd ComfyUI/custom_nodes
git clone https://github.com/StarAsh042/ComfyUI_RollingArtist.git
仓库自带 danbooru_art_001.csv(artist,trigger,count)与 danbooru_character_001.csv(character,copyright,trigger,core_tags,count),克隆即用。换数据见数据预处理。
ra_core/、locales/、web/docs/ 由 ComfyUI 按目录约定自动加载;后两者缺失只影响文案。节点名、参数名与 tooltip 跟随 Comfy.Locale(文案在 locales/zh/、locales/en/),「信息」面板取 web/docs/RollingArtist/<语言>.md,缺失时回退 web/docs/RollingArtist.md。新增语言:复制 locales/en/ 为 locales/<语言代码>/ 并翻译 nodeDefs.json,帮助页同理。
danbooru_art_full.csv / danbooru_character.csv(加工脚本的输入)用 Git LFS 存储,节点运行不需要它们——只有重跑加工脚本才需 git lfs install + git lfs pull。
RollingArtist(画师)
下列顺序即界面顺序;advanced 参数折叠在“高级输入”中。
| 参数 | 类型 | 范围 | 说明 |
|---|---|---|---|
artist_count |
INT | 1-10 | 生成人数(默认 3) |
artist_top_ratio |
FLOAT | 0.01-1.0 | Top 池占前百分比(默认 0.01) |
artist_top_count |
INT | 1-10 | 输出中的 Top 人数(默认 1) |
weight_min / weight_max |
FLOAT | 0.1-2.0 | 单个权重的最小 / 最大值 |
weight_total |
FLOAT | 0.0-20.0 | 权重总和(默认 2.0) |
weight_curve |
ENUM | flat / dominant / ramp | 分配曲线(默认 flat) |
artists_prefix |
BOOLEAN | - | 添加 artist: 前缀 |
seed |
INT | 0-4294967295 | 随机种子 |
可选参数
use_top_priority(默认开):启用 Top 优先池;关闭后从完整 CSV 均匀抽取sort_by_weight(默认开):按权重降序排序exclude_artists/force_include:逗号分隔的名单;force_include必定出现,优先级高于排除名单dedup_mode(默认none):none不去重(仍记录);full_prompt顺序与权重全同才算重复;artist_set只看集合;artist_list比较排序后名字。完整对比见web/docs/RollingArtist/zh.mdmax_attempts(1-100,默认 10):重试上限;仍全命中时接受最后一次并打 WARNINGcustom_csv_path/tested_db_path:留空用默认 CSV /rollingartist.sqlite;换数据库路径等于重置去重进度
固定读 trigger 列(已转义,如 hammer_\(sunset_beach\))。没有该列时回退首列并记 WARNING;若输出里出现数字或网址(把 count、url 当成了人名),就是这种情况。
RollingCharacter(角色)
从 danbooru_character_001.csv 抽取,按 角色标签,作品标签,角色描述 逐行输出(多角色间用「逗号+换行」分隔),不带权重。读取列固定 trigger,经 34,416 行全量校验是恒定两段:第 1 段 = 转义后的 character(角色名),第 2 段 = 转义后的 copyright(作品标签)。
hakurei_reimu,touhou,1girl,brown eyes,long hair,
ganyu_\(genshin_impact\),genshin_impact,1girl,horns
关闭「开启角色描述」后为 hakurei_reimu,touhou。空的部分自动省略;角色描述(core_tags)行内去重;多角色行尾补逗号(最后一行不补),顺序即抽样顺序。
| 参数 | 类型 / 范围 | 说明 |
|---|---|---|
character_count |
INT 1-10 | 每次生成数(默认 1),每个角色一行 |
character_top_ratio |
FLOAT 0.01-1.0 | 候选数 = 作品筛选之后的角色数 |
character_top_count |
INT 1-10 | 每次至少抽几个人气池角色 |
seed |
INT | 随机种子 |
use_top_priority |
BOOLEAN | 优先从人气池抽 |
exclude_characters / force_include |
STRING | 名单;强制包含允许写不在 CSV 里的名字 |
copyright_pick |
COMBO | 列出全部作品(默认约 3,460 个,按 count 总和降序、并列按名字升序),首项 (不限);可打字筛选、忽略大小写 |
describe_character |
BOOLEAN | 每行末尾拼上角色描述;默认开启 |
custom_csv_path / tested_db_path |
STRING | 留空用 danbooru_character_001.csv / rollingcharacter.sqlite(与画师分开) |
角色节点不做权重分配(故无 weight_* / sort_by_weight);输出不接受前缀包装(没有画师那样的 artists_prefix 开关);没有去重模式参数,改用固定规则的窗口。
重复回避:窗口存最近 10 条输出记录(每条 = 一次生成,可含多个角色),抽取前把窗口内角色名从候选排除,因此 character_count=3 相当于「最近 30 个角色内不重复」。窗口在节点实例内存里(重启清零);外部脚本可用 node.reset_recent() 清空、node.recent_names() 查看。窗口吃掉全部候选时退回「允许重复」并打 WARNING。
输出三个:prompt、characters_json([{"name","copyright","top","count","core_tags"}])、tested_count。
注意:约 22% 的角色没有描述,这些行只有角色标签与作品标签,角色多时输出会明显变长。角色名唯一(34,416 行无重名)。记录带 kind=character 标记、权重列按 1.0 占位,与画师共用数据库也不会互相冒充。
记录与去重(SQLite)
单个 SQLite 文件(WAL 模式)存已测记录;判重键写入时算好并建索引,判重是索引查询,历史再大也不占内存。「判重 → 生成 → 记录」整段在同一 BEGIN IMMEDIATE 事务:同进程靠可重入锁,多进程靠 SQLite 文件锁。艺术家名与权重以 JSON 存列,名字含 |、:、逗号都不破坏解析。
记录不自动裁剪;默认路径的数据库每次启动会被清理(prestartup_script.py 删 rollingartist.sqlite / rollingcharacter.sqlite 及 -wal / -shm)。想跨会话保留,把 tested_db_path 指到自己的文件——只清理默认路径。
数据安全与路径防护
custom_csv_path / tested_db_path 不再原样透传:命中受保护目标时直接拒绝并抛出 PathNotAllowedError。
- 拦截:系统关键目录(Windows 的
Windows/Program Files/ProgramData,Linux/macOS 的/etc/usr/bin/sbin/lib/boot/proc/sys/dev)、凭据目录(~/.ssh~/.aws~/.gnupg~/.kube~/.docker)、ComfyUI 自身代码(comfy、.git、custom_nodes,本节点目录下的数据文件除外)、本节点目录内的源码文件 - 数据库写入额外校验:目标已存在且不是 SQLite 文件时拒绝覆写
- 规范化:先剥离 Windows 扩展长度 / 设备前缀(
\\?\、\\.\)与备用数据流后缀(data.csv:evil按data.csv判定);本机管理共享(\\localhost\C$\Windows)还原为盘符路径再比较;指向其它主机的共享一律拒绝
已知限制:这是纵深防御,不是沙箱,不能替代访问控制——暴露到公网且无鉴权时仍可读取未列入名单的普通文件;不解决 TOCTOU;盘符黑名单只覆盖本机盘符。若 ComfyUI 对局域网或公网开放,请加访问控制。
逃生开关:单机自用可设 ROLLINGARTIST_ALLOW_ANY_PATH=1 完全关闭防护——仅在确认环境可信时使用。同一记录数据库不要被多个实例共用同一个网络盘(WAL 要求本地文件系统)。
使用示例
添加 RollingArtist 节点 → 连接文本编码器 → 调整参数。Prompt 输出形如:
artist:Jane_Smith,(artist:John_Doe:0.8),(artist:FooBar:0.2),
权重为 1.0 时直接输出 artist:名称(无括号与权重);末尾总是带逗号,方便拼接角色节点的多行输出。同时输出 artists_json(各项 name / weight / top,status 恒为 OK)与 tested_count。
调参与注意事项
- 权重以 0.1 为整数单位运算,因此任一权重严格落在
[weight_min, weight_max]内,总和精确等于weight_total artist_count用 3-5 更容易聚焦风格;想要「一个主风格 + 若干弱参考」把weight_curve设为dominantartist_top_ratio是相对比例:默认数据 50,018 人配 0.01 约等于 500 人 Top 池,数据更大时调小- 降级必有信号:可用艺术家不足、重试耗尽、记录写入失败均输出 WARNING / ERROR,不静默返回空提示词
数据预处理
两个脚本把 danbooru 导出裁成节点可读的精简 CSV,共用 danbooru_csv_tool.py 的筛选 / 转义 / 备份 / 原子写回:
| 脚本 | 默认输入(行数) | 默认输出(行数) | 输出列 |
|---|---|---|---|
modify_danbooru_art.py |
danbooru_art_full.csv(419,789) |
danbooru_art_001.csv(50,018) |
artist,trigger,count |
modify_danbooru_character.py |
danbooru_character.csv(244,932) |
danbooru_character_001.csv(34,416) |
character,copyright,trigger,core_tags,count |
python modify_danbooru_art.py # 默认:count >= 30,只转义 trigger 列
python modify_danbooru_art.py -n 100 # 换成 count >= 100
规则(两脚本一致):只保留 count ≥ 阈值(默认 30)并按 count 降序;只输出上表列;只转义 trigger 列(按逗号分段,段内空白 / 短横线折叠为下划线、丢弃空段、补转义括号),其余列原样;写回前备份为 <输出名>.bak,写回用临时文件 + 原子替换。
- 角色文件的
character列没有转义(只处理 trigger),带括号的仍有 16,380 条(如ganyu_(genshin_impact));这些括号进提示词会被权重解析器当分组语法吃掉,需精确匹配请自行加工该列 trigger段内连字符会变成下划线(itomugi-kun→itomugi_kun),想保留原始连字符改danbooru_csv_tool.transform_text一处
测试
pip install -e ".[dev]"
pytest
测试不需要 ComfyUI:ra_core/ 是纯逻辑,节点文件只 import 标准库与 ra_core,可直接实例化。覆盖纯逻辑、两个节点的接口与行为(含回避窗口)、加工脚本与跨进程去重。
变更记录
见 CHANGELOG.md。
许可证
基于 MIT License 发布,Copyright (c) 2026 StarAsh042。可自由使用、修改、分发与商用,仅需保留版权声明与许可声明。