mcpField
S
sn-infographic

sn-infographic

github.com/opensensenova设计与 UI6.0k174 次安装2 天前更新
代码仓库

关于 sn-infographic

sn-infographic 是用于生成信息图的技能,面向需要将文字需求转化为图片的 Agent。它可评估并扩写提示词,通过多轮生成和视觉语言模型审查排序输出。

主要功能

  1. 01评估提示词质量
  2. 02按需扩写提示词
  3. 03多轮生成与视觉审查
  4. 04按质量排序结果
  5. 05友好或详细输出模式

适用场景

  1. 01将简短需求转为图像提示词
  2. 02比较多轮生成的图像结果
  3. 03按指定比例与尺寸生成信息图

MCP 相关

此输入未说明其与 MCP 的关系。

安装

复制下面的命令,在终端中运行。

$npx skills add https://github.com/opensensenova/sensenova-skills --skill sn-infographic

安装后在 Claude Code 中输入/sn-infographic确认已加载。

包含的文件

除 SKILL.md 外,安装时一起下载的参考资料和脚本。

references/
analysis-framework.md
base-prompt.md
evaluation-standard.md
layout-style-selection.md
references/layouts/
asymmetry.md
axial-expansion.md
bento-grid.md
big-typography.md
binary-comparison.md
breaking-the-grid.md
bridge.md
center-focus.md
chapter-layout.md
character-guide.md
circular-flow.md
collage-glitch.md
comic-strip.md
comparison-matrix.md
conflict-contrast.md
containerization.md
dashboard.md
data-landscape.md
deconstruction.md
diagonal-composition.md
disrupted-flow.md
edge-tension.md
editorial-vogue.md
emotional-gradient.md
f-pattern.md
flashback.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字符串friendlyfriendly:一行内容描述 + 排名第 1 的单张图像
verbose:完整质量排名 + 计时统计 + 所有图像(按排名排序)
prompts_expand_mode字符串autoauto:先评估 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 > 环境变量 > 内置默认值),无需显式传入。

调用类型工具身份验证参数说明
LLMsn-text-optimize(评估/扩展)默认按 SN_TEXT_API_KEY -> SN_CHAT_API_KEY -> SN_API_KEY 的顺序读取内置默认值指向 Sensenova 内部网络服务
VLMsn-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 工作流
  1. 从用户请求中提取参数,分三轮进行:

    1. 行内 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。

    2. 关键词识别(不区分大小写,针对剔除标记后的文本执行)——根据下表填写尚未通过行内 KV 设置的参数:

      参数触发关键词解析值
      output_modeverbose、详细、详尽、完整统计verbose
      friendly、简洁、精简friendly
      max_roundsN 轮、N rounds、重试 N 次(解析 N)N,限制在 [1, 8] 范围内
      prompts_expand_mode强制扩写、force expand、force expansionforce
      不扩写、跳过扩写、disable expansion、no expanddisable
      aspect_ratio明确指定受支持的比例(16:9 9:16 4:3 3:4 1:1 2:3 3:2 4:5 5:4 21:9 9:21),可带或不带 宽高比 / 画面比例 / 比例 / aspect ratio 前缀对应比例(根据 runtime-parameters.md 中的受支持比例集合验证;不受支持的值 → 留空,由 Worker 推断)
      image_size明确指定受支持的尺寸(2k 4k),可带或不带 image_size / 分辨率 / 清晰度 / image size 前缀对应尺寸(模糊的画质词语,如 高清 / 超清,不计入);不受支持的值 → 留空,由 Worker 推断
    3. 默认值 — 任何仍未设置的参数均使用以下默认值:max_rounds=1、output_mode=friendly、prompts_expand_mode=auto。aspect_ratio 和 image_size 没有主 Agent 默认值:未检测到明确值时,将它们留空,由 Worker 在步骤 0 中推断。

    优先级:行内 KV > 关键词识别 > 默认值。根据输入规范验证行内 KV 中的值(超出范围的 max_rounds 限制在 [1, 8] 范围内;无法识别的枚举值回退为默认值,且主 Agent 应记录不匹配情况)。

  2. 发送统一的预检消息:"Using sn-infographic skill to generate infographic, please wait..."

  3. 启动 Worker Agent(子 Agent),传入完整参数和工作目录

  4. 当 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,详细模式:渲染详细模板(替换规则参见输出格式 → 详细模式),发送模板,然后按排名顺序发送所有图片
  5. 如果 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_PROMPTMain Agent 输入 — 用户的原始请求第 1 步评估;第 2.0 步内容分析
MAX_ROUNDSMain Agent 输入(默认值为 1)第 3 步循环边界;提前终止条件
PROMPTS_EXPAND_MODEMain Agent 输入(默认值为 auto)第 1 步分支
SKILL_DIRAgent 运行时解析当前 skill 的安装路径(例如 ~/.openclaw/skills/sn-infographic、~/.hermes/skills/sn-infographic)读取 references/*
SN_IMAGE_BASEAgent 运行时根据 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 步 — 初始化
  1. 生成 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"
    
  2. 初始化一个空的 rounds 列表

  3. 解析 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 模式(默认):

  1. 运行评估调用(强制)。内部评估 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")
    
  2. 决定 should_expand:

    • required_pass:required_results 中所有 answer 均为 "yes"
    • optional_pass:optional_results 中 answer="yes" 的数量 / 总数 ≥ 0.6
    • should_expand = not (required_pass and optional_pass)
  3. 保守回退:如果 EVAL_STATUS 不是 ok(评估调用本身失败),或 extract_json.py 以非零状态退出,则默认 should_expand = true。与步骤 2.0 / 2.3 不同,评估失败不会中止 Worker——auto 会回退为扩展提示词。

  4. 如果 should_expand = true:执行步骤 2。

  5. 如果 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 中各读取一次。

  1. 从临时目录 $TEMP_DIR/analysis.json 读取分析结果;
ANALYSIS=$(cat "$TEMP_DIR/analysis.json")
  1. 根据 data_type / tone / audience,按 $SKILL_DIR/references/layout-style-selection.md 中定义的候选项查找与加权随机抽样流程,获取一个 LAYOUT 名称和一个 STYLE 名称(仅限名称,不读取文件);
  2. 通过检查定义文件是否存在来验证选择结果(仅使用 [ -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
  1. 将选择结果保存到临时目录:$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_count
  • vlm.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>stiming.total_elapsed_seconds。始终存在。
Prompt evaluation <t>stiming.prompt_evaluation.elapsed_seconds。如果 Return JSON 中没有 prompt_evaluation,则完全省略此 | Prompt evaluation … 片段。
Content analysis <t>stiming.content_analysis.elapsed_seconds。不存在时完全省略此片段。
Prompt expansion <t>stiming.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)。

评论

支持 Markdown