fix(posts): consultant final review — release ready (v1.2)
Deploy / build (push) Successful in 29s

02 comfyui (EN+ZH)
- unify the asset numbers end to end: 108 cover pairs = 216 banner+OG
  assets. The intro, the frontmatter metric, the description and the
  `ws.close()` comment all still carried the old "89", which contradicted
  the 216/25.9-min figure in the result section (consultant finding).
- state the timing scope explicitly: end-to-end per slug, diffusion plus
  the Pillow clearance audit and the two-size WebP encode.
- disclose the limit of the mtime evidence: mtime keeps only the last
  write, so gate-rejected re-queues from an earlier pass do not lengthen
  the measured window.

01 payments (EN+ZH)
- the idempotency comment now names the 72h bank reconciliation window,
  which is the boundary that makes EXPIRED a legitimate fulfilment entry
  point (line count unchanged at 27).
This commit is contained in:
hoelee committed 2026-10-29 14:29:03 +08:00
1 parent bfcf61c7ea
commit 403d4c0d9f
4 files changed
+16 -16

No files matched your search

@@ -106,7 +106,7 @@ public function callback(): ResponseInterface
return $this->response->setStatusCode(404)->setBody('UNKNOWN_BILL');
}
// Exactly two states may enter fulfilment: a fresh PENDING order, or an
// EXPIRED bill the bank settled late. Everything else (PROCESSING already
// EXPIRED bill the bank settled late, inside the 72h reconciliation window.
// holds a queue slot, FULFILLED is done, RETRY_QUEUE is retrying) is a
// replay and must be absorbed here — checking only for 'FULFILLED' leaves
// the whole PROCESSING window open to a second queue push.
@@ -2,7 +2,7 @@
ogImage: "/og/batch-generating-80-technical-covers-with-comfyui.jpg"
banner: "/banners/batch-generating-80-technical-covers-with-comfyui.jpg"
title: "Batch Generating 80+ Technical Covers with ComfyUI: Constraining Style, Space, and Typography"
description: "How I automated the generation of 89 high-contrast technical article covers using a headless ComfyUI API pipeline: enforcing negative space, dark palettes, and zero-hallucination text boundaries."
description: "How I automated the generation of 108 cover pairs (216 banner and Open Graph assets) using a headless ComfyUI API pipeline: enforcing negative space, dark palettes, and zero-hallucination text boundaries."
pubDate: 2026-10-27
category: ai
blueprint: ai-agent-automation
@@ -14,8 +14,8 @@ summary:
audience: "AI Engineers, Content Automation Leads & Creative Technologists"
painPoint: "Generating article covers via diffusion models produces random visual styles, garbled hallucinatory text, and zero compositional space for typography headlines."
impact:
- metric: "89 Covers Automated"
detail: "Built a headless ComfyUI workflow executing via WebSocket API on a local 12GB VRAM node, generating 89 consistent technical covers in 48 minutes."
- metric: "108 Cover Pairs Automated"
detail: "Built a headless ComfyUI workflow executing via WebSocket API on a local 12GB VRAM node: a single batch run wrote 216 cover assets (108 banner + OG pairs) inside a 25.9-minute window, timestamped by the filesystem."
- metric: "100% Text Separation"
detail: "Banned text generation in diffusion prompts; forced visual models to generate clean background negative space and composited typography programmatically."
- metric: "Dark System Cohesion"
@@ -34,10 +34,10 @@ When building a high-credibility technical knowledge base or blog archive, visua
is non-negotiable. If one article features a glossy 3D cartoon, the next an anime illustration,
and a third a photorealistic macro lens shot, the site feels like an uncurated content farm.
Recently, the technical learning portal I manage (`hoelee-learning`) needed 89 individual cover assets
to replace generic SVG placeholders.
Recently, the technical learning portal I manage (`hoelee-learning`) needed 108 cover pairs — 216 individual banner and
Open Graph assets — to replace generic SVG placeholders.
Attempting to generate 89 covers manually via WebUI interfaces or Discord bots introduces
Attempting to generate over a hundred covers manually via WebUI interfaces or Discord bots introduces
three structural failure modes:
1. **Style Drift**: Different seeds and random prompts cause lighting, camera angles, and art directions to wander uncontrollably.
2. **Diffusion Text Hallucination**: Diffusion models notoriously struggle with text. They produce garbled alien glyphs, pseudo-English letters, and smeared gibberish across the focal plane.
@@ -158,7 +158,7 @@ def generate_cover(slug, topic_metaphor):
return prompt_id
raise
finally:
ws.close() # 89 covers x 1 socket: never closed, it leaks handles silently
ws.close() # 108 covers x 1 socket: never closed, it leaks handles silently
def prompt_in_history(prompt_id):
with urllib.request.urlopen(f"http://{COMFY_HOST}/history/{prompt_id}", timeout=10) as r:
@@ -233,7 +233,7 @@ def audit_top_negative_space(img_path: str) -> tuple[bool, str]:
## The result
By turning visual asset creation into a deterministic, API-driven engineering pipeline:
* **216 cover assets in a 25.9-minute window**: a single batch run wrote 108 banner + OG pairs (timestamped by the filesystem, so the figure is auditable rather than estimated) on one on-premise RTX 3060 node.
* **216 cover assets in a 25.9-minute window**: a single batch run wrote 108 banner + OG pairs on one on-premise RTX 3060 node. The figure is end-to-end per slug — diffusion inference plus the Pillow clearance audit and the two-size WebP encode — and is taken from filesystem timestamps rather than estimated, so it is auditable. One honest limit of that evidence: mtime records only the last write, so covers rejected and re-queued by the clearance gate in an earlier pass would not lengthen the measured window.
* **100% brand consistency**: Every single article shares the identical dark-mode color temperature, technical mood, and compositional negative space.
* **Zero manual prompting**: Once the topic metadata was defined, the entire batch executed unattended, and the resulting WebP assets were verified and committed straight to Git.
* **The pipeline is its own proof**: every cover image on this blog — including the one above this article — came out of this exact loop, not out of a design tool.
@@ -97,7 +97,7 @@ public function callback(): ResponseInterface
$this->db->transRollback();
return $this->response->setStatusCode(404)->setBody('UNKNOWN_BILL');
}
// 只有两种状态可以进入履约:全新的 PENDING,或银行延迟结算的 EXPIRED。
// 只有两种状态可以进入履约:全新的 PENDING,或 72 小时对账窗口内银行延迟结算的 EXPIRED。
// 其余状态(PROCESSING 已占一个队列位、FULFILLED 已完成、RETRY_QUEUE 在重试)
// 都属于重放,必须在此吸收——只判 'FULFILLED' 会留下整个 PROCESSING 窗口,
// 让第二次推送穿透幂等检查。
@@ -2,7 +2,7 @@
ogImage: "/og/zh-batch-generating-80-technical-covers-with-comfyui.jpg"
banner: "/banners/batch-generating-80-technical-covers-with-comfyui.jpg"
title: "用 ComfyUI 批量闭环 80+ 张技术图文封面:设计规范约束、留白控制与批处理工作流"
description: "如何通过 Headless ComfyUI API 流水线自动化生成 89 张高对比度技术博客封面:深度实战留白预留、暗色调约束与零文本幻觉的批处理闭环方案。"
description: "如何通过 Headless ComfyUI API 流水线自动化生成 108 组(216 张 Banner 与 Open Graph)高对比度技术博客封面:深度实战留白预留、暗色调约束与零文本幻觉的批处理闭环方案。"
pubDate: 2026-10-27
category: ai
blueprint: ai-agent-automation
@@ -14,8 +14,8 @@ summary:
audience: "AI 工程师、内容自动化负责人与创意技术架构师"
painPoint: "直接用扩散模型生成文章封面会导致风格混乱飘忽、画面充斥外星乱码伪文字,且视觉中心过于拥挤导致无法排版叠加标题文本。"
impact:
- metric: "89 张封面全量批处理"
detail: "基于本地 12GB VRAM 生产节点构建无头 ComfyUI 异步 WebSocket 批处理管线,单批次在 25.9 分钟窗口内写出 216 个封面资产(108 个 slug × banner + OG 卡片)。"
- metric: "108 组封面全量批处理"
detail: "基于本地 12GB VRAM 生产节点构建无头 ComfyUI 异步 WebSocket 批处理管线,单批次在 25.9 分钟窗口内写出 216 个封面资产(108 个 slug × banner + OG 卡片),耗时取自文件系统时间戳可核验。"
- metric: "图像与文本排版解耦"
detail: "提示词中严厉禁止模型生成任何文字,专注于渲染上部 45% 的干净负空间,后续标题完全交由代码程序化叠加。"
- metric: "品牌视觉系统一致性"
@@ -32,7 +32,7 @@ dynamicCta: true
在维护高专业度的技术知识库或技术博客矩阵时,视觉设计的一致性是确立专业信任感的重要基石。如果第一篇文章配的是糖果色 3D 卡通插图,第二篇变成了日系二次元动漫,第三篇又跳成了写实的微距摄影,整个站点就会立刻呈现出缺乏把控的粗糙拼凑感。
近期,我所维护的技术学习门户(`hoelee-learning`)需要为全量存量文章补充 89 张独一无二的高清图文封面,以彻底替换早期的通用占位图。
近期,我所维护的技术学习门户(`hoelee-learning`)需要为全量存量文章补充 108 组(共 216 张 Banner 与 Open Graph)高清图文封面,以彻底替换早期的通用占位图。
如果依赖人工在 WebUI 界面或群聊机器人中逐张抽卡生成,会立刻陷入三大结构性困境:
1. **风格漂移(Style Drift)**:不同的随机种子与自由发散的提示词,会导致光影色温、镜头视角与艺术风格四处乱飘。
@@ -149,7 +149,7 @@ def generate_cover(slug, topic_metaphor):
return prompt_id
raise
finally:
ws.close() # 89 张图 × 1 个套接字,不关闭就是静默句柄泄漏
ws.close() # 108 张图 × 1 个套接字,不关闭就是静默句柄泄漏
def prompt_in_history(prompt_id):
with urllib.request.urlopen(f"http://{COMFY_HOST}/history/{prompt_id}", timeout=10) as r:
@@ -216,7 +216,7 @@ def audit_top_negative_space(img_path: str) -> tuple[bool, str]:
## 交付结果
通过将视觉物料生产工程化为确定性 API 流水线:
* **25.9 分钟窗口内写出 216 个封面资产**:单批次产出 108 组 banner + OG 卡片(时间戳来自文件系统,可核验而非估算),全部在单块 12GB 显卡节点上完成。
* **25.9 分钟窗口内写出 216 个封面资产**:单批次产出 108 组 banner + OG 卡片,全部在单块 12GB 显卡节点上完成。该口径是端到端每 slug 耗时——扩散推理加上 Pillow 留白审计与双尺寸 WebP 转码——取自文件系统时间戳而非估算,因此可核验。这条证据有一处必须承认的局限:mtime 只记录最后一次写入,若某些封面在更早一轮被留白门禁判为不合格并重跑,那部分耗时不会体现在这个窗口里。
* **100% 保持品牌设计调性一致**:所有配图在暗色调对比、光影重心以及排版空间上呈现出高度收敛的专业秩序感。
* **实现无人工值守**:一旦文章的元数据与核心隐喻就绪,流水线即可全自动批处理、校验合规性并直接回流 Git。
* **这条管线本身就是证据**:本站每一张封面图——包括本文题图——都出自这条闭环,而不是出自设计软件。