关于 sn-infographic
sn-infographic 是用于生成信息图的技能,面向需要将文字需求转化为图片的 Agent。它可评估并扩写提示词,通过多轮生成和视觉语言模型审查排序输出。
主要功能
- 01评估提示词质量
- 02按需扩写提示词
- 03多轮生成与视觉审查
- 04按质量排序结果
- 05友好或详细输出模式
适用场景
- 01将简短需求转为图像提示词
- 02比较多轮生成的图像结果
- 03按指定比例与尺寸生成信息图
MCP 相关
此输入未说明其与 MCP 的关系。
安装
复制下面的命令,在终端中运行。
npx skills add https:/ / github.com/ opensensenova/ sensenova-skills --skill sn-infographic安装后在 Claude Code 中输入/sn-infographic确认已加载。
包含的文件
除 SKILL.md 外,安装时一起下载的参考资料和脚本。
references/analysis-framework.mdbase-prompt.mdevaluation-standard.mdlayout-style-selection.mdreferences/layouts/asymmetry.mdaxial-expansion.mdbento-grid.mdbig-typography.mdbinary-comparison.mdbreaking-the-grid.mdbridge.mdcenter-focus.mdchapter-layout.mdcharacter-guide.mdcircular-flow.mdcollage-glitch.mdcomic-strip.mdcomparison-matrix.mdconflict-contrast.mdcontainerization.mddashboard.mddata-landscape.mddeconstruction.mddiagonal-composition.mddisrupted-flow.mdedge-tension.mdeditorial-vogue.mdemotional-gradient.mdf-pattern.mdflashback.md详细介绍
sn-infographic
信息图生成场景技能(第 1 层),依赖 sn-image-base(第 0 层)提供的 sn-image-generate、sn-image-recognize 和 sn-text-optimize 工具。
功能:
- 评估提示词质量(自动模式)
- 扩展提示词(强制/自动模式)
- 多轮图像生成和 VLM 审核
- 根据质量排名输出最佳结果
输入规范
| 参数 | 类型 | 默认值 | 说明 |
|---|---|---|---|
user_prompt | 字符串 | 必填 | 用户的原始请求。UTF-8 文本;可以包含 Markdown、URL 或结构化数据。长度仅受底层 LLM 上下文预算限制。 |
max_rounds | 整数 | 1 | 最大生成轮数。有效范围:1–8。当 max_rounds=1 时,会同时跳过步骤 3 的 VLM 审核和提前终止检查。 |
output_mode | 字符串 | friendly | friendly:一行内容描述 + 排名第 1 的单张图像 |
verbose:完整质量排名 + 计时统计 + 所有图像(按排名排序) | |||
prompts_expand_mode | 字符串 | auto | auto:先评估 user_prompt 的质量;仅当质量不足时才进入步骤 2 扩展 |
force:跳过评估,始终执行步骤 2 扩展 | |||
disable:跳过步骤 2,直接将 user_prompt 用作 expanded_prompt | |||
aspect_ratio | 字符串 | 推断得出(16:9) | 当用户明确指定支持的比例(例如 16:9/9:16,也可以通过 宽高比/画面比例/aspect ratio 指定)时,由 Main Agent 设置;否则留空,由 Worker 在步骤 0 中根据 user_prompt(方向/场景线索)按照 references/runtime-parameters.md 推断。 |
image_size | 字符串 | 推断得出(2k) | 当用户明确指定尺寸(2k/4k)时,由 Main Agent 设置;否则由 Worker 在步骤 0 中推断(目前只有一个选项 2k)。当 SN_IMAGE_GEN_MODEL=sensenova-u1.5-lite 时支持 4k;其他模型可能会拒绝该值,届时技能会显示相应错误。 |
参数提取说明: Main Agent 提取参数时,仅在用户明确指定的情况下解析
max_rounds、output_mode、prompts_expand_mode和aspect_ratio/image_size。未明确指定的aspect_ratio和image_size由 Worker 在步骤 0 中推断。
API 配置
此技能中的所有 API 调用均通过 sn-image-base 技能的 sn_agent_runner.py 执行,身份验证参数使用默认值(CLI > 环境变量 > 内置默认值),无需显式传入。
| 调用类型 | 工具 | 身份验证参数 | 说明 |
|---|---|---|---|
| LLM | sn-text-optimize(评估/扩展) | 默认按 SN_TEXT_API_KEY -> SN_CHAT_API_KEY -> SN_API_KEY 的顺序读取 | 内置默认值指向 Sensenova 内部网络服务 |
| VLM | sn-image-recognize(图像审核) | 默认按 SN_VISION_API_KEY -> SN_CHAT_API_KEY -> SN_API_KEY 的顺序读取 | 内置默认值指向 Sensenova 内部网络服务 |
| 图像生成 | sn-image-generate | 默认读取 SN_IMAGE_GEN_API_KEY -> SN_API_KEY;仅在需要覆盖图像专用配置时才需要 SN_IMAGE_GEN_API_KEY | 使用 sn-image-base 的图像生成配置 |
遇到 MissingApiKeyError 或需要指定模型时:通过 CLI 参数显式传入,参数参考 $SN_IMAGE_BASE/references/api_spec.md。
$SN_IMAGE_BASE 路径说明:$SN_IMAGE_BASE 是 sn-image-base 技能的安装目录(其中包含 SKILL.md)。
Agent 可在已安装技能列表中按技能名称 sn-image-base 查找此路径。
架构:主 Agent + 工作 Agent
此技能采用两层 Agent 架构:
| 角色 | 职责 |
|---|---|
| 主 Agent | 接收用户请求、规范化参数、发送预检信息、启动工作 Agent、收集结果,并向用户发送文本和图片 |
| 工作 Agent | 执行生成流水线(扩展 → 多轮生成 + 审核 → 排序),返回结构化 JSON |
职责边界:
- 工作 Agent 不会直接向用户发送任何消息,只返回结构化 JSON
- 主 Agent 负责发送所有用户可见的消息
- 工作 Agent 的最后一条消息必须且只能是 Return Contract 中定义的 JSON 字符串
- 工作 Agent 的内部 VLM 调用始终直接执行,不会生成子 Agent
工作流
主 Agent 工作流
-
从用户请求中提取参数,分三轮进行:
-
行内 KV 指令 — 解析
key=value形式的标记,其中key∈ {max_rounds、output_mode、prompts_expand_mode、aspect_ratio、image_size};从用户消息中移除已识别的标记,剩余内容成为user_prompt。示例:"生成一张信息图 max_rounds=3 output_mode=verbose"→user_prompt="生成一张信息图"、max_rounds=3、output_mode=verbose。 -
关键词识别(不区分大小写,针对剔除标记后的文本执行)——根据下表填写尚未通过行内 KV 设置的参数:
参数 触发关键词 解析值 output_modeverbose、详细、详尽、完整统计verbosefriendly、简洁、精简friendlymax_roundsN 轮、N rounds、重试 N 次(解析N)N,限制在[1, 8]范围内prompts_expand_mode强制扩写、force expand、force expansionforce不扩写、跳过扩写、disable expansion、no expanddisableaspect_ratio明确指定受支持的比例( 16:99:164:33:41:12:33:24:55:421:99:21),可带或不带宽高比/画面比例/比例/aspect ratio前缀对应比例(根据 runtime-parameters.md中的受支持比例集合验证;不受支持的值 → 留空,由 Worker 推断)image_size明确指定受支持的尺寸( 2k4k),可带或不带image_size/分辨率/清晰度/image size前缀对应尺寸(模糊的画质词语,如 高清/超清,不计入);不受支持的值 → 留空,由 Worker 推断 -
默认值 — 任何仍未设置的参数均使用以下默认值:
max_rounds=1、output_mode=friendly、prompts_expand_mode=auto。aspect_ratio和image_size没有主 Agent 默认值:未检测到明确值时,将它们留空,由 Worker 在步骤 0 中推断。
优先级:行内 KV > 关键词识别 > 默认值。根据输入规范验证行内 KV 中的值(超出范围的
max_rounds限制在[1, 8]范围内;无法识别的枚举值回退为默认值,且主 Agent 应记录不匹配情况)。 -
-
发送统一的预检消息:
"Using sn-infographic skill to generate infographic, please wait..." -
启动 Worker Agent(子 Agent),传入完整参数和工作目录
-
当 Worker Agent 返回
status=ok且need_main_agent_send=true时:- max_rounds = 1:根据返回 JSON 中的
expanded_prompt生成文本摘要(长度和语言规则参见输出格式 → 简洁模式),发送摘要,然后发送排名第 1 的单张图片 - max_rounds > 1,简洁模式:根据排名第 1 轮的
result和violations生成文本摘要,发送摘要,然后发送排名第 1 的单张图片 - max_rounds > 1,详细模式:渲染详细模板(替换规则参见输出格式 → 详细模式),发送模板,然后按排名顺序发送所有图片
- max_rounds = 1:根据返回 JSON 中的
-
如果 Worker Agent 返回
status=error,向用户报告error字段中的实际内容
Worker Agent 工作流
Worker Agent 接收 user_prompt、max_rounds、prompts_expand_mode、可选的 aspect_ratio 和 image_size(仅当用户明确指定时才设置),以及此技能的工作目录(SKILL_DIR)。(output_mode 保留在主 Agent 侧 — Worker 没有依赖它的分支。)
Worker 环境
下方 bash 代码片段中引用的变量均采用 $NAME 形式。Worker 必须在使用变量的步骤之前为其赋值。
| 变量 | 来源 | 使用位置 |
|---|---|---|
USER_PROMPT | Main Agent 输入 — 用户的原始请求 | 第 1 步评估;第 2.0 步内容分析 |
MAX_ROUNDS | Main Agent 输入(默认值为 1) | 第 3 步循环边界;提前终止条件 |
PROMPTS_EXPAND_MODE | Main Agent 输入(默认值为 auto) | 第 1 步分支 |
SKILL_DIR | Agent 运行时解析当前 skill 的安装路径(例如 ~/.openclaw/skills/sn-infographic、~/.hermes/skills/sn-infographic) | 读取 references/* |
SN_IMAGE_BASE | Agent 运行时根据 skill 名称 sn-image-base 在已安装 skill 注册表中解析 | 运行 scripts/sn_agent_runner.py |
TASK_ID | 第 0 步(date +%Y%m%d_%H%M%S) | 唯一性标识 |
TEMP_DIR | 第 0 步(/tmp/openclaw/sn-infographic/${TASK_ID}) | 所有中间产物的临时目录 |
IMAGE_SIZE | 用户指定明确尺寸时使用 Main Agent 输入,否则第 0 步根据 USER_PROMPT 推断(当前唯一选项为 2k) | sn-image-generate --image-size |
ASPECT_RATIO | 用户指定明确比例时使用 Main Agent 输入,否则第 0 步根据 USER_PROMPT 推断(默认值为 16:9) | sn-image-generate --aspect-ratio |
EXPANDED_PROMPT | 第 1 步(跳过第 2 步时复制 USER_PROMPT)或第 2.3 步(扩展后的结果) | sn-image-generate --prompt |
LAYOUT、STYLE | 第 2.1 步的选择结果(未选定时回退到 hub-spoke / corporate-memphis) | 第 2.3 步系统提示词组装 |
ROUND | 第 3 步循环计数器(for ROUND in $(seq 1 "$MAX_ROUNDS")) | 每轮文件命名(round_${ROUND}.png) |
命名:自有文件使用 $SKILL_DIR;跨 skill 引用使用 $SN_<SKILL_NAME>(例如 $SN_IMAGE_BASE)。
JSON 解析:每次 sn_agent_runner.py ... -o json 调用都会在标准输出中打印 JSON 信封({"status", "result", "model", ...};诊断信息会输出到标准错误)。调用失败时,status 会设为非 ok 值(例如 failed),并省略 result,因此读取 .result 前务必确认信封中的 .status == ok——否则,缺失的 .result 会以字面值 null 出现;它本身是有效 JSON,会绕过 jq -r 和 extract_json.py(不会引发错误)。大模型自身的 JSON(评估/分析步骤)位于 result 字符串内,可能带有多余的文字或 ```json 围栏。执行任何 jq 前,先将 runner 输出传入 $SN_IMAGE_BASE/scripts/extract_json.py(从标准输入读取,输出恢复出的 JSON;找不到 JSON 时以非零状态退出);对于解析大模型/VLM 内部 JSON 的步骤,也要将 .result 传入该脚本。状态非 ok 或 extract_json.py 以非零状态退出,都表示响应不可用 → 返回 Error Flow JSON。
第 0 步 — 初始化
-
生成
task_id(时间戳,格式为YYYYMMDD_HHMMSS),并创建统一的临时目录/tmp/openclaw/sn-infographic/<task_id>/,将其设为TEMP_DIR。在后续任何步骤向其中写入内容之前,TEMP_DIR必须已存在:TASK_ID=$(date +%Y%m%d_%H%M%S) TEMP_DIR="/tmp/openclaw/sn-infographic/${TASK_ID}" mkdir -p "$TEMP_DIR" -
初始化一个空的
rounds列表 -
解析
aspect_ratio和image_size(绑定到ASPECT_RATIO/IMAGE_SIZE):如果存在明确的 Main Agent 值,则使用该值;否则根据$SKILL_DIR/references/runtime-parameters.md,从user_prompt推断。默认值:aspect_ratio→16:9;image_size当前只有一个推断选项,即2k。
步骤 1 — 决定是否重写图像提示词(始终运行)
此步骤决定在步骤 3 生成图像之前,是否要重写/扩展用户的图像生成 prompt 文本,并生成布尔值 should_expand。如果跳过步骤 2,此步骤还会设置 EXPANDED_PROMPT 并记录 prompts_expand_skipped = true。
范围(不要望文生义)。 这里的“扩展”仅指重写图像生成的文本提示词,别无其他。这不是任务分解、计划生成或计划审查关卡;步骤 1 不会启动自己的 Agent——它只是 Worker 自行调用一次 sn-text-optimize。不要将其套用到任何 subagent-driven-development / delegate_task 式工作流中,也不要编写计划文件。(此技能只使用一个子 Agent,即 Worker,由 Main Agent 启动一次;Worker 不会再启动自己的 Agent——参见 Responsibility Boundaries。)
PROMPTS_EXPAND_MODE 是 Main Agent 传入的已解析输入——步骤 1 根据它执行操作,而不会重新解析用户请求。解析模式值(Main Agent 参数提取)和执行此决策是两项不同的工作:完成前者并不代表完成了步骤 1。不要跳过此步骤;在 auto 模式下,下面的评估调用是强制的——绝不要根据提示词表面上的质量推断 should_expand。
只有**步骤 2(扩展提示词)**会被跳过,而且只有此步骤作出相应决定时才会跳过。分支取决于 PROMPTS_EXPAND_MODE:
auto 模式(默认):
-
运行评估调用(强制)。内部评估 JSON 位于
.result中,其架构定义在$SKILL_DIR/references/evaluation-standard.md(required_results、optional_results)。EVAL_ENVELOPE=$(python "$SN_IMAGE_BASE/scripts/sn_agent_runner.py" sn-text-optimize \ --system-prompt-path "$SKILL_DIR/references/evaluation-standard.md" \ --user-prompt "$USER_PROMPT" \ --output-format json | python "$SN_IMAGE_BASE/scripts/extract_json.py") # A failed runner envelope (status != ok) carries no .result. EVAL_STATUS=$(printf '%s' "$EVAL_ENVELOPE" | jq -r '.status') EVAL=$(printf '%s' "$EVAL_ENVELOPE" | jq -r '.result' \ | python "$SN_IMAGE_BASE/scripts/extract_json.py") -
决定
should_expand:required_pass:required_results中所有answer均为"yes"optional_pass:optional_results中answer="yes"的数量 / 总数 ≥ 0.6should_expand = not (required_pass and optional_pass)
-
保守回退:如果
EVAL_STATUS不是ok(评估调用本身失败),或extract_json.py以非零状态退出,则默认should_expand = true。与步骤 2.0 / 2.3 不同,评估失败不会中止 Worker——auto会回退为扩展提示词。 -
如果
should_expand = true:执行步骤 2。 -
如果
should_expand = false:跳过步骤 2,将原始提示词设为EXPANDED_PROMPT,并记录prompts_expand_skipped = true:EXPANDED_PROMPT="$USER_PROMPT" echo "$EXPANDED_PROMPT" > "$TEMP_DIR/expanded-prompt.txt"
force 模式:
- 跳过评估,始终执行步骤 2(必须扩展)。
- 不记录
prompts_expand_skipped——只有跳过步骤 2 时,Return JSON 中才会出现此字段(参见 Return Contract 规则)。
disable 模式:
-
跳过评估和步骤 2;直接使用
user_prompt作为expanded_prompt:EXPANDED_PROMPT="$USER_PROMPT" echo "$EXPANDED_PROMPT" > "$TEMP_DIR/expanded-prompt.txt" -
记录
prompts_expand_skipped = true。
步骤 2 — 内容分析 + 布局与风格选择 + 提示词扩展
2.0 内容分析(使用 sn-image-base 的 sn-text-optimize 工具):
ANALYSIS_ENVELOPE=$(python "$SN_IMAGE_BASE/scripts/sn_agent_runner.py" sn-text-optimize \
--system-prompt-path "$SKILL_DIR/references/analysis-framework.md" \
--user-prompt "$USER_PROMPT" \
--output-format json | python "$SN_IMAGE_BASE/scripts/extract_json.py")
将 .result 中的内部分析 JSON(而非外层封装,这样步骤 2.1 就能直接通过 jq 读取 data_type / tone / audience)保存到 $TEMP_DIR/analysis.json。下方的保护逻辑会先检查外层封装是否失败(status 不是 ok,或 extract_json.py 返回非零 → 使用 .error 进入错误流程):
# A failed runner envelope (status != ok) has no .result → return Error Flow.
if [ "$(printf '%s' "$ANALYSIS_ENVELOPE" | jq -r '.status')" != "ok" ]; then
ANALYSIS_ERROR=$(printf '%s' "$ANALYSIS_ENVELOPE" | jq -r '.error')
# return Error Flow JSON {"status":"error","error":"$ANALYSIS_ERROR"} to Main Agent and stop
fi
printf '%s' "$ANALYSIS_ENVELOPE" | jq -r '.result' \
| python "$SN_IMAGE_BASE/scripts/extract_json.py" > "$TEMP_DIR/analysis.json"
架构:$SKILL_DIR/references/analysis-framework.md(定义步骤 2.1 / 2.2 所用的 data_type、tone、audience 及其他字段)。
2.1 布局与风格选择
这是从 $SKILL_DIR/references/layout-style-selection.md 中的候选表按名称级别进行的加权随机选择;操作对象纯粹是布局/风格的名称。此处不要打开 references/layouts/ 或 references/styles/ 下的任何文件,也不要通过“比较选项”来挑选最合适的方案——选择是随机的,而非根据文件内容进行判断。所选的一个布局文件和一个风格文件会在稍后的步骤 2.3 中各读取一次。
- 从临时目录
$TEMP_DIR/analysis.json读取分析结果;
ANALYSIS=$(cat "$TEMP_DIR/analysis.json")
- 根据
data_type/tone/audience,按$SKILL_DIR/references/layout-style-selection.md中定义的候选项查找与加权随机抽样流程,获取一个LAYOUT名称和一个STYLE名称(仅限名称,不读取文件); - 通过检查定义文件是否存在来验证选择结果(仅使用
[ -f ]检查是否存在,仍不读取文件);若文件缺失,则回退到hub-spoke+corporate-memphis:
[ -f "$SKILL_DIR/references/layouts/${LAYOUT}.md" ] || LAYOUT=hub-spoke
[ -f "$SKILL_DIR/references/styles/${STYLE}.md" ] || STYLE=corporate-memphis
- 将选择结果保存到临时目录:
$TEMP_DIR/layout-style.json;
layout-style.json 的格式:
{
"layout": "<layout>",
"style": "<style>"
}
2.2 结构化内容生成
读取分析结果和结构化内容模板,根据模板规则将 user_prompt 转换为适合设计的结构化内容:
ANALYSIS=$(cat "$TEMP_DIR/analysis.json")
LAYOUT_STYLE=$(cat "$TEMP_DIR/layout-style.json")
STRUCTURED_CONTENT_TEMPLATE=$(cat "$SKILL_DIR/references/structured-content-template.md")
遵循模板定义的三个阶段(高层大纲 → 分节展开 → 数据完整性检查),结合 analysis.json 中的学习目标、视觉呈现机会和关键数据,生成结构化内容并保存到临时目录:
cat > "$TEMP_DIR/structured-content.md" << 'EOF'
<Content generated based on structured-content-template.md format>
EOF
结构:$SKILL_DIR/references/structured-content-template.md。
规则:必须原样保留所有数据。不要改写。不要添加源内容中没有的信息。
2.3 提示词扩展(使用 sn-image-base 的 sn-text-optimize 工具):
读取布局/风格选择结果,然后通过直接拼接文件来组装系统提示词(不要使用 heredoc——布局/风格文件中包含反引号和 $(...),未加引号的 heredoc 正文会执行这些内容):
LAYOUT=$(jq -r '.layout' "$TEMP_DIR/layout-style.json")
STYLE=$(jq -r '.style' "$TEMP_DIR/layout-style.json")
{
cat "$SKILL_DIR/references/prompts-expand-system.md"
printf '\n\n---\n\n## Selected Layout: %s\n\n' "$LAYOUT"
cat "$SKILL_DIR/references/layouts/${LAYOUT}.md"
printf '\n\n---\n\n## Selected Style: %s\n\n' "$STYLE"
cat "$SKILL_DIR/references/styles/${STYLE}.md"
printf '\n\n---\n\n## Output Template Reference\n\n'
cat "$SKILL_DIR/references/base-prompt.md"
} > "$TEMP_DIR/expand-system-prompt.md"
将 structured-content.md 的内容用作用户提示词(通过 --user-prompt-path 传递,以避免 argv 长度和引号问题),从临时文件读取系统提示词,然后调用 sn-text-optimize:
EXPAND_ENVELOPE=$(python "$SN_IMAGE_BASE/scripts/sn_agent_runner.py" sn-text-optimize \
--system-prompt-path "$TEMP_DIR/expand-system-prompt.md" \
--user-prompt-path "$TEMP_DIR/structured-content.md" \
--output-format json | python "$SN_IMAGE_BASE/scripts/extract_json.py")
提取 result 字段作为 expanded_prompt 并写入临时目录。此处的 .result 是扩展后的提示词文本(不是 JSON),因此只通过 extract_json.py 解析外层封装。请先确认 .status == ok:失败的封装中没有 .result,所以 jq -r '.result' 会输出字面字符串 null,并将 "null" 写成图像提示词:
# A failed runner envelope (status != ok) has no .result → return Error Flow.
if [ "$(printf '%s' "$EXPAND_ENVELOPE" | jq -r '.status')" != "ok" ]; then
EXPAND_ERROR=$(printf '%s' "$EXPAND_ENVELOPE" | jq -r '.error')
# return Error Flow JSON {"status":"error","error":"$EXPAND_ERROR"} to Main Agent and stop
fi
EXPANDED_PROMPT=$(printf '%s' "$EXPAND_ENVELOPE" | jq -r '.result')
echo "$EXPANDED_PROMPT" > "$TEMP_DIR/expanded-prompt.txt"
expanded-prompt.txt:单个 UTF-8 字符串,在步骤 3 中原样传递给 sn-image-generate --prompt。
除上述状态检查外,如果解析失败或疑似内容被截断(返回内容不完整),Worker 也必须返回错误流程 JSON(status=error,包含真实错误消息)并终止——不得直接向用户发送消息(参见责任边界)。
步骤 3 — 图像生成循环
依次执行从 1 到 max_rounds 的 ROUND。在每次迭代中,将 shell 变量 ROUND 设为当前轮次编号,并在每个路径中使用 ${ROUND},以免连续轮次相互覆盖:
for ROUND in $(seq 1 "$MAX_ROUNDS"); do
# the Generate Image / Review Image / Save Round Result blocks below run inside this loop body
:
done
生成图像(使用 sn-image-base 的 sn-image-generate 工具):
python "$SN_IMAGE_BASE/scripts/sn_agent_runner.py" sn-image-generate \
--prompt "$EXPANDED_PROMPT" \
--image-size "$IMAGE_SIZE" \
--aspect-ratio "$ASPECT_RATIO" \
--save-path "$TEMP_DIR/round_${ROUND}.png" \
-o json
审查图像(仅当 max_rounds > 1 时执行):
- 如果未配置 VLM 模型:返回 Error Flow JSON,建议用户添加 VLM 配置或设置
max_rounds=1。 - 如果 VLM 调用失败或超时:不进行回退;返回包含真实错误的 Error Flow JSON。
python "$SN_IMAGE_BASE/scripts/sn_agent_runner.py" sn-image-recognize \
--system-prompt-path "$SKILL_DIR/references/prompts-critic-system.md" \
--user-prompt "Evaluate the diagram in the image against the rules. Output your assessment." \
--images "$TEMP_DIR/round_${ROUND}.png" \
--output-format json
将 VLM 响应映射到每轮记录中(VLM 响应架构定义在 $SKILL_DIR/references/prompts-critic-system.md 中;每条违规项都是包含四个字段的对象):
vlm.result→rounds[i].result(原样传递——"PASS"或"FAIL")vlm.violations→rounds[i].violations(原样透传——由{ rule_id, rule_name, detail, revised_description }对象组成的数组)len(vlm.violations)→rounds[i].violations_countvlm.reasoning→rounds[i].reasoning(原样传递的字符串)
当 max_rounds=1(不调用 VLM)时,将该轮记录默认设为 result="PASS"、violations=[]、violations_count=0、reasoning=""。
保存轮次结果:
{
"round": 1,
"image": "$TEMP_DIR/round_1.png",
"result": "PASS|FAIL",
"violations_count": 1,
"violations": [
{
"rule_id": "5",
"rule_name": "Illegible Text",
"detail": "<offending element description>",
"revised_description": "<suggested fix per the prompts-critic-system.md standards>"
}
],
"reasoning": "<VLM reasoning, or \"\" when max_rounds=1>",
"timing": {
"image_generation": { "elapsed_seconds": 12.34, "model": "sn_image_model" },
"vlm_review": { "elapsed_seconds": 5.67, "model": "sensenova-6.8-flash-lite" }
}
}
提前终止检查(仅当 max_rounds > 1 时执行):
- 如果
result=PASS,立即退出循环,不再继续生成 - 如果
result=FAIL,继续下一轮(如果还有剩余轮次)
步骤 4 — 图像质量排序
按 violations_count 升序、round 升序对图像排序,并将结构化 JSON 返回给 Main Agent。
返回约定
Worker Agent 完成后,其最后一条消息必须且只能是以下 JSON 字符串(裸 JSON,不带代码围栏,也不带前置或后置文本)。
下方示例中的符号说明:
<...>— 文档占位符;运行时替换为实际值。A|B— 列出的字面值之一;返回的 JSON 必须且只能包含其中一个(例如,"result": "PASS"或"result": "FAIL",绝不能是字面字符串"PASS|FAIL")。$VAR— 序列化前必须替换为解析后的值。例如,架构中的"image": "$TEMP_DIR/round_1.png"必须返回 Step 3 实际写入的绝对路径(例如,"/tmp/openclaw/sn-infographic/20260521_120000/round_1.png"),绝不能是字面字符串"$TEMP_DIR/round_1.png"。- 条件字段 — Rules 条目中注明“在……时省略”的每个字段,在对应情况下都必须从 JSON 中实际省略,不能以
null的形式保留。
正常流程:
{
"status": "ok",
"need_main_agent_send": true,
"expanded_prompt": "<original user_prompt if prompts_expand_skipped, else expanded result from Step 2.3>",
"prompts_expand_skipped": true,
"early_terminated": true,
"timing": {
"total_elapsed_seconds": 35.12,
"prompt_evaluation": { "elapsed_seconds": 2.11, "model": "sensenova-6.8-flash-lite" },
"content_analysis": { "elapsed_seconds": 3.22, "model": "sensenova-6.8-flash-lite" },
"prompt_expand": { "elapsed_seconds": 8.45, "model": "sensenova-6.8-flash-lite" }
},
"rounds": [
{
"round": 1,
"image": "$TEMP_DIR/round_1.png",
"result": "PASS|FAIL",
"violations_count": 1,
"violations": [
{
"rule_id": "5",
"rule_name": "Illegible Text",
"detail": "<offending element description>",
"revised_description": "<suggested fix>"
}
],
"reasoning": "<VLM reasoning, or \"\" when max_rounds=1>",
"timing": {
"image_generation": { "elapsed_seconds": 12.34, "model": "sn_image_model" },
"vlm_review": { "elapsed_seconds": 5.67, "model": "sensenova-6.8-flash-lite" }
}
}
]
}
错误流程:
{
"status": "error",
"error": "<Actual error information>"
}
规则:
status=ok必须包含need_main_agent_send: true。expanded_prompt:在status=ok时始终存在;当prompts_expand_skipped=true时,值为原始user_prompt,否则为 Step 2.3 的结果。prompts_expand_skipped:仅当跳过 Step 2 时存在(prompts_expand_mode=disable,或auto且评估通过),值为true;否则省略。early_terminated:仅当 Step 3 通过PASS提前退出循环时存在,值为true;否则省略(包括所有max_rounds=1的运行)。violations:由 VLM 响应提供的对象数组,架构见$SKILL_DIR/references/prompts-critic-system.md(rule_id、rule_name、detail、revised_description)。当result=PASS或max_rounds=1时为[]。violations_count:len(violations);当max_rounds=1时为0。reasoning:VLM 的reasoning字段原样返回;当max_rounds=1时为""。- 当
max_rounds=1时,单轮的result默认为"PASS"(图片已交付,不进行 VLM 检查)。 - 顶层
timing:total_elapsed_seconds:Worker 从 Step 0 到返回 JSON 的耗时。prompt_evaluation:Step 1 评估的{elapsed_seconds, model}。仅当prompts_expand_mode=auto时存在。content_analysis:Step 2.0 的{elapsed_seconds, model}。当prompts_expand_skipped=true时省略。prompt_expand:Step 2.3 的{elapsed_seconds, model}。当prompts_expand_skipped=true时省略。
rounds[].timing.image_generation.model:固定为"sn_image_model"(sn-image-generate 不会返回 model 字段)。rounds[].timing.vlm_review:当max_rounds=1时省略。
输出格式
友好模式(默认)
文本摘要 — 由 Main Agent 生成的一句话描述。长度:无论使用何种语言,均不超过 50 个字符(1 个汉字 = 1 个单位,1 个 ASCII 字符 = 1 个单位)。语言:遵循 user_prompt 的主要语言(以中文为主 → 输出中文;否则 → 输出英文)。
- 当
max_rounds = 1时:根据expanded_prompt提炼描述(重点说明信息图描绘的内容)。 - 当
max_rounds > 1时:根据 rank=1 轮次的result和violations提炼描述:result=PASS:语气积极。result=FAIL(1–2 项违规):简要指出具体问题。result=FAIL(≥ 3 项违规):客观概括主要问题。
图片:rank=1 的单张图片。
详细模式
Quality ranking result (high -> low)
---
Expanded prompt: [expanded | not expanded, using original prompt]
<expanded_prompt>
---
#1 round=<n> result=<PASS|FAIL> violations=<n> [early terminated]
#2 round=<n> result=<PASS|FAIL> violations=<n>
...
---
Time statistics: Total <total>s | Prompt evaluation <t>s | Content analysis <t>s | Prompt expansion <t>s | Image generation <t>s×<n> rounds | VLM review <t>s×<n> rounds
---
Images (sent in rank order)
替换规则:
| 占位符 | 规则 |
|---|---|
[expanded | not expanded, using original prompt] | 当 Return JSON 中存在 prompts_expand_skipped=true 时,为 not expanded, using original prompt;否则为 expanded。 |
<expanded_prompt> | Return JSON 中的 expanded_prompt 字段,原样呈现。 |
#k round=<n> result=… violations=… | rounds[] 中每个条目对应一行,按排名顺序排列(k = 1..len(rounds));<n> 为 rounds[i].round。 |
[early terminated] | 仅追加到实际触发提前终止的轮次(即结束循环的 result=PASS 轮次)。其他行均省略。如果 Return JSON 中没有 early_terminated,则不出现此标签。 |
Total <total>s | timing.total_elapsed_seconds。始终存在。 |
Prompt evaluation <t>s | timing.prompt_evaluation.elapsed_seconds。如果 Return JSON 中没有 prompt_evaluation,则完全省略此 | Prompt evaluation … 片段。 |
Content analysis <t>s | timing.content_analysis.elapsed_seconds。不存在时完全省略此片段。 |
Prompt expansion <t>s | timing.prompt_expand.elapsed_seconds。不存在时完全省略此片段。 |
Image generation <t>s×<n> rounds | <t> = rounds[].timing.image_generation.elapsed_seconds 的总和;<n> = len(rounds)。 |
VLM review <t>s×<n> rounds | <t> = rounds[].timing.vlm_review.elapsed_seconds 的总和(仅计入存在此字段的轮次);<n> = 进行 VLM 审核的轮次数。max_rounds=1 时完全省略此片段(未进行 VLM 审核)。 |
Images (sent in rank order) | 章节标题;图像本身的传递遵循宿主运行时的通道约定。 |
调用关系
- 底层依赖:
sn-image-base→sn-image-generate、sn-image-recognize、sn-text-optimize
参考资料
references/analysis-framework.md- 分析方法references/base-prompt.md- 提示词模板references/evaluation-standard.md- 评估标准references/layout-style-selection.md- 布局和样式选择规则references/prompts-expand-system.md- 提示词扩展系统提示词references/prompts-critic-system.md- 提示词评审系统提示词references/runtime-parameters.md- 运行时参数references/structured-content-template.md- 结构化内容模板references/layouts/<layout>.md- 布局定义(87 种布局)references/styles/<style>.md- 样式定义(66 种样式)
在步骤 2.3 中,仅阅读选定的布局/样式文件;切勿批量读取这两个目录来进行选择——选择仅基于名称且为随机选择(步骤 2.1)。