公众号图文图片管理(模板化 + 视觉校验)
图片模式与跳过条件(运行控制驱动)
公众号文章的封面与正文配图由 user message 的结构化运行控制 article_image_mode 决定。缺失时按 cover_and_content。本 skill 不解析自然语言禁令:
article_image_mode |
受影响阶段 |
|---|---|
cover_and_content |
Phase 2/3/4 全部执行 |
cover_only |
Phase 3(配图规划)+ Phase 4(配图生成)跳过——不写 image-plan.md/images.json;正文不内联 <img>;模板 image_count.min 不再生效,不得据此强制生成配图 |
content_only |
Phase 2(封面生成)跳过——封面已委托 article-cover-design skill,见其「跳过条件」;不生成 $DIR/cover.png,不取 media_id/$COVER_PATH |
text_only |
Phase 2/3/4 全跳过 |
封面关·配图开时,Phase 4 正文图因无封面作 ref_image_path 风格锚点,改为各自独立生成(不传 ref_image_path,或链到首张已生成图),严禁指向不存在的 $DIR/cover.png。Phase 0/1(模板选择、节奏规划、三维风格分析)不受开关影响,始终执行。
下方各 Phase 顶部再次标注其跳过条件;质量验证的图片相关项在配图开关关闭时跳过。
公众号图片尺寸与展示规则
公众号图片的比例和大小由本 skill 固定,并在 MCP generate_image 参数中显式传入;不依赖项目级/任务级 image ratio 自动推断。项目/任务的 image ratio 可服务其他平台,但公众号文章优先使用下列固定规则:
| 图片类型 / slot | MCP size |
HTML image_size |
用途 |
|---|---|---|---|
| 封面 / hero | size="21:9" |
full-bleed |
服务端裁剪到 900×383,用作 thumb_media_id |
section_opener / 普通正文配图 |
size="4:3" |
full-width |
段落之间的章节图,适合公众号阅读流 |
inline_detail / 段内细节图 |
size="1:1" |
inline |
局部特写、操作细节、补充说明 |
| 信息图 / 流程图 / 对比图 / 清单总结图 | 默认 size="4:3",仅当内容更适合方形时用 size="1:1" |
full-width 或 inline |
信息密度高但不能撑满正文 |
visual-rhythm-plan.md 中正文图 slot 默认不要滥用 full-bleed;正文阅读流优先 full-width 或 inline。render_template 会按 image_size 控制展示宽度:full-bleed=100%、full-width=86%、inline=68%。
受控文字策略
图片上是否需要文字由场景决定,不再一律纯图:
- 封面:当标题利益点强、系列感明显、教程/清单/杂志编辑风、或用户/项目视觉风格明确需要时,可生成 2-8 个字的短标题/关键词;普通氛围图、真实场景摄影、情绪意象封面默认无字。
- 正文图:真实场景/氛围图默认无字;信息图、流程图、对比图、清单总结图可带少量中文标签或短句。
- 所有文字必须写入 prompt 与 verification_prompt,vision 校验必须检查文字是否短、清晰、无乱码、无水印、无 logo、无密集排版;文字失败时优先改为无字图或重试。
MCP 工具
| MCP 工具 | 说明 |
|---|---|
generate_image (project_id, prompt, image_type, output_path, task_id, size, ref_image_path, verify_with_vision?, verification_prompt?, upload_to_cdn?) |
生成单张图片。upload_to_cdn=true(生成与上传原子化)时在同一调用内完成"生成→保存→视觉校验→压缩→上传微信 CDN",直接返回 wechat_url + media_id;校验未通过则不上传;上传失败返回 upload_error(生成不浪费,仅重试上传)。返回 download_url(始终为可 HTTP fetch 的存储 URL,不再返回 base64 data URL)、file_path、wechat_url、media_id、verification(可选) |
analyze_image (project_id, image_url 或 file_path, prompt) |
用 vision 模型分析图片,用于人工二次校验或失败诊断 |
upload_image (project_id, file_path) |
上传外部/下载来的图片到微信 CDN,返回 CDN URL。已生成的图不再用此工具——生成时直接用 generate_image(upload_to_cdn=true) 原子上传 |
download_image (project_id, url) |
下载在线图片 |
compress_image (file_path) |
压缩图片 |
五阶段流程
Phase 0: 模板选择 + 节奏规划
└─ 读取 03-article.md → 选模板 → 写 visual-rhythm-plan.md
Phase 1: 三维风格分析
└─ 账号定位 + 内容主题 + 受众 → $VISUAL_STYLE / $COLOR_PALETTE / $MOOD
Phase 2: 封面生成
└─ 基于风格分析 + 文章核心隐喻 → 生成 + 上传
Phase 3: 配图规划
└─ 逐章节提取 visual_brief + required_entities + must_match_excerpts → 写 image-plan.md
Phase 4: 配图生成(带 vision 校验)
└─ 按 rhythm-plan slot 顺序生成 → vision 校验 → 失败重试 → 写 images.json
Phase 0:模板选择与节奏规划
步骤 0a:选择文章类型模板
读取 $DIR/03-article.md(或 04-article-final.md),根据结构特征匹配模板:
| 特征 | 模板 | 文件 |
|---|---|---|
| 标题/大纲含"3 个/5 种/N 条"+ 并列项 | listicle |
templates/article/listicle.yaml |
| 按步骤序号组织(步骤 1 / 步骤 2 / step N) | tutorial |
templates/article/tutorial.yaml |
| 情节弧、场景描写、人物/时间线 | story-narrative |
templates/article/story-narrative.yaml |
| 其他(深度观点、评论、分析) | long-form-essay |
templates/article/long-form-essay.yaml(默认) |
自动决策原则:不向用户询问。特征模糊时优先选 long-form-essay。
步骤 0b:创建 visual-rhythm-plan.md
读取 $DIR/03-article.md,对每个 ## 章节,分配一个 slot。详细模板和示例见 references/rhythm.md。
每个 slot 必须包含:
slot_id:hero / section_opener / inline_detail / footersection_index:对应##章节的 0-based 序号(footer 用 -1)image_size:full-bleed / full-width / inline(正文阅读流优先 full-width / inline,避免正文图撑满)module:从模板的modules.preferred中选,可为 nullcomposition_type:从 8 种构图类型中选(参见 references/content.md)chapter_anchor:对应章节的标题或核心论点(1 句话)
产出:$DIR/visual-rhythm-plan.md
Phase 1:视觉风格确定(配置优先,分析兜底)
步骤 1a:读取任务已解析的视觉风格(权威来源)
公众号"模板"由三个正交维度组成:图片视觉(visual_style)、写作者(writer)、排版样式(theme)。三者各自独立解析,互不推导——写作者绝不决定图片视觉。
get_project_profile 已按 task > project 解析并返回视觉维度的最终值:
$VISUAL_STYLE_CONFIGURED= profile 的visual_style字段(解析后的视觉风格描述/关键词)$VISUAL_STYLE_SOURCE= profile 的visual_style_source(task / project)
关键规则:
- 若
$VISUAL_STYLE_CONFIGURED非空 → 它是权威视觉锚点。以它为$VISUAL_STYLE的核心,三维分析只做补充细化(配色、情绪、构图),绝不可覆盖或偏离配置的视觉方向。例如配置了"温暖自然的生活摄影",分析就只能往暖色调、自然光、真实场景细化,不得生成维多利亚木刻/黑白版画等冲突风格。 - 若
$VISUAL_STYLE_CONFIGURED为空(所有层级都未配置视觉)→ 执行完整三维分析兜底。
步骤 1b:三维风格分析(细化 / 兜底)
基于 get_project_profile 返回的 $ACCOUNT_POSITIONING / $ACCOUNT_KEYWORDS / $ACCOUNT_AUDIENCE 和 $DIR/04-article-final.md 内容,执行三维分析。当步骤 1a 有配置锚点时,分析必须向该锚点收敛(即用账号/内容主题来充实已指定的视觉方向),而非另起炉灶。
详细规范见 references/cover.md。
产出:$VISUAL_STYLE(含配置锚点 + 细化方向)/ $COLOR_PALETTE / $MOOD / $VISUAL_STYLE_SOURCE
Phase 2:封面生成(委托 article-cover-design skill)
封面开关守卫:当
article_image_mode为content_only或text_only时,Phase 2 整体跳过——不调generate_image、不生成$DIR/cover.png、不取media_id/$COVER_PATH。article-cover-designskill 同步跳过(见其「跳过条件」)。封面关·配图开时,Phase 4 正文图改用无锚点独立生成。
封面是全篇风格锚点(产物 $DIR/cover.png 供 Phase 4 内容图 ref_image_path 继承)。封面设计已独立成稿——using the article-cover-design skill,它硬编码官方比例(900×383 / 2.35:1)、中心安全区构图(转发卡 1:1 兼容)、受控文字策略、从文章核心隐喻推导视觉概念、vision 6 维评分卡把关。本阶段只交代与本 skill 的衔接:
- 核心规格:大图 2.35:1(900×383px,服务端强制精确裁剪),转发卡 1:1 由中心安全区自动覆盖,受控文字策略(按真实场景决定是否带短文字)。
- 生成调用:
generate_image(project_id=$PROJECT_ID, prompt=<封面提示词>, image_type="cover", output_path="$DIR/cover.png", task_id=$TASK_ID, size="21:9", upload_to_cdn=true, verify_with_vision=true, verification_prompt=<6 维评分卡>)。size="21:9"是生成提示比(Volcengine 支持的最近比);服务端按platform=article + image_type=cover把成品精确裁到 900×383 并像素断言——微信零裁剪,告别「需要手动裁剪的纯图」。upload_to_cdn=true:vision 校验通过才上传,直接返回media_id(封面 thumb)+wechat_url;校验未通过不上传(不浪费素材位)。
- vision 评分卡不过 → 按
sharper_prompt_hint锐化 prompt 重试,最多 3 次;仍不过请求用户协助,不得用未通过封面发布。 - 详细推导链、6 维评分卡模板、迭代策略、
cover-prompt.md审计见 article-cover-design/SKILL.md;三维风格方向参考见 references/cover.md。
产出:$DIR/cover.png, media_id, $COVER_PATH
Phase 3:配图内容规划(升级 schema)
配图开关守卫:当
article_image_mode为cover_only或text_only时,Phase 3 整体跳过——不创建image-plan.md;模板image_count.min不再生效,不得据此强制规划配图。节奏规划(Phase 0b)仍创建,所有非 hero slot 的image_url=null。
新 schema:visual_brief + required_entities + must_match_excerpts
旧 schema 的 visual_subject 字段过于抽象("商务场景"、"科技背景"),已废弃。新 schema 强制要求三个具体字段:
| 字段 | 含义 | 示例 |
|---|---|---|
visual_brief |
1-2 句白话描述"这张图必须画什么" | "一颗石头路上的裂缝中钻出嫩绿新芽,背景是虚化的晨光。" |
required_entities |
必须出现的具体物体列表 | ["stone path with crack", "tender green shoots", "soft morning light (background blur)"] |
must_match_excerpts |
章节中支撑这些实体的原句 | ["他说,'你看这条石板路的缝里,不也长出了新芽?'"] |
详细正反例和规划流程见 references/content.md。
产出:$DIR/image-plan.md
Phase 4:配图生成(带 vision 校验循环)
配图开关守卫:当
article_image_mode为cover_only或text_only时,Phase 4 整体跳过——不生成任何正文图、不写images.json、正文不内联<img>。封面关·配图开时本 Phase 仍执行,但步骤 4c 的ref_image_path不得指向未生成的$DIR/cover.png(改不传或链首图)。
按 $DIR/visual-rhythm-plan.md 中 slot 的顺序生成。每个 slot 执行:
步骤 4a:构建 prompt
基于 image-plan.md 中对应章节的:
visual_brief(主体描述)required_entities(必须出现的实体清单)composition_type(构图约束)- 叠加
$VISUAL_STYLE/$COLOR_PALETTE风格语言
步骤 4b:构建 vision 校验 prompt
按下方模板构建 verification_prompt(必须在 4c 调用 generate_image 前就绪,服务端要求 verify_with_vision=true 时 verification_prompt 非空):
这张图用于文章《$ARTICLE_TITLE》的章节《$CHAPTER_TITLE》。
章节核心论点:$CORE_POINT
必须出现的视觉元素:$REQUIRED_ENTITIES(逐项列出)
视觉简报:$VISUAL_BRIEF
请按 JSON 格式回答:
{
"all_entities_present": true/false,
"missing_entities": ["缺的实体 1", ...],
"relevance_score": "high" | "medium" | "low",
"has_forbidden_content": true/false,
"forbidden_notes": "文字/水印/低俗等问题描述",
"overall_pass": true/false,
"sharper_prompt_hint": "如不通过,给出更锐化的 prompt 建议"
}
步骤 4c:生成图片(带 vision 校验 + 原子上传)
generate_image(
project_id=$PROJECT_ID,
prompt=<步骤 4a 构建的 prompt>,
image_type="content",
output_path="$DIR/img_N.png",
task_id=$TASK_ID,
ref_image_path=<封面开关开启时 "$DIR/cover.png";封面关时省略或链到首张已生成图>,
verify_with_vision=true,
size=<按 slot 固定:section_opener 用 "4:3";inline_detail 用 "1:1";信息图/流程图/对比图默认 "4:3">,
verification_prompt=<步骤 4b 构建的校验 prompt>,
upload_to_cdn=true
)
关键:
size:必须显式传入,普通正文配图/信息图用size="4:3",段内细节图用size="1:1";不得依赖项目级/任务级 image ratio。ref_image_path:封面开关开启时用$DIR/cover.png(风格锚点);封面关·配图开时不传(或链到首张已生成图),严禁指向不存在的$DIR/cover.png。upload_to_cdn=true让生成与上传原子化:同一调用内完成生成→保存→校验→压缩→上传微信 CDN。校验通过才上传(不浪费素材位),返回值直接带wechat_url+media_id;校验失败则不上传,结果无wechat_url。不再有独立的upload_image阶段——每张图生成的瞬间即持久化到 CDN。
旧版 server 兼容:若 server 不支持 verify_with_vision / upload_to_cdn 参数,去掉这两个参数生成图后,单独调用 analyze_image 做校验 + upload_image 上传,并按 references/content.md 的容错解析规则处理返回文本:
analyze_image(
project_id=$PROJECT_ID,
file_path=$DIR/img_N.png,
prompt=<步骤 4b 构建的校验 prompt>
)
步骤 4d:失败重试策略
读取 generate_image 返回的 verification 对象(字段名是服务端归一化后的 passed/score/missing_entities/notes,不是 LLM 原始 JSON 的 overall_pass/relevance_score):
passed=true→ 通过,继续下一步passed=false且score=medium→ 用notes中的sharper_prompt_hint锐化 prompt 重试(最多 2 次,共 3 次尝试)passed=false且score=low→ 同上重试- 3 次仍失败 → 标记
quality_status=failed,继续后续 slot
锐化 prompt 策略:
- 在 prompt 开头加 "MUST CONTAIN: " +
verification.missing_entities列表 - 把 visual_brief 改写得更具体(加入材质、颜色、方位)
- 移除任何抽象风格词,只保留具体场景描述
步骤 4e:记录并立即原子落盘(生成即持久化)
generate_image(upload_to_cdn=true) 返回时,wechat_url + media_id 已就绪(或返回 upload_error)。无需调用 upload_image。立即把这张图记录写回 $DIR/images.json——每张图返回即落盘,使中断最多丢失"正在生成的那一张"。
- 从
generate_image返回值取wechat_url→ 写入记录的url字段;upload_error时记到upload_error字段并用upload_image(file_path=...)单独重试上传(不重新生成)。 - 原子写
$DIR/images.json:先写临时文件$DIR/.images.json.tmp→fsync→rename覆盖$DIR/images.json。绝不要"攒齐所有图再一次性写"——那是丢失窗口。 - 每条记录必须包含:
{ "index": 1, "slot_id": "section_opener", "section_index": 1, "image_type": "content", "chapter_title": "...", "composition_type": "三分法", "visual_brief": "...", "required_entities": ["..."], "must_match_excerpts": ["..."], "prompt": "Final prompt used", "verification": { "passed": true, "score": "high", "missing_entities": [], "notes": "", "raw": "<vision 模型原始输出>" }, "verification_audit": { "attempt_count": 1, "sharper_prompt_history": [] }, "ref_image_path": "$DIR/cover.png 或 null(封面关·配图开时)", "file_path": "$DIR/img_01.png", "url": "https://cdn.../img_01.png", "wechat_url": "https://cdn.../img_01.png", "media_id": "媒体素材ID(来自 generate_image upload_to_cdn=true)", "quality_status": "passed" }verification必须直接来自服务端generate_image(verify_with_vision=true)返回值的verification字段;verification_audit由 agent 维护。
步骤 4f:插入到文章
按 slot_id 和 section_index 把  插入到 $DIR/04-article-final.md:
section_opener:紧跟## 章节标题之后inline_detail:在after_paragraph_index指定的段落之后hero:紧跟文章第一个##之前(如有 hero module 文字,则在 hero module 之后)
质量验证
配图开关守卫:配图开关关闭时,下方所有图片相关检查项(文件完整性/风格一致性/视觉多样性/Vision 通过率/审计完整性/CDN 持久化)跳过,不计为失败;节奏完整性、模板一致性(slot 映射)仍执行。封面关·配图开时,「风格一致性」改为"无
ref_image_path或链首图"。
生成完成后执行 7 项检查:
- 节奏完整性:
visual-rhythm-plan.md中每个##都映射到一个 slot - 模板一致性:所选模板的 rhythm 规则被遵守(如 listicle 的 section_opener 必填、inline_detail forbidden)
- 文件完整性:所有图片文件存在且可访问
- 风格一致性:封面+配图均开启时,
images.json中所有内容图ref_image_path="$DIR/cover.png";封面关·配图开时无ref_image_path或链首图,且不得指向不存在的$DIR/cover.png - 视觉多样性:3 张以上配图使用 3 种以上不同
composition_type(清单模板可豁免,因要求统一构图) - Vision 校验通过率:至少 80% 的内容图
verification.passed=true - 审计完整性:
images.json每条含visual_brief/required_entities/must_match_excerpts/verification/slot_id/section_index/wechat_url/media_id - CDN 持久化:
images.json每条都有非空wechat_url(每张图生成即上 CDN);缺 URL 的 slot 用generate_image(upload_to_cdn=true)补或upload_image重传
未通过检查时:
- 单图失败 → 重试或降级标记
- 节奏/模板违规 → 回到 Phase 0 重新规划
- Vision 通过率 < 80% → 检查 prompt 构建逻辑,必要时回退到 Phase 3 重新规划
保存结果
- 含 CDN 图片链接的文章覆盖写回
$DIR/04-article-final.md - 所有配图信息保存为
$DIR/images.json
技术规范
微信图片限制:
- 最大尺寸:10MB(超出自动压缩)
- 最大宽度:1920px(保持比例压缩)
- 支持格式:JPG、PNG、GIF、WebP
公众号常用比例:
- 封面图(公众号封面):2.35:1(900x383px 标准)
- 正文配图(section_opener):4:3,MCP 显式传
size="4:3" - 章节内细节图(inline_detail):1:1,MCP 显式传
size="1:1" - Hero slot:full-bleed 2.35:1
常见失败与修复
| 问题 | 原因 | 修复 |
|---|---|---|
| Vision 校验持续失败 | prompt 过于抽象 | 锐化 visual_brief,明确每个 required_entity 的材质、颜色、方位 |
| 配图与章节无关 | required_entities 与章节原文脱节 | 回到 Phase 3 重新提取,确保 must_match_excerpts 是章节原句 |
| 所有配图构图雷同 | 未在 rhythm-plan 中分配不同 composition_type | 重新规划 rhythm-plan,强制 3+ 种构图(清单模板除外) |
| 风格漂移 | 封面开启时未使用封面作为参考图;或封面关闭时错误引用不存在的封面 | 封面+配图均开启时确保内容图 ref_image_path="$DIR/cover.png";封面关·配图开时不传或链首图 |
| 封面与文章脱节 | 封面 prompt 缺少内容隐喻 | 在封面 prompt 中加入文章核心论点的视觉隐喻 |
| 节奏违反模板规则 | 未读模板 YAML 的 rhythm 字段 | 重新加载模板,按 rhythm 字段约束 slot 分配 |
参考文档
- references/cover.md — 封面设计规范(三维风格分析 + prompt 模板)
- references/content.md — 配图规划与生成(新 schema + vision 校验循环)
- references/rhythm.md — 节奏规划与模板选择(visual-rhythm-plan.md 模板)