Script path description: This Skill depends on
image_gen.pylocated in this SKILL.md in the same directory'sscripts/under. Before AI execution, first confirm the script exists:ls {SKILL所在目录}/scripts/image_gen.pySpecify the path when running the command:python3 {SKILL所在目录}/scripts/image_gen.py ...
Convert WPS note content into a complete Xiaohongshu image-and-text plan, including each page's image and text, AI-generated images, and topic tags.
Iron rules (highest priority)
0. Read images (must be completed before Step 2)
Call outline to find all image blocks, call read-image on each one to read and make a visual description, recording each image's visual content, style and color tone, and which page it is suitable for.
wpsnote-cli outline --note_id {note_id} --json
wpsnote-cli read-image --note_id {note_id} --block_id {block_id} --json
MCP fallback:read_image({ note_id, block_id })
After reading is complete, report in the conversation: "The original text has N images in total, image 1 [visual description], suitable for P{page number}; image 2..."
When the original text has no images: say "the original text has no images" and continue.
1. All output must be written into WPS notes; it is forbidden to output the body text directly in the conversation
- It is forbidden to output any image-and-text content, copy body text, or tag lists in conversation messages
- The only legal output method: through
create_note+batch_edit/edit_blockwrite into WPS notes - After successful writing, only say in the conversation: note title, page count, one-sentence summary, "written into notes"
- If any of the above is violated, stop immediately and rewrite through the tool
2. Questions must include options
Only two things can be done in the conversation:Ask questions + Status notification。
- When asking questions, 2-4 alternative options must be attached
- Status notification: before calling a tool, say in one sentence what is being done
4. Copy must be faithful to the original text (most error-prone, highest priority)
Core principle: This is a "rewrite and condense" task, not a "recreate" task.
- Each page's body text must come from the real content of the corresponding section in the original text, and must not be freely expanded or supplemented by AI
- Directly rewrite the original paragraphsinto a colloquial Xiaohongshu style; core viewpoints, data, and examples must be consistent with the original text
- Prioritize retaining the original text's golden lines, such as "organizing is AI's job, thinking is the user's job", "just throw it in", etc.
- Which section of the original text each page corresponds to must be clear(mark it during planning, such as "P2 → original text 01 The periodic law of note-taking software")
Strictly prohibited behaviors:
❌ 用自己的话"总结"原文,丢失具体细节
❌ 添加原文没有的观点、类比、案例
❌ 用通用小红书套话替换原文独特表达
❌ 把多个不相关章节内容混写成一页
5. Image generation must prioritize using original images as reference images
When original images are available, direct text-to-image generation is forbidden:
- When reading the source note in Step 2, all
imageblocks must be scanned; prioritize using the CLI to read base64 andimmediately use visual understanding to describe the image content(see Step 2, step 3):
MCP fallback:wpsnote-cli read-image --note_id {note_id} --block_id {block_id} --json # 返回 data.image_base64 字段read_image({ note_id, block_id }) - When generating images, select a source image from the page content nearby as a reference image:
# 先将 base64 保存为临时文件 python3 -c "import base64; open('/tmp/ref_pN.jpg','wb').write(base64.b64decode('{data.image_base64}'))" # 再传入 --image python3 scripts/image_gen.py ... --image /tmp/ref_pN.jpg - The visual description (prompt) must be written based on the actual image content, not an invented atmospheric image:
✅ 原图是:男生坐在电脑前,周围漂浮着笔记软件图标,困惑表情,线条插画风 → prompt:年轻男生坐在书桌前,Notion/Obsidian图标环绕飘散,眉头紧皱,同款线条插画风,奶油色调,竖版构图 ❌ 凭空写:温馨书房,女生整理笔记,日系风格(完全不参考原图) - Pure text-to-image is allowed only in the following cases:
- the source has no images
- the provider is dashscope (does not support reference images)
- the provider is ark (Jimeng) and there are only local images (ark supports only public URLs)
3. WPS note writing specification (violation will cause an error)
batch_edit The operations field name must be op, not type:
✅ { "op": "insert", "anchor_id": "...", "position": "after", "content": "..." }
❌ { "type": "insert", ... }
op Valid values are only:replace / insert / delete / update_attrs
insert of position can only be "before" or "after",anchor_id must be a real block id, cannot be null:
✅ { "op": "insert", "anchor_id": "aB3kLm9xZq", "position": "after", "content": "..." }
❌ { "op": "insert", "anchor_id": null, "position": "begin", ... }
❌ { "op": "insert", "anchor_id": null, "position": "end", ... }
To append at the end of the note: first get_note_outline get the id of the last block → anchor_id fill in that id,position fill in "after"
content must be a pure XML string, not an array and not natural language:
✅ content: "<h2>封面页(P1)</h2><p>内容...</p>"
❌ content: [{"type": "text", "text": "..."}]
❌ content: "把第二段改成..."
Concatenate multiple paragraphs of content in one go, do not insert in multiple times:
✅ 一次 insert,content 里拼多个块级标签
❌ 每个块单独 insert 一次(容易乱序、锚点失效)
When appending continuously, use last_block_id as the chained anchor (when batching is required):
第一次 insert → 返回 last_block_id: "id_A"
第二次 insert → anchor_id 用 "id_A",不要重新 outline
Core workflow
加载偏好 → 读取源笔记 → 分析内容 → 规划图文结构 → 生成各页文案 → 逐页生图 → 生成标签 → 确认是否更新偏好
Step 1: Load preferences
Use search_notes to search the keyword 小红书创作偏好。
- find the preference note → read and extract preference parameters, inform the user:
已加载小红书偏好:风格={风格} | 页数={页数} | 字数/页={字数} | 话题方向={方向} - preference note not found → enter first-time configuration process
Step 2: Read the source note
Ask the user:
"Please tell me the title or ID of the note you want to convert, and I will help you generate a Xiaohongshu image-text plan."
After obtaining the note identifier:
- Use
search_notesorget_note_outlineto locate the note - Use
read_noteto read the full content - Scan and understand the source images (important):
- Call
get_note_outline/wpsnote-cli outline --note_id {id} --jsonto find allimagetype blocks - For each image, prefer reading with CLI (fall back to MCP):
MCP fallback:wpsnote-cli read-image --note_id {note_id} --block_id {block_id} --jsonread_image({ note_id, block_id }) - After reading base64, immediately use visual understanding to describe the image content, record format:
图片1:block_id=xxx,位置第N页附近 画面内容:{描述图里有什么:人物/场景/元素/布局} 风格色调:{插画/摄影/扁平/日系/科技感/色调} 可用于:P{页码}(与该页主题最相关) - No images → record "no source images, use pure text-to-image"
- Call
- Analyze the following elements:
- Core theme (1 sentence)
- Key knowledge points (3-7)
- Content type (practical tutorial / experience sharing / knowledge popularization / emotional story)
- Audience profile (beginners / experienced people / specific groups)
- Highlights suitable for conversion
Inform the user: "Read the note 《{Title}》, identified as 「{Content type}」, with the core being 「{Theme}」. The source contains {N} images, which will be prioritized for reference-image generation of accompanying images."
Step 3: Plan the image-text structure
Based on the content type and the page count setting in the preferences, plan the theme of each page:
Standard image-text structure (6-9 pages recommended)
| Page number | Type | Function |
|---|---|---|
| P1 | Cover page | Title + core hook, to make people click in |
| P2-PN-1 | Content page | One knowledge point/step/highlight per page |
| PN | Ending page | Summary/key quote + encourage interaction (like/save/comment) |
Page count suggestion
| Content type | Recommended page count |
|---|---|
| Practical tutorial | 7-9 pages (step breakdown) |
| Experience sharing | 6-7 pages (story + takeaways) |
| Knowledge popularization | 6-8 pages (concept + case) |
| Emotional story | 5-6 pages (tight pacing) |
After planning is complete, call create_note to create a new note (title:{源笔记标题} - 小红书图文), use batch_edit to write the planning structure (placeholders only), then inform the user of the page count allocation,continue directly without waiting for user confirmation。
When planning the theme of each page,you must mark the corresponding chapter or paragraph of the original text(e.g., "P2 → Original text 01 The periodic law of note-taking software"), ensuring every page has an original-text anchor and nothing is fabricated.
Step 4: Generate image-text content
Preparation that must be done before writing
- Call
get_note_outline(note_id)to get the current block structure, and record the id of the last block as the firstanchor_id - Assemble all page content into a complete XML string in one go, and use one
edit_block'sinsertwrite to avoid multiple calls causing disorder or block_id invalidation - If writing must be done in batches: after each insert, take the returned
last_block_idas the nextanchor_id,Do not reuse old ids
Content structure of each page
Each page includes:
- Page title: 6-12 characters, eye-catching and powerful,must be distilled from the original text, not invented
- Body copy: according to the preferred word count/page, rewrite the original text in colloquial language,no making things up(see Iron Rule No. 4)
- Visual description(image generation prompt): subject + scene + style + color tone,prioritize referencing the image style of the original text(see Iron Rule No. 5)
Complete structure written into the note
<h1>{源笔记标题} - 小红书图文</h1>
<p><tag>#小红书</tag></p>
<p>来源笔记:{标题} | 页数:{N}页 | 风格:{风格}</p>
<h2>封面页(P1)</h2>
<p><strong>页面标题:</strong>{封面标题,12字以内,有爆款感}</p>
<p><strong>副标题:</strong>{副标题/钩子句,20字以内}</p>
<p><strong>视觉描述:</strong>{生图prompt}</p>
<p><strong>配图:</strong>生成中…</p>
<h2>内容页 P2:{页面主题}</h2>
<p><strong>页面标题:</strong>{标题}</p>
<p><strong>正文:</strong>{内容文案}</p>
<p><strong>视觉描述:</strong>{生图prompt}</p>
<p><strong>配图:</strong>生成中…</p>
<!-- 更多内容页… -->
<h2>结尾页(PN)</h2>
<p><strong>页面标题:</strong>{金句或总结}</p>
<p><strong>正文:</strong>{互动引导文案,如:觉得有用就收藏吧~}</p>
<p><strong>视觉描述:</strong>{生图prompt}</p>
<p><strong>配图:</strong>生成中…</p>
<h2>发布文案</h2>
<p><strong>标题:</strong>{发布标题,含关键词,≤20字}</p>
<p><strong>正文:</strong>{完整发布正文,200-500字,首行必须吸引眼球}</p>
<p><strong>话题标签:</strong></p>
<p>{标签1} {标签2} {标签3} … (8-15个)</p>
<h2>推荐发布时间</h2>
<p>{工作日 / 周末} {上午 / 午休 / 晚间},约 {具体时段}</p>
After writing, inform: "The image-text plan has been written, {N} pages in total." Then proceed to Step 5 to check the image generation Key.
Step 5: Illustrate page by page
Iron Rule 6: Image generation Key check (must be executed once before all image generation)
If an external provider is already set in preferences:
- Search the note library for notes whose titles contain
图像生成 Keyand find the corresponding provider'sciphertext_b64 - Found → use note mode(
--key note:{笔记ID} --ciphertext {密文}) - Not found → stop and ask the user:
没有找到你的 {provider} Key,无法生图。请选择:
A. 现在提供 Key(可选择是否保存到笔记)
B. 跳过配图,只保留文案方案
Silent downgrade to built-in tools is strictly prohibited, and you must wait for the user to make an explicit choice before continuing.
Image decision for each page (judge in this order, do not skip)
铁律0 已读取到该页原文图片(read-image base64)?
├─ 是 → provider 支持垫图(openrouter / gemini)?
│ ├─ 是 → 【方式A】原图 + 文案 → 排版生图
│ └─ 否(ark / dashscope)→ ⛔ 跳过,该页不配图,占位文字保留
└─ 否(原文无图)→ 【方式B】纯文生图(兜底)
- When ark / dashscope encounters a page with an original image: skip directly, do not downgrade to text-to-image, do not generate any image
- Only if the user explicitly says "regenerate image" or "do not use the original image" → is it allowed to switch that page to Method B
[Method A] Original image + copy → layout image generation (preferred)
Core idea: Pass the original image + the copy for the current page to the image generation AI at the same time; the AI directly outputs a laid-out Xiaohongshu vertical card image. The AI takes your image and your text, and is responsible for the layout.
Execution steps:
# Step 1:将 read-image 取到的 base64 存为临时文件
python3 -c "
import base64
data = '{从read-image取到的完整base64字符串}'
with open('/tmp/ref_p{页码}.jpg', 'wb') as f:
f.write(base64.b64decode(data))
print('saved')
"
# Step 2:把原图 + 排版文案一起传给生图 AI
python3 scripts/image_gen.py \
--provider "{偏好provider}" \
--model "{对应模型,见下表}" \
--key "note:{key笔记id}" --ciphertext "{密文}" \
--image /tmp/ref_p{页码}.jpg \
--prompt "小红书竖版卡片排版,3:4 比例。
页面标题(大字居中):{当页标题}
正文内容:{当页文案,不超过80字}
风格:参考输入图片的画风、色调和视觉元素,保持一致。
要求:文字清晰可读,留白充足,符合小红书视觉审美。" \
--aspect "3:4" \
--out "./output"
provider corresponding model (hardcoded, cannot be modified):
| provider | Model | Whether local file image insertion is supported |
|---|---|---|
| openrouter | google/gemini-3.1-flash-image-preview |
✅ Supported |
| gemini | gemini-3-pro-image-preview |
✅ Supported |
| ark (Jimeng) | doubao-seedream-5-0-260128 |
❌ Not supported → skip this page |
| dashscope | qwen-image-2.0-pro |
❌ Not supported → skip this page |
[Method B] Text-to-image only (used when the original text has no image)
Used when the page in the original text itself has no image / the user explicitly requests regenerating the image. ark / dashscope users do not use this path for pages that have original images.
python3 scripts/image_gen.py \
--provider "{偏好provider}" \
--model "{对应模型}" \
--key "note:{key笔记id}" --ciphertext "{密文}" \
--prompt "小红书竖版卡片排版,3:4 比例。
页面标题(大字居中):{当页标题}
正文内容:{当页文案,不超过80字}
视觉风格:简约插画风,奶油色调
要求:文字清晰可读,留白充足,符合小红书视觉审美。" \
--aspect "3:4" \
--out "./output"
Built-in tool fallback (when image_gen.py cannot be used):
wpsnote-cli gen-image \
--prompt "{排版指令+文案}" \
--width 1080 --height 1350 --json
Or MCP:generate_image({ prompt: "...", width: 1080, height: 1350 })
⚠️ The built-in tool is rate-limited to 1 image per minute; before generating multiple pages, inform the user of the estimated time required (number of pages × about 60 seconds)
Image backfill steps
After each image is generated, execute in the following order:
1. Obtain the image URL
image_gen.pyImage generation: from[saved] {路径}take the local path and pass it as--srcImage generation: from the JSON output takewpsnote-cli gen-image, and pass it directly as the URLdata.image_url2. Refresh outline to obtain anchor_id
Find the block_id corresponding to the paragraph where "Image: generating…" is located as the
wpsnote-cli outline --note_id "{笔记ID}" --json
(when writing the note structure, the position of the "image" placeholder block for each page has already been recorded; take the id of the previous block as the anchor). anchor_id3. Insert the image (prefer CLI)
4. Delete the placeholder paragraph
wpsnote-cli insert-image \
--note_id "{笔记ID}" \
--anchor_id "{占位段落的前一个block_id}" \
--position "after" \
--src "{URL或本地路径}" \
--json
After successful insertion, use
delete to delete the "Image: generating…" placeholder paragraph. edit_block 5. Fallback: if CLI fails, use MCP
The note is required to be open in the WPS editor, otherwise it reports
insert_image({ note_id: "...", anchor_id: "...", position: "after", src: "..." })
⚠️
insert-image. When encountering this error, prompt the user to open the note and retry.INTERNAL_ERRORAfter each image is completed, say: "Image {N} ({page type}) has been written." After all are completed, say: "All {N} pages of images have been written into the note 《{note title}》."
Step 6: Confirm whether to update preferences
Ask: "This time the "{style}" style was used, {N} page plan. Are there any parameters that need adjustment? A. Update preferences B. No"
If the user says update →
- replace the entire preferences note, and after completion say "Preferences updated"
edit_blockIf the user says no → end - First-time configuration process
When no preferences note is found, ask:
After receiving it:
我没找到你的小红书创作偏好,先配置一下:
1. 内容风格?(知识干货 / 生活分享 / 情感共鸣 / 时尚美妆)
2. 默认页数?(6页 / 8页 / 10页 / 自动判断)
3. 每页字数?(50字以内 / 80字左右 / 100字以上)
4. 主要话题方向?(如:职场/读书/设计/健康/育儿/...)
5. 图片风格偏好?(插画风 / 摄影风 / 信息图表风 / 自动匹配)
6. 生图服务商?(openrouter需代理 / dashscope百炼国内直连 / ark即梦国内直连 / gemini需代理 / 用内置工具)
Call
- to create a note titled
create_noteCreate title小红书创作偏好notes - Write the preferences as a table (see the template below)
- Inform "Preferences saved, will load automatically next time"
- Continue executing Step 2
Preferences note template
<h1>小红书创作偏好</h1>
<p><tag>#小红书</tag></p>
<table>
<tr>
<td><p><strong>配置项</strong></p></td>
<td><p><strong>当前值</strong></p></td>
<td><p><strong>可选项</strong></p></td>
</tr>
<tr>
<td><p>内容风格</p></td>
<td><p>{风格}</p></td>
<td><p>知识干货 / 生活分享 / 情感共鸣 / 时尚美妆</p></td>
</tr>
<tr>
<td><p>默认页数</p></td>
<td><p>{页数}</p></td>
<td><p>6页 / 8页 / 10页 / 自动判断</p></td>
</tr>
<tr>
<td><p>每页字数</p></td>
<td><p>{字数}</p></td>
<td><p>50字以内 / 80字左右 / 100字以上</p></td>
</tr>
<tr>
<td><p>话题方向</p></td>
<td><p>{方向}</p></td>
<td><p>职场 / 读书 / 设计 / 健康 / 育儿 等</p></td>
</tr>
<tr>
<td><p>图片风格</p></td>
<td><p>{图片风格}</p></td>
<td><p>插画风 / 摄影风 / 信息图表风 / 自动匹配</p></td>
</tr>
<tr>
<td><p>生图服务商</p></td>
<td><p>{provider}</p></td>
<td><p>openrouter / dashscope(百炼) / ark(即梦) / gemini / 内置工具</p></td>
</tr>
</table>
Hashtag generation rules
Generate 8-15 tags, in three tiers:
| Tier | Quantity | Example |
|---|---|---|
| Core topics (high traffic) | 2-3 | #读书笔记 #学习方法 |
| Content topics (medium traffic) | 4-6 | #高效阅读 #知识管理 #笔记整理 |
| Long-tail topics (precise traffic) | 2-4 | #{内容具体关键词} |
Common issue handling
| Scenario | Handling method |
|---|---|
| Source note content is too little (<200 characters) | Prompt the user: The content is relatively little; we will try our best to enrich and extend it. Continue? |
| Source note content is too much (>5000 characters) | Use search_note_content to locate the core paragraphs, then refine and transform |
| The user requests reducing the number of pages | Merge pages with similar themes and keep the most essential knowledge points |
| image_gen.py image generation failed | Automatically downgrade to wpsnote-cli gen-image, and if it fails again, downgrade to MCP |
| All image generation failed | Keep the "visual description" text placeholder and tell the user they can manually add images |
| No provider is set in preferences | Use the built-in tool to generate images directly, and prompt the user that they can configure an external provider in preferences |
| The user says "the style is wrong" | Ask for the specific adjustment direction: color scheme/illustration/text layout/emotion |