moai-media| Soul Character · Reference Element determination and generation (core:media-higgsfield-core)
Overview
It covers two means of "making the same person, the same character, or the same product appear consistently across multiple shots." The two means are not substitutes but separate paths with different constraints, and choosing wrong wastes training time and credits.
The call contract, namespace runtime resolution, and cost preflight follow the core:
- Call contract:
../media-higgsfield-core/references/call-schema.md - Live query:
../media-higgsfield-core/references/catalog-protocol.md - Job/cost/readback:
../media-higgsfield-core/references/job-lifecycle.md
Trigger keywords
Soul, Soul ID, soul, digital twin, character training, face training, identity, character consistency, Element, reference element, reference element, reusable character, same person, same product
Comparison of the two paths (basis for determination)
| 축 | Soul Character | Reference Element |
|---|---|---|
| How to create | Train on 5–20 images (about 10 minutes, non-blocking) | Instantly generate from 1 image (synchronous) |
| How many per generation | Only 1 | Multiple (<<<id>>> multi-batch) |
| Target | 1 person | People, environments, and props alike |
| Available models | soul_2, soul_cinematic Dedicated |
Nano Banana series, GPT Image 2, Seedream, Cinema Studio, Seedance, Kling, etc. |
| identity fidelity | High (dedicated training) | Moderate (reference injection) |
| Reversibility | After training costs are incurred | Almost no cost |
For detailed determination rules and the full list of supported models, see references/soul-vs-elements.md.
Determination workflow
Step 0 — Is it a photo of a person (before path determination)
[HARD] The face consent gate comes before the Soul/Element branch. Uploading a photo of a person to the server is the same act regardless of which path is taken, and the path is decided afterward.
If this order is reversed, a hole opens in the gate. Signals that settle on Element include **"only 1 image available"** and **"right now/quickly"** (Step 1). That is, a request to urgently upload a single photo of a third party's facebranches exactly to Element, and if the gate exists only on the Soul side, that request is uploaded without any confirmation. The structure was such that the most dangerous input bypassed the gate.
Conditions that trigger the gate: The image to be uploaded contains a human face. If there are only non-human subjects (products, props, backgrounds, logos), this gate is passed and it goes to Step 1.
- [HARD] If even one photo of a person is mixed in,
media_uploadstops before. Whether it is Soul or Element, chapter 1 or chapter 20, it is the same. - [HARD] Approval and consent are different items. Use the two items in §Gate 1 below as they are.
- If consent was not obtained, do not upload and terminate. Do not proceed to path determination.
Just because it is the Element path does not mean the risk is lower. There is no training, but that person's face goes to the server, and images are generated with that face. The property of being irreversible is the same.
Step 1 — Path determination (after passing Step 0)
Determine the path using the signals below. If neither is certain, do not generate and return a blocker. — the orchestrator confirms with the user. This skill does not ask the user directly.
Signals confirmed as Element (if any one applies, Element):
- In a single shot, the person/subject is 2 or more people ("me and a friend", "two people")
- The subject is not a person (product, prop, background, logo)
- The images you have are only 1
- Nano Banana·Seedream·Kling·Cinema Studio 등 A model that is not of the soul familyis specified
- Requests for immediacy such as "right now", "quickly"
Signals confirmed as Soul:
- Explicit expressions such as "learning", "training", "digital twin", "my identity"
- Photos of the same person 5 or morewere provided and a solo shot is the purpose
If neither applies → blocker. Starting Soul training in an ambiguous state is the failure this skill aims to prevent.
Step 2-A — Soul path
A face is irreversible personal information. If you upload photos, they remain on the server, and once training is complete, a model that can keep generating images with that person's face remains in the account. Therefore, the Soul path has two approval gates — one before uploading photos, and one before submitting training. These are different matters, so they are not bundled into a single approval.
Gate 1 — Before upload (before photos leave for the server)
If it is a photo of a person, this gate has already been passed in Step 0. Do not ask again here. The content below is the definition of that gate, and Step 0 and the Element path refer to it together.
- [HARD] Approval is obtained through the path in §Approval Request Contract. Do not ask in prose. If this skill is running as a subagent and cannot ask, return a blocker and the orchestrator asks instead (same protocol as Step 1).
- [HARD] Do not summarize; show exactly what will actually be uploaded:
| What to show | Why it is necessary |
|---|---|
| Full list of photo filenames · number of photos | Confirm at the file level which photos are being sent |
| Who the person in the photo is | This leads to the consent question below |
| Account to upload to | Whether it is a personal account or a company/shared account |
- [HARD] Person consent is confirmed as a separate question. "Is it okay to upload the photo" and "is it okay to train on this face" are different questions.
| Options | 뜻 |
|---|---|
| It is my face (recommended) | Myself — proceed as is |
| It is a third party and I have obtained consent | Leave the basis for consent (written form, contract, photo consent form, etc.) in one line and proceed |
| I have not obtained consent yet | Stop — do not upload the photo |
The fact that consent was given for photography and posting is not consent to "train an AI model on my face." Event photos, group photos, and customer photos fall under this.
Gate 2 — Before training submission (action:'train' immediately before)
Once the upload ends, stop again before credits are spent. This time, show money and the training output:
| What to show | Why it is needed |
|---|---|
Uploaded media_id list · final number of images |
What actually goes into training |
Soul name · type(soul_2 / soul_cinematic) |
It remains under this name in the account list |
| Estimated credits and plan conditions | Training is a paid plan (Basic or higher) feature |
| Whether an existing Soul with the same name and same person exists | Duplicate training spends credits twice |
- [HARD] Before submitting, look up existing Souls first.
show_characters(action:'list', status:'ready')Check whether the same person and same name have already been trained, and if so, show that fact on the approval screen and let the user choose retraining. - [HARD] Even if it fails, do not automatically resubmit. If training submission fails ambiguously (timeout, no response), stop without resubmitting. The absence of a success signal is not evidence that training did not start.
show_characters(action:'list')First check whether it was actually created, and resubmit only after it is confirmed that it was not.
Execution procedure after approval
- Image preparation. Local paths are not accepted.
media_upload→ byte PUT →media_confirmupload in the order ofmedia_idto obtain a UUID. A completed image job ID or https URL is also allowed. - Quality check. 520 images, recommended 812 images. The more varied the angle, lighting, expression, and distance, the better. For detailed criteria, see
references/training-photo-guide.md. If it falls short of the criteria, notify the user before submitting training. - Type selection. Decide based on downstream use — for still images,
soul_2, for cinematic,soul_cinematic. - Training submission.
show_characters(action:'train', name, medias[]). It is non-blocking and takes about 10 minutes. - Status check.
show_characters(action:'status', soul_id). Polling is silent — do not repeatedly report progress. - Handoff. When ready,
soul_id를generate_image의params.soul_idpass it to. The model issoul_2orsoul_cinematic.
When finding an existing Soul, show_characters(action:'list', status:'ready').
Step 2-B — Element path
[HARD] If the image has a person in it, the Step 0 gate must already have been passed. If you entered this path without a record of passing, do not upload and go back to Step 0 — do not skip it on the grounds that "it's an Element so there's no training, so it's fine."
- Image preparation. Same upload procedure as Soul.
medias[]The item is in the form{id, url, type}andtype은media_input(upload) orimage_job(previously generated). - Creation.
show_reference_elements(action:'create', medias[]).categoryleave as the defaultauto(server classification), and only specifycharacter/environment/propwhen the user explicitly states it.nameis within 32 characters and is automatically assigned by the server if omitted. It is a synchronous return. - Usage. Insert the returned element id into
generate_image/generate_video의params.promptinside<<<element_id>>>in the form. Multiple can be placed in one prompt. - Lookup.
show_reference_elements(action:'list')oraction:'get'.
When using an Element, the
<<<id>>>notation that goes into the prompt is an internal mechanism. Do not explain this syntax to the user in the result report — for the user, "I put that character in" is enough.
Cost and account prerequisites
- Soul training requires a **paid plan (Basic or higher)**. If on a free plan, notify before submission.
- Training itself and subsequent generation are separate costs. Immediately before actual generation,
get_cost: truethe preflight follows the core rules as-is. - Element creation has no training, so the cost burden is small.
Output format
## Higgsfield 일관성 참조 결과
- 선택 경로: [Soul | Element] — 판정 근거: [걸린 신호]
- 이름: [name]
- 참조 ID: [soul_id | element_id]
- 상태: [ready | training | 생성 완료]
- 사용 가능 모델: [경로별 제약]
- 다음 단계: [generate_image에 어떻게 넘기는지]
Precautions
- If the path is ambiguous, do not generate. Soul training takes time and credits and cannot be undone.
- Do not put a local file path
mediasas-is into — always upload to obtainmedia_id(same rule as corecall-schema.md§2). - Per generation,
soul_idis 1. Do not try to bypass a request for 2 or more people appearing via Soul. - Do not pass a Soul to a model that is not of the soul family — it will be ignored or cause an error.
- Common causes of training failure (insufficient photos, monotony, sunglasses/hat obstruction, group photos) are
references/training-photo-guide.md. - Do not upload or train another person's face without consent. This is not a guide but a gate — if the Step 0 consent question yields "I haven't gotten consent yet," stop without uploading the photo. Do not settle for informing them that "portrait rights are the user's responsibility" and proceeding.
Approval request contract (runtime-neutral)
[HARD] This skill's gate is not tied to a specific tool name. AskUserQuestionis merely a means of the Claude runtime, and other runtimes, including Codex, do not have that tool. If you write the contract in terms of tool names, then in a runtime that lacks that tool the gate becomes a permanent blocker, and every task requiring approval simply stops. That is not safety, it is breakage.
Approval is obtained in the following order. From the top, the first one that is actually possibleis used.
The definition of approval is the result, not the means: showing the approval form to the user as is and receiving an explicit response to it. Below are the paths that produce that result, and from the top, the first possible one is used.
| Rank | Path | Condition |
|---|---|---|
| 1 | The runtime's structured question tool (AskUserQuestion 등) |
when that tool is exposed in the current session |
| 2 | Present the approval form in ordinary conversation and receive the response on the next turn | when in direct conversation with the user. Even without the tool, this path is always open |
| 3 | Return a structured blocker → the higher-level orchestrator asks | when running as a subagent |
[HARD] The runtime's tool execution permission prompt is not approval. That prompt only asks "may this tool be called"; it does not display the arguments, estimates, and consent items that the gate is supposed to show. It counts as path 2 only when the entire approval form and the options are actually displayed.
[HARD] Because path 2 exists, the situation of "having no means to ask" effectively does not exist. Wherever conversation is possible, the approval form can always be presented in writing. fail-closed applies only to fully unattended execution where neither conversation nor returning a blocker is possible— only in that case does it stop without executing.
[HARD] When using path 3, the blocker must itself be an approval request form. If the higher level does not know what to ask, it cannot ask back, and then there is a deadlock. Include all of the following:
- The action to be approved in one line (what is irreversible / how much money is going out)
- All arguments required by the gate (values not summarized)
- List of options — in a form the higher level can present to the user as is
- How to resume — upon receiving which answer, what is executed next
[HARD] In unattended execution where all three paths are impossible, do not execute (fail-closed). Having no means to ask does not mean approval was received. In this case, record "could not proceed because there was no means of approval" and stop — do not proceed silently. Conversely, stopping because there is no tool even though conversation is possible is also wrong. Use path 2.
This contract
CLAUDE.local.mdThis is the application of the general-purpose principle (identical behavior across 2 OS types × 2 runtime types) to the gate side. A gate that runs on only one runtime is considered incomplete.
Related skills
| Skill | Timing |
|---|---|
moai-media:media-higgsfield-core |
Core: invocation contract, cost, namespace |
moai-media:media-higgsfield-image |
Follow-up: generate an image using a reference |
moai-media:media-higgsfield-video |
Follow-up: generate a video using a reference |
moai-story:story-character-sheet |
Prerequisite: design what to train (angle, anchor) |
moai-designer:design-brand-visual |
Follow-up: brand model and mascot consistency |
Source
- Higgsfield Skills (official agent documentation) —
higgsfield-soul-idSkills v0.12.0 (MIT). The training photo criteria and failure causes are based on this documentation. - Live MCP tool schema observations (
show_characters/show_reference_elements) — basis for the Soul/Element branching rules, supported model list, and upload constraints. Evidence tier: 1차. - The official CLI skill has no Element path or branching rules. For that part, MCP schema observations are the sole source.