# 创作官行为规范 (Writer Guidelines)

> 本规范为创作官的硬性执行标准，所有创作产出必须遵守。违反即视为不合格脚本。

---

## 一、镜头规范

### 1.1 每个镜头必须有 image_prompt

**这是最硬的底线。** 没有image_prompt的镜头 = 无法生成画面 = 废镜头。

image_prompt必须包含：
- **人物外观**：面部特征、发型、服装（引用角色档案中的appearance和outfit_style）
- **动作姿态**：具体到身体部位的位置和动作
- **表情**：情绪的外在表现
- **环境细节**：场景中的关键物体、空间关系
- **光影氛围**：光源方向、色温、明暗对比
- **构图**：景别、镜头角度、主体位置

```
✅ 好的image_prompt：
"A young Chinese woman with round face and shoulder-length black hair, wearing a beige knit sweater, standing at a coffee shop entrance at dusk, looking down at phone with slight frown, warm yellow interior light through glass window, cinematic composition, soft bokeh background, 85mm lens, film grain"

❌ 坏的image_prompt：
"一个女人站在咖啡店门口"  （太笼统，无法生成）
```

### 1.2 video_prompt与image_prompt的区别

| 字段 | 用途 | 侧重点 |
|------|------|--------|
| image_prompt | 生成参考图/关键帧 | 静态画面细节、构图、光影 |
| video_prompt | 生成视频片段 | 动态过程、镜头运动、动作变化、氛围流动 |

video_prompt必须额外包含：
- **镜头运动描述**：zoom in, tracking, pan等
- **动作变化过程**：从A状态到B状态
- **氛围流动**：情绪如何随画面变化

### 1.3 镜头时长分配

**短视频模式（40-120s）：**
- 开场钩子镜头：2-4秒
- 内容铺垫镜头：3-8秒/个
- 高潮/反转镜头：4-10秒
- 结尾镜头：3-5秒

**短剧分镜模式：**
- 环境交代镜头：4-8秒
- 对话镜头：3-6秒/个
- 情绪特写镜头：3-5秒
- 转场/留白镜头：2-4秒

---

## 二、角色描述规范

### 2.1 角色档案必须完整

每个出场角色（包括配角）都必须有完整档案，包含以下字段：

| 字段 | 要求 | 重要性 |
|------|------|--------|
| name | 真实感姓名，避免"小明""小红" | 必须 |
| appearance | 面部特征+发型+体型+标志性特征 | 必须 |
| outfit_style | 日常穿搭偏好，具体到颜色和款式 | 必须 |
| personality | 核心性格，用具体行为描述而非抽象词 | 必须 |
| speech_style | 说话风格+口头禅+举例句式 | 必须 |
| habits | 专属小动作/小习惯 | 必须 |
| weakness | 软肋/执念/底线 | 强烈建议 |
| relationships | 与其他角色的关系 | 强烈建议 |

### 2.2 角色描述避坑

```
✅ 好的角色描述：
personality: "嘴硬心软，嘴上说不关心但会偷偷帮忙，被夸奖会不自在地转移话题"
speech_style: "说话快，喜欢用反问句，口头禅'你管我呢'，紧张时会摸耳垂"

❌ 坏的角色描述：
personality: "善良、勇敢、坚强"  （太抽象，无法指导创作）
speech_style: "说话温柔"  （太笼统，没有辨识度）
```

### 2.3 人设一致性检查

创作过程中，每写一段台词/动作，必须自问：
- 这句话符合角色的speech_style吗？
- 这个动作符合角色的habits吗？
- 这个反应符合角色的personality吗？
- 如果不符合，必须修改，不能为了剧情需要而OOC

---

## 三、场景描述规范

### 3.1 场景必须包含环境细节

每个场景的atmosphere字段必须包含：
- **光影**：光源、色温、明暗
- **温度感**：冷暖、干湿
- **声音环境**：环境音、背景声
- **气味/质感**：增加沉浸感

```
✅ 好的场景氛围：
"暖黄色灯光从店内透出，街灯刚亮，空气中有淡淡的咖啡香，地面微湿反光，秋天的凉意"

❌ 坏的场景氛围：
"温馨的咖啡店"  （太抽象，无法指导画面生成）
```

### 3.2 场景参考图提示词

每个场景必须有image_prompt，用于生成场景环境参考图。这个提示词侧重环境而非人物，需要包含：
- 地点特征和空间布局
- 时间光影
- 天气和空气感
- 关键道具/装饰
- 整体氛围调性

---

## 四、台词规范

### 4.1 口语化是底线

```
✅ 口语化台词：
"你……你到底想怎样嘛。我真的累了。"
"行吧行吧，你说了算。"
"不是，你听我说完啊——"

❌ 书面化台词：
"时光荏苒，我们终将面对命运的审判。"
"你的话语如同利刃，刺穿了我的心房。"
"让我们携手共进，共创美好未来。"
```

### 4.2 台词要有情绪

- 用省略号表示犹豫/停顿：「你……你确定？」
- 用破折号表示打断：「我不是那个意思——」
- 用语气词增加真实感：「嗯」「啊」「嘛」「呢」「吧」
- 允许不完整的句子，人说话本来就不完整

### 4.3 台词要符合人设

- 每个角色的台词必须有辨识度
- 同一场景中，不同角色的说话方式要有差异
- 角色的口头禅和习惯用语要贯穿始终
- 紧张/开心/愤怒时，台词风格可以微调但不能OOC

### 4.4 字幕短句化（短视频模式）

- 每行字幕不超过15字
- 提炼核心信息，去掉语气词
- 字幕≠台词原文，可以精简

```
台词：「你……你到底想怎样嘛。我真的累了。」
字幕：「我真的累了」
```

---

## 五、节奏规范

### 5.1 短视频节奏（40-120s）

**3秒抓眼原则：**
- 第一个镜头必须是强钩子
- 钩子类型：反常识、扎心提问、视觉冲击、悬念开场
- 前3秒决定用户是否继续看

**节奏公式：**
```
0-3s:   黄金开场（强钩子）
3-30s:  内容铺垫（痛点/冲突/细节）
30-75s: 观点升华/情节推进（共情+输出）
75-90s: 结尾互动（留提问/留共鸣/引导评论）
```

**信息密度：**
- 短视频每3-5秒必须有一个信息点或情绪点
- 不允许超过5秒的纯环境镜头
- 节奏紧凑但不赶，有呼吸感

### 5.2 短剧分镜节奏

**慢铺垫原则：**
- 开场不急于抛冲突，先建立氛围和人物
- 情绪递进要自然，不跳步
- 允许沉默和留白，这是节奏的一部分

**节奏公式：**
```
开场（10-15%）: 缓慢入戏，建立氛围
中段（50-60%）: 核心内容，情绪拉扯
高潮（15-20%）: 情绪到位，完成反转/升华
收尾（10-15%）: 闭环+留钩子
```

**关键节奏点：**
- 场景切换时节奏可以变化
- 对话场景节奏稍快，独白/环境镜头节奏放慢
- 高潮前要有蓄力（节奏放慢），高潮时节奏加快

---

## 六、避坑清单

### 6.1 绝对禁止（违反即不合格）

| 编号 | 禁止项 | 原因 |
|------|--------|------|
| B1 | 排比句/对仗句 | AI套路，观众一眼假 |
| B2 | 空洞鸡汤 | 无信息量，浪费时间 |
| B3 | 角色OOC | 破坏人设一致性 |
| B4 | 无image_prompt的镜头 | 无法生成画面 |
| B5 | 书面化台词 | 不真实，出戏 |
| B6 | 强行反转 | 为反转而反转，逻辑不通 |
| B7 | 狗血剧情 | 降智，观众反感 |
| B8 | 千人一面的台词 | 没有角色辨识度 |

### 6.2 强烈建议避免

| 编号 | 避免项 | 原因 |
|------|--------|------|
| W1 | 每集结构一模一样 | 观众审美疲劳 |
| W2 | 人设反复横跳 | 前后矛盾，不可信 |
| W3 | 剧情断层 | 伏笔不回收，烂尾 |
| W4 | 场景只有地点没有氛围 | 无法指导画面生成 |
| W5 | 镜头只有动作没有情绪 | 缺乏感染力 |
| W6 | 所有角色说话方式一样 | 没有辨识度 |
| W7 | 过度使用旁白 | 懒惰叙事，应该用画面讲故事 |
| W8 | 结尾不闭环也不留钩子 | 既不完整也不吸引追看 |

### 6.3 常见AI套路识别

以下表达出现时，必须替换为更真实的写法：

| AI套路 | 替换为 |
|--------|--------|
| "时光荏苒" | 具体的时间细节："窗外的梧桐叶黄了又落" |
| "内心五味杂陈" | 具体的情绪动作："她攥紧了手里的纸条，指节发白" |
| "不禁感慨万千" | 具体的感慨内容："原来都十年了啊……" |
| "命运的齿轮开始转动" | 删掉，用具体事件推动 |
| "眼中闪过一丝XX" | 具体的表情变化："她愣了一下，嘴角往下撇了撇" |
| "仿佛整个世界都安静了" | 具体的安静描写："周围的声音好像突然远了，只剩自己的心跳" |

---

## 七、质量检查流程

创作完成后，必须按以下顺序逐项检查：

### 第一轮：结构检查
1. [ ] JSON格式是否合法？
2. [ ] 所有必填字段是否完整？
3. [ ] 每个场景是否有image_prompt？
4. [ ] 每个镜头是否有image_prompt和video_prompt？
5. [ ] 角色档案是否完整（6个必填字段）？

### 第二轮：内容检查
6. [ ] 台词是否口语化？有无书面化表达？
7. [ ] 角色言行是否与人设一致？
8. [ ] 场景描述是否包含环境细节和光影氛围？
9. [ ] 镜头描述是否具体到可生成程度？
10. [ ] 是否有排比句/空洞鸡汤？（有则删除重写）

### 第三轮：节奏检查
11. [ ] 短视频：前3秒是否有强钩子？
12. [ ] 短视频：信息密度是否足够（每3-5秒一个点）？
13. [ ] 短剧：节奏是否有呼吸感（不赶不拖）？
14. [ ] 结尾是否有闭环或钩子？
15. [ ] 总时长是否在目标范围内？

### 第四轮：AI套路检查
16. [ ] 逐句扫描，是否有AI套路表达？（参照第六节对照表）
17. [ ] 不同角色的台词是否有辨识度？
18. [ ] 是否有万能模板化的痕迹？

---

## 八、续更衔接规范（短剧模式）

### 8.1 续更前置要求

每次生成新集内容时，必须：
1. 回顾前文所有角色人设，确保不OOC
2. 承接上一集结尾剧情，自然衔接
3. 保持前文的情绪基调和叙事节奏
4. 新增细节铺垫，不跳步
5. 结尾预留适度悬念

### 8.2 续更禁止事项

- ❌ 无视前文伏笔，另起炉灶
- ❌ 角色性格突变（除非有剧情原因并铺垫）
- ❌ 前后矛盾（时间线、人物关系、事件细节）
- ❌ 丢失前文建立的氛围感

status exitCode durationMs aggregated cwd


找到了完整的创作官行为规范。现在同时处理问题2、3、4：

exec

# 问题2: 第二步审核失败 - 检查can_execute_step中的审核逻辑
grep -n "can_execute_step\|def.*execute_step\|execute_review\|step.*review" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/user_driven_task_system.py | head -15


300:        steps = ["collect", "write", "produce", "review"]
320:    def can_execute_step(self, task_id: str, step: str) -> bool:
374:        if not self.can_execute_step(task_id, "collect"):
925:        if not self.can_execute_step(task_id, "write"):
1235:        if not self.can_execute_step(task_id, "produce"):
1456:        task_data["current_step"] = "review"
1469:            "next_step": "review",
1475:    def execute_review(self, task_id: str, user_feedback: Optional[Dict] = None) -> Dict[str, Any]:
1481:        if not self.can_execute_step(task_id, "review"):
1485:        task_data["current_step"] = "review"
1500:            "action": "execute_review",
2052:                # 先将状态切回PRODUCED，让can_execute_step允许review
2054:                task_data["current_step"] = "review"
2056:                review_resp = self.execute_review(task_id, None)
2336:        elif step == "review" or step == "publisher":


def can_execute_step(self, task_id: str, step: str) -> bool:
        """检查是否可以执行指定步骤"""
        task_data = self._load_task(task_id)
        if not task_data:
            return False

        status = task_data.get("status", "")

        step_status_map = {
            "collect": [self.STATUS["CREATED"], self.STATUS["WAITING_COLLECT"]],
            "write": [self.STATUS["COLLECTED"], self.STATUS["WAITING_WRITE"]],
            "produce": [self.STATUS["WRITTEN"], self.STATUS["WAITING_PRODUCE"]],
            "review": [self.STATUS["PRODUCED"], self.STATUS["WAITING_REVIEW"]]
        }

        # 允许从已完成/已审核状态重新执行任何步骤（用户主动回退）
        reentry_statuses = [self.STATUS["REVIEWED"], self.STATUS["COMPLETED"]]
        if status in reentry_statuses:
            return True

        # 允许从当前步骤之后的状态重新执行任何步骤（如从written状态重新执行write）
        # 步骤顺序: collect < collected < written < produced < reviewed
        step_order = {
            self.STATUS["CREATED"]: 0,
            self.STATUS["COLLECTING"]: 1,
            self.STATUS["COLLECTED"]: 2,
            self.STATUS["WRITING"]: 3,
            self.STATUS["WRITTEN"]: 4,
            self.STATUS["PRODUCING"]: 5,
            self.STATUS["PRODUCED"]: 6,
            self.STATUS["REVIEWING"]: 7,
            self.STATUS["REVIEWED"]: 8,
            self.STATUS["COMPLETED"]: 9,
        }
        target_step_order = {
            "collect": 1,
            "write": 3,
            "produce": 5,
            "review": 7,
        }
        current_order = step_order.get(status, 0)
        target_order = target_step_order.get(step, 0)
        # 如果当前状态已经到达或超过了目标步骤，允许重新执行
        if current_order >= target_order and current_order < 8:  # 不包括reviewed/completed（已上面处理）
            return True

        return status in step_status_map.get(step, [])

    def execute_collect(self, task_id: str, user_input: Optional[Dict] = None) -> Dict[str, Any]:
        """执行采集步骤 - 支持修改意见重新生成,优先查询已入库素材"""
        task_data = self._load_task(task_id)


# 问题2根因: review步骤要求status是PRODUCED或WAITING_REVIEW
# 但当前任务task_20260517_160247_d51ea1d7的status是written（还没执行produce）
# 而前端"审核"按钮调用的是 POST /steps/review
#
# 用户要的是"提前审核"创作结果（不经过produce步骤）
# 但can_execute_step只允许在PRODUCED状态执行review
#
# 修复：允许在WRITTEN状态也执行审核（提前审核创作内容）

# 问题3: 角色图未生成
# 检查任务数据
python3 -c "
import json
with open('/root/data/disk/projects/tasks/task_20260517_160247_d51ea1d7/task.json') as f:
    d = json.load(f)
script = d.get('results',{}).get('script',{})
chars = script.get('characters',[])
print(f'characters: {len(chars)}')
for c in chars:
    print(f'  {c.get(\"name\",\"?\")}: image_path={c.get(\"image_path\",\"无\")}')
print(f'status: {d.get(\"status\")}')
print(f'current_step: {d.get(\"current_step\")}')
images = d.get('results',{}).get('script',{}).get('image_assets',{})
print(f'image_assets: {images}')
"


characters: 4
  星野莉亚: image_path=/root/data/disk/projects/tasks/task_20260517_160247_d51ea1d7/images/image_1779006856_0.jpeg
  佐藤阳太: image_path=/root/data/disk/projects/tasks/task_20260517_160247_d51ea1d7/images/image_1779006587_0.jpeg
  便利店店长大叔: image_path=/root/data/disk/projects/tasks/task_20260517_160247_d51ea1d7/images/image_1779006587_0.jpeg
  橘色小猫: image_path=/root/data/disk/projects/tasks/task_20260517_160247_d51ea1d7/images/image_1779006595_0.jpeg
status: written
current_step: produce
image_assets: {'character_images': 4, 'scene_images': 5, 'shot_ref_images': 6}


角色图实际上是生成了的（4个），但可能是前端没显示。问题3可能是用户看到的数据是修复JSON之前的状态。

现在修复问题2——允许在WRITTEN状态提前审核：

edit

"review": [self.STATUS["PRODUCED"], self.STATUS["WAITING_REVIEW"], self.STATUS["WRITTEN"]]


Successfully replaced 1 block(s) in /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/user_driven_task_system.py.

      ...
  328         step_status_map = {
  329             "collect": [self.STATUS["CREATED"], self.STATUS["WAITING_COLLECT"]],
  330             "write": [self.STATUS["COLLECTED"], self.STATUS["WAITING_WRITE"]],
  331             "produce": [self.STATUS["WRITTEN"], self.STATUS["WAITING_PRODUCE"]],
- 332             "review": [self.STATUS["PRODUCED"], self.STATUS["WAITING_REVIEW"]]
+ 332             "review": [self.STATUS["PRODUCED"], self.STATUS["WAITING_REVIEW"], self.STATUS["WRITTEN"]]
  333         }
  334
  335         # 允许从已完成/已审核状态重新执行任何步骤（用户主动回退）
  336         reentry_statuses = [self.STATUS["REVIEWED"], self.STATUS["COMPLETED"]]
      ...


现在处理问题4——全面排查所有按钮是否有对应方法：

exec

# 列出HTML中所有有id的按钮
grep -o 'id="btn[A-Za-z]*"' /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator_final.html | sort -u


id="btnConfirmDraft"
id="btnCreateTask"
id="btnExecuteCollect"
id="btnExecuteProduce"
id="btnExecuteReview"
id="btnExecuteWrite"
id="btnModifyCollect"
id="btnModifyWrite"
id="btnRefreshTasks"
id="btnRegenerateCollect"
id="btnRegenerateProduce"
id="btnRegenerateReview"
id="btnRegenerateWrite"
id="btnReviewWrite"
id="btnSaveConfig"
id="btnStitchVideos"


# 列出JS中所有按钮的事件监听器
grep -o "getElementById('btn[A-Za-z]*')" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator.js | sort -u


getElementById('btnCancelCollectModification')
getElementById('btnCancelModification')
getElementById('btnConfirmDraft')
getElementById('btnCreateTask')
getElementById('btnExecuteCollect')
getElementById('btnExecuteImprove')
getElementById('btnExecuteProduce')
getElementById('btnExecuteReview')
getElementById('btnExecuteWrite')
getElementById('btnModifyCollect')
getElementById('btnModifyWrite')
getElementById('btnRefreshTasks')
getElementById('btnRegenerateCollect')
getElementById('btnRegenerateProduce')
getElementById('btnRegenerateReview')
getElementById('btnRegenerateWrite')
getElementById('btnReviewWrite')
getElementById('btnSaveConfig')
getElementById('btnSaveModification')
getElementById('btnStitchVideos')
getElementById('btnSubmitCollectModification')
getElementById('btnViewCollect')
getElementById('btnViewProduce')
getElementById('btnViewReview')
getElementById('btnViewWrite')


# 对比: HTML中的按钮 vs JS中的监听
echo "=== HTML有但JS无监听 ==="
comm -23 <(grep -o 'id="btn[A-Za-z]*"' /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator_final.html | sed 's/id="//;s/"//' | sort -u) <(grep -o "getElementById('btn[A-Za-z]*')" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator.js | sed "s/getElementById('//;s/')//" | sort -u)

echo ""
echo "=== JS有但HTML无按钮 ==="
comm -13 <(grep -o 'id="btn[A-Za-z]*"' /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator_final.html | sed 's/id="//;s/"//' | sort -u) <(grep -o "getElementById('btn[A-Za-z]*')" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator.js | sed "s/getElementById('//;s/')//" | sort -u)


=== HTML有但JS无监听 ===

=== JS有但HTML无按钮 ===
btnCancelCollectModification
btnCancelModification
btnExecuteImprove
btnSaveModification
btnSubmitCollectModification
btnViewCollect
btnViewProduce
btnViewReview
btnViewWrite


# JS有但HTML无的按钮:
# btnCancelCollectModification / btnSubmitCollectModification - 采集修改的弹窗按钮
# btnCancelModification / btnSaveModification - 修改弹窗按钮
# btnExecuteImprove - 审核后的improve按钮（在审核结果中动态渲染）
# btnViewCollect/btnViewProduce/btnViewReview/btnViewWrite - 查看结果按钮

# 检查HTML中是否有View按钮
grep "btnView" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator_final.html


(Command exited with code 1)


# btnView* 按钮完全不在HTML中！JS中有监听但HTML没有按钮
# 同样检查btnModify*和btnRegenerate*是否在HTML中
grep "btnView\|btnModify\|btnRegenerate" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator_final.html


<button class="btn btn-outline-warning" id="btnModifyCollect" disabled>修改要求</button>
                        <button class="btn btn-outline-warning" id="btnRegenerateCollect" disabled>重新生成</button>
                        <button class="btn btn-outline-info" id="btnModifyWrite" disabled>修改</button>
                        <button class="btn btn-outline-info" id="btnRegenerateWrite" disabled style="display:none">重新生成</button>
                        <button class="btn btn-outline-primary" id="btnRegenerateProduce" disabled>重新生成</button>
                        <button class="btn btn-outline-success" id="btnRegenerateReview" disabled>重新审核</button>


# btnViewCollect/Write/Produce/Review 不在HTML中！
# 但JS中有事件监听。这些按钮需要添加到HTML中

# 同时检查JS中的btnView*事件处理
grep "btnViewCollect\|btnViewWrite\|btnViewProduce\|btnViewReview" /root/.openclaw/workspace/versions/user_driven_final_v3.0.1/manhua_studio_web_8000/static/user_driven_coordinator.js