Claude Skill

short-drama-image-prompts

为短剧人物、造型、地点、道具和状态编写或修改可直接复制的图片提示词 Markdown。用户提到角色设定图、三视图、参考图、场景板、道具图、风格帧、Look Development、状态变体或局部编辑提示词时使用;不生成图片,也不调用供应商。

LLM Mart · 0 points · 8 views 0 listing impressions 0 install-command copies
Virus-scanned Reviewed automatically before listing.

Full trust report

Download zenstory-ai-drama-skills-skills_short-drama-image-prompts-9e78a57.zip · 59 KB
Part of zenstory-ai/drama-skills — 11 skills

Install

skills CLI npx skills add https://github.com/zenstory-ai/drama-skills/tree/main/skills/short-drama-image-prompts
Claude Code claude plugin marketplace add https://llmmart.ai/marketplace.json && claude plugin install zenstory-ai-drama-skills@llmmart
Git git clone https://github.com/zenstory-ai/drama-skills.git

The skills CLI installs just this skill, for any of its supported agents. Claude Code installs the whole zenstory-ai/drama-skills collection as a plugin from our marketplace. Git is the plain clone.

Skill manifest

短剧资产图片提示词

把视觉事实写成可复用、可修改、可直接复制的角色板、场景板、道具板或状态图提示词,统一保存到 剧集/<EP>/图片提示词.md。每项用 IMG-... 标题,正文放在 ### 可复制提示词 引用块。 IMG-... 只是该提示词条目的稳定 ID,不声明图片已生成或可用;实际图片只能来自创作者已提供的输入,或经确认后的生产结果。

Quick Start

用 $short-drama-image-prompts 为 EP001 已确定的人物、地点和道具写可直接复制的图片提示词

入口

有当前视觉设定即可直接开始;剧本只在提示词需要确认剧情状态时读取。Look Development 是可选分支。 先确认用途:身份板、造型/状态变体、地点板、道具板、组合 production sheet 或比较风格帧。 分镜需要生产尾帧时,可把已接受的「收尾关键帧提示词」落实为独立 IMG-... 状态图条目: 说明来源 SHOT 与终点,沿用视觉事实和参考范围,不重新设计动作。实际生成以该 IMG 条目为来源。

创作者可读说明跟随项目语言;可复制正文跟随 short-drama.json#/format/prompt_language。没有 short-drama.json 时正文默认 使用 en,并在同一任务中保持一致;不能从创作者说明语言推断提示词语言。

工作流

  1. 锁定这一张图要固定的身份、状态、空间或比较变量。
  2. 只读所需资产事实、视觉方向、负面约束和已提供参考图。
  3. 按“主体与身份锚点 → 当前变体 → 构图/视角 → 光色/材质 → 背景边界 → 禁止项”写正文。
  4. 每张参考只控制身份、造型、地理、构图或风格中的明确部分,并在 REF-... 槽位里写出封闭词表中的 用途。
  5. 检查身份与变体、文字政策、视角和光线是否冲突。
  6. 用户要全部资产就完成全部,资产组只是内部批次。

提示词要求

  • 开头先写对象和用途,不用风格词淹没身份。
  • 只包含当前图能同时满足的要求;多视图/状态对照写清版面关系。
  • 保留稳定识别锚点,变体只改允许变化的部分。
  • 被《视觉设定.md》连续性锁点名的条目,锁面原样出现在可复制正文里,让这张参考图本身就把跨镜事实定住。
  • 避免无验证作用的质量词堆砌。
  • 可见文字、logo、水印、界面和字幕明确允许或禁止。
  • 正文可直接复制,不含占位符、流程说明、文件路径或 QA 结论。

按需知识

默认只读本 SKILL 和当前视觉设定。遇到对应问题时只打开一份:

完成与投产

每个点名对象都有明确用途、可复制正文、参考边界和禁止项,且相互不矛盾,即完成。本次请求同时 修改图片提示词与分镜时,当轮刷新受影响镜头的「图片提示词项」,不另建对账产物。实际生成必须 转 $short-drama-produce,展示精确任务并取得显式确认;本技能不调用外部服务。 五份创作文档齐备后,可转 $short-drama 对跨文档结构做一次机械核对;内容质量仍由创作者审查。

安装维护

只有安装、升级或排障时运行 python3 scripts/selftest.py。

Files (drama-skills)
  • agents
    • openai.yaml 301 B
      interface:
        display_name: "短剧资产图提示词"
        short_description: "为人物场景道具及局部编辑编写可追溯、可复用的图片提示词"
        default_prompt: "使用 $short-drama-image-prompts 为已接受资产编写可复制的人物、场景、道具或编辑图片提示词。"
      
  • assets
    • image-prompt-spec.jsonl.md 5.6 KB
      # `image-prompt-specs.jsonl` 填写模板
      
      首行是 `sources` 声明记录,之后每行一个候选规格对象,用于接受前预览;示例值不是默认答案。删除不适用字段,不要添加
      媒体任务、供应商或接口字段。上游引用默认绑定准确的已接受快照;只有与本对象同次发布的目标才写
      `authority:candidate`。对象接受状态由事务生命周期记录,不能靠改状态字样伪造。
      
      ## 首行:`sources` 声明
      
      本文件用到的每个上游快照在这里声明一次,键取产物文件名(`characters`、`looks`、`props`),
      在本文件内唯一且稳定:
      
      ```json
      {
        "record_type": "sources",
        "schema_version": "1.0.0",
        "sources": {
          "<identity-owner>": {
            "owner": "short-drama-assets",
            "artifact": "设定集/<identity-owner-file>.jsonl"
          },
          "<variant-owner>": {
            "owner": "short-drama-assets",
            "artifact": "设定集/<variant-owner-file>.jsonl"
          },
          "props": {
            "owner": "short-drama-assets",
            "artifact": "设定集/props.jsonl"
          },
          "<reference>": {
            "owner": "<reference-owner>",
            "artifact": "<project-relative-reference-record>"
          },
          "<edit-target>": {
            "owner": "short-drama-image-prompts",
            "artifact": "<精确目标>"
          }
        }
      }
      ```
      
      引用用 `src` 指向声明键,再写本条引用自己的 `record_id` 和 `field`:
      `{"src": "<identity-owner>", "record_id": "CHAR-<id>"}`。
      
      ## 规格行
      
      ```json
      {
        "spec_id": "IMG-<stable-id>",
        "status": "candidate",
        "purpose": "character_sheet | location_plate | prop_plate | look_state_variant | edit_delta",
        "asset_binding": {
          "identity_ref": {
            "src": "<identity-owner>",
            "record_id": "CHAR/LOC/PROP-<id>"
          },
          "variant_ref": {
            "src": "<variant-owner>",
            "record_id": "LOOK/VIEW/PSTATE-<id>"
          }
        },
        "source_refs": [
          {
            "src": "<identity-owner>",
            "record_id": "<record>",
            "field": "/<field>",
            "role": "identity_anchor | variant_delta | geography | scale | text_policy"
          }
        ],
        "reference_bindings": [
          {
            "slot_id": "REF-<stable-slot>",
            "order": 1,
            "artifact_ref": {
              "src": "<reference>",
              "record_id": "<accepted-reference-record>"
            },
            "role": "composition",
            "may_control": [
              "<本次允许借用的构图事实>"
            ],
            "must_not_control": [
              "<身份/内容/文字/状态等禁入事实>"
            ],
            "admission_status": "unverified | creator_described | visually_inspected",
            "reference_observation_ref": null,
            "unresolved_risks": [
              "<没有观察证据时保留的文字/水印/裁切风险>"
            ]
          }
        ],
        "recipe": {
          "name": "<type-recipe>",
          "version": "<suite recipe version>"
        },
        "intent": {
          "reuse_job": "<这张参考图后续保持什么>",
          "audience": "<使用者/阶段>"
        },
        "identity_or_form_anchors": [
          "<稳定、可见、可比较的锚点>"
        ],
        "variant_deltas": [
          {
            "field": "<变化对象>",
            "observable_change": "<位置/范围/结果>",
            "valid_range": "<接受的有效范围>"
          }
        ],
        "composition": {
          "view": "<观察方向/视图>",
          "framing": "<主体占比或板式>",
          "orientation": "<方向定义>",
          "scale_relation": "<尺度参照>",
          "spatial_relations": [
            "<锚点之间的关系>"
          ]
        },
        "appearance": {
          "materials": [
            "<识别所需材质>"
          ],
          "palette": "<主次色关系>",
          "lighting": "<光源、方向、用途>",
          "atmosphere": "<有事实依据的气氛>"
        },
        "background": {
          "policy": "clean | contextual | empty_stage",
          "details": "<背景与允许出现内容>"
        },
        "text_handling": {
          "source_policy_ref": {
            "src": "props",
            "record_id": "PROP-<id>",
            "field": "/text_policy"
          },
          "source_mode": "exact_readable | graphic_only | no_readable_text | pending_creator_text",
          "render_treatment": {
            "mode": "readable | symbolic | blank | postproduction",
            "surface": "<承载面>",
            "exact_text": "<仅 readable 且来自接受源时填写>",
            "layout_or_reserved_area": "<方向/区域/行数>"
          },
          "mapping_rationale": "<为何本次呈现保持 source policy>"
        },
        "constraints": [
          "<必须出现/保持>"
        ],
        "negative_constraints": [
          "<仅当前高风险且不矛盾的排除>"
        ],
        "edit": {
          "changes": [
            "<有边界变化>"
          ],
          "preserve": [
            "<身份/构图/光线/未影响区域>"
          ],
          "continuity_impact": "<影响的 accepted variant/binding 或 none>",
          "target_ref": {
            "src": "<edit-target>",
            "record_id": "IMG-<target-id>",
            "field": "/generic_prompt"
          },
          "entity_or_region": "<区域>"
        },
        "creator_overrides": [
          {
            "rule_id": "<IMG-*>",
            "choice": "<覆盖选择>",
            "rationale": "<原因>"
          }
        ],
        "generic_prompt": "<从本规格渲染的可复制通用提示词>",
        "derivation": {
          "renderer": "generic-markdown"
        },
        "provenance": "creator_project"
      }
      ```
      
      
      复制后按 `purpose` 删除不适用字段和悬空引用,`sources` 只保留仍被引用的键。Look Development 不使用本超集模板,改读
      [`lookdev-frame-spec.jsonl.md`](lookdev-frame-spec.jsonl.md),避免普通人物、地点和道具规格加载
      风格帧专属字段。
      每条参考只声明一个用途,多参考的 `slot_id` 稳定且 `order` 显式。类型取舍、文字政策与
      参考准入由技能按 `references/common-recipe.md` 判断。候选与已接受对象分开发布;自然语言修改先形成
      候选和内容差异,不直接覆盖原记录。
      
    • image-prompts.md 2.5 KB
      # `image-prompts.md` 可复制输出模板
      
      此文件由已接受规格生成。元信息用于核对来源;只复制引用块内的通用提示词。不要手写供应商参数。
      
      **这份模板属于结构化管线**(`image-prompt-specs.jsonl` 一路)。creator-first 项目的《图片提示词.md》骨架以 `SKILL.md` 为准:`## IMG-... · 中文名`,字段写成不加粗的
      `- 参考:`(取「无外部参考」或完整 `REF-...` 语法),正文标题是 `### 可复制提示词`。
      不要把这里的加粗字段名、`参考图用途`、`本次呈现` 或 `### 可复制通用提示词` 搬进 creator-first 文档——
      `creator_markdown_check.py` 按 `SKILL.md` 的骨架校验,照本模板写会被判「缺少参考字段」。
      
      ```markdown
      # EP<编号> · 资产图片提示词
      
      > 来源:`image-prompt-specs.jsonl` 的已接受记录
      > 配方:`<recipe>@<version>`
      > 范围:本文件仅提供提示词,不触发媒体服务;实际图片生产交 `$short-drama-produce`
      
      ## `<display name>` · `<purpose>`
      
      - **规格**:`IMG-<id>`
      - **绑定**:`<asset-id>` + `<variant-id>`
      - **用途**:<后续复用目标>
      - **参考图用途**:`<slot_id / order / reference>` 只决定 `<role / may_control>`;不得导入 `<must_not_control>`;检查状态 `<observation ref | unverified + risks>`;无参考则写“无”
      - **文字来源政策**:`exact_readable | graphic_only | no_readable_text | pending_creator_text`
      - **本次呈现**:`readable | symbolic | blank | postproduction`(附 source → treatment 映射)
      - **注意**:<未阻断的警告 / 创作者明确调整;无则写“无”>
      
      ### 可复制通用提示词
      
      > <正文语言按 `short-drama.json#/format/prompt_language`(独立运行时由用户指定,未指定为 `en`)——这一格不预设中文。用途/主体与区分性锚点在前,状态、构图、空间/尺度、材质/光线、背景、文字政策、保持/排除依次展开。不要出现字段名、hash、审查话术或生成历史。>
      
      ### 变体/编辑说明
      
      - **相对基准**:<基础版本;非变体可省略>
      - **变化**:<看得见的变化;无则省略>
      - **必须保持**:<`preserve_set`;非局部修改可简写或省略>
      - **连续性影响**:<已接受的绑定 / 无;非局部修改可省略>
      
      ---
      ```
      
      每个资产或版本独立一节;不要把多个互相冲突的造型、观察方向或状态合成一个可复制段落。
      该文件被手改过时,先按 `restore | adopt` 流程预览将要恢复或采用的内容。
      
    • lookdev-frame-spec.jsonl.md 4 KB
      # `lookdev-frame` 填写模板
      
      只在 `purpose: lookdev_frame` 时读取。首行是 `sources` 声明记录,之后每行一个候选风格帧规格;它投影已接受视觉方向,
      不替普通人物、地点、道具规格增加字段。删除当前测试轴不需要的可选项。
      
      ## 首行:`sources` 声明
      
      本文件用到的每个上游快照在这里声明一次,键取产物文件名,在本文件内唯一且稳定。视觉方向与
      制作形态同出于 `short-drama.json`,共用一个键:
      
      ```json
      {
        "record_type": "sources",
        "schema_version": "1.0.0",
        "sources": {
          "short-drama": {
            "owner": "creator",
            "artifact": "short-drama.json"
          },
          "<identity-owner>": {
            "owner": "short-drama-assets",
            "artifact": "设定集/<identity-owner-file>.jsonl"
          },
          "<variant-owner>": {
            "owner": "short-drama-assets",
            "artifact": "设定集/<variant-owner-file>.jsonl"
          },
          "screenplay-index": {
            "owner": "short-drama-write",
            "artifact": "剧集/<EP>/screenplay-index.jsonl"
          },
          "<reference>": {
            "owner": "<reference-owner>",
            "artifact": "<project-relative-reference-record>"
          }
        }
      }
      ```
      
      引用用 `src` 指向声明键,再写本条引用自己的 `record_id` 和 `field`。
      
      ## 规格行
      
      ```json
      {
        "spec_id": "LOOKDEV-<stable-id>",
        "status": "candidate",
        "purpose": "lookdev_frame",
        "lookdev_axis": "character_expression | core_location | high_pressure_scene",
        "direction_ref": {
          "src": "short-drama",
          "field": "/creator_authority/visual_direction/choices/look_development"
        },
        "production_profile_ref": {
          "src": "short-drama",
          "field": "/creator_authority/production_profile"
        },
        "subject_bindings": [
          {
            "identity_ref": {
              "src": "<identity-owner>",
              "record_id": "CHAR/LOC/PROP-<id>"
            },
            "variant_ref": {
              "src": "<variant-owner>",
              "record_id": "LOOK/VIEW/PSTATE-<id>"
            },
            "role": "expression_subject | location | pressure_actor | evidence"
          }
        ],
        "story_context_refs": [
          {
            "src": "screenplay-index",
            "record_id": "BLK-<EP>-<SC>-<kind><nn>",
            "field": "/<exact-source-field-if-needed>",
            "role": "scene_heading | action | dialogue | information_permission | story_state"
          }
        ],
        "reference_bindings": [
          {
            "slot_id": "REF-<stable-slot>",
            "order": 1,
            "artifact_ref": {
              "src": "<reference>",
              "record_id": "<stable-record-id>"
            },
            "role": "style",
            "may_control": [
              "<色彩层级/材质处理/阴影边缘/景深倾向/画面密度>"
            ],
            "must_not_control": [
              "<角色身份/固定地理/剧情状态/人数/持物/道具文字>"
            ],
            "admission_status": "unverified | creator_described | visually_inspected",
            "reference_observation_ref": null,
            "unresolved_risks": []
          }
        ],
        "test_question": "<本帧要暴露哪一种视觉方向风险>",
        "stable_visual_rules": [
          "<跨测试轴必须保留的可观察规则>"
        ],
        "allowed_variation": [
          "<本场允许变化的光比/冷暖/留白/密度>"
        ],
        "composition_and_state": "<只写当前代表帧需要的构图、空间与剧情状态>",
        "appearance": {
          "materials": [
            "<材质处理>"
          ],
          "palette": "<色彩层级>",
          "lighting": "<光源逻辑与阴影边缘>",
          "depth_or_density": "<景深/画面密度>"
        },
        "constraints": [
          "<必须保持的身份、地理、文字与信息权限>"
        ],
        "generic_prompt": "<只含可被画出的自然表述,语言按 #/format/prompt_language,不含字段名/hash/审查话术>",
        "derivation": {
          "renderer": "generic-markdown"
        },
        "provenance": "creator_project"
      }
      ```
      
      人物与地点测试没有剧情职责时删除 `story_context_refs` 及其 `sources` 键;高压力场景必须保留真实 `BLK-…`
      来源。单主体也使用一项 `subject_bindings[]`,不再与 `asset_binding` 二选一。无参考媒体时
      `reference_bindings` 为空;多参考的 `slot_id` 稳定、`order` 唯一。
      
    • lookdev-prompts.md 1.8 KB
      # `lookdev-prompts.md` 可复制输出模板
      
      此文件由已接受 Look Development 规格派生。它展示视觉方向怎样跨测试轴保持,
      只复制引用块内的自然语言提示词;本文件不触发图片或媒体服务,实际生产交
      `$short-drama-produce` 并单独确认。
      
      **这是项目级文件,不是某一集的创作文档。** 它不参与 `creator_markdown_check.py` 的
      五文档校验;某一集要用的资产提示词写进该集的《图片提示词.md》,骨架以 `SKILL.md` 为准。
      
      ```markdown
      # 项目 Look Development 提示词
      
      > 来源:`lookdev-image-prompt-specs.jsonl` 的已接受记录
      > 视觉方向:`short-drama.json#/creator_authority/visual_direction/choices/look_development`
      > 范围:仅代表帧提示词,不拥有角色身份、地点地理或剧情状态
      
      ## `LOOKDEV-<id>` · `<人物表现 | 核心地点 | 高压力场景>`
      
      - **测试问题**:<本帧要暴露的视觉方向风险>
      - **绑定事实**:<准确身份/变体;高压力帧再列 scene/block refs>
      - **跨轴稳定**:<形状、材质、色彩、阴影、景深或密度中的共同规则>
      - **本帧可变**:<当前场景允许变化的部分>
      - **风格参考权限**:`<slot_id / order / reference>` 只决定 `<may_control>`,不得导入 `<must_not_control>`
      - **仍未知**:<只能由授权生产观察回答的风险;无则写“无”>
      
      ### 可复制通用提示词
      
      > <只写可被画出的主体、空间、构图、材质、光色和状态;不含字段名、hash、审查话术、供应商参数或生成历史。>
      
      ---
      ```
      
      三类测试帧不要求固定数量或宫格。人物/地点帧没有剧情职责时不列 scene/block refs;高压力帧必须
      显示其准确来源。规格或视觉方向改了就重新派生本文件,不直接手改缓存。
      
  • examples
    • minimal-image-prompt-specs.jsonl 2.3 KB · in bundle
  • references
    • character-and-look.md 8.3 KB
      # 人物设定图与 Look Variant
      
      ## 身份测试 (`IMG-03`)
      
      人物设定图必须始终可识别为同一个 accepted identity,同时只呈现一套自洽
      Look。不要把互不兼容的服装、发型、伤势、年龄或风化状态平均成一个合成人。
      
      ## 目录
      
      1. 人物设定图解决什么
      2. 身份层与 Look 层
      3. 构图方法
      4. Look/state variant
      5. 输出与审查
      6. 制作形态投影与模板槽位
      
      ## 1. 人物设定图解决什么
      
      人物设定图的首要任务是让后续镜头认出“同一个人、此刻这一套状态”,而不是把一生造型或情绪表演塞入一张图。输入包括接受的 Character、一个精确 Look、用途、视觉风格、构图、背景/光线以及来源指针。
      
      **`reviewed_invariant`**:一条 character-sheet 规格必须保持一个身份和一套内在一致的 Look。互斥年龄、发型、服装、伤势、干湿或清洁状态不能并存。
      
      ## 2. 身份层与 Look 层
      
      ### Character 身份锚点
      
      只选跨该项目多个 Look 仍稳定的识别事实:
      
      - 年龄区间与体态(确有识别价值时);
      - 面部轮廓、眉眼/鼻唇的相对特征,不用审美评分;
      - 固定发质/发际/自然发色;若发型会换则放 Look;
      - 不会随场景消失的痣、胎记、旧伤或身体特征;
      - 与身份绑定、项目确认长期保留的配饰。
      
      不要为了“独特”新造疤痕、异色瞳、纹身。不要用“网红脸、完美五官、顶级美女”覆盖已接受的不对称或生活痕迹。
      
      ### Look 可变状态
      
      Look 描述一个有效区间内的整体:发型整理方式、服装单品与穿法、鞋、妆面、临时配饰、污渍/水/血/新伤、服装损坏。每个 delta 应回答:相对哪个 base,变了什么,为什么/从何时生效,保持到哪里。
      
      - **`craft_default`**:先写剪裁、层次、领口/袖口、材质与主次色,再写“职业感”“落魄”等抽象效果。
      - **`reviewed_invariant`**:服装和状态要能在同一时刻成立。例如“外套完整扣好”和“外套撕开露出内层”需明确区域,否则冲突。
      - **`taste_option`**:姿态、表情范围、视图数量依参考用途决定,不固定三视图或固定表情格。
      
      ## 3. 构图方法
      
      ### 单图选择
      
      1. **身份板**:中性全身或三分之二身为主,清楚显示比例与一套 Look;可附少量正/侧细节,但所有视图是同一时刻、同一 Look。
      2. **面部识别板**:头肩为主,均匀光,发际与轮廓完整;适合妆面/身份锚点,不承担服装全貌。
      3. **服装 Look 板**:全身正面与必要背面/局部,突出层次、穿法和鞋;面部仍保持身份,不能换成无脸 mannequin 除非创作者明确只做服装。
      4. **状态板**:同一 Look 的有因果差异,如雨后湿袖、包扎后的左腕;只展示已接受状态,不把“前后对比”默认塞进一个画面。
      
      ### 参考友好性
      
      - 身体不要被道具、极端透视或强烈运动遮住关键特征。
      - 背景与光线服务识别;默认简洁、中性、均匀,但视觉风格可覆盖。
      - 表情以用途为准:身份板可平静或低强度角色态;表演测试可给有限表情范围,但不要把不同剧情时刻混成同一 pose。
      - 配饰说明佩戴位置、相对尺度、材质与是否属于 Look;手持剧情道具不是默认身份锚点。
      
      ### 提示词写作顺序
      
      ```text
      人物设定图用途 + 角色身份锚点
      → 当前单一 Look(从头到脚、delta 清楚)
      → 构图/视图/姿态/表情
      → 材质与主次色、识别友好光线
      → 简洁背景
      → 保持与排除
      ```
      
      “23 岁”若来源只写“二十多岁”,不得假精确。身体描述以可见生产需要为限,避免与剧情无关的物化细节。
      
      ## 4. Look/state variant
      
      Variant prompt 不是完整身份重写。先复用 Character anchors,再突出 delta:
      
      - **基准**:`CHAR-* + LOOK-base` 的精确接受引用;
      - **变化**:位置、范围、材质/颜色变化,例如“右袖肘以下被雨淋深一度,肩部仍干”;
      - **保持**:脸、发际、体态、未变服装结构、未受影响区域;
      - **连续性**:起因、有效场景/镜头范围及下游绑定。
      
      若只是镜头内瞬时表情或姿势,通常由 storyboard/keyframe 拥有,不新建 Look。若 delta 要改变身份事实,先退回 assets,而不是用 edit prompt 越权。
      
      ## 5. 输出与审查
      
      ### 失败征兆
      
      - 同时写制服和便装、受伤和无伤、干发和滴水发;
      - 不同视图变脸、换衣或配饰位置漂移;
      - 只有“年轻漂亮、电影感、精致五官”,没有身份锚点;
      - 强戏剧阴影遮住脸部或服装结构,却声称是识别板;
      - 把一次手持物、表情、站姿永久写入人物身份。
      
      ### 证据式检查
      
      | 问题 | 分类 | 证据 |
      |---|---|---|
      | exact Character/Look 是否解析 | `structural_invariant` | `视觉设定.md` 的可见 ID 与当前变体 |
      | 是否只有一个连贯 Look | `reviewed_invariant` | Look 字段与 prompt 对应句 |
      | 是否保持区别性身份 | `reviewed_invariant` | Character anchors 与画面描述 |
      | 泛化美词是否挤压锚点 | `craft_default` | 指出可删词与缺失的可见事实 |
      | 中性姿态/背景是否适合 | `craft_default` | 用途与构图的关系 |
      | 表情强度、板式数量 | `taste_option` | 创作者/视觉方向 |
      
      最终在 `图片提示词.md` 产生一个 `IMG-...` 人物板条目和一段无需资产库暗知识也能复制理解的正文;
      不产生图片。
      
      ## 6. 制作形态投影与模板槽位
      
      `视觉设定.md` 的项目视觉方向与已明确制作形态决定这张人物板用什么词汇画,不决定画的是谁。
      
      ### 从形态取什么
      
      | 取用项 | 形态回答的问题 | 落到提示词的位置 |
      |---|---|---|
      | 形状语言 | 轮廓简化到什么程度、比例体系是否夸张 | 身份锚点的表达颗粒度 |
      | 线条与表面 | 线稿封闭还是散边、平涂/厚涂/照片式表面 | 材质与主次色段 |
      | 材质对光的响应 | 布料、皮肤、金属在该形态里怎样出现明暗与高光 | 识别友好光线段 |
      | 层拆 | 身份层、服装可动层、效果层各自承担什么 | 构图与保持/排除段 |
      | 识别通道 | 观众主要靠面部结构、剪影、还是线条特征认人 | 锚点选择与视图数量 |
      
      ### 形态不得改写什么
      
      - Character 身份锚点集合本身:年龄区间、体态、面部结构、永久特征、长期配饰;
      - Look 的已接受组成、cause 与有效范围;
      - 手持道具的归属(仍属 Prop/State)与可读文字政策;
      - 故事状态:伤势、湿污、包扎的因果与生效时间。
      
      形态改变的是**同一锚点走哪条表达通道**,不是锚点集合。若形态以剪影为主要识别通道,就要
      为已确认锚点找到剪影能承载的写法(发际形状→发型剪影缺口、旧伤→轮廓上的缺口、体态→肩背
      重心),而不是新增、替换或悄悄删掉锚点。找不到可靠通道时标为“需创作者决定”,退回
      资产或创作者,不擅自换一个更好画的身份。
      
      ### 模板槽位不得覆盖身份锚点
      
      **`reviewed_invariant`**:模板槽位不得覆盖已确认的身份锚点;当模板默认值与当前身份冲突时,
      **身份优先,模板让位**。
      
      合成例:角色甲的身份是五十岁上下、体格厚重、肩背略沉。若人物板模板对每个角色机械
      追加“九头身黄金比例、极度修长的双腿”,这条默认槽位就把角色甲改写成了另一个人,而且因为它
      出现在每张板上,下游会把它当成风格统一而不是错误。角色乙即使确实修长,也应由当前
      Character 锚点写出,而不是由模板默认值代写。
      
      排查方式:把同一批人物板的提示词并排看,找出**逐字重复且与身份无关**的句子。重复出现的
      审美句若不能追溯到某个角色的当前视觉设定,就是模板残留,删除或改写成该角色的真实锚点。
      
      | 检查 | 分类 | 证据 |
      |---|---|---|
      | 形态投影是否只落在词汇层 | `reviewed_invariant` | 形态卡字段与提示词对应句 |
      | 锚点是否在该形态下真的可见 | `reviewed_invariant` | 识别通道与所选锚点 |
      | 模板默认值是否覆盖身份 | `reviewed_invariant` | 跨角色重复句与当前视觉设定 |
      | 形态未定时是否停在提问 | `structural_invariant` | `视觉设定.md` 明确标为未决 |
      
    • common-recipe.md 15.4 KB
      # 通用资产图片提示词配方
      
      ## 目录
      
      1. 目的与输入
      2. 从资产事实到画面语言
      3. 八段式配方
      4. 锚点、约束与取舍
      5. 输出、失败征兆与检查
      
      ## 本文负责的做法
      
      - `IMG-01` — 先把规格绑定到状态为 `accepted` 的准确资产 ID 和版本 ID,再写自然语言;
        别名或“看起来像”不算有效绑定。
      - `IMG-02` — 识别性身份、地理、尺度和当前状态优先;质量/风格词只能精炼
        这些事实,不能替代它们。
      - `IMG-07` — 将文字策略解析为结构化选择。必须可读的文字与全局“不要文字”
        约束不能同时激活。
      - `IMG-08` — 参考图进入制作前也要通过文字政策审查;“不要文字”之类的负面提示不能清除
        参考图已经携带的字形、标牌、界面、水印或字幕残留。
      - `IMG-09` — 每张参考图只决定已经声明的内容;同时写明可以参考和不能照搬的
        可见事实,避免构图/尺度/效果参考改写身份、文字或故事状态。
      
      ## 1. 目的与输入
      
      资产提示词不是剧情镜头,也不是形容词收藏。它要把已接受资产中最值得稳定的事实,变成一张便于识别、比较和后续复用的参考图意图。
      
      开始前取得:`视觉设定.md` 中准确的资产 ID 和当前变体、来源场景、用途、目标构图、视觉风格、
      背景与光线、文字政策、创作者引用 `REF-*`、约束与排除项。身份尚未确定时停在提案,
      不要用提示词文案掩盖缺口。
      
      ## 2. 从资产事实到画面语言
      
      把事实分成四类,而不是把整本设定集照抄进去:
      
      | 篮子 | 问题 | 写法 |
      |---|---|---|
      | 识别锚点 | 去掉服装/天气后,凭什么认出它? | 可见形状、比例、相对位置、材质特征 |
      | 状态差异 | 这次与基准版本具体差在哪? | 有边界、能直接看到的变化 |
      | 复用几何 | 后续镜头最怕哪里漂移? | 方位、尺度、入口、握持面、结构关系 |
      | 呈现条件 | 怎样最利于读清以上事实? | 构图、视角、背景、光线、空场政策 |
      
      抽象标签需要翻译成证据。例如“冷峻”本身不够;可在人物表情、站姿、服装线条或冷色环境中选择与资产事实相符的可见载体,但不得臆造伤疤、身份或剧情。
      
      ### 锚点选择启发
      
      - **`craft_default`**:选少量、作用不重复的锚点。轮廓、比例、一个局部特征和一个材质或
        色彩关系,通常比十个近义形容词更稳。
      - **`reviewed_invariant`**:锚点必须足以让审查者区分该身份及所选版本;
        “漂亮、奢华、高清”不能代替识别证据。
      - **`craft_default`**:用相对关系表达空间,如“服务台在主入口右前方,后墙有唯一金属门”,比散列物件清单更可复用。
      - **`taste_option`**:锚点可以用简洁技术文风或富有气氛的中文表达,只要不改变事实优先级。
      
      ## 3. 八段式配方
      
      顺序是信息保真策略,不是必须出现八段标题的僵硬格式。省略不适用段,不省略类型必需事实。
      
      1. **用途与主体**:先说是人物设定图、场景空镜、道具参考还是局部修改,以及主体是谁。
      2. **稳定锚点**:身份、地理或形制的持久事实;写可见和可比较的内容。
      3. **版本差异**:只写这次造型、视角或状态相对基准版本的差异,以及当前状态。
      4. **构图与尺度**:视角、画幅用途、主体占比、方向、相对位置、比例参照。
      5. **材质、色彩与光线**:说明对识别有用的表面、主次色关系、光向和亮暗逻辑。
      6. **背景/舞台政策**:干净背景、环境内展示或 `empty_stage`;说明是否允许人群、手或支架。
      7. **文字与功能**:引用资产来源中的文字政策,再明确选择
         `readable | symbolic | blank | postproduction` 这四种呈现方法之一,并说明功能件怎样可见。
      8. **排除与保留**:只写当前最可能出现的误读;局部修改要先说明必须保留什么。
      
      ### 可复制文体
      
      把内部字段翻译成 `#/format/prompt_language` 声明的那门语言的自然表述——不是固定的中文,
      模板与本节都不替项目决定这件事。避免输出 JSON 键名、`hash`、审查指令、重试历史、
      “请模型务必”、权重语法或某家模型专用的控制词。ID 与来源放在 Markdown 元信息里,
      不要塞进正文。正文可以分句,但离开内部资料后仍应读得懂。
      
      ### 通用骨架
      
      ```text
      [参考图类型与用途],[主体与稳定身份/地理/形制锚点];当前为[该版本的可见差异]。
      采用[构图/视角/方向/尺度与空间关系];[材质、色彩、光向和气氛];[背景或空场政策]。
      文字政策:[政策与精确要求]。保持[必要事实];排除[与必需事实不冲突的高风险误读]。
      ```
      
      这只是填写顺序,不是固定答案。删掉空项和机械标签,使成品像视觉部门能直接使用的工作说明。
      
      ### 按产物类型裁剪规格
      
      - `character_sheet`:身份锚点绑定一个造型版本,选择便于识别的构图;没有文字承载面时删除文字字段。
      - `location_plate`:写清地理、方向和空场政策;标牌文字必须先有已接受的资产政策。
      - `prop_plate`:同时交代轮廓、功能、尺度和适用的文字处理。
      - `look_state_variant`:绑定基础来源、可见变化和有效范围;姿势本身不自动成为新版本。
      - `edit_delta`:只保留精确目标、变化、保持项和连续性影响;上游负责的变化先取得其接受。
      
      参考说明不是普通图片清单。每张只声明一个主要用途,分别写清可借用和不可带入的事实;没有参考
      媒体就不写参考段,没有观察证据时保持“未验证”并列出风险。
      
      ## 4. 锚点、约束与取舍
      
      ### 身份
      
      身份锚点必须在临时状态改变后仍然成立。服装、淋湿、污渍、手持物和当下表情通常属于
      造型或状态,而非身份。若“银灰短发”既可能是永久特征,也可能是假发,先回资产环节
      解决,不在提示词里擅自定性。
      
      ### 场景地理
      
      场景地理用固定入口、主要区块、视觉轴和锚点之间的关系表达。镜头角度变化不会自动
      创造新地点。提示词可以选择一个视角,但不得为了“好看”搬动门窗。
      
      空间纵深来自可通行路线、遮挡、重叠、尺度参照、光向和空气层次共同建立。前/中/后景
      是可选组织方法,不是每条场景提示词必须填满的三栏;单房、平面化视觉方向或需要明确
      留白时可以不用。资产场景参考图默认说明可复用地理,不把剧中盟友、敌人和当前动作提前
      摆进去;人物关系、站位与视线由分镜关键帧在准确剧情状态下拥有。
      
      ### 尺度
      
      尺度最好绑定同画面中的中性参照或明确尺寸关系,而不是只写“巨大”或“小巧”。参照物
      不可引入剧情角色,也不能与 `empty_stage` 的空场要求冲突;道具可以用带刻度的底座、
      常见手掌尺度或已知功能结构作参照。
      
      ### 文字政策
      
      文字有两层,不得混成一个枚举:
      
      1. **资产来源政策(由资产负责人管理)**:`exact_readable | graphic_only |
         no_readable_text | pending_creator_text`,回答剧情/资产真相是什么。
      2. **本次提示词的呈现方法(由图片提示词环节管理)**:`readable | symbolic |
         blank | postproduction`,回答这次参考图怎样处理该真相。
      
      条目必须指向 `视觉设定.md` 的资产 ID 与文字事实,并写清两层选择和对应理由。
      默认映射:
      
      | 资产来源政策 | 允许的呈现方法 | 要求 |
      |---|---|---|
      | `exact_readable` | `readable` 或 `postproduction` | 前者逐字引用;后者保留承载区与精确文字引用 |
      | `graphic_only` | `symbolic` | 保留图形存在/布局,不新造可辨字义 |
      | `no_readable_text` | `blank` 或明确不可读的 `symbolic` | 不得偶然造成新名字/号码 |
      | `pending_creator_text` | `postproduction` 暂存,或阻断 `readable` | 不猜文字;保留 `unresolved` 状态与下游影响 |
      
      不按默认对应关系时,必须有创作者明确改写,并且不得篡改资产来源政策。
      
      - `readable`:正文逐字引用已接受文字,并允许清晰可读;不要同时要求“不要文字”。
      - `symbolic`:允许文字感图形,但明确不要求可辨字义。
      - `blank`:承载面保持空白。
      - `postproduction`:预留干净区域与透视/光照条件,文字后期加入。
      
      文字政策不是对模型效果的保证,而是创作和后期工作的要求。专名、号码或网址尚未获得
      明确接受时,不要编造。
      
      “语义上必须出现签名”不等于已经拥有可复制的正式签名字形。只有签名归属或剧情职责、没有
      创作者确认的字形资产时,保留准确来源说明并阻断 `readable`;仅在当前文字政策允许
      `postproduction` 时可预留承载区,不得用姓名、伪签名或自行设计的笔画冒充正式字形。
      若人物的接收或反转依赖这项文字,不得一面保留空白承载区、一面让人物认出签名;候选文本
      明确写“正式签名字形未提供”,并点名受影响的 `IMG-...` / `SHOT-...`;在字形或已确认的后期处理
      真正到位前,不写可读签名正文。
      
      ### 检查输入参考图(`IMG-08`)
      
      文字政策同时管输出意图和输入参考。只有创作者/参考图权利人给出可以核对的画面
        说明时把状态写为 `creator_described`;运行环境明确授权智能体检查输入参考并完成检查时,
      把状态写为 `visually_inspected`。此时才判断可辨文字、近似字形、号码、
      标牌、屏幕界面、水印和字幕残留;不能只检查提示词正文有没有写“无文字”。只有文本
      记录、媒体不可见或未获授权时保持 `unverified`,不能编造观察结论。
      
      - `no_readable_text`:若参考仍带文字风险,先**裁切、清理、遮罩或替换**;会破坏
        身份/地理/构图时,退回资产或选择后期处理,不得靠更强的负面词假装风险消失。
      - `exact_readable`:只允许批准的承载面和逐字内容;旧版本、冲突号码、其他标牌或
        字幕不能借参考图进入生成。
      - `graphic_only`:允许的只是已接受的图形职责,不把偶然可辨的伪字当作合格符号。
      - 这一步只记录输入参考图的检查资料与文字风险;本提示词阶段不生成或验收成片,也不从
        提示词声称文字已经正确渲染。
      
      **`reviewed_invariant`**:依据创作者或参考图权利人提供的画面说明,审查者
      核对参考图、文字政策与裁切/清理/遮罩/替换决定是否有来源、是否互相矛盾;没有
      检查资料时保持 `unresolved`。**“不要文字”之类的负面提示不能清除**参考图中已有的文字风险。
      
      ### 参考图可以决定哪些内容(`IMG-09`)
      
      每张真实参考图使用稳定 `REF-...` 槽位;槽位在创作文档里逐字写成 `REF-<slot>(顺序:<n>)· <项目相对路径>《<中文名称>》(用途:<用途>;控制:<范围>;不得控制:<范围>)`,并另行说明观察状态与未决风险。
      调整顺序或插入新参考不能改变已有槽位的语义;换图时在同一槽位明确修订 locator,不把旧图的控制边界静默转给新槽位。`IMG-...` 只定位当前《图片提示词.md》的提示词条目。`用途` 是封闭词表,只能取 `身份`、`造型状态`、
      `地理`、`构图`、`尺度`、`效果`、`起始帧`、`结束帧`、`风格` 之一;一张图承担两件事就拆成两个槽位,
      不写「全参考」,也不自造新用途。资产板通常只用到前六个——`起始帧` 和 `结束帧` 属于镜头,不属于资产板。
      
      - 身份参考不自动决定姿势、构图或临时造型;
      - 构图/尺度参考只借用占比、机位所在一侧、留白或相对尺度,不带入图中人物与事件;
      - 效果参考只控制已接受目标的形态/范围,不让非目标对象一起消失、复制或变形;
      - 任一参考都继续服从文字政策与已确认来源,冲突时退回负责方,不用“全参考”。
      
      这项质量要结合当前项目资料判断,不能按参考图数量、用途关键词或固定裁切方式机械判定。
      
      ### 负面约束
      
      - **`craft_default`**:负面约束针对可预见失败,如“不要混入第二套制服”“空场,不出现演员”。
      - 不要用“不要模糊、不要肢体错误、杰作”等套话覆盖真正的锚点。
      - 排除项不得否定必需项,例如要求旧铜锈又排除所有磨损,要求 `readable` 又全局禁字。
      - **`reviewed_invariant`**:审查排除项是否会把人物特色、场景功能或道具使用方式一并抹掉。
      
      ### 审美语言
      
      “电影感、质感、高级、氛围感”只有在落实为构图、材质、色彩关系、光向或景深选择时才有信息量。
      
      - **`craft_default`**:每个审美词尽量落到一个可观察选择;删掉相互替换不改变画面的近义词。
      - **`craft_default`**:先建立清楚,再添加风格。参考板需要可比较性时,均匀光常优于戏剧光;但这是用途相关默认,不是硬规则。
      - **`taste_option`**:写实度、媒介、颗粒、色调和镜头感由视觉风格或创作者决定。
      - 禁止用固定词表或形容词比例阻断交付;描述是否空泛,由审查者指出具体缺了什么。
      
      ### 光学与表面描述
      
      **`craft_default`**:对需要明确透视或写实质感的画面,写明机位、取景距离和可见表面特征。
      焦段可辅助表达,但不能据此承诺模型会精确模拟光学。
      
      根据画面尺度选择毛孔、布料折痕或金属使用痕迹;「干净」不必等同于没有任何纹理和折痕。
      不要给每张图添加相同的相机参数、瑕疵清单或排除词。
      
      **`taste_option`**:表面是否平滑、是否修饰,以及写实程度由已接受的视觉风格决定。
      结果用对照图检查;像素纹理指标只作辅助,不能代替人物与材质的视觉判断。
      
      ## 5. 输出、常见问题与检查
      
      ### 输出
      
      - 一条带准确来源引用与配方版本的结构化规格;
      - 一条标注清楚、可以复制的通用提示词;
      - 必要的警告或改写说明,不含媒体文件或远端任务信息。
      
      ### 失败征兆
      
      - 单看提示词无法分辨究竟是哪一个身份或版本;
      - 锚点被风格套话淹没;临时伤势被写进永久面貌;
      - 空间只有物品清单,没有方向/关系;尺度靠“很大”;
      - “不要文字”与 `readable` 同时存在;负面约束否定了主体;
      - 参考图含有与文字政策冲突的标牌、界面、号码、水印或字幕,却只在正文追加“不要文字”;
      - 文案含用户抱怨、内部字段、生成次数或“根据上图保持一致”却无目标引用。
      
      ### 检查
      
      1. **结构**:检查 ID、版本、类型必需字段、来源引用、参考图准入状态、来源政策到呈现方法
         的对应关系,以及可以直接确定的矛盾。
      2. **内容**:审查者引用资产字段和提示词句子,判断身份、场景地理和尺度是否保持,
         不能只说“不够高级”。
      3. **默认**:把泛化词提前、堆砌或重复视作可改进警告;只在必需事实缺失时才升级。
      4. **选择**:风格和文体差异不单独阻断;记录创作者选择后,在重新导出文本时应保持。
      
    • edit-and-revision.md 5.1 KB
      # Scoped Edit 与自然语言修订
      
      ## 有界编辑合同 (`IMG-06`)
      
      每次 edit 都声明精确目标/区域、要改什么、必须保留什么,以及预期的连续性影响。如果期望变更会
      改写身份或已确认上游事实,路由给该 owner,不要伪装成局部提示词修订。
      
      ## 目录
      
      1. 两类修改
      2. Edit-delta 配方
      3. 自然语言要求 → 差异预览 → 确认 → 重写
      4. 当前文件与旧预览不一致时的处理
      5. 失败与检查
      
      ## 1. 两类修改
      
      - **对画面目标的 edit**:产出 `edit_delta` 提示词,例如改变一件衣服局部状态;不执行图像编辑。
      - **对提示词本身的 revision**:创作者用自然语言修改规格;先提案 diff,接受后重渲染 Markdown。
      
      二者都不能改写 assets 拥有的身份/variant 事实。若请求是“把这扇门移到另一面墙”但 Location 地理未变更,应发 assets/storyboard 相关 revision request,而不是悄悄写进 edit。
      
      ## 2. Edit-delta 配方
      
      四个问题缺一不可:
      
      ```text
      Target:哪个可见 `IMG-...`、对象和区域?
      Change:哪些有边界、可观察的变化?
      Preserve:身份、构图、光线、空间以及哪些未影响 entity/region 必须不变?
      Continuity impact:预期对应哪个已确认状态或引用,有效到哪里?
      ```
      
      ### Target
      
      - 用可见 `IMG-...` 和对象名绑定目标;可复制正文用自然语言明确主体和区域。
      - “改背景”“让她更狼狈”过宽;需要具体新 View/区域与可观察变化。
      - 多个不相干 target 默认拆为多个 edit,防止 preserve 集失焦。
      
      ### Change
      
      按位置、方向、范围、程度、材质/色彩结果写 delta。例如“右袖肘部以下呈雨水浸湿后的深色,衣料贴合但无撕裂”,比“衣服弄湿”可控。不得补写未接受的伤势或剧情因果。
      
      ### Preserve
      
      先列最容易被误改的高价值事实:面部/体态身份、未变 Look 部件、固定地理、道具轮廓与文字、构图/机位、光向、未选区域。不要写“其他全部保持”代替边界思考;允许最后用它概括已经点名的 preserve set。
      
      ### Continuity impact
      
      引用 道具状态/Look/View 或提出 owner revision;记录受影响的 prompt/shot/keyframe,而非在 edit 中成为新的连续性权威。若没有影响,也明确 `none` 及理由。
      
      - **`structural_invariant`**:目标、区域、变化、保持项和影响必须存在且没有显式冲突。
      - **`reviewed_invariant`**:修改范围是否足够清楚、preserve 是否保护真正身份/地理,需要 reviewer 引用证据判断。
      - **`craft_default`**:一次 edit 聚焦少量相互关联的 delta;复杂重构改用新 variant/plate。
      - **`taste_option`**:变化的视觉强度由创作者决定,只要状态事实未变。
      
      ## 3. 自然语言修订
      
      用户不需要知道内部字段。对“把工作服换成深蓝,但保留脸和袖口油渍”执行:
      
      1. 读取当前 `视觉设定.md` 条目和 `图片提示词.md` 的 `IMG-...`;
      2. 区分提示词可改措辞、资产 owner 才能改的事实、含糊项和连续性影响;
      3. 展示简短语义差异:改前、改后、理由、保持项、影响和是否需要上游修改;
      4. 展示新的可复制正文,让创作者看到实际效果;
      5. 确认后直接更新同一个 `IMG-...`;拒绝时当前文件保持不变;
      6. 列出需要同步检查的 `SHOT-...` 或其他 `IMG-...`,不自动改用户未点名的文档。
      
      建议预览:
      
      ```markdown
      ### 提议修改 `IMG-...`
      - 深灰蓝工作服 → 深蓝工作服
      - 保持:脸、服装剪裁、右袖口旧油渍的形状与位置、背景、构图、光向
      - 影响:仅当前造型提示词;若 `视觉设定.md` 还没有深蓝变体,先交给 assets 修改
      
      **新正文预览**
      > ...
      ```
      
      对“更有电影感”不能擅自堆一串风格词。给两三个互斥且可观察的候选,例如光比、构图或色彩关系,
      作为 `taste_option` 让创作者选择。
      
      ## 4. 当前文件冲突
      
      如果另一个编辑或人工修改已经改变当前 `IMG-...`,不要用旧预览覆盖:
      
      - 重新读取当前条目;
      - 展示人工改动与本次修改的语义差异;
      - 能安全合并时生成新的完整预览;
      - 无法无损对应、触及上游事实或存在冲突时保留当前文件,并交给创作者选择。
      
      不得把“最后写入者获胜”当创作规则,也不得为了恢复格式丢掉人工增加的有效语义。
      
      ## 5. 失败与检查
      
      ### 失败征兆
      
      - 只改可复制正文,却不核对 `视觉设定.md`;
      - 差异只写“优化措辞”,没有语义影响和保持项;
      - 把身份、地点地理或道具状态在提示词层擅自改掉;
      - edit 只有 Change,没有 Preserve;
      - 发现冲突后自动覆盖人工修改。
      
      ### 完成检查
      
      - 上游事实请求已路由给正确 owner;
      - 目标、区域、变化、保持项和连续性影响都清楚;
      - 差异预览可读、可拒绝,新正文可直接复制;
      - 拒绝不改变当前文件,冲突不静默吞掉;
      - 本流程不调用媒体生成或 provider API;实际生产交 `$short-drama-produce`,并对精确任务预览单独确认。
      
    • location-plate.md 8.8 KB
      # 场景空镜与地理保持
      
      ## 地理测试 (`IMG-04`)
      
      场景空镜保持 accepted layout、orientation、fixed anchors、materials 与光向。
      默认不带角色,以保持作为地理参考的复用性;只在创作者明确需要尺度参照
      或剧情所有的 occupancy state 时加人。
      
      ## 目录
      
      1. 目的与输入
      2. Location 与 View
      3. 地理优先的编写法
      4. 光线、气氛与空场
      5. 输出与审查
      6. 制作形态投影
      
      ## 1. 目的与输入
      
      Location plate 的价值是让后续镜头共享同一可导航空间。输入是已接受 Location、一个精确 View/时间天气状态、固定锚点、材质与视觉风格、空场政策、光向及来源指针。
      
      **`reviewed_invariant`**:提示词必须保持场景的地理、方向、固定锚点及其相对关系。装饰丰富不能补救门窗移位或尺度不明。
      
      ## 2. Location 与 View
      
      - **Location** 拥有不会随镜头轻易变化的边界、入口、功能区、固定结构和关键材质。
      - **View** 选择观察方向、可见区块、局部 dressing、时间/天气/灯光状态;它不是随意重建 Location。
      - 镜头焦段、机位高低或画幅通常属于构图选择,不足以单独成为新 Location。若一个角度显示不同侧,需要 View 而非新场景。
      
      先画“文字地图”:从哪个入口看向哪个方向,前/中/后景分别是什么,关键锚点在彼此哪一侧,演员可能从哪里进出。只有与识别、调度或连续性有关的结构进入 prompt。
      
      ## 3. 地理优先的编写法
      
      ### 必要层次
      
      1. **身份与功能**:这是什么空间,服务什么活动,整体尺度。
      2. **View 与方向**:观察位置、朝向、可见边界;必要时给左右以画面/场内参照,避免“左边”含义漂移。
      3. **入口与路线**:门、走廊、楼梯、通道在哪里,彼此如何连接。
      4. **固定锚点**:柜台、柱、窗、机器、壁炉等不可移动物及相对关系。
      5. **材料与色彩**:对辨认结构有用的墙地顶、磨损和主次色。
      6. **当前 state**:摆设、天气、时间与光线变化,不把临时 dressing 写成永久地理。
      
      ### 空间语言
      
      - **`craft_default`**:用“两两关系 + 视线终点”而非无序 inventory。例如“从卷帘门向内看,检修台沿右墙延伸,尽头唯一安全门正对通道”。
      - **`craft_default`**:优先保持一至三个强锚点,次要装饰可概括,防止提示词在细节噪声中失去布局。
      - **`reviewed_invariant`**:同一 View 中的前后左右、入口和光向必须能共存;不能在一句中把同一门同时置于左右墙。
      - **`taste_option`**:广角或标准视角、对称或偏心构图、写实或插画由视觉方向决定。
      
      ## 4. 光线、气氛与空场
      
      ### 光线连续性
      
      说明主光来源与方向、时间/天气关系、实际灯具及需要保留的暗区。不要只说“电影光”。若 visual style 要冷色但场景有暖色实际灯,写清主次关系而非删掉其一。
      
      ### 跨 View 的光线一致性 (`IMG-10`)
      
      上一条管的是**一个 View 内部**光向自洽。同一 Location 通常按观察方向拆成多个 View
      (例如同一条走廊分别做朝北与朝东两块板),这些板会被同一场戏的正反打互相剪接,
      所以它们之间也要能对上。
      
      **`reviewed_invariant`**:同一 Location 在同一时间/天气 state 下的各个 View,必须共享
      同一套主光来源、色温关系与光比方向;差异只能来自已记录的成因,并写进对应的 delta。
      
      失效机制是不对称的:地理错位一眼能看出来,色温和主光位不一致却常常各自都“很好看”,
      只在两块板被剪在一起时才暴露成两个不同的时间或两个不同的房间。逐板单独审查抓不到它,
      必须把同一 Location 同一 state 的板并排比。
      
      对齐清单(同一 Location + 同一 time/weather state 内):
      
      - **主光来源**:是同一个窗、同一组灯具、同一片天空吗?换 View 只应改变我们从哪一侧看它,
        不改变它是什么。
      - **色温关系**:冷暖主次是否一致。某块板把暖色实际灯升为主光而别的板压成次要,就是一次
        未记录的变化。
      - **光比与暗区方向**:亮暗落差的量级,以及暗区落在空间的哪一侧。
      - **实际灯具开关状态**:同一 state 下不能一块板亮着吊灯、另一块板熄着。
      
      允许且应当记录的差异:View 朝向决定的逆光/顺光关系、遮挡造成的局部落影、以及朝窗与
      背窗的自然亮度差。这些是同一光源在不同观察方向下的正常表现,写清来源即可,不需要拉平。
      
      需要改光时(时段推进、停电、开灯、天气转变),走 delta:它是一个新的 time/weather state,
      同一 Location 的**所有**已存在 View 都要一起交代如何变化,不能只改被用到的那一块。
      
      ### `empty_stage` 政策
      
      - `required`:不出现剧情角色、临时群众或叙事动作;固定家具/功能设备保留。
      - `preferred`:以空场为主,允许不具身份的尺度提示,但必须不妨碍地理读取。
      - `not_required`:可有人群或工作痕迹,但不能编造具体角色事件。
      
      **`structural_invariant`**:`empty_stage: required` 与“主角站在入口”等演员要求显式冲突。若确需人物尺度参照,先改政策或使用无身份中性参照,经创作者接受。
      
      ### 气氛
      
      把“压抑、危险、温暖”翻译为已经有依据的空间选择:通道狭窄感、光比、材质反射、空气状态、色温关系。不得为气氛新增剧情事故、封锁出口或移动固定结构。
      
      ## 5. 输出与审查
      
      ### 失败征兆
      
      - 场景像装饰清单,没有入口、方向或相对位置;
      - 为不同 View 搬动固定门窗,或把临时箱子写成永久锚点;
      - `empty_stage` 要求空场却出现演员、冲突人群或剧情动作;
      - 夜雨状态被混入晴天基准 plate,没有 variant;
      - 光线来源互相矛盾;所谓“宽阔”没有任何尺度关系;
      - 同一 Location 同一 state 的各 View 各自选了不同主光或冷暖主次,单看都成立、剪在一起
        却像两个时间。
      
      ### 检查
      
      | 检查 | 分类 | 处理 |
      |---|---|---|
      | Location/View ID 与版本可解析 | `structural_invariant` | 未解析阻断 |
      | empty-stage 与人物要求显式冲突 | `structural_invariant` | 先解决政策 |
      | 地理、方向、固定锚点被保留 | `reviewed_invariant` | reviewer 引用资产字段与 prompt |
      | 装饰是否压过布局 | `craft_default` | 精简无功能 inventory |
      | 光线是否可解释且连续 | `reviewed_invariant` | 指出光源/方向冲突 |
      | 同一 Location 同一 state 各 View 的主光、色温与光比是否对齐 | `reviewed_invariant` | 并排比同组 View,差异需成因与 delta |
      | 镜头审美与构图 | `taste_option` | 保留创作者选择 |
      
      输出一个 `IMG-...` 地点板条目和可复制正文;ID 留在标题,正文用清楚自然语言。不得生成地点板图片。
      
      ## 6. 制作形态投影
      
      `视觉设定.md` 的项目视觉方向与已明确制作形态决定这张场景板用什么词汇表达空间,不决定空间
      长什么样。
      
      ### 从形态取什么
      
      - **背景密度与信息层级**:绘制形态常靠密度差和留白建立主次,实拍形态常靠光比、景深和
        空气层次;同一份地理在两种形态里选择不同的详略分配。
      - **层拆**:固定地理层、可动层(帘、水、灯)、效果层各自画什么;哪些层在参考板上必须
        处于静止的已接受状态。
      - **边缘处理**:封闭轮廓、散边、洇化或摄影式虚实——决定入口与锚点的边界怎样被读出来。
      - **材质对光的响应**:墙地顶的反射、粗糙与透明关系在该形态里由什么承担(笔触、平涂关系、
        真实光源)。
      - **留白是否是合法的空间语言**:某些形态用留白表达纵深与压力,这是可执行词汇,不是省略。
      
      ### 形态不得改写什么
      
      - 入口、路径、固定锚点及其相对关系与观察方向;
      - `empty_stage` 政策与允许出现的人物类别;
      - 标牌与界面的文字政策及承载面;
      - 已接受的时间、天气、光态版本与光源的可解释来源。
      
      **`reviewed_invariant`**:简化掉的只能是装饰,不能是本 View 必须可核对的地理证据。若形态
      要求大面积留白或两层平涂,先确定“从卷帘门向内看,检修台沿右墙延伸,尽头唯一安全门正对
      通道”这类关系仍然可读;不能因为并进墙面更整齐就让安全门消失。做不到时缩小留白范围或
      改选观察面,并把冲突记为 `creator_decision_needed`,不静默丢锚点。
      
      同理,形态可以决定“气氛靠什么承担”,但不得为了形态好看新增剧情事故、封锁出口、移动固定
      结构,或把临时 dressing 提升为永久地理。
      
    • look-and-state-variant.md 5.3 KB
      # Look、View 与道具状态变体提示词
      
      ## 目录
      
      1. 什么时候需要变体
      2. Base—delta—validity
      3. 三类变体的写法
      4. 变体 plate 与 edit 的区别
      5. 输出、失败与审查
      
      ## 1. 什么时候需要变体
      
      变体的目标是在不改变持久身份的前提下,把有因果、可复用、在一定范围内持续的视觉状态明确出来。它不是为了给每个表情、角度或手势建一张新资产图。
      
      先用 `视觉设定.md` 的当前判断区分:
      
      - **reuse**:身份/地理/功能和需要保持的 state 都没变,直接复用;
      - **variant**:同一身份上出现可逆或时间有界的 Look/View/道具状态差异;
      - **new asset**:持久身份、固定地理或基本功能已改变;
      - **unresolved**:无法确定,停止写提示词并让创作者选择。
      
      图片提示词不能自行做这项身份决定,只把已确认变体写成可见参考。
      
      ## 2. Base—delta—validity
      
      一个 `IMG-...` 变体条目必须能回答:
      
      1. **Base**:它从哪个准确身份/变体 ID 派生?
      2. **Preserved anchors**:哪些 Character/Location/Prop 身份事实不变?
      3. **Delta**:哪里发生了什么可观察变化,范围和强度如何?
      4. **Cause/source**:变化来自哪个场景、连续性事实或创作者决定?
      5. **Validity**:从哪里开始、持续到哪里、何时恢复/再变化?
      6. **Affected work**:哪些 `IMG-...`、`SHOT-...` 或关键帧需要此变体?
      
      - **`structural_invariant`**:基底、变体 ID、来源与有效范围可解析;不得同时使用不相容变体。
      - **`reviewed_invariant`**:delta 与持久锚点没有混层,也没有超过 source 支持的范围。
      - **`craft_default`**:正文先短述保持的身份,再把注意力放在 delta;不要重写全部 base。
      - **`taste_option`**:单独 variant plate、同版对照或局部细节板由复用目的决定;默认单独 plate 更少歧义。
      
      ## 3. 三类变体的写法
      
      ### Character / Look
      
      常见 delta:衣服/穿法、发型整理、妆面、临时配饰、污湿、血迹、新伤、包扎、年龄化阶段。写清身体/衣物位置、覆盖范围、材料反应和未变区域。
      
      示例机制(合成):同一维修员夜班 Look 经雨后,只有外套右肩至肘部明显湿深,头发末端微湿;脸型、断眉、服装剪裁、左胸布贴和右袖旧焊痕保持。不要把“雨后”扩成新伤、换装或全身滴水。
      
      瞬时目光、一次抬手、单镜头表情通常属于 shot/keyframe,不建 Look。
      
      ### Location / View-state
      
      常见 delta:特定观察方向、临时 dressing、营业/停业状态、时间、天气和光线。固定入口、主要分区、建筑结构及关键锚点保持;写清从 base View 哪些可见条件改变。
      
      夜景不是把门窗重新布局。临时堆放物不要升级为固定地理。若洪水、坍塌等永久改变动线,应由 assets 判断是否仍是 variant。
      
      ### 道具状态(Prop/State)
      
      常见 delta:开/关、内容物、损坏、污渍、文字、持有者与功能状态。写清铰链/缺口/裂纹位置、内容可见程度、承载面文字政策和未变轮廓材料。
      
      换手不一定需要新的 plate;只有下游识别/连续性确需一个持续状态时才做。道具完全断成两件且功能改变,可能需要 owner 决定新 State 或新 asset,prompt 不代判。
      
      ## 4. 变体 plate 与 edit 的区别
      
      - **Variant plate** 描述一个已确认、可被多个镜头复用的完整当前状态;它可以从零编写提示词,不依赖某张待编辑图片。
      - **Edit-delta** 针对可见 `IMG-...`、对象和区域,说明变化、保持项与连续性影响;用于“从现有参考改成当前变体”的提示词。
      
      若创作者说“把袖子改湿”:
      
      1. 已有明确的湿衣 Look,且目标是复用状态 → 可以写变体板或局部编辑;
      2. 湿衣 Look 尚未确认 → 先向 assets 提变体选择;
      3. 只发生在单镜头动作末端、没有持续复用 → 可能应由 storyboard continuity 拥有,不自动创建资产 prompt。
      
      不要把 before/after 两个互斥人物叠在一张身份板,除非用途明确是比较板,且两个区域/标签不会造成身份融合;这属于可覆盖的 craft choice,不是默认。
      
      ## 5. 输出、失败与审查
      
      ### 失败征兆
      
      - 只有“更脏、更老、更阴森”,没有位置、范围和可观察 delta;
      - delta 覆盖整个人/地点/物件,实际已改变持久身份却仍叫 variant;
      - prompt 复制 base 全文后,把真正变化藏在末尾;
      - 有状态但无 cause/validity,导致后续镜头不知道何时复用;
      - 把 pose、机位或一次 reaction 当成资产变体;
      - 同一 plate 同时画完好/损坏、白天/夜晚或两套 Look,未声明比较用途。
      
      ### 检查
      
      | 检查 | 分类 |
      |---|---|
      | 准确基底/变体、来源、有效范围解析 | `structural_invariant` |
      | delta 是否保持 identity/geography/function | `reviewed_invariant` |
      | 是否误把瞬时 shot 状态升级为 asset variant | `reviewed_invariant` |
      | delta 是否比 base boilerplate 更醒目 | `craft_default` |
      | 单图或对照板、变化强度与呈现媒介 | `taste_option` |
      
      输出一个写清基底、变化、保持项、有效范围和受影响工作的 `IMG-...` 条目,以及一段聚焦当前状态的
      可复制正文。不得生成图片,也不得声称变体画面已经验证成功。
      
    • lookdev-frame.md 2.4 KB
      # Lookdev 风格帧提示词
      
      Lookdev 风格帧把 `视觉设定.md` 中项目级视觉方向投影成可比较的通用图片提示词。它不选择画风,
      不生成图片,也不从一张参考图推断整部作品的规则。
      
      ## 三类测试轴
      
      - `character_expression`:绑定准确 CHAR/LOOK,检查身份锚点、材质/线条和表演可读性;
      - `core_location`:绑定准确 LOC/VIEW,检查地理、材质、色彩层级与光源逻辑;
      - `high_pressure_scene`:绑定准确场景、人物状态与来源块,检查冲突中的注意中心、遮挡和密度。
      
      不要求三类都固定生成若干张。选择本项目最能暴露方向失效的代表帧,并在条目中写清测试问题。
      
      ## 写条目
      
      在 `图片提示词.md` 使用 `IMG-...` 标题,写明用途为 Lookdev、测试轴和对应的“项目视觉方向”章节。
      高压力场景还要绑定真实场景 ID、动作和信息权限,不能从提示词发明剧情状态。再写:稳定项、
      允许变化项、要保护的身份/地理/剧情事实,以及删除风格标签后真正改变的材质、光、色、边缘、
      景深或空间表达。
      
      风格参考标明用途为“风格”:
      
      - “允许控制”只列色彩层级、材质处理、阴影边缘、景深倾向、画面密度等本次准许内容;
      - “不得控制”保护角色身份、固定场景地理、剧情状态、人数、持物与道具文字;
      - 每张真实参考图使用稳定 `REF-...` 槽位,绑定可见项目相对路径或其他明确 artifact locator、中文名称、显式顺序和封闭词表里的用途(风格帧通常是 `风格`);换图时显式修订槽位的 locator,不把旧图的控制语义静默转给新槽位。`IMG-...` 仅用于当前《图片提示词.md》的提示词条目。
      
      角色、地点或压力场景的事实仍来自它们各自 owner。高压力测试帧不得为了“更有冲击力”提前
      泄露身份、发明动作结果或改变文字政策。
      
      ## 比较与修订
      
      比较人物、地点和压力场景是否共享可辨认语言,同时记录哪一部分允许逐场变化。没有授权生成结果
      观察时,只能指出文字层风险。若收到绑定准确提示词、参考、配置和结果的项目观察,局部修订写清
      变化与保持项,一次只改诊断所需变量;不把一次结果推广为其他项目或制作配置的规律。
      
    • production-sheet-recipes.md 11.4 KB
      # 生产参考板决策:角色、场景与道具
      
      ## 目录
      
      - [角色参考板](#一角色参考板)
      - [场景方位板](#二场景方位板)
      - [道具参考板](#三道具参考板)
      - [合成与修改](#四首帧合成与定点修改指令)
      - [资产范围](#五资产范围决策craft_default)
      - [质量判据](#六质量判据与反模式)
      
      来自对角色、场景、物品资产如何进入后续镜头的定性案例阅读,示例均为合成改写。
      通用方法见 [common-recipe.md](common-recipe.md);本文档提供可按项目调整的生产版式。
      核心原则:**先明确资产负责的稳定身份与当前版本,再让分镜负责本镜呈现**。纯白底、
      无情绪、三视图只是便于识别的一种项目选择;带环境的背景、单视图或带状态的参考板
      只要更符合复用目的且不混淆身份与临时状态,也可以由创作者选择(IMG-03/IMG-04)。
      
      ## 一、角色参考板
      
      先写 `reuse_job`:下游需要保持身份识别、当前造型、某种状态,还是某个可操作部位?然后
      选择最少但足够比较的视图、背景和光线。头肩、全身、侧背、单视图、上下文参考或中性
      板式都可以;背景和视图数量不是角色身份的一部分。
      
      以下是可选记录方式;与 `reuse_job` 无关的行可以省略:
      
      ```text
      用途:<这张板要让下游保持什么>。
      身份识别特征:<少量稳定、可见、彼此不重复的脸型/发型/体态/识别标记>。
      当前造型或状态:<只写已接受版本的可见变化和有效范围>。
      版式:<为复用职责选择的视图、占画关系、背景与比较方式;多视图并排时写明画面内不出现视图标签、引线箭头、尺寸标注与图注>。
      光线与文字:<帮助识别材质/结构的光线;已接受的文字方案与显示位置>。
      排除:<当前最可能越权导入或漂移的事实>。
      ```
      
      若项目已验证特殊分隔、权重或引子,可在最后交付时采用;通用资产说明不保存这些
      供应商写法,也不把分辨率、质量词或固定收尾当成资产质量。
      
      ### 决策规则
      
      - **布光服务识别职责**:先问哪些脸部结构、材质、轮廓或状态必须可比较,再选择光源
        方向、面积和反差。光型不自动编码性别、阶级、善恶或权力;同一造型的识别锚点与
        参考图用途必须保持稳定。
      - **社会处境要有已接受依据**:磨损、整洁、改制、借用、制服纪律或刻意伪装都可能
        承载人物处境,但不能从贫富、性别、年龄或题材标签自动推出服装和布光。先引用角色
        行动、职业条件、当前选择或已接受设定,再决定哪些可见细节值得复用。
      - **视觉细节要有职责**(IMG-02 的强化):它应服务身份识别、当前状态、结构功能或
        下游复用。写不出职责或与其他锚点竞争的装饰优先删除。
      - **状态何时建立新版本由复用决定**:被俘或重伤等状态若跨镜复用、影响识别或连续性,
        固化为新的造型或状态版本;只在一镜发生且已完整写入镜头边界时不必扩张资产表。
      - **风格标签按项目添加**:按项目风格前置 `【真人风格,写实风格】` /
        `【国漫风,二次元画风】` 等,设计稿本体不带标签。
      
      ### 布光词汇:按“要比较什么”选,不按身份标签映射
      
      先确定这张板必须让下游比较什么——骨骼体积、表面材质、外轮廓与体量、服装层次,还是状态
      痕迹——再从下列词汇里选。每种光型的条目只说明它让什么结构变得可比较、又压掉什么。
      
      | 光型 | 让什么可比较 | 压掉什么 |
      |---|---|---|
      | 均匀正面光(平光) | 五官相对位置、妆面、服色与图案 | 颧骨、鼻梁、下颌等体积起伏 |
      | 侧光 / 高位斜侧光 | 明暗交界线两侧的骨骼体积与轮廓起伏 | 暗侧细节;同时放大不对称 |
      | 顶光 | 眼窝、鼻下、颌下的纵向结构关系 | 暗区中的识别细节与服装层次 |
      | 底光 | (反转日常明暗方向)非常规体积读法 | 常规结构读法,做识别板时不可用 |
      | 大面积柔光 | 材质纹理、肤质、布料表面状态 | 形状边界与轮廓锐度 |
      | 小面积硬光 | 反射差异、磨损、镜面高光与工艺痕迹 | 过渡信息;放大瑕疵与形变 |
      | 轮廓光 / 逆光边缘光 | 外轮廓、发型剪影、服装廓形与前后分离 | 面部识别信息,不单独承担身份板 |
      | 场景内实际光源 | 状态板与环境内参考板的光向可核对性 | 中性比较条件,需与场景已接受光向一致 |
      
      **解耦声明**:以上词汇只按“本板必须让人比较什么”选择,**不按性别、年龄、贫富或题材标签
      映射**。同一光型可用于任何角色;项目里若出现“女性一律柔光、男性一律侧光”这类默认,那是
      未经证据的模板化,先删除再按 `reuse_job` 重选。社会处境仍按上一条规则从已接受依据取证。
      
      绘制形态里“光”由上色关系与阴影形状承担,这张表的选择依据不变——变的只是它落到哪一层的
      阴影形状与边缘处理,由已接受的制作形态决定。
      
      ### 合成判断例:同一角色的伪装期
      
      - `identity`:窄长脸、左眉旧缺口、略前倾但稳定的走路重心;这些跨造型保持。
      - `look_state`:本段穿借来的制服,袖长不合身,胸牌按上游要求设为 `graphic-only`;
        这些只在伪装有效范围内保持。
      - `reuse_job`:近景靠眉缺口识别,全身调度靠重心和制服轮廓识别。
      - `layout`:选择一个能看清面部锚点的视图和一个能比较制服轮廓的视图;背景只需不
        干扰识别,不要求白底或固定占比。两视图并排等高,写「画面内无视图标签、无引线箭头、
        无尺寸标注、无图注」。
      - `exclusion`:不从“伪装者”标签追加阴影脸、可疑眼神或无来源武器。
      
      ## 二、场景方位板
      
      只有摄影方向会改变入口、可见地理、光源、遮挡或叙事功能时才建立观察视角。方向可以用
      罗盘、门内/外、主桌侧/证人侧等项目语汇;不为“完整”做齐所有方向。
      
      以下是可选记录方式;只写当前观察面需要核对的内容:
      
      ```text
      观察视角:<摄影机在哪一侧、朝向哪里、为何需要这个观察面>。
      固定地理:<入口、路径、区域、遮挡、可操作部位及其相对关系>。
      本版本:<有依据的时间、光线、损坏、占用或天气状态>。
      可见边界:<此观察视角能看到和看不到什么;哪些事实暂缓揭示>。
      文字/人物政策:<空场、允许的人物类别、标牌与已接受的文字方案>。
      ```
      
      - 清点顺序以当前空间最容易混淆的关系为起点,不要求中心、地面、四向和头顶全部出现。
      - 光源只写其固定来源和当前版本;反打能否咬合靠相同地理与光向核对,不靠“背后
        来光”公式。
      - 观察视角不自动携带情绪。时间、光线和戏剧状态若变化,明确它属于场景的固定事实、
        观察面的可见差异还是本场版本,避免为每个方向发明一套气氛真相。
      
      ## 三、道具参考板
      
      道具板优先让轮廓、可操作部位、尺度关系、当前状态和文字政策可比较。白底产品照只是一种
      适合孤立结构的版式;道具依赖佩戴、安装或环境尺度时,可选择有控制的上下文背景。
      
      以下是可选记录方式;字段由道具功能和复用风险决定:
      
      ```text
      用途与归属:<谁如何识别、握持、佩戴、安装、转交或损坏它>。
      稳定形制:<轮廓、材质、结构、可操作部位及可比较尺度>。
      当前状态:<有依据的磨损、开启、缺失、污染或修复>。
      版式与光线:<让上述职责可读的视图、背景和材质照明>。
      文字:<`exact-readable` / `graphic-only` / `no-readable-text` 及受控显示位置>。
      ```
      
      颜色、材质和工艺只是常见识别重点;对钥匙可能是齿形,对药瓶可能是封口与文字政策,
      对可穿戴物则可能是佩戴关系。字段由功能和复用风险决定(IMG-05)。
      
      ## 四、首帧合成与定点修改指令
      
      资产参考进入关键帧提示词时,先声明每张参考的用途 `role` 和可以参考的内容,不能让整张图
      同时决定身份、构图、状态和文字(仍只产出提示词文本,不涉及调用):
      
      ```text
      参考 A:`role=identity`;`may_control=<脸型/识别标记>`;`must_not_control=<姿势/背景/文字>`。
      参考 B:`role=geography`;`may_control=<入口/路径/固定锚点>`;`must_not_control=<临时人物/故事状态>`。
      本镜:从已接受起点写出人物相对站位、朝向、遮挡与可见状态;构图和景别服从本镜目的
      与观众应看到的信息;文字服从上游的逐字保留要求。
      ```
      
      只写当前执行需要的站位、朝向、尺度和文字风险。若创作者提供的项目观察证明某类
      漂移反复发生,针对该风险补局部约束;不把“人物过大/字幕”预设为所有镜头缺陷。
      
      局部修改要同时写清**修改项与保持项**(IMG-06 的实际写法)。可以分句解释复杂区域,
      但每项变化都要能指向精确 `IMG-...`、对象和区域,未受影响的事实明确保持:
      
      ```text
      画面中右侧的甲去掉,画面中不要出现甲,其他角色站位动作保持不变,其他内容保持不变。
      ```
      
      多张参考图即使使用位置编号,也要逐条写清用途 `role`、`may_control`、`must_not_control` 与检查
      结论;“五官参考若干图、其他全照图一”这类让整图顺带决定多类内容的指令,应先拆成
      可审查的参考绑定。
      
      ## 五、资产范围决策(`craft_default`)
      
      | 决策 | 判断方式 |
      |---|---|
      | 是否建角色资产 | 后续需要重复识别、绑定造型、配音或保持连续时才建立。 |
      | 是否拆地点与观察视角 | 摄影方向会改变可见地理、入口、光源或叙事功能时拆分。 |
      | 是否建物品资产 | 物品会被识别、持有、转手、损坏、读字或承担回扣时建立。 |
      | 描述写多长 | 写到能稳定识别与执行即可;删除不能归因身份、结构、状态或用途的装饰。 |
      | 一次覆盖多少集 | 先抽取完整已接受范围,再按创作者停靠点接受;不从固定资产数量倒推剧情。 |
      
      ## 六、质量判据与反模式
      
      判据:每个细节是否服务身份、当前版本、功能、地理或下游复用;背景、光线和视图是否
      适合 `reuse_job`;角色、道具和场景的参考权限有没有互相越界;场景 `View` 是否能核对
      入口、路径与光向;文字政策、角色名和资产绑定是否一致。带环境的背景或状态光线不是
      天然失败,但必须明确属于哪一层,并避免污染稳定身份。
      
      反模式(定性案例中的返工机制):
      
      1. 声称做中性身份板,却让一次性场景光、动作或背景成为身份识别特征;反之,项目选择
         上下文状态板却被机械清空,丢失其复用职责。
      2. 表单字段直贴描述("身份:女配\n年龄身高:20岁")。
      3. 描述没有提供足以识别、操作或核对状态的事实,不论文字长短。
      4. 无语义命名(资产名叫 '1'、'站位'、'参考'——下游无法按名索引)。
      5. 收到生产反馈后不诊断身份、构图、文字或状态风险,只重复同一描述。
      6. 描述内角色名与资产登记名不一致(写 A 名生成 B 人)。
      
    • prop-plate.md 6.7 KB
      # 道具 Plate:尺度、功能、状态与文字
      
      ## 识别测试 (`IMG-05`)
      
      道具 Plate 保持尺度、形状、材质、磨损、功能/活动部件与 accepted text policy。
      它应展示当前 State,但不能悄悄重新设计底层 prop identity。
      
      ## 目录
      
      1. 目的与输入
      2. 身份与 State
      3. 可复用 plate 配方
      4. 文字政策
      5. 输出与审查
      6. 制作形态投影
      
      ## 1. 目的与输入
      
      道具 plate 要让后续画面保持同一件物体的轮廓、尺度、材料、功能和当前状态。输入是精确 道具身份与状态、来源指针、用途、尺度参照、视角、功能件、磨损/损坏、主人关联、文字政策、背景与光线。
      
      道具身份不等于“谁在拿”。换手、打开、装入内容、沾水、裂损或贴上标签通常是 State;永久形制改变才可能需要重新做资产决策。
      
      ## 2. 身份与 State
      
      ### 持久身份
      
      - 整体轮廓与主要比例;
      - 尺寸或与中性参照的比例;
      - 主材质、表面工艺和固有色;
      - 接缝、扣件、开口、把手、铰链等功能结构;
      - 有识别价值的长期磨损或制造特征。
      
      ### 当前 State
      
      - 开/关、折叠/展开、完整/损坏;
      - 当前内容物和是否可见;
      - 污渍、水、烧灼、血、灰尘等有因果的表面变化;
      - 所有权/持有关系以及状态有效范围;
      - 文字内容与承载面状态。
      
      **`reviewed_invariant`**:提示词必须能让形状、材料、功能彼此成立。例如“透明玻璃密封瓶”不能同时写成“无开口的实心石块”。
      
      ## 3. 可复用 plate 配方
      
      顺序建议:
      
      1. **类型、用途、主体**:道具全貌参考、结构细节或状态 plate。
      2. **尺度与轮廓**:真实尺寸范围或中性参照,长宽厚关系,主轮廓。
      3. **材料与色彩**:主材、次材、反射/粗糙/透明关系。
      4. **功能结构**:活动件、开启方向、握持区域、接口;展示到足以理解功能,不自动演示剧情动作。
      5. **道具状态**:损伤、内容、表面状态、owner relevance 的可见部分。
      6. **视图与背景**:主体占比、正/侧/必要局部,干净背景与易读光线。
      7. **文字政策**:精确选择并说明承载面。
      8. **保持/排除**:防止变形、错材、错状态或多出复制品。
      
      - **`craft_default`**:若尺度容易误判,加入不带身份的参照或给出功能性尺寸关系;不要用剧情角色的手当默认参照。
      - **`craft_default`**:对可动部件,选择一个明确状态;如确需开/关两态,分为两个道具状态条目。
      - **`taste_option`**:产品式悬浮、台面陈列、正交视图或环境内静物由复用目的决定。
      
      ## 4. 文字政策
      
      文字是一项资产状态和制作决策,不是随手加的装饰。
      
      不要改写 assets owner 的 `exact_readable | graphic_only | no_readable_text |
      pending_creator_text`。本 skill 只为当前道具板选择下列呈现方式,并在条目中保留资产 ID 与映射理由。完整映射表见
      [common-recipe.md](common-recipe.md)。
      
      ### `readable`
      
      逐字使用已接受文本,说明位置、方向、行数/层级和承载面。正文不要改写或自动纠错关键文书。若需要保密/后期合成,可改为 `postproduction`,不能一边要求可读一边写“画面中不要任何文字”。
      
      ### `symbolic`
      
      保留标签/刻痕的视觉存在和布局,但明确为不可辨识符号,不得偶然形成新名字、号码或 URL。
      
      ### `blank`
      
      指定承载面保持干净空白,同时保留其材料、透视和光照。不等于抹掉道具其他结构。
      
      ### `postproduction`
      
      预留清楚、无遮挡、透视可跟踪的区域;描述面积、位置、方向、材质和光线,实际字后期添加。可在 creator note 记录精确文字,但 generic image prompt 不要求生成它。
      
      **`structural_invariant`**:单个文字承载面不能同时选择互斥政策;`readable` 与全局 no-text 冲突时必须先解决。
      
      ## 5. 输出与审查
      
      ### 失败征兆
      
      - 只说“古老钥匙、精致盒子”,没有比例、形制和材料;
      - 打开/关闭、完好/断裂、空/装满同时存在;
      - 可动件不知如何连接,功能靠抽象标签;
      - 文字内容由 prompt 作者临时编造,或 `readable` 被 no-text 否定;
      - 道具主人被画成 plate 主体,或不同视图中尺寸/损伤位置漂移。
      
      ### 检查
      
      | 问题 | 分类 |
      |---|---|
      | 道具身份与状态、source refs、text policy 可解析且不冲突 | `structural_invariant` |
      | 尺度/形状/材料/功能/current State 足以识别 | `reviewed_invariant` |
      | 磨损与状态是否有因果、没有污染永久身份 | `reviewed_invariant` |
      | 中性参照、视图数量、背景方式 | `craft_default` |
      | 产品感、写实度、陈列审美 | `taste_option` |
      
      输出一个精确绑定的 `IMG-...` 道具板条目和可复制正文;不承诺文字最终生成准确,也不生成媒体。
      
      ## 6. 制作形态投影
      
      `视觉设定.md` 的项目视觉方向与已明确制作形态决定这件道具用什么词汇被画出来,不决定它是什么。
      
      ### 从形态取什么
      
      - **轮廓简化程度**:该形态允许省略到哪一级仍能与同类物区分;
      - **功能件的表达通道**:铰链、开口、握持面、接缝是靠线条、靠材质明暗,还是靠真实结构;
      - **材质对光的响应**:金属、玻璃、木、布在该形态里怎样出现反射、透明与粗糙差异;
      - **尺度参照的成立方式**:绘制形态常靠对比物与透视线索,实拍形态可用真实景深与已知尺寸;
      - **磨损与损坏的通道**:笔触、色块边界、表面纹理还是实拍痕迹。
      
      ### 形态不得改写什么
      
      - 形制、主要比例与功能结构的连接关系;
      - 当前 State(开合、内容物、损伤、污染)及其有效范围;
      - 文字政策与承载面;
      - 所有权/持有关系与 owner relevance。
      
      **`craft_default`**:形态越简化,越要先保住“能区别这一件与同类物”的一两处结构。Q 版、
      水墨或强笔触形态可以省略次要装饰,但钥匙的齿形、药瓶的封口、箱扣的咬合方式属于识别通道,
      省掉之后 plate 就不再是这件道具的参考。
      
      **`structural_invariant`**:形态不能修改文字政策。若 `readable` 在高度笔触化或极简形态下
      无法逐字承载,改为 `postproduction` 并写明理由与预留区域;不得降级为 `symbolic` 而把已接受
      文本悄悄丢掉,也不得为了画面整洁抹去承载面本身。
      
      合成例:角色甲交给角色乙的旧钥匙,形态选择为强笔触绘制。齿形与柄部缺口仍逐项写出,
      柄上刻字按上游政策保持 `graphic_only` → `symbolic`;笔触只影响边缘与表面质感的写法,
      不影响“同一把钥匙、当前带有那道缺口”的判定。
      
    • review-and-fixtures.md 5.2 KB
      # 图片提示词审查量表与合成案例
      
      ## 目录
      
      1. 审查方式
      2. 证据量表
      3. 完成前结构检查
      4. 合成正例
      5. 合成反例
      
      ## 1. 审查方式
      
      先做可确定检查,再由与作者分离的 reviewer 判断语义和 craft。Reviewer 不替 owner 修改;finding
      包含文件与 `IMG-...`、精确证据、影响、所需修订、owner、严重程度和状态。不要以固定长度、词数、
      形容词比例或“像 AI”判质量。
      
      ## 2. 证据量表
      
      对每条提示词逐项给出 `PASS | REVISE | NOTE` 和引用:
      
      | 维度 | 要问的问题 | 合格证据 |
      |---|---|---|
      | 绑定 | 是哪个身份与当前变体? | `视觉设定.md` 的可见 ID 与提示词引用 |
      | 区分度 | 不看显示名,能否认出或区分? | 稳定锚点与当前变化 |
      | 单一目的 | 是否把互斥参考需求混在一起? | 用途、构图与状态一致 |
      | 空间/尺度 | 关系能否同时成立并复用? | 地理/尺度事实与正文句子 |
      | 文字 | 政策、内容、承载面与排除是否相容? | 文字事实与呈现方法 |
      | 经济性 | 参考已承载的内容是否被无意义重复? | 可删句与未受影响事实 |
      | 越权 | 是否新造资产、故事或连续性事实? | 来源事实与冲突句 |
      | 可复制 | 去掉标题元信息后正文是否自足? | 可复制正文 |
      
      Finding 的修复必须可执行,例如“补回安全门相对检修台的位置”,不能只写“加强细节”。审美替代
      方案属于 NOTE,除非违反已确认约束。
      
      ## 3. 完成前结构检查
      
      - 每个 `IMG-...` 标题唯一,并引用真实视觉设定条目;
      - 人物、地点或道具的当前变体与有效范围没有冲突;
      - 可读文字与全局禁字没有同时出现;
      - 局部编辑包含目标、变化、保持项和连续性影响;
      - 每张真实参考图用独立稳定的 `REF-...` 槽位绑定顺序、项目相对路径/明确 artifact locator 和中文名称,并写明封闭词表里的用途、允许控制、不得控制与未验证风险;
      - 可复制正文不含 ID、文件路径、占位符、流程说明或 QA 结论。
      
      只有本地可证明的结构冲突直接阻断。语义问题由 reviewer 引用来源与正文后给 `REVISE`;默认做法与
      审美选项可由创作者覆盖。
      
      ## 4. 合成正例
      
      以下人物、地点、物件与文字均为虚构合成材料。
      
      ### 输入摘要
      
      - `CHAR-LUOJING`:三十岁上下,窄长脸,右眉尾有自然断点,黑色短卷发,瘦高;
      - `LOOK-RADIO-NIGHT`:墨绿工装衬衣、米白旧 T 恤、左胸圆形台标布贴,右袖口有一处旧焊痕;
      - 用途:后续镜头识别同一人物和夜班 Look。
      
      ### 合格 generic prompt
      
      > 人物全身设定参考图:瘦高的三十岁上下女性,窄长脸,右眉尾有一处自然断点,黑色短卷发,保持克制而警觉的低强度表情。只呈现夜班造型:墨绿工装衬衣敞开一颗领扣,内搭米白旧 T 恤,左胸缝圆形无文字台标布贴,右袖口保留拇指宽的浅褐旧焊痕,深色直筒长裤与耐磨短靴。自然站立的全身正面为主,附同一造型的头肩侧面小视图;比例真实,无夸张透视。中性浅灰背景,均匀柔光,清楚呈现面部轮廓、服装层次和布料磨损。保持同一张脸、同一发长、同一套衣服;不增加首饰、伤口、手持工具或第二套造型,不出现可读文字。
      
      为何有效:身份锚点与 Look 分层;构图服务识别;“无文字”不否定无文字台标;没有借设定图演一场戏。
      
      ### 合格 Location 摘要
      
      > 社区广播站维修间空场参考:从朝南的窄门向内看,长形房间右墙是一列齐腰高木质检修台,台尽头连接后墙唯一的灰色金属安全门;左墙两扇高窗与检修台相对,窗下固定一排浅柜,房间中央保留一条从入口直通安全门的走道……空场,不出现演员或剧情动作。
      
      关键不是装饰多,而是入口、检修台、安全门、窗和走道的关系可复用。
      
      ## 5. 合成反例
      
      ### 反例 A:泛化且混 Look
      
      > 顶级电影质感的绝美女主,时而穿墨绿工装,时而穿红色礼服,头发既短又飘逸及腰,浑身湿透但衣服保持完全干燥,8K,大师杰作,无任何瑕疵。
      
      Finding:
      
      - evidence:同一规格同时出现两套服装、两种发长和互斥干湿状态;
      - impact:无法成为一个 accepted Look 的复用参考,并抹去断眉/脸型等锚点;
      - required fix:绑定一个 Look,仅保留该状态的可观察 delta,把其他 Look 拆为独立规格;
      - classification:`reviewed_invariant`,owner `image-prompts`,severity `error`。
      
      ### 反例 B:文字矛盾
      
      > 桌面上的值班登记簿,封面必须清楚写“设备复核记录”,画面中不要任何文字、字母或符号。
      
      `readable` 与全局 no-text 可由本地检查证明冲突。修复不是祈求“正确生成”,而是在 `readable` 与 `postproduction` 中选择一种并调整正文。
      
      ### 反例 C:越权 edit
      
      > 保持所有东西不变,把维修间改造成豪华酒店大堂,再把后门移到左侧。
      
      目标、View 和 preserve 边界不清;同时改写 Location 身份与固定地理。先路由 assets 形成新 Location/View 决定,不能在 edit prompt 内偷改。
      
    • stage-contract.md 3.6 KB
      # 图片提示词阶段契约
      
      本阶段只拥有 `剧集/<EP>/图片提示词.md` 中的 `IMG-...` 项:用途、参考边界和可复制正文。它继承
      视觉设定与项目视觉方向,不改写资产身份、地理、剧情状态或镜头边界。
      
      每项参考都写清可以控制什么、不能控制什么;没有获授权的像素观察时保持未知。局部修改直接写目标、
      变化、保持项和连续性影响,不建立 prompt spec、QA 或接受记录。
      
      ## 本阶段规则
      
      ### `IMG`
      
      | ID | Class | Knowledge |
      |---|---|---|
      | IMG-01 | structural_invariant | Each `IMG-...` item names the exact visual-setting item and current variant it depicts. |
      | IMG-02 | craft_default | Put distinguishing identity, geometry, scale, or state before generic quality language. |
      | IMG-03 | reviewed_invariant | Character sheets preserve identity while depicting one coherent Look. |
      | IMG-04 | reviewed_invariant | Location plates preserve geography, orientation, anchors, material, and light, normally without cast. |
      | IMG-05 | reviewed_invariant | Prop plates preserve scale, shape, material, wear, function, and text policy. |
      | IMG-06 | structural_invariant | Edit prompts declare exact target, changes, preserve set, and expected continuity impact. |
      | IMG-07 | structural_invariant | Readable text cannot coexist with a global no-text constraint. |
      | IMG-08 | reviewed_invariant | A claim about reference pixels requires a creator/reference-owner description or authorized input-reference observation bound to the inspected bytes; otherwise admission stays unresolved, and a negative prompt cannot stand in for evidence. |
      | IMG-09 | reviewed_invariant | Each reference states its purpose, what may be copied, and what must not be copied; a composition-, scale-, or effect-only reference cannot redefine identity, content, text, or story state. |
      | IMG-10 | reviewed_invariant | Views of one Location in the same time/weather state share key-light source, colour-temperature relation, and contrast direction; any difference cites a recorded cause and its delta. |
      | IMG-11 | reviewed_invariant | A lookdev frame binds accepted visual direction and production profile across a declared character-expression, core-location, or high-pressure test axis; a high-pressure frame also binds exact screenplay blocks for story state and information permission, while style references may control only declared surface treatment and never identity, fixed geography, story state, cast count, or prop text. |
      | IMG-12 | reviewed_invariant | Each real input reference has a stable `REF-...` slot binding explicit order, a visible project-relative path or other unambiguous artifact locator, a Chinese label, and may-control/must-not-control scope. Reordering preserves slot identity; replacing media explicitly revises that slot's locator. `IMG-...` remains reserved for image-prompt headings. |
      | IMG-13 | structural_invariant | An `IMG-...` item named by a continuity lock in `视觉设定.md` carries that lock's surface verbatim in its copyable prompt. |
      | IMG-14 | structural_invariant | Every `REF-...` slot an image-prompt item declares carries one 用途 from the closed set 身份/造型状态/地理/构图/尺度/效果/起始帧/结束帧/风格, the same vocabulary the storyboard uses, so one picture answers one question. An asset board normally uses the first six; 起始帧 and 结束帧 belong to a shot. |
      
      规则分级由高到低:`structural_invariant`(结构缺陷,阻断)、
      `reviewed_invariant`(需证据判断)、`craft_default`(常用做法,可覆盖)、
      `taste_option`(创作者选择,不作缺陷)。创作者已接受的事实优先于本表。
      
  • scripts
    • image_prompt_check.py 17.5 KB
      #!/usr/bin/env python3
      """Validate standalone image-prompt specs without generating media."""
      
      from __future__ import annotations
      
      import argparse
      import json
      import re
      import sys
      from pathlib import Path
      from typing import Any, NamedTuple
      
      MINIMUM_PYTHON = (3, 9)
      if sys.version_info < MINIMUM_PYTHON:
          raise SystemExit("image_prompt_check.py requires Python 3.9 or newer")
      
      # ---------------------------------------------------------------------------
      # REFERENCE RESOLVER -- reference implementation.
      #
      # Each skill checker carries its own copy of this block. The suite has no shared
      # library on purpose: a skill must stay runnable after copying only its own
      # directory, so duplicating these few lines across skills is the correct shape.
      # Copy the block verbatim; do not import it.
      # ---------------------------------------------------------------------------
      
      SOURCES_RECORD_TYPE = "sources"
      SOURCES_SCHEMA_VERSION = "1.0.0"
      
      
      class ResolvedRef(NamedTuple):
          """An upstream reference with its snapshot resolved, whichever form it used."""
      
          owner: str
          artifact: str
          record_id: str | None
          field: str | None
          authority: str | None
      
      
      class RefFinding(NamedTuple):
          """A structural defect in a reference object."""
      
          code: str
          location: str
          detail: str
      
      
      def load_sources(document: Any) -> dict[str, dict[str, Any]]:
          """Return the ``sources`` declaration of a parsed file, or ``{}`` if absent.
      
          Accepts a parsed ``.json`` document (a dict) or the parsed record list of a
          ``.jsonl`` file, whose declaration lives on the first record.
          """
          if isinstance(document, list):
              document = document[0] if document else None
          if not isinstance(document, dict):
              return {}
          declared = document.get("sources")
          if not isinstance(declared, dict):
              return {}
          return {key: value for key, value in declared.items() if isinstance(value, dict)}
      
      
      def resolve_ref(
          ref: Any, sources: dict[str, dict[str, Any]], location: str
      ) -> tuple[ResolvedRef | None, RefFinding | None]:
          """Resolve a reference object written in either the compact or expanded form."""
          if not isinstance(ref, dict):
              return None, RefFinding("REF_IS_NOT_AN_OBJECT", location, f"got {type(ref).__name__}")
          src = ref.get("src")
          if isinstance(src, str):
              entry = sources.get(src)
              if entry is None:
                  return None, RefFinding(
                      "REF_SRC_IS_NOT_DECLARED", location, f"src {src!r} has no sources entry"
                  )
              owner, artifact = entry.get("owner"), entry.get("artifact")
              if not (isinstance(owner, str) and isinstance(artifact, str)):
                  return None, RefFinding(
                      "SOURCE_ENTRY_IS_INCOMPLETE", location, f"sources[{src!r}] needs owner/artifact"
                  )
          elif all(isinstance(ref.get(key), str) for key in ("owner", "artifact")):
              owner, artifact = ref["owner"], ref["artifact"]
          else:
              return None, RefFinding(
                  "REF_HAS_NO_UPSTREAM_BINDING", location, "needs src, or owner+artifact"
              )
          optional = {
              key: ref[key] for key in ("record_id", "field", "authority") if isinstance(ref.get(key), str)
          }
          return (
              ResolvedRef(
              owner,
              artifact,
                  optional.get("record_id"),
                  optional.get("field"),
                  optional.get("authority"),
              ),
              None,
          )
      
      
      # ---------------------------------------------------------------------------
      # END REFERENCE RESOLVER
      # ---------------------------------------------------------------------------
      
      SKILL_ROOT = Path(__file__).resolve().parents[1]
      HASH_RE = re.compile(r"[0-9a-f]{64}")
      # `common-recipe.md` forbids weight syntax and any one engine's control words: a
      # generic prompt that carries provider control syntax has stopped being generic.
      # This checks syntax only. Whether the prose leans on generic quality language is
      # `IMG-02`, a `craft_default` a creator may override with a reason, so it is a
      # reviewer's call citing what the description actually lacks — see
      # `common-recipe.md`, which forbids blocking delivery on a fixed word list.
      ENGINE_SYNTAX_RE = re.compile(
          r"(?:^|[\s,,((])--(?:ar|v|q|niji|style|no|seed|cref|sref)\b"
          r"|::-?\d"
          # Weight syntax is written (x:1.2); prose writes "(aperture: 1.8)" with a space.
          r"|:[01]\.\d\s*[))]",
          re.IGNORECASE,
      )
      PURPOSES = {
          "character_sheet",
          "location_plate",
          "prop_plate",
          "look_state_variant",
          "edit_delta",
          "lookdev_frame",
      }
      VENDOR_FIELDS = {
          "authorization",
          "credential",
          "credentials",
          "model",
          "model_id",
          "model_name",
          "provider",
          "provider_id",
          "api_key",
          "task_id",
          "remote_id",
          "access_token",
          "token",
          "secret",
          "password",
      }
      NORMALIZED_VENDOR_FIELDS = {re.sub(r"[^a-z0-9]", "", key) for key in VENDOR_FIELDS}
      
      
      # The source policy -> render treatment mapping from `common-recipe.md`. A
      # treatment outside its policy's row is a structural defect: the fix is a
      # creator override that changes the accepted policy, never a quiet widening here.
      ALLOWED_TREATMENTS = {
          "exact_readable": {"readable", "postproduction"},
          "graphic_only": {"symbolic"},
          "no_readable_text": {"blank", "symbolic"},
          "pending_creator_text": {"postproduction"},
      }
      
      # A blanket "no text in the image" instruction, however it is phrased. Matching
      # two literals (`no text` / `无文字`) let the reference document's own worked
      # counter-example through: `画面中不要任何文字` contains neither.
      NO_TEXT_CONSTRAINT = re.compile(
          r"(无任何(文字|字|文本)|无文字|不要(任何)?(文字|字|文本)|不出现(任何)?(文字|字)"
          r"|没有(任何)?(文字|字)|不含(任何)?(文字|字)|禁止(出现)?(文字|字)"
          r"|no\s+(visible\s+)?(text|lettering|writing|words|typography)"
          r"|without\s+(any\s+)?text|text[-\s]free)",
          re.IGNORECASE,
      )
      
      
      class ValidationError(ValueError):
          pass
      
      
      def resolve_input(value: str | Path) -> Path:
          path = Path(value).expanduser()
          if path.exists() or path.is_absolute():
              return path
          return SKILL_ROOT / path
      
      
      def load_jsonl(value: str | Path) -> tuple[dict[str, dict[str, Any]], list[dict[str, Any]]]:
          """Return the file's ``sources`` declaration and its prompt-spec records.
      
          A leading ``{"record_type": "sources", ...}`` header declares the upstream
          snapshots the specs point at; it is not a spec and never counts as one.
          """
          path = resolve_input(value)
          records: list[dict[str, Any]] = []
          for number, line in enumerate(path.read_text(encoding="utf-8").splitlines(), 1):
              if not line.strip():
                  continue
              try:
                  record = json.loads(line)
              except json.JSONDecodeError as exc:
                  raise ValidationError(f"{path}:{number}: invalid JSON") from exc
              if not isinstance(record, dict):
                  raise ValidationError(f"{path}:{number}: each record must be an object")
              records.append(record)
          sources: dict[str, dict[str, Any]] = {}
          if records and records[0].get("record_type") == SOURCES_RECORD_TYPE:
              header = records.pop(0)
              if not isinstance(header.get("sources"), dict):
                  raise ValidationError(f"{path}: the sources header must declare a sources object")
              sources = load_sources(header)
          if not records:
              raise ValidationError(f"{path}: no prompt specs")
          return sources, records
      
      
      def text(record: dict[str, Any], key: str, label: str) -> str:
          value = record.get(key)
          if not isinstance(value, str) or not value.strip():
              raise ValidationError(f"{label}: {key} must be non-empty text")
          return value
      
      
      def nonempty_list(record: dict[str, Any], key: str, label: str) -> list[Any]:
          value = record.get(key)
          if not isinstance(value, list) or not value:
              raise ValidationError(f"{label}: {key} must be a non-empty list")
          return value
      
      
      def validate_ref(
          value: Any,
          sources: dict[str, dict[str, Any]],
          label: str,
          *,
          field_allowed: bool = True,
      ) -> None:
          if not isinstance(value, dict):
              raise ValidationError(f"{label}: reference must be an object")
          resolved, finding = resolve_ref(value, sources, label)
          if finding is not None:
              raise ValidationError(f"{label}: {finding.code}: {finding.detail}")
          if resolved is None:
              raise ValidationError(f"{label}: reference could not be resolved")
          if not resolved.owner.strip() or not resolved.artifact.strip():
              raise ValidationError(f"{label}: owner and artifact must be non-empty text")
          if "record_id" not in value and (not field_allowed or "field" not in value):
              raise ValidationError(f"{label}: record_id or field is required")
      
      
      def validate_reference_bindings(
          record: dict[str, Any], sources: dict[str, dict[str, Any]], label: str
      ) -> None:
          bindings = record.get("reference_bindings", [])
          if not isinstance(bindings, list):
              raise ValidationError(f"{label}: reference_bindings must be a list")
          slots: set[str] = set()
          orders: set[int] = set()
          for index, binding in enumerate(bindings, 1):
              item = f"{label}.reference_bindings[{index}]"
              if not isinstance(binding, dict):
                  raise ValidationError(f"{item}: binding must be an object")
              slot = text(binding, "slot_id", item)
              order = binding.get("order")
              if slot in slots:
                  raise ValidationError(f"{item}: duplicate slot_id {slot}")
              if not isinstance(order, int) or order < 1 or order in orders:
                  raise ValidationError(f"{item}: order must be a unique positive integer")
              slots.add(slot)
              orders.add(order)
              validate_ref(binding.get("artifact_ref"), sources, f"{item}.artifact_ref")
              text(binding, "role", item)
              nonempty_list(binding, "may_control", item)
              nonempty_list(binding, "must_not_control", item)
              admission = binding.get("admission_status")
              if admission not in {"unverified", "creator_described", "visually_inspected"}:
                  raise ValidationError(f"{item}: invalid admission_status")
              if admission == "unverified" and not binding.get("unresolved_risks"):
                  raise ValidationError(f"{item}: unverified references need unresolved_risks")
      
      
      def vendor_field_paths(value: object, prefix: str = "") -> list[str]:
          leaked: list[str] = []
          if isinstance(value, dict):
              for key, child in value.items():
                  name = str(key)
                  path = f"{prefix}.{name}" if prefix else name
                  normalized = re.sub(r"[^a-z0-9]", "", name.casefold())
                  if normalized in NORMALIZED_VENDOR_FIELDS:
                      leaked.append(path)
                  leaked.extend(vendor_field_paths(child, path))
          elif isinstance(value, list):
              for index, child in enumerate(value):
                  leaked.extend(vendor_field_paths(child, f"{prefix}[{index}]"))
          return leaked
      
      
      def validate_asset_spec(
          record: dict[str, Any], sources: dict[str, dict[str, Any]], label: str
      ) -> None:
          binding = record.get("asset_binding")
          if not isinstance(binding, dict):
              raise ValidationError(f"{label}: asset_binding must be an object")
          validate_ref(binding.get("identity_ref"), sources, f"{label}.asset_binding.identity_ref")
          validate_ref(binding.get("variant_ref"), sources, f"{label}.asset_binding.variant_ref")
          for index, ref in enumerate(nonempty_list(record, "source_refs", label), 1):
              validate_ref(ref, sources, f"{label}.source_refs[{index}]")
          nonempty_list(record, "identity_or_form_anchors", label)
      
          if record["purpose"] == "edit_delta":
              edit = record.get("edit")
              if not isinstance(edit, dict):
                  raise ValidationError(f"{label}: edit_delta requires edit")
              validate_ref(edit.get("target_ref"), sources, f"{label}.edit.target_ref")
              nonempty_list(edit, "changes", f"{label}.edit")
              nonempty_list(edit, "preserve", f"{label}.edit")
              text(edit, "continuity_impact", f"{label}.edit")
      
          handling = record.get("text_handling")
          if isinstance(handling, dict):
              if "source_policy_ref" in handling:
                  validate_ref(
                      handling.get("source_policy_ref"),
                      sources,
                      f"{label}.text_handling.source_policy_ref",
                  )
              treatment = handling.get("render_treatment")
              if not isinstance(treatment, dict):
                  raise ValidationError(f"{label}: text_handling.render_treatment is required")
              # `common-recipe.md` gives the source policy -> render treatment mapping
              # as a structural check. Nothing implemented it, so a prop whose accepted
              # policy is `no_readable_text` could ask for readable lettering and come
              # back `valid` -- inventing a name or a number the creator never accepted.
              source_mode = handling.get("source_mode")
              allowed = (
                  ALLOWED_TREATMENTS.get(source_mode)
                  if isinstance(source_mode, str)
                  else None
              )
              mode = treatment.get("mode")
              if allowed is not None and mode not in allowed:
                  raise ValidationError(
                      f"{label}: text policy {source_mode!r} allows "
                      f"{' or '.join(sorted(allowed))}, not {mode!r}; a creator "
                      f"override must change the policy rather than the treatment"
                  )
              if source_mode == "exact_readable" and mode == "readable":
                  text(treatment, "exact_text", f"{label}.text_handling.render_treatment")
                  negatives = " ".join(str(item) for item in record.get("negative_constraints", []))
                  if NO_TEXT_CONSTRAINT.search(negatives):
                      raise ValidationError(f"{label}: readable text conflicts with a no-text constraint")
      
      
      def validate_lookdev_spec(
          record: dict[str, Any], sources: dict[str, dict[str, Any]], label: str
      ) -> None:
          validate_ref(record.get("direction_ref"), sources, f"{label}.direction_ref")
          validate_ref(record.get("production_profile_ref"), sources, f"{label}.production_profile_ref")
          subjects = nonempty_list(record, "subject_bindings", label)
          for index, subject in enumerate(subjects, 1):
              if not isinstance(subject, dict):
                  raise ValidationError(f"{label}.subject_bindings[{index}]: must be an object")
              item = f"{label}.subject_bindings[{index}]"
              validate_ref(subject.get("identity_ref"), sources, f"{item}.identity_ref")
              if "variant_ref" in subject:
                  validate_ref(subject.get("variant_ref"), sources, f"{item}.variant_ref")
              text(subject, "role", item)
          text(record, "test_question", label)
          nonempty_list(record, "stable_visual_rules", label)
          if record.get("lookdev_axis") == "high_pressure_scene":
              refs = nonempty_list(record, "story_context_refs", label)
              for index, ref in enumerate(refs, 1):
                  validate_ref(ref, sources, f"{label}.story_context_refs[{index}]")
      
      
      def validate_records(
          records: list[dict[str, Any]], sources: dict[str, dict[str, Any]] | None = None
      ) -> dict[str, Any]:
          sources = sources or {}
          identifiers: set[str] = set()
          for index, record in enumerate(records, 1):
              label = f"spec[{index}]"
              spec_id = text(record, "spec_id", label)
              if spec_id in identifiers:
                  raise ValidationError(f"{label}: duplicate spec_id {spec_id}")
              identifiers.add(spec_id)
              purpose = record.get("purpose")
              if purpose not in PURPOSES:
                  raise ValidationError(
                      f"{label}: invalid purpose {purpose!r}; "
                      f"use one of {', '.join(sorted(PURPOSES))}"
                  )
              if record.get("status") not in {"candidate", "accepted"}:
                  raise ValidationError(f"{label}: status must be candidate or accepted")
              leaked = sorted(vendor_field_paths(record))
              if leaked:
                  raise ValidationError(f"{label}: provider execution fields are forbidden: {', '.join(leaked)}")
              prompt = text(record, "generic_prompt", label)
              if HASH_RE.search(prompt) or "<sha256>" in prompt:
                  raise ValidationError(f"{label}: generic_prompt leaks internal hashes")
              engine_syntax = ENGINE_SYNTAX_RE.search(prompt)
              if engine_syntax:
                  raise ValidationError(
                      f"{label}: generic_prompt carries engine-specific syntax "
                      f"{engine_syntax.group(0).strip()!r}; keep it in a provider adapter"
                  )
              validate_reference_bindings(record, sources, label)
              if purpose == "lookdev_frame":
                  validate_lookdev_spec(record, sources, label)
              else:
                  validate_asset_spec(record, sources, label)
          return {
              "status": "valid",
              "specs": len(records),
              "sources": len(sources),
              "checks": [
                  "unique_ids",
                  "accepted_bindings",
                  # Named for what it does: every reference names a snapshot this
                  # file declares. Whether that record exists in the target artifact
                  # is not knowable here -- the checker is handed this file only.
                  "source_declaration",
                  "reference_slots",
                  "prompt_hygiene",
              ],
          }
      
      
      def validate_file(path: str | Path) -> dict[str, Any]:
          sources, records = load_jsonl(path)
          return validate_records(records, sources)
      
      
      def main() -> int:
          parser = argparse.ArgumentParser(description=__doc__)
          parser.add_argument("specs")
          args = parser.parse_args()
          try:
              result = validate_file(args.specs)
          except (OSError, ValidationError) as exc:
              print(f"image prompt check failed: {exc}", file=sys.stderr)
              return 2
          print(json.dumps(result, ensure_ascii=True, indent=2))
          return 0
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      
    • selftest.py 3.8 KB
      #!/usr/bin/env python3
      """Offline self-test for the standalone image-prompt checker."""
      
      from __future__ import annotations
      
      import copy
      import sys
      from typing import Any
      
      from image_prompt_check import SKILL_ROOT, ValidationError, load_jsonl, validate_records
      
      MINIMUM_PYTHON = (3, 9)
      if sys.version_info < MINIMUM_PYTHON:
          raise SystemExit("selftest.py requires Python 3.9 or newer")
      
      
      def require(condition: bool, message: str) -> None:
          if not condition:
              raise AssertionError(message)
      
      
      def fail(records: list[dict[str, Any]], sources: dict[str, dict[str, Any]], marker: str) -> None:
          try:
              validate_records(records, sources)
          except ValidationError as exc:
              require(marker in str(exc), f"expected {marker!r}, got {exc!s}")
          else:
              raise AssertionError(f"expected failure containing {marker!r}")
      
      
      def expanded(ref: dict[str, Any], sources: dict[str, dict[str, Any]]) -> dict[str, Any]:
          entry = sources[ref["src"]]
          inline = {key: entry[key] for key in ("owner", "artifact")}
          inline.update({key: value for key, value in ref.items() if key != "src"})
          return inline
      
      
      def main() -> int:
          sources, records = load_jsonl(SKILL_ROOT / "examples/minimal-image-prompt-specs.jsonl")
          require(validate_records(records, sources)["specs"] == 1, "valid fixture count")
          require(len(sources) == 3, "fixture declares its upstream snapshots once")
      
          duplicate = [records[0], copy.deepcopy(records[0])]
          fail(duplicate, sources, "duplicate spec_id")
      
          bad_order = copy.deepcopy(records)
          bad_order[0]["reference_bindings"].append(copy.deepcopy(bad_order[0]["reference_bindings"][0]))
          fail(bad_order, sources, "duplicate slot_id")
      
          leaked = copy.deepcopy(records)
          leaked[0]["provider"] = "example"
          fail(leaked, sources, "provider execution fields")
      
          # A/B Round 2: the suite forbids provider control syntax in a generic prompt,
          # but nothing enforced it — the only prompt check was for leaked hashes.
          # Generic quality language is `IMG-02`, a `craft_default`; it is not checked
          # here, because a validator cannot block delivery on a fixed word list.
          for syntax in ("--ar 9:16", "(red coat:1.2)", "cat::2"):
              engine_syntax = copy.deepcopy(records)
              engine_syntax[0]["generic_prompt"] += f" {syntax}"
              fail(engine_syntax, sources, "engine-specific syntax")
      
          nested_provider = copy.deepcopy(records)
          nested_provider[0]["reference_bindings"][0]["provider"] = "example"
          fail(nested_provider, sources, "reference_bindings[0].provider")
      
          nested_secret = copy.deepcopy(records)
          nested_secret[0]["asset_binding"]["credentials"] = {"token": "not-safe"}
          fail(nested_secret, sources, "asset_binding.credentials")
      
          undeclared = copy.deepcopy(records)
          undeclared[0]["asset_binding"]["identity_ref"]["src"] = "no-such-source"
          fail(undeclared, sources, "REF_SRC_IS_NOT_DECLARED")
      
          unbound = copy.deepcopy(records)
          del unbound[0]["source_refs"][0]["src"]
          fail(unbound, sources, "REF_HAS_NO_UPSTREAM_BINDING")
      
          # Projects released before the sources declaration write the snapshot inline on
          # every reference; both forms resolve to the same upstream binding.
          inline = copy.deepcopy(records)
          binding = inline[0]["asset_binding"]
          binding["identity_ref"] = expanded(binding["identity_ref"], sources)
          binding["variant_ref"] = expanded(binding["variant_ref"], sources)
          inline[0]["source_refs"] = [expanded(ref, sources) for ref in inline[0]["source_refs"]]
          for slot in inline[0]["reference_bindings"]:
              slot["artifact_ref"] = expanded(slot["artifact_ref"], sources)
          require(validate_records(inline, {})["specs"] == 1, "inline snapshots resolve without sources")
      
          print("10 self-tests passed")
          return 0
      
      
      if __name__ == "__main__":
          raise SystemExit(main())
      
  • SKILL.md 4.4 KB
    ---
    name: short-drama-image-prompts
    description: 为短剧人物、造型、地点、道具和状态编写或修改可直接复制的图片提示词 Markdown。用户提到角色设定图、三视图、参考图、场景板、道具图、风格帧、Look Development、状态变体或局部编辑提示词时使用;不生成图片,也不调用供应商。
    license: MIT
    ---
    
    # 短剧资产图片提示词
    
    把视觉事实写成可复用、可修改、可直接复制的角色板、场景板、道具板或状态图提示词,统一保存到
    `剧集/<EP>/图片提示词.md`。每项用 `IMG-...` 标题,正文放在 `### 可复制提示词` 引用块。
    `IMG-...` 只是该提示词条目的稳定 ID,不声明图片已生成或可用;实际图片只能来自创作者已提供的输入,或经确认后的生产结果。
    
    ## Quick Start
    
    ```text
    用 $short-drama-image-prompts 为 EP001 已确定的人物、地点和道具写可直接复制的图片提示词
    ```
    
    ## 入口
    
    有当前视觉设定即可直接开始;剧本只在提示词需要确认剧情状态时读取。Look Development 是可选分支。
    先确认用途:身份板、造型/状态变体、地点板、道具板、组合 production sheet 或比较风格帧。
    分镜需要生产尾帧时,可把已接受的「收尾关键帧提示词」落实为独立 `IMG-...` 状态图条目:
    说明来源 SHOT 与终点,沿用视觉事实和参考范围,不重新设计动作。实际生成以该 IMG 条目为来源。
    
    创作者可读说明跟随项目语言;可复制正文跟随 `short-drama.json#/format/prompt_language`。没有
    `short-drama.json` 时正文默认
    使用 `en`,并在同一任务中保持一致;不能从创作者说明语言推断提示词语言。
    
    ## 工作流
    
    1. 锁定这一张图要固定的身份、状态、空间或比较变量。
    2. 只读所需资产事实、视觉方向、负面约束和已提供参考图。
    3. 按“主体与身份锚点 → 当前变体 → 构图/视角 → 光色/材质 → 背景边界 → 禁止项”写正文。
    4. 每张参考只控制身份、造型、地理、构图或风格中的明确部分,并在 `REF-...` 槽位里写出封闭词表中的 `用途`。
    5. 检查身份与变体、文字政策、视角和光线是否冲突。
    6. 用户要全部资产就完成全部,资产组只是内部批次。
    
    ## 提示词要求
    
    - 开头先写对象和用途,不用风格词淹没身份。
    - 只包含当前图能同时满足的要求;多视图/状态对照写清版面关系。
    - 保留稳定识别锚点,变体只改允许变化的部分。
    - 被《视觉设定.md》连续性锁点名的条目,锁面原样出现在可复制正文里,让这张参考图本身就把跨镜事实定住。
    - 避免无验证作用的质量词堆砌。
    - 可见文字、logo、水印、界面和字幕明确允许或禁止。
    - 正文可直接复制,不含占位符、流程说明、文件路径或 QA 结论。
    
    ## 按需知识
    
    默认只读本 SKILL 和当前视觉设定。遇到对应问题时只打开一份:
    
    - 阶段边界与规则分级:[阶段契约](references/stage-contract.md)
    - 普通单图的最小配方:[通用配方](references/common-recipe.md)
    - 人物身份板与造型一致性:[人物与造型](references/character-and-look.md)
    - 地点地理、视角和光线:[地点板](references/location-plate.md)
    - 功能道具、尺度、材质与文字:[道具板](references/prop-plate.md)
    - 造型和状态变体:[造型与状态变体](references/look-and-state-variant.md)
    - 多对象组合板:[Production Sheet 配方](references/production-sheet-recipes.md)
    - 比较视觉方向的代表帧:[Lookdev 风格帧](references/lookdev-frame.md)
    - 局部修改和 preserve set:[定点修改](references/edit-and-revision.md)
    - 完成前的可生成性检查:[审查与示例](references/review-and-fixtures.md)
    
    ## 完成与投产
    
    每个点名对象都有明确用途、可复制正文、参考边界和禁止项,且相互不矛盾,即完成。本次请求同时
    修改图片提示词与分镜时,当轮刷新受影响镜头的「图片提示词项」,不另建对账产物。实际生成必须
    转 `$short-drama-produce`,展示精确任务并取得显式确认;本技能不调用外部服务。
    五份创作文档齐备后,可转 `$short-drama` 对跨文档结构做一次机械核对;内容质量仍由创作者审查。
    
    ## 安装维护
    
    只有安装、升级或排障时运行 `python3 scripts/selftest.py`。
    

Comments (0)

Sign in to join the conversation.

No comments yet.

Reviews (0)

No reviews yet.

Related