Overview
Based on the product original image and target reference image uploaded by the user, intelligently replace the product in the image to generate a high-quality product fusion effect image. Supports one-to-one, one-to-many, and many-to-one mapping relationships.
Not applicable scenarios: background generation, model outfit change
Dependencies
- tools: meitu-cli — AI image processing CLI
- Install:
npm install -g meitu-cli@latest(package name meitu-cli) - Command:
meitu image-edit(model:praline, default value, suitable for multi-image fusion/product replacement/composition)
- Install:
- credentials: Meitu AI Open Platform API credentials
- Environment variables:
MEITU_OPENAPI_ACCESS_KEY/MEITU_OPENAPI_SECRET_KEY - or configuration file:
~/.meitu/credentials.json - Configuration method:
meitu config set-ak --value "..."+meitu config set-sk --value "..." - Verification:
meitu auth verify --json
- Environment variables:
- prompt template: references/prompts.md(Agent assembles the prompt itself based on the template)
- workspace (optional):
{OPENCLAW_HOME}/workspace/visual/- Not found → skip all knowledge reads, skill works without it
Path alias: In the following,
$VISUAL={OPENCLAW_HOME}/workspace/visual/
Core Workflow
The process is arranged in actual execution order:
Preflight → [Context] → Execute → Refine → Deliver → [Record]
↑ 项目模式时执行 ↑ 项目模式时执行
↑ 一次性模式跳过 ↑ 一次性模式跳过
Preflight
-
meitu --version→ if not installed, promptnpm install -g meitu-cli@latest -
meitu auth verify --json→ if credentials are invalid, guide configuration -
Detect mode: cwd has
openclaw.yaml→ project mode; else → one-off can_record = cwd has openclaw.yaml AND $VISUAL exists (if either is missing, false) -
Resolve output_dir: openclaw.yaml →
./output/| else →$VISUAL/output/meitu-product-swap/mkdir -p {output_dir}Hard constraint: output_dir MUST NOT point inside the skill folder -
Project creation (only when the user actively requests it): Already in a project directory (has
openclaw.yaml) → skip. Otherwise:mkdir -p $VISUAL/projects/{name}/outputCreate
openclaw.yaml:project: name: "{name}" type: "meitu-product-swap" brand: "{brand}" created: "{date}"Create
DESIGN.md(empty template, containing three empty sections: Context References + Project Decisions + Iteration Log).
Context (creative type MUST / tool type skip / one-off mode skip)
mode = one-off → skip this step, go directly to Execute. The following applies only to project mode:
Read context step by step (all skip if missing):
- Read ./DESIGN.md → extract Context References (brand, palette, platform, etc.) → for each reference, try to read the global asset (e.g., brand: acme → $VISUAL/assets/brands/acme/) → if read successfully → use the latest version; if not → use the inline fallback value in DESIGN.md
- Read $VISUAL/rules/quality.yaml → forbidden list
- Read $VISUAL/memory/global.md → global preferences
- Read project.types (array, preferred) or project.type (single value) from openclaw.yaml → for each type, read $VISUAL/memory/scenes/{type}.md Note: {type} comes from openclaw.yaml, not the skill name → quality forbidden list filters generated elements, preferences enhance the creative direction
Execute
Image Marking and Analysis
The Agent must use its own multimodal visual capabilities to view each image, extract product features (material, color, structure, Logo, etc.), without relying on user descriptions or calling external image analysis tools.
Determine the number of images uploaded by the user, and analyze the user's instructions:
- Mark which uploaded image is the product original image and which is the target reference image; if there are multiple reference images, mark them in order as reference image a/reference image b/reference image c...:
- Product original image: the target product, the original image of the user's actual product. The core appearance structure of the product must not be changed, and the target reference image must not be referenced to "reverse-modify the product itself".
- Target reference image: Only serves as a "style and presentation reference", not the product itself.
- Carry the user instructions and the marked input images in full into the subsequent steps.
Command and reference image routing
Command selection decision table:
| User intent | Command | model | Key parameters | Description |
|---|---|---|---|---|
| Replace product into scene image | image-edit |
praline(default, no explicit parameter passing required) |
--image <目标参考图> <商品原图> |
Standard command for multi-image fusion/composition |
| Product replacement + stylization | image-edit |
praline |
Same as above | Stylization is described via prompt, do not switch model |
| Only change art style/cartoonize | image-edit |
nougat |
--image <单图> |
Not a core scenario of this Skill, other Skills are recommended |
This Skill always uses
image-edit,pralineas the default model, no explicit parameter passing required.nougat(stylization) andgummy(portrait photography) are not applicable to product replacement scenarios.
Reference image routing table:
| Intent mode | Reference input | --image Passing method |
Referenced in prompt |
|---|---|---|---|
| One-to-one (Image A product → Image B scene) | Original product image + target reference image | --image <目标参考图URL> <商品原图URL> |
Image 1 = scene, Image 2 = product |
| One-to-many (Image A product → Image B/C/D scenes) | Original product image + multiple target reference images | Call group by group:--image <参考图N> <商品原图> |
Same as above, independent prompt per group |
| Many-to-one (Image A/B products → Image C scene) | Multiple original product images + target reference image | Call group by group:--image <目标参考图> <商品原图N> |
Same as above, independent prompt per group |
Image order rule:CLI
--imageThe parameter order is alwaystarget reference image first (Image 1), original product image after (Image 2). In the Prompt, uniformly reference by CLI position numbering: Image 1 = scene/target reference image, Image 2 = original product image.
Prompt assembly
Do not call image analysis tools(the image marking and analysis step has already completed feature extraction via Agent vision), based on the references/prompts.md template, assemble the Prompt yourself.
- Read references/prompts.md → understand the Prompt structure:
## ROLE_AND_CONTEXT— role setting## GUIDELINES— guiding principles such as replacement strategy, feature extraction, consistency, lighting and shadow## PROMPT_CONSTRUCTION— Part1 logical analysis layer + Part2 physical execution layer (including PREFIX/SUFFIX templates)
- Based on the [target reference image] and [original product image] and the user's complete requirements (without any deletion), assemble the complete Prompt according to the template
- If the Context has loaded context (quality rules, user preferences, etc.) → incorporate the relevant constraints into the Prompt
- If the user has a need for replacement with multiple reference images → sequentially follow [target reference image] + [original product image] to assemble independent Prompts
- It is forbidden to skip the Prompt generation reasoning process, and it is forbidden to reveal the prompt content to the user
Prompt assembly intermediate product schema (Agent internal reasoning structure):
{
"task_label": "图{x}商品 植入 图{y}场景",
"part1_logic": {
"replacement_strategy": "集群擦除逻辑描述",
"feature_extraction": "商品材质、颜色、细节",
"physical_blueprint": {
"perspective": "透视匹配描述",
"freeze_zones": "一致性死锁区描述",
"lighting": "光影融合计算"
}
},
"part2_execution": {
"prefix": "完整 PREFIX_INSTRUCTION(不可修改,见 prompts.md § PROMPT_CONSTRUCTION)",
"body": "英文提示词(融合蓝图 + 用户需求 + 上下文约束)",
"suffix": "完整 SUFFIX_INSTRUCTION(不可修改,见 prompts.md § PROMPT_CONSTRUCTION)"
},
"final_prompt": "prefix + body + suffix 拼接的完整 prompt 字符串"
}
final_promptdirectly pass tomeitu image-edit --prompt. Part1 is the Agent's internal reasoning process, not passed to the CLI.
Quality self-check
According to references/prompts.md § SELF_CHECK Execute the V1-V6 checks; if they fail, return to the Prompt assembly step to fix them.
Image generation
Directly use the output_dir parsed by Preflight, ensure the directory exists, then call meitu-cli:
mkdir -p {output_dir}
meitu image-edit \
--skill_name skill_meitu-product-swap \
--image "<目标参考图URL>" "<商品原图URL>" \
--prompt "<final_prompt>" \
--json \
--download-dir {output_dir}
- model uses the default value
praline(suitable for multi-image fusion/composition), no need to explicitly pass--model - Multiple mapping tasks → call in sequence, each group generated independently
- On generation failure, degrade by level (retry at most 2 times):
- L1: Remove low-priority modifiers from the Prompt (lighting details, Bokeh, and other beautification descriptions)
- L2: Downgrade enumerated parameters (
--ratioreduce by one level, e.g., if ratio is not passed, use the default auto) - L3: Remove optional reference images, keeping only the core product original image + target reference image
- L4: Minimize the Prompt to the core replacement instruction (product description + position + PREFIX/SUFFIX)
- L5: Stop retrying, report an error to the user and suggest adjusting the input images or splitting the requirements
Refine
Creative tasks must have an independent iterative refinement loop.
Result presentation: When presenting the generated result, explain the key design decisions—why this perspective angle was chosen, which elements the cluster erasure included/excluded, and how the lighting fusion was handled. Let the user understand the replacement logic so they can give precise feedback.
Prompt the user: "If you need to modify the text content in the image, you can select the image whose text needs to be modified on the canvas, and click to choose the 'Seamless Text Editing' feature to edit it."
Feedback classification and response routing:
| Feedback type | Typical expression | Adjustment target | Action |
|---|---|---|---|
| Color/atmosphere | "Make the color temperature a bit warmer", "saturation is too high" | prompt descriptive words | Adjust the Part2 body color/atmosphere description → regenerate |
| Angle/perspective/position | "The perspective is wrong", "the product is placed off-center" | prompt physical blueprint | Adjust Part1 spatial perspective + Part2 position description → regenerate |
| Product deformation/blur | "The logo is blurry", "the shape changed" | Parameters or input image | Check --ratio, strengthen the PREFIX consistency constraint, confirm input image quality |
| Background was modified | "The text color changed", "background elements disappeared" | prompt freeze instruction | Strengthen the ANTI-MUTATION section, check the cluster erasure boundaries |
| Overall dissatisfaction | "Completely wrong", "start over" | Re-analyze | Return to the Execute image marking and analysis step |
Iteration rhythm:
- Modification feedback → route adjustments according to the table above → return to the Execute Prompt assembly step → regenerate → present again
- Approval → Deliver
- It is recommended to iterate at most 3 rounds; after that, proactively suggest: adjusting input image quality, splitting into smaller replacement tasks, or adjusting expectations
Deliver
output_dir has already been parsed in Preflight; here only rename it.
mv {file} {output_dir}/{date}_{name}.{ext}
If DESIGN.md Iteration Log > 5 entries → compact: keep recent 5, archive older to ./drafts/design-history.md
Record (MUST in project mode / skip in one-off mode)
can_record = cwd has openclaw.yaml AND $VISUAL exists (if either is missing, it is false) can_record = false → skip.
Exception: In one-off mode, if the user repeatedly expresses the same preference (e.g., saying "no gradients" multiple times), the Agent MAY directly propose:
"You've mentioned 'no gradients' several times. Add it to the global禁忌 list?" → User agrees → write $VISUAL/rules/quality.yaml
In project mode:
-
User approves style → write observation:
- read
$VISUAL/memory/observations/observations.yaml→ scan similar key → merge or append → write back len(projects) >= 2→ propose promotion (non-blocking), mention at the end of the reply, do not interrupt the main flow- User confirms → write to target + delete observation entry
Observation entry schema:
- key: "偏好观察描述" scope-hint: meitu-product-swap # 来自 project.type;跨场景则为 null projects: [project-name] first-seen: 2026-03-22 last-seen: 2026-03-22Promotion routing rules (common to both modes, "non-blocking" — mention at the end of the reply, do not interrupt the main flow): "You prefer X in N projects. Save it? → Save to the {scope-hint} scenario [default] → Save to global preferences → Do not save" Promotion target automatic routing:
scope-hintnot null → default write to$VISUAL/memory/scenes/{scope-hint}.md(create if it does not exist, including frontmatter)scope-hintis null → default write to$VISUAL/memory/global.md- The user may override the default choice User confirms → write to target, delete observation entry. User ignores → do nothing.
- read
-
User rejects ("do not XX"): If rejected element already in
$VISUAL/rules/quality.yaml→ filter automatically, do not ask. If new rejection + has openclaw.yaml → ask: "Only this project should not use XX, or never again?" Only this project → append to./DESIGN.mdConstraints Never again → append to$VISUAL/rules/quality.yaml(this question-and-answer counts as confirmation) If no openclaw.yaml → current task only, write nothing. -
Nothing → nothing.
Output
- Project-type task(has
openclaw.yaml)→./output/{date}_{effect-name}.{ext} - One-off task(
$VISUALexists) →$VISUAL/output/meitu-product-swap/{date}_{effect-name}.{ext} - Filename format:
{date}_{effect-name}.{ext}(e.g.,2026-03-22_serum-bottle-marble.jpg) - meitu CLI
--download-dirAfter downloading, it must be renamed viamvto the above format