1. 项目概述:当 ComfyUI 不再是“点一下出一张图”的玩具,而是一条能自动喂料、自动排程、自动质检的出图流水线
“我用 WorkBuddy 把本地 ComfyUI 管成了一条出图流水线”——这句话刚在几个AI绘图技术群刷出来时,我盯着看了三遍。不是因为WorkBuddy多神秘,而是因为“流水线”这个词太扎眼。ComfyUI 本身是节点式工作流,逻辑清晰、可复现性强,但默认状态下它更像一台需要全程盯梢的手动车床:你得手动加载模型、手动填提示词、手动调参数、手动保存结果、手动检查失败任务……一个批量出50张图的任务,光是反复点击“Queue Prompt”和切换标签页就能耗掉半小时,还容易漏掉某张图因CLIP编码器超时而静默失败。这种状态根本谈不上“管线”,顶多算“单点作业”。
WorkBuddy 的价值,恰恰就卡在这个“从单点到管线”的临界点上。它不是另一个UI壳子,也不是把ComfyUI打包成exe的懒人工具,而是一个运行在本地、深度嵌入ComfyUI后端服务生命周期的任务调度与状态中枢。它不碰你的节点图,不改你的模型路径,也不干涉你的采样器选择;它只做三件事:监听ComfyUI的API请求队列、解析任务元数据(比如提示词哈希、模型版本、种子值)、按预设规则触发后续动作。你可以把它理解成工厂里那个戴蓝帽子的班组长——他不管机床怎么切削,但清楚每张工单该走哪条产线、哪个环节超时了要报警、成品图是否达到尺寸公差(比如分辨率≥1024×1024且文件大小<8MB)。
这个项目解决的不是“能不能出图”的问题,而是“能不能让出图这件事,在你去泡咖啡的15分钟里,自己完成从接单、排产、加工、质检到入库的全过程”。适合三类人:一是每天要稳定产出30+张商用图稿的自由插画师,需要保证风格统一、命名规范、无遗漏交付;二是带学生做AI图像生成实验的某高校导师,得批量跑不同提示词组合对比效果,还要自动生成实验报告;三是正在搭建内部AI设计中台的某公司技术负责人,需要把ComfyUI接入现有Jira任务系统和NAS存储体系。他们共同的痛点不是算力不够,而是“人”成了整个流程里最不可靠的环节。
我实测过一组数据:用纯ComfyUI UI手动处理100个含LoRA微调的肖像生成任务(每个任务含3个变体),平均耗时47分钟,其中32%的时间花在重复操作上,2个任务因提示词含特殊字符导致前端崩溃而丢失。换成WorkBuddy接管后,同样100个任务通过CSV批量导入,总耗时19分钟,失败率归零,所有输出图自动按“人物_发型_表情_时间戳”规则重命名并存入指定文件夹。最关键的是——这19分钟里,我可以同时调试另一个ControlNet姿态控制工作流,完全不用分心。这才是“流水线”该有的样子:它不让你更快地点击鼠标,而是让你彻底忘记鼠标的存在。
2. 核心设计思路拆解:为什么选WorkBuddy而不是写Python脚本或改ComfyUI源码?
很多人第一反应是:“不就是批量提交API请求吗?我用requests写个for循环不就完了?”——这话没错,但错在把“能跑通”和“能管住”混为一谈。我试过三种主流方案,最终锁定WorkBuddy,不是因为它功能最多,而是它在稳定性、侵入性、扩展性三个维度上找到了最务实的平衡点。
2.1 方案对比:脚本派、魔改派、中间件派的硬伤
| 方案类型 | 典型做法 | 关键缺陷 | 我踩过的坑 |
|---|---|---|---|
| Python脚本派 | 用requests.post("http://127.0.0.1:8188/prompt", json=payload)循环提交 | 无法感知任务真实状态(如卡在VAE解码、显存OOM静默失败);重试逻辑复杂;无法与ComfyUI UI实时同步进度条 | 写了个监控脚本,结果某次显卡驱动更新后,ComfyUI返回HTTP 500但脚本误判为成功,导致57张图全被标记为“已完成”,实际全是黑图 |
| ComfyUI源码魔改派 | 直接修改server.py里的queue_prompt函数,插入日志和回调 | 每次ComfyUI官方更新都要重新打补丁;节点图编辑器UI与后端状态可能不一致;调试成本极高 | 改完发现WebUI里“中断当前任务”按钮失效,因为新加入的状态监听阻塞了主线程,最后回滚了三天工作 |
| WorkBuddy中间件派 | 作为独立进程,监听ComfyUI的/history和/queueAPI,解析JSON响应做决策 | 零代码侵入ComfyUI;状态感知精准(直接读取历史记录);支持热插拔规则引擎;天然兼容所有ComfyUI版本 | 初期配置错了一个WebSocket心跳间隔,导致连续7小时没收到任务完成通知,但排查起来只需看它自己的日志文件 |
WorkBuddy本质上是个“旁路监听器”。它不向ComfyUI发任何指令,只做两件事:定时GET/queue看当前排队数,定时GET/history查已完成任务详情。这种设计看似被动,实则极其稳健——ComfyUI哪怕崩了重启,WorkBuddy只要活着,就能从/history里捞出上次崩溃前已完成的任务,继续执行后续动作(比如自动上传到NAS)。这就像工厂的MES系统不控制机床开关,但能精确记录每台机床的启停时间、加工件号、良品率,这才是生产管理该有的姿态。
2.2 WorkBuddy的核心能力边界:它能做什么,不能做什么
必须划清这条线,否则你会陷入“以为它万能,结果摔得很惨”的陷阱。WorkBuddy 是任务流编排层,不是模型计算层,更不是UI交互层。它的能力象限非常清晰:
它能做的:
- ✅ 解析
/history返回的JSON,提取prompt_id、status、outputs、prompt原始字典(含所有节点参数) - ✅ 基于提示词内容(如检测到“cyberpunk”关键词)、模型名称(如
realisticVisionV60B1_v51VAE.safetensors)、种子值范围(如seed >= 1000000)等条件,触发不同动作 - ✅ 调用外部命令:
ffmpeg -i input.png -vf "scale=1024:1024" output.jpg、python post_process.py --input %INPUT_PATH%、curl -X POST https://my-nas/api/upload -F "file=@%OUTPUT_PATH%" - ✅ 生成结构化报告:CSV格式的执行日志(含开始时间、结束时间、耗时、输出路径、错误信息)
- ✅ 通过Webhook通知:任务完成时发消息到企业微信/钉钉机器人
- ✅ 解析
它坚决不做的:
- ❌ 修改ComfyUI的节点执行逻辑(比如强制给某个KSampler加
cfg_scale=7) - ❌ 替代ComfyUI UI进行图像预览(它没有Canvas渲染能力)
- ❌ 管理模型文件下载(不会帮你从Civitai拉模型)
- ❌ 处理GPU显存分配(不碰
--gpu-device参数)
- ❌ 修改ComfyUI的节点执行逻辑(比如强制给某个KSampler加
这个边界意识救了我两次。第一次是想让它自动清理临时缓存图,结果发现WorkBuddy根本没有文件系统写权限(它默认以只读模式运行),立刻转向用它调用一个有权限的shell脚本;第二次是想让它根据输出图质量动态调整重绘次数,但很快意识到“质量判断”需要CV模型,这已超出其定位,转而用它触发一个独立的PyTorch质检脚本。真正的高手,永远清楚工具的刀锋指向哪里,而不是拿菜刀去雕玉。
2.3 为什么WorkBuddy的规则引擎比YAML配置更贴近真实需求?
WorkBuddy用JSON写规则,这点常被吐槽“不如YAML优雅”。但实操下来,JSON的严格语法反而成了优势。举个真实案例:我要实现“当提示词含‘anime’且使用SDXL模型时,自动对输出图做二次放大,并存入/anime_upscaled文件夹”。用YAML写可能这样:
rules: - name: "anime upscale" condition: prompt_contains: "anime" model_name: "sdxl_1.0.safetensors" actions: - type: "run_command" command: "realesrgan -i {output_path} -o {output_path}_upscaled.png" - type: "move_file" src: "{output_path}_upscaled.png" dst: "/anime_upscaled/{filename}_upscaled.png"看起来很美,但问题来了:{output_path}这个变量到底指代什么?是ComfyUI原始输出路径?还是WorkBuddy临时中转路径?YAML解析器不会告诉你。而WorkBuddy的JSON规则强制你面对现实:
{ "name": "anime upscale", "condition": { "prompt_contains": ["anime"], "model_name": ["sdxl_1.0.safetensors"] }, "actions": [ { "type": "run_command", "command": "realesrgan -i {{output_path}} -o {{output_path}}_upscaled.png", "env": {"PATH": "/usr/local/bin:/opt/homebrew/bin"} }, { "type": "move_file", "src": "{{output_path}}_upscaled.png", "dst": "/anime_upscaled/{{filename}}_upscaled.png" } ] }注意{{output_path}}和{{filename}}这两个双大括号变量——它们不是WorkBuddy发明的,而是直接从ComfyUI/historyAPI返回的JSON字段里原样提取的。比如ComfyUI返回的history片段是:
{ "12345": { "prompt": { /* ... */ }, "outputs": { "9": { "images": [{ "filename": "ComfyUI_00012.png", "subfolder": "", "type": "output" }] } } } }WorkBuddy会自动把"filename": "ComfyUI_00012.png"映射为{{filename}},把完整路径/path/to/ComfyUI/output/ComfyUI_00012.png映射为{{output_path}}。这种“所见即所得”的变量绑定,让规则编写者永远知道自己在操作什么数据,而不是在猜解析器的脑回路。我见过太多YAML配置因缩进空格或引号缺失导致整条规则静默失效,而JSON的语法校验器(比如VS Code内置的)会在你保存时就报错:“Expected comma or '}'”。这对生产环境来说,不是优雅问题,是可靠性问题。
3. 核心细节解析与实操要点:从零部署WorkBuddy并打通ComfyUI流水线
WorkBuddy本身是Go语言写的单二进制文件,但让它真正“管起ComfyUI”,需要跨过三个隐形门槛:环境隔离、API权限对齐、状态同步精度。这三个点不搞定,后面所有规则都是空中楼阁。
3.1 环境准备:为什么必须用独立Python虚拟环境启动ComfyUI?
这是90%新手栽跟头的第一步。WorkBuddy需要稳定、可预测的ComfyUI API行为,而ComfyUI默认启动方式(直接python main.py)会受系统全局Python环境干扰。某次我帮一位设计师部署,他电脑上装了TensorFlow 2.15和PyTorch 2.0,结果ComfyUI启动后/historyAPI返回的JSON里,outputs字段总是空的——查了4小时才发现是torch.compile()在特定CUDA版本下触发了静默异常,导致节点输出未被序列化。
正确姿势是:为ComfyUI创建专属虚拟环境,并禁用所有可能冲突的优化特性。
# 创建干净环境(以macOS为例,Windows替换python3为python) python3 -m venv ~/comfyui_env source ~/comfyui_env/bin/activate pip install --upgrade pip # 安装ComfyUI依赖(务必指定版本!) pip install torch==2.1.0 torchvision==0.16.0 --index-url https://download.pytorch.org/whl/cu118 pip install xformers==0.0.23.post1 --force-reinstall --no-deps # 进入ComfyUI目录安装 cd /path/to/ComfyUI pip install -r requirements.txt关键参数:启动ComfyUI时必须加--disable-smart-memory和--cpu(如果测试阶段)或--gpu-device 0(生产阶段),并显式指定端口:
python main.py --listen 127.0.0.1 --port 8188 --disable-smart-memory提示:
--listen 127.0.0.1比--listen 0.0.0.0更安全,WorkBuddy和ComfyUI在同一台机器,无需暴露给局域网;--disable-smart-memory能避免某些显存管理bug导致/history记录不全。
验证是否成功:浏览器打开http://127.0.0.1:8188,上传一个最简工作流(比如仅含一个KSampler+SaveImage),点击“Queue Prompt”,然后立即访问http://127.0.0.1:8188/history。你应该看到类似这样的JSON:
{ "12345": { "prompt": { /* ... */ }, "status": {"status_str": "success", "completed": true}, "outputs": { "9": { "images": [{"filename": "ComfyUI_00012.png", "subfolder": "", "type": "output"}] } } } }如果outputs为空,或者status_str不是success,说明ComfyUI底层有问题,WorkBuddy再强也无能为力。此时请回退到虚拟环境步骤,检查pip list里是否有版本冲突包。
3.2 WorkBuddy配置核心:config.json里那5个决定生死的字段
WorkBuddy的config.json只有12个字段,但其中5个是“命门”,配错一个,整条流水线就瘫痪。我把它打印成便签贴在显示器边框上:
{ "comfyui_url": "http://127.0.0.1:8188", // 必须和ComfyUI启动端口完全一致,末尾不加'/' "poll_interval_ms": 2000, // 监听频率!太小(<1000)拖慢ComfyUI,太大(>5000)错过短任务 "history_limit": 100, // 只读最近100条历史,避免JSON解析超时 "rules_dir": "./rules", // 规则文件存放目录,必须是相对WorkBuddy二进制的路径 "log_level": "info" // 生产环境用"warn",调试时切"debug" }逐个解释为什么它们致命:
comfyui_url:看似简单,但新手常犯两个错。一是写成http://localhost:8188——某些系统localhost解析慢,导致WorkBuddy超时;二是末尾加了/,比如http://127.0.0.1:8188/,结果WorkBuddy拼接API地址变成http://127.0.0.1:8188//history,404。我的经验是:复制ComfyUI启动日志里显示的URL,一个字符别改。poll_interval_ms:这是WorkBuddy的心跳。设为2000(2秒)是黄金值。为什么?ComfyUI单个任务最短执行时间约800ms(纯CPU模式下的快速草图),最长可能120s(SDXL+Refiner+高清修复)。2秒轮询既能捕捉到短任务(2秒内完成→下次轮询立刻捕获),又不会对ComfyUI造成压力(每秒0.5次请求)。我试过设成500ms,结果ComfyUI的/queueAPI响应延迟从12ms飙到230ms,反拖慢出图速度。history_limit:ComfyUI的/historyAPI返回所有历史,包括几个月前的测试任务。一个跑了几千次的ComfyUI实例,/historyJSON可能超10MB。WorkBuddy默认只取最后100条,既保证能覆盖近期任务,又避免JSON解析内存溢出。如果你的流水线要求追溯30天内的所有任务,那就得自己写个脚本定期备份/history到SQLite。rules_dir:路径必须是WorkBuddy二进制所在目录的相对路径。比如你的WorkBuddy放在/opt/workbuddy/workbuddy,规则文件在/opt/workbuddy/rules/anime_rule.json,那么这里必须写"./rules"。绝对路径/opt/workbuddy/rules会报错,因为Go的os.ReadDir不认绝对路径字符串。log_level:调试时设"debug",你会看到每轮轮询的详细日志:DEBUG[0001] Polling /queue... queue_size=0 DEBUG[0002] Polling /history... found 3 new tasks DEBUG[0003] Applying rule 'anime upscale' to task 12345一旦上线,立刻切回
"warn",否则日志文件一天就能涨到2GB。
3.3 规则编写实战:从“自动重命名”到“智能质检”的三级跃迁
WorkBuddy的规则不是写一次就完事,而是随着业务复杂度升级,自然演进为三层能力。我按实际项目顺序展示这三级:
第一级:基础自动化(解决80%重复劳动)
目标:所有输出图按{主题}_{风格}_{时间戳}.png格式重命名,存入/final_output文件夹。
rules/basic_rename.json:
{ "name": "basic rename", "condition": { "always": true }, "actions": [ { "type": "run_command", "command": "mv {{output_path}} /final_output/{{prompt_hash}}_{{timestamp}}.png", "env": {"SHELL": "/bin/zsh"} } ] }关键技巧:{{prompt_hash}}是WorkBuddy内置变量,对提示词字符串做SHA256哈希取前8位,确保相同提示词生成的图名一致;{{timestamp}}是任务完成时的Unix毫秒时间戳。这里用mv而非cp,避免磁盘空间浪费——WorkBuddy默认把ComfyUI输出图当作“中间产物”,移动后原路径就空了。
注意:
/final_output文件夹必须提前创建,且WorkBuddy进程要有写权限。Mac用户特别注意:如果ComfyUI输出在~/ComfyUI/output,而WorkBuddy在/opt/workbuddy,两者用户组可能不同,用sudo chown -R $USER:staff /final_output统一权限。
第二级:条件分支(应对业务多样性)
目标:当提示词含“product shot”时,额外执行背景移除,并存入/product_clean;否则走基础重命名。
rules/product_shot.json:
{ "name": "product shot cleanup", "condition": { "prompt_contains": ["product shot"] }, "actions": [ { "type": "run_command", "command": "backgroundremover -i {{output_path}} -o /product_clean/{{filename}}_clean.png" } ] }这里的关键是规则优先级。WorkBuddy按文件名ASCII顺序加载规则(01_basic.json先于02_product.json),所以基础重命名规则必须命名为01_basic_rename.json,产品规则命名为02_product_shot.json。否则product_shot规则匹配后,basic_rename还会再执行一次,导致文件被移动两次而报错。
第三级:闭环质检(构建可信交付链)
目标:对所有输出图做三重校验——①分辨率≥1024×1024;②文件大小<10MB;③用OpenCV检测是否存在大面积纯黑/纯白区域(判定为VAE解码失败)。任一失败则发企业微信告警,并存入/failed_inspection。
rules/quality_control.json:
{ "name": "quality control", "condition": { "always": true }, "actions": [ { "type": "run_command", "command": "python3 /scripts/inspect_image.py --input {{output_path}} --output_dir /failed_inspection", "timeout_sec": 30 } ] }/scripts/inspect_image.py核心逻辑:
import cv2 import sys import os from pathlib import Path def check_quality(img_path): img = cv2.imread(img_path) if img is None: return False, "cv2.imread failed" h, w = img.shape[:2] if h < 1024 or w < 1024: return False, f"Resolution too small: {w}x{h}" if os.path.getsize(img_path) > 10 * 1024 * 1024: return False, "File size > 10MB" # 检测纯黑/纯白区域(VAE失败典型特征) gray = cv2.cvtColor(img, cv2.COLOR_BGR2GRAY) black_ratio = cv2.countNonZero(gray == 0) / gray.size white_ratio = cv2.countNonZero(gray == 255) / gray.size if black_ratio > 0.3 or white_ratio > 0.3: return False, f"Black/white ratio too high: {black_ratio:.2f}/{white_ratio:.2f}" return True, "OK" if __name__ == "__main__": input_path = sys.argv[1] output_dir = sys.argv[2] ok, msg = check_quality(input_path) if not ok: # 移动到失败目录并记录日志 Path(output_dir).mkdir(exist_ok=True) new_path = f"{output_dir}/{Path(input_path).name}" os.rename(input_path, new_path) print(f"FAILED: {input_path} -> {new_path} | Reason: {msg}") # 这里可以加企业微信Webhook调用 sys.exit(1)这个质检脚本的价值在于:它把“人工抽检”变成了“100%自动拦截”。我曾用它揪出ComfyUI一个隐藏bug——当启用--lowvram参数时,某些SDXL模型的VAE解码会在第17张图后开始随机输出纯黑图,而UI界面毫无报错。WorkBuddy+质检脚本在第17张图生成后立即移动到/failed_inspection并告警,让我在2小时内定位到问题根源。
4. 实操过程与核心环节实现:一条完整流水线的7个关键步骤
现在我们把所有碎片组装成一条可运行的流水线。这不是理论推演,而是我上周为某设计工作室部署的真实流程,每一步都附带终端命令和预期输出。全程在macOS Sonoma 14.5 + RTX 4090 + ComfyUI v0.9.17环境下实测。
4.1 步骤1:准备ComfyUI工作流与测试数据
目标:创建一个标准化的“产品图生成”工作流,包含固定节点结构,便于WorkBuddy稳定解析。
在ComfyUI中加载一个SDXL基础工作流,确保包含以下节点:
CheckpointLoaderSimple(加载sdxl_1.0.safetensors)CLIPTextEncode(正向提示词)CLIPTextEncode(负向提示词)KSampler(采样器设为dpmpp_2m_sde_gpu,steps=30)VAEDecode(必须存在,否则/history无outputs)SaveImage(保存路径设为output/,文件名留空)
导出为
product_workflow.json,内容需包含明确的节点ID(WorkBuddy靠ID识别输出):"9": { "class_type": "SaveImage", "inputs": { "filename_prefix": "ComfyUI", "images": ["10", 0] } }准备测试CSV(
batch_input.csv),含3列:prompt、negative_prompt、seed:prompt,negative_prompt,seed "a sleek wireless earbud on white marble background, product shot, studio lighting","text, watermark, blurry",123456 "a matte black smartwatch on brushed steel surface, product shot, soft shadows","deformed, low quality, jpeg artifacts",789012
4.2 步骤2:启动ComfyUI并验证API
# 激活虚拟环境 source ~/comfyui_env/bin/activate # 启动ComfyUI(后台运行,方便后续操作) nohup python main.py --listen 127.0.0.1 --port 8188 --disable-smart-memory > comfyui.log 2>&1 & # 检查是否启动成功 tail -n 20 comfyui.log | grep "Starting server" # 应输出:Starting server at http://127.0.0.1:8188 # 测试API curl -s http://127.0.0.1:8188/history | jq 'keys | length' # 应返回数字,如0(空历史)或大于0的数4.3 步骤3:部署WorkBuddy并配置
# 下载WorkBuddy(以macOS ARM64为例) curl -L https://github.com/workbuddy-org/workbuddy/releases/download/v0.3.2/workbuddy-darwin-arm64 -o workbuddy chmod +x workbuddy # 创建配置目录 mkdir -p ./config ./rules ./logs # 编写config.json cat > ./config/config.json << 'EOF' { "comfyui_url": "http://127.0.0.1:8188", "poll_interval_ms": 2000, "history_limit": 100, "rules_dir": "./rules", "log_level": "info" } EOF # 创建基础规则 mkdir ./rules cat > ./rules/01_basic.json << 'EOF' { "name": "basic move", "condition": {"always": true}, "actions": [ { "type": "run_command", "command": "mv {{output_path}} /tmp/final/{{prompt_hash}}_{{timestamp}}.png" } ] } EOF4.4 步骤4:编写批量提交脚本(绕过UI的手动点击)
WorkBuddy不负责提交任务,所以需要一个轻量脚本把CSV转成ComfyUI API请求:
submit_batch.py:
import csv import json import requests import time # 读取工作流模板 with open('product_workflow.json', 'r') as f: workflow = json.load(f) # 读取CSV with open('batch_input.csv', 'r') as f: reader = csv.DictReader(f) for i, row in enumerate(reader): # 注入提示词和种子 workflow["6"]["inputs"]["text"] = row["prompt"] # 正向CLIP节点ID workflow["7"]["inputs"]["text"] = row["negative_prompt"] # 负向CLIP节点ID workflow["3"]["inputs"]["seed"] = int(row["seed"]) # KSampler节点ID # 提交API payload = {"prompt": workflow} r = requests.post("http://127.0.0.1:8188/prompt", json=payload) print(f"Task {i+1}: {r.status_code} - {row['prompt'][:30]}...") # 防抖:避免请求过密 time.sleep(0.5)运行:
python submit_batch.py # 输出应类似: # Task 1: 200 - a sleek wireless earbud on white... # Task 2: 200 - a matte black smartwatch on bru...4.5 步骤5:启动WorkBuddy并观察日志
# 启动WorkBuddy(指定配置文件) ./workbuddy --config ./config/config.json --log-file ./logs/workbuddy.log # 实时查看日志 tail -f ./logs/workbuddy.log # 正常启动日志: # INFO[0000] WorkBuddy started with config: &{ComfyUIURL:http://127.0.0.1:8188 ...} # INFO[0002] Found 2 new tasks in history # INFO[0002] Applying rule 'basic move' to task 123454.6 步骤6:验证流水线输出
等待约1分钟(取决于任务复杂度),检查输出:
ls -la /tmp/final/ # 应看到类似: # -rw-r--r-- 1 user staff 4212345 5 20 14:22 8a3f1b2c_1716214942123.png # -rw-r--r-- 1 user staff 3890123 5 20 14:23 5d7e9a4f_1716214943456.png # 检查文件头确认是PNG file /tmp/final/*.png # 输出:PNG image data, 1024 x 1024, 8-bit/color RGB, non-interlaced4.7 步骤7:添加企业微信告警(生产环境必备)
在rules/02_alert.json中加入Webhook动作:
{ "name": "wechat alert", "condition": {"always": true}, "actions": [ { "type": "webhook", "url": "https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=YOUR_WEBHOOK_KEY", "method": "POST", "headers": {"Content-Type": "application/json"}, "body": { "msgtype": "text", "text": { "content": "✅ WorkBuddy流水线完成!\n• 任务ID: {{prompt_id}}\n• 提示词: {{prompt_text}}\n• 输出: {{output_path}}\n• 耗时: {{duration_ms}}ms" } } } ] }注意:
{{prompt_text}}和{{duration_ms}}是WorkBuddy高级变量,需在config.json中开启"enable_advanced_vars": true。企业微信Webhook key需在管理后台创建,测试时先用curl手动发一条验证格式。
这条流水线跑通后,我做了压力测试:连续提交500个任务(用submit_batch.py),WorkBuddy稳定运行47分钟,无内存泄漏,日志文件增长12MB,所有输出图命名规范、路径正确、无遗漏。最关键是——我不用守在电脑前,它自己完成了从“接单”到“交付”的全部动作。
5. 常见问题与排查技巧实录:那些文档里不会写的血泪教训
WorkBuddy的文档很简洁,但真实世界远比文档复杂。我把过去三个月在多个项目中遇到的典型问题整理成速查表,每一条都附带“为什么发生”和“怎么秒解”,全是掏心窝的经验。
5.1 问题速查表:高频故障与根因分析
| 现象 | 根本原因 | 秒解方案 | 我的实测耗时 |
|---|---|---|---|
| WorkBuddy日志显示“Found 0 new tasks”,但ComfyUI UI里明明有完成任务 | ComfyUI的/historyAPI返回空JSON,常见于--lowvram模式或VAE解码失败 | 1. 检查ComfyUI日志:grep -i "error|exception" comfyui.log2. 临时关闭 --lowvram重试3. 在 SaveImage节点前加PreviewImage节点强制刷新输出缓冲 | 3分钟(查日志)+ 2分钟(重启) |
规则执行后,mv命令报“Permission denied” | WorkBuddy进程用户与目标文件夹用户不一致(如ComfyUI用sudo启动,WorkBuddy用普通用户) | 运行ls -ld /target/folder查看权限,执行sudo chown -R $USER:staff /target/folder统一归属 | 1分钟(查权限)+ 10秒(chown) |
{{prompt_hash}}变量在日志里显示为空字符串 | WorkBuddy无法从/historyJSON中提取prompt字段,通常因工作流里CLIP节点 |