{"id":"74e70a18-feac-48df-9480-3b50ed046101","entityType":"agent","slug":"clawhub-jinxuchen2020-ai-video-auto-generator","name":"AI video auto generator","canonicalUrl":"https://www.xpersona.co/agent/clawhub-jinxuchen2020-ai-video-auto-generator","canonicalPath":"/agent/clawhub-jinxuchen2020-ai-video-auto-generator","generatedAt":"2026-10-11T21:00:21.414Z","source":"CLAWHUB","claimStatus":"UNCLAIMED","verificationTier":"NONE","summary":{"evidence":{"source":"editorial-content","verified":true,"confidence":"high","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":null},"description":"AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Skill: AI video auto generator Owner: jinxuchen2020 Summary: AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Tags: latest:2.7.1 Version history: v2.7.1 | 2026-07-16T07:52:11.271Z | user ai-video-auto-generator 2.7.1 - Added new documentation and audit files for code and docs review, including detailed memory logs und","descriptionLabel":"Technical summary","evidenceSummary":"Capability contract not published. No trust telemetry is available yet. 1K downloads reported by the source. Last updated 10/11/2026.","installCommand":"clawhub skill install s17dj5rezr54vyehjjtkx8avvn8a518w:ai-video-auto-generator","sourceUrl":"https://clawhub.ai/jinxuchen2020/ai-video-auto-generator","homepage":"https://clawhub.ai/jinxuchen2020/skills/ai-video-auto-generator","primaryLinks":[{"label":"View on ClawHub","url":"https://clawhub.ai/jinxuchen2020/ai-video-auto-generator","kind":"source"},{"label":"Homepage","url":"https://clawhub.ai/jinxuchen2020/skills/ai-video-auto-generator","kind":"homepage"}],"safetyScore":84,"overallRank":62,"popularityScore":60,"trustScore":null,"claimedByName":null,"isOwner":false,"seoDescription":"AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Skill: AI "},"coverage":{"evidence":{"source":"public-profile","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":null},"protocols":[{"protocol":"OPENCLEW","label":"OpenClaw","status":"self-declared","notes":"Declared in the public agent profile."}],"capabilities":[],"verifiedCount":0,"selfDeclaredCount":1,"capabilityMatrix":{"rows":[{"key":"OPENCLEW","type":"protocol","support":"unknown","confidenceSource":"profile","notes":"Listed on profile"}],"flattenedTokens":"protocol:OPENCLEW|unknown|profile"}},"adoption":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":null},"stars":null,"forks":null,"downloads":1013,"likes":null,"task":null,"library":null,"packageName":null,"latestVersion":"2.7.1","tractionLabel":"1K downloads"},"release":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"medium","updatedAt":"2026-10-11T18:02:45.310Z","emptyReason":null},"lastUpdatedAt":"2026-10-11T18:02:45.380Z","lastCrawledAt":"2026-10-11T18:02:45.310Z","lastIndexedAt":null,"nextCrawlAt":"2026-10-12T18:02:45.310Z","lastVerifiedAt":null,"highlights":[{"version":"2.7.1","createdAt":"2026-07-16T07:52:11.271Z","changelog":"ai-video-auto-generator 2.7.1 - Added new documentation and audit files for code and docs review, including detailed memory logs under .workbuddy/memory/. - Removed the previous skill-card.md file. - No changes to user-facing features or core skill workflow.","fileCount":84,"zipByteSize":377541},{"version":"2.7.0","createdAt":"2026-07-16T07:06:41.676Z","changelog":"- Major internal refactor: moves all pipeline and optimizer modules under `skills/project-generate/scripts/`, restructures project commands. - Adds new modular scripts for project extraction, status reporting, VLM QA, and optimizer rules. - Introduces detailed memory and audit files for traceability and quality review. - CLI usage and demo instructions changed: pipeline entrypoint is now under `skills/project-generate/scripts/pipeline.py`. - Removes deprecated flat script files in favor of structured, modular codebase.","fileCount":81,"zipByteSize":356147},{"version":"1.0.2","createdAt":"2026-07-10T01:03:28.667Z","changelog":"Script-layer auto-fixes: Character field: auto-match from description, inherit/merge across scene groups Fuzzy count words removed: \"三人\" → actual character names Clause punctuation: auto-insert commas at Chinese clause boundaries Shot continuity: action transitions, perspective jumps, spatial consistency Scene group transitions: auto-add transition descriptions between groups Hook detection: front 3 shots without hook elements get \"突然\" inserted (deduplicated) Emotional arc: auto-add transition text for abrupt mood changes Total duration: proportional scaling to match script.duration_seconds Video Prompt Accuracy 5 new content-level checks ensure video prompts accurately reflect the intended shot: Character coverage (all named characters present in prompt) Action coverage (all motion verbs from description in [动画内容]) Scene consistency (scene keywords match between description and [场景描述]) Dialogue presence (shot dialogue reflected in prompt) Fuzzy name detection (\"三人\"/\"两人\" flagged and auto-replaced) fix_prompts now actually works — previously it only scanned script.json, missing prompt file issues entirely. Pipeline Restructuring Pipeline compressed from 10 to 9 stages (redundant narrative repair merged into optimize) sync and hf-stitch CLI commands removed generate-troops / gt CLI added for troop card assets Prompt files reorganized: video prompts → prompts/videos/, first frame prompts → prompts/storyboard/ Other Highlights GitHub upload: skip PUT for existing files, drop compression (50% fewer API calls) .url sidecar files: provider URLs saved alongside images, verified with HEAD before falling back to GitHub Duration deviation threshold tightened from 15% to 10% Import collision between agnes-ai and project-generate config modules resolved --fix-prompts enabled by default in optimize","fileCount":74,"zipByteSize":339195},{"version":"1.0.1","createdAt":"2026-07-08T08:45:14.996Z","changelog":"- No code or content changes detected in this version. - Version bump only; functionality remains the same. - No impact on users or usage.","fileCount":73,"zipByteSize":310332},{"version":"1.0.0","createdAt":"2026-07-08T08:18:43.717Z","changelog":"**Major update: Fully automated AI video generation with agent-driven script creation and robust workflow enhancements.** - Script generation is now handled entirely by the AI Agent within the chat; manual prompt-based commands are deprecated. - Introduces a fully automated multi-stage pipeline (from requirements to final video) with checkpoint resume and quality verification at each stage. - Adds self-healing mechanisms for fault tolerance, with auto-classification and strategic retries. - Enhanced CLI with new modes: demo (preview without API key), validate, poll-only, and setup for rapid environment configuration. - Expanded documentation and quick start guides, including English instructions. - Broader platform compatibility (WorkBuddy, QClaw, ima, Claude Code, Cursor).","fileCount":73,"zipByteSize":310994}]},"execution":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No published capability contract is available yet."},"installCommand":"clawhub skill install s17dj5rezr54vyehjjtkx8avvn8a518w:ai-video-auto-generator","setupComplexity":"low","setupSteps":["Setup complexity is LOW. This package is likely designed for quick installation with minimal external side-effects.","Final validation: Expose the agent to a mock request payload inside a sandbox and trace the network egress before allowing access to real customer data."],"contract":{"contractStatus":"missing","authModes":[],"requires":[],"forbidden":[],"supportsMcp":false,"supportsA2a":false,"supportsStreaming":false,"inputSchemaRef":null,"outputSchemaRef":null,"dataRegion":null,"contractUpdatedAt":null,"sourceUpdatedAt":null,"freshnessSeconds":null},"invocationGuide":{"preferredApi":{"snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/trust"},"curlExamples":["curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/snapshot\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/contract\"","curl -s \"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/trust\""],"jsonRequestTemplate":{"query":"summarize this repo","constraints":{"maxLatencyMs":2000,"protocolPreference":["OPENCLEW"]}},"jsonResponseTemplate":{"ok":true,"result":{"summary":"...","confidence":0.9},"meta":{"source":"CLAWHUB","generatedAt":"2026-10-11T21:00:21.408Z"}},"retryPolicy":{"maxAttempts":3,"backoffMs":[500,1500,3500],"retryableConditions":["HTTP_429","HTTP_503","NETWORK_TIMEOUT"]}},"endpoints":{"dossierUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/dossier","snapshotUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/snapshot","contractUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/contract","trustUrl":"https://www.xpersona.co/api/v1/agents/clawhub-jinxuchen2020-ai-video-auto-generator/trust"}},"reliability":{"evidence":{"source":"runtime-metrics","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No trust, reliability, or runtime telemetry is available."},"trust":{"status":"unavailable","handshakeStatus":"UNKNOWN","verificationFreshnessHours":null,"reputationScore":null,"p95LatencyMs":null,"successRate30d":null,"fallbackRate":null,"attempts30d":null,"trustUpdatedAt":null,"trustConfidence":"unknown","sourceUpdatedAt":null,"freshnessSeconds":null},"decisionGuardrails":{"doNotUseIf":["Contract metadata is missing or unavailable for deterministic execution."],"safeUseWhen":[],"riskFlags":["missing_or_unavailable_contract","trust_data_unavailable","schema_references_missing"],"operationalConfidence":"low"},"executionMetrics":{"observedLatencyMsP50":null,"observedLatencyMsP95":null,"estimatedCostUsd":null,"uptime30d":null,"rateLimitRpm":null,"rateLimitBurst":null,"lastVerifiedAt":null,"verificationSource":null},"runtimeMetrics":{"successRate":null,"avgLatencyMs":null,"avgCostUsd":null,"hallucinationRate":null,"retryRate":null,"disputeRate":null,"p50Latency":null,"p95Latency":null,"lastUpdated":null}},"benchmarks":{"evidence":{"source":"no-benchmark-data","verified":false,"confidence":"low","updatedAt":null,"emptyReason":"No benchmark suites or observed failure patterns are available."},"suites":[],"failurePatterns":[]},"artifacts":{"evidence":{"source":"CLAWHUB","verified":false,"confidence":"high","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":null},"readme":"Skill: AI video auto generator\n\nOwner: jinxuchen2020\n\nSummary: AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated.\n\nTags: latest:2.7.1\n\nVersion history:\n\nv2.7.1 | 2026-07-16T07:52:11.271Z | user\n\nai-video-auto-generator 2.7.1\n\n- Added new documentation and audit files for code and docs review, including detailed memory logs under .workbuddy/memory/.\n- Removed the previous skill-card.md file.\n- No changes to user-facing features or core skill workflow.\n\nv2.7.0 | 2026-07-16T07:06:41.676Z | user\n\n- Major internal refactor: moves all pipeline and optimizer modules under `skills/project-generate/scripts/`, restructures project commands.\n- Adds new modular scripts for project extraction, status reporting, VLM QA, and optimizer rules.\n- Introduces detailed memory and audit files for traceability and quality review.\n- CLI usage and demo instructions changed: pipeline entrypoint is now under `skills/project-generate/scripts/pipeline.py`.\n- Removes deprecated flat script files in favor of structured, modular codebase.\n\nv1.0.2 | 2026-07-10T01:03:28.667Z | user\n\nScript-layer auto-fixes:\n\nCharacter field: auto-match from description, inherit/merge across scene groups\nFuzzy count words removed: \"三人\" → actual character names\nClause punctuation: auto-insert commas at Chinese clause boundaries\nShot continuity: action transitions, perspective jumps, spatial consistency\nScene group transitions: auto-add transition descriptions between groups\nHook detection: front 3 shots without hook elements get \"突然\" inserted (deduplicated)\nEmotional arc: auto-add transition text for abrupt mood changes\nTotal duration: proportional scaling to match script.duration_seconds\nVideo Prompt Accuracy\n5 new content-level checks ensure video prompts accurately reflect the intended shot:\n\nCharacter coverage (all named characters present in prompt)\nAction coverage (all motion verbs from description in [动画内容])\nScene consistency (scene keywords match between description and [场景描述])\nDialogue presence (shot dialogue reflected in prompt)\nFuzzy name detection (\"三人\"/\"两人\" flagged and auto-replaced)\nfix_prompts now actually works — previously it only scanned script.json, missing prompt file issues entirely.\n\nPipeline Restructuring\nPipeline compressed from 10 to 9 stages (redundant narrative repair merged into optimize)\nsync and hf-stitch CLI commands removed\ngenerate-troops / gt CLI added for troop card assets\nPrompt files reorganized: video prompts → prompts/videos/, first frame prompts → prompts/storyboard/\nOther Highlights\nGitHub upload: skip PUT for existing files, drop compression (50% fewer API calls)\n.url sidecar files: provider URLs saved alongside images, verified with HEAD before falling back to GitHub\nDuration deviation threshold tightened from 15% to 10%\nImport collision between agnes-ai and project-generate config modules resolved\n--fix-prompts enabled by default in optimize\n\nv1.0.1 | 2026-07-08T08:45:14.996Z | user\n\n- No code or content changes detected in this version.\n- Version bump only; functionality remains the same.\n- No impact on users or usage.\n\nv1.0.0 | 2026-07-08T08:18:43.717Z | auto\n\n**Major update: Fully automated AI video generation with agent-driven script creation and robust workflow enhancements.**\n\n- Script generation is now handled entirely by the AI Agent within the chat; manual prompt-based commands are deprecated.\n- Introduces a fully automated multi-stage pipeline (from requirements to final video) with checkpoint resume and quality verification at each stage.\n- Adds self-healing mechanisms for fault tolerance, with auto-classification and strategic retries.\n- Enhanced CLI with new modes: demo (preview without API key), validate, poll-only, and setup for rapid environment configuration.\n- Expanded documentation and quick start guides, including English instructions.\n- Broader platform compatibility (WorkBuddy, QClaw, ima, Claude Code, Cursor).\n\nArchive index:\n\nArchive v2.7.1: 84 files, 377541 bytes\n\nFiles: .workbuddy/memory/2026-07-15.md (8401b), .workbuddy/memory/2026-07-16.md (32039b), .workbuddy/memory/MEMORY.md (8151b), CHANGELOG.md (15441b), config/config.toml (1285b), config/keys.example.env (1030b), pipeline-diagram.svg (6629b), README.md (5257b), references/asset-generation.md (23311b), references/e2e-walkthrough.md (5967b), references/editing-specs.md (2995b), references/pacing-narrative.md (4229b), references/prompt-rules.md (14080b), references/provider-config.md (2838b), references/repair-strategy.md (6104b), references/script-json-checklist.md (8375b), references/segment-design.md (7621b), references/setup-guide.md (5047b), references/shot-scales.md (9633b), references/templates.json (2058b), references/troubleshooting.md (7706b), references/types/default.md (2797b), references/types/文旅.md (8348b), references/types/电影级长剧.md (10432b), references/types/短剧.md (17793b), references/video-modes.md (3256b), requirements.txt (72b), sample/README.md (1122b), sample/script.json (1884b), scripts/_paths.py (9045b), scripts/_shared_tools.py (11192b), scripts/create_project.py (6567b), scripts/make_ref_board.py (5943b), scripts/stitch_face_details.py (3029b), skill-card.md (2631b), SKILL.md (14259b), skills/agnes-ai/scripts/generate_image.py (6085b), skills/agnes-ai/scripts/generate_video.py (5936b), skills/agnes-ai/scripts/modules/__init__.py (1031b), skills/agnes-ai/scripts/modules/api.py (428b), skills/agnes-ai/scripts/modules/config.py (1959b), skills/agnes-ai/scripts/modules/image_api.py (13789b), skills/agnes-ai/scripts/modules/prompt.py (18323b), skills/agnes-ai/scripts/modules/video_api.py (12860b), skills/agnes-ai/SKILL.md (22673b), skills/project-generate/scripts/modules/agnes_provider.py (21502b), skills/project-generate/scripts/modules/audio.py (13763b), skills/project-generate/scripts/modules/base_provider.py (11183b), skills/project-generate/scripts/modules/config.py (4256b), skills/project-generate/scripts/modules/data_validator.py (3640b), skills/project-generate/scripts/modules/error_utils.py (5241b), skills/project-generate/scripts/modules/extract_module.py (14484b), skills/project-generate/scripts/modules/feishu.py (20720b), skills/project-generate/scripts/modules/hyperframes_stitch.py (20499b), skills/project-generate/scripts/modules/img_host.py (5785b), skills/project-generate/scripts/modules/launch_background.py (2778b), skills/project-generate/scripts/modules/project_commands/__init__.py (33587b), skills/project-generate/scripts/modules/project_diff.py (4687b), skills/project-generate/scripts/modules/project_preview.py (9296b), skills/project-generate/scripts/modules/project_stats.py (8004b), skills/project-generate/scripts/modules/project_status.py (11636b), skills/project-generate/scripts/modules/project_verify.py (88343b), skills/project-generate/scripts/modules/provider_factory.py (6653b), skills/project-generate/scripts/modules/script_generator.py (19609b), skills/project-generate/scripts/modules/speech.py (11629b), skills/project-generate/scripts/modules/stitch_base.py (2117b), skills/project-generate/scripts/modules/stitch_ffmpeg.py (13456b), skills/project-generate/scripts/modules/stitch.py (1381b), skills/project-generate/scripts/modules/task_tracker_feishu.py (14407b), skills/project-generate/scripts/modules/task_tracker_local.py (5394b), skills/project-generate/scripts/modules/task_tracker.py (2654b), skills/project-generate/scripts/modules/type_registry.py (5338b), skills/project-generate/scripts/modules/video_utils.py (17621b), skills/project-generate/scripts/modules/vlm_qa.py (16316b), skills/project-generate/scripts/modules/xiaoyunqiao_provider.py (19364b), skills/project-generate/scripts/pipeline.py (15304b), skills/project-generate/scripts/project_generate.py (19645b), skills/project-generate/scripts/type_defs/military.json (540b), skills/project-generate/SKILL.md (15782b), skills/script-optimizer/scripts/optimize/__init__.py (159208b)\n\nFile v2.7.1:SKILL.md\n\n---\r\nname: ai-video-auto-generator\r\nversion: 2.7.0\r\ndescription: \"AI 短视频全自动流水线：从想法到成片，一键出视频。脚本生成→自动修复→资产生成→视频→音频→字幕，全自动无人值守。| AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated.\"\r\ncategory: video-generation\r\nplatforms:\r\n  - WorkBuddy\r\n  - QClaw\r\n  - ima\r\n  - Claude Code\r\n  - Cursor\r\ntags:\r\n  - video\r\n  - ai-video\r\n  - pipeline\r\n  - automation\r\n  - short-video\r\n  - tts\r\n  - subtitle\r\n  - script-generation\r\n---\r\n\r\n> 📖 **README**: `README.md` | **CHANGELOG**: `CHANGELOG.md`\r\n\r\n# ai-video-auto-generator\r\n\r\n将书面需求转换为结构化视频脚本，用于AI视频生成流水线。\r\n\r\n**目录**\r\n- <a href=\"#agent-mode\">🤖 Agent 使用模式（核心工作流）</a>\r\n- <a href=\"#quick-start\">⚡ Quick Start（4 路径出片）</a>\r\n- <a href=\"#architecture\">🏗️ 流水线架构</a>\r\n- <a href=\"#verification\">🔍 验证体系</a>\r\n- <a href=\"#self-healing\">🩹 自愈机制</a>\r\n- <a href=\"#cli\">🛠️ 流水线 CLI</a>\r\n- **参考文档**\r\n  - [端到端案例](references/e2e-walkthrough.md)\r\n  - [脚本生成检查清单](references/script-json-checklist.md)\r\n  - [Provider 配置](references/provider-config.md)\r\n  - [景别设计](references/shot-scales.md)\r\n  - [剪辑与包装](references/editing-specs.md)\r\n  - [节奏与叙事结构](references/pacing-narrative.md)\r\n  - [Prompt 工程规则](references/prompt-rules.md)\r\n  - [视频生成模式](references/video-modes.md)\r\n  - [环境搭建](references/setup-guide.md)\r\n  - [流水线排错](references/troubleshooting.md)\r\n  - [Segment 合并设计](references/segment-design.md) — 仅小云雀 Provider\r\n\r\n---\r\n\r\n<h2 id=\"quick-start\">⚡ Quick Start（4 路径出片）</h2>\r\n\r\n**🔥 尝鲜（30 秒出预览，无需 API Key）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n**💬 一句话生成视频（推荐，通过 AI Agent）：**\r\n```bash\r\n# 1. 在 WorkBuddy 中加载 ai-video-auto-generator skill\r\n# 2. 直接告诉 AI Agent 你的需求，例如：\r\n#    \"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n# 3. Agent 会自动：分析需求 → 生成 script.json → 跑流水线 → 出片\r\n```\r\n\r\n> 📌 **脚本生成已由 AI Agent 接管。** 之前的 `--mode generate` / `--prompt` 命令已废弃，保留入口但不再执行脚本生成。所有脚本生成直接在对话中完成。\r\n\r\n**📄 从文档生成视频（通过 AI Agent）：**\r\n```bash\r\n# 直接把文件/URL/飞书链接发给 AI Agent\r\n# Agent 会自动读取内容 → 生成 script.json → 跑流水线\r\n```\r\n\r\n**📦 从模板创建（手动编辑）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython scripts/create_project.py --project \"$HOME/WorkBuddy/我的视频\" --template short_drama\r\ncd \"$HOME/WorkBuddy/我的视频\" && python skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n> 详细说明见 `README.md`。\r\n\r\n---\r\n\r\n<h2 id=\"agent-mode\">🤖 Agent 使用模式（核心工作流）</h2>\r\n\r\n> **你提供需求，AI Agent（当前对话）帮你搞定一切。** 不需要手动调命令，直接说就好。\r\n\r\n### 如何与 Agent 配合\r\n\r\n| 你的输入 | Agent 自动执行 |\r\n|---------|---------------|\r\n| `\"帮我做一个军事短剧，紧张氛围\"` | ① 解析需求 → 生成 `script.json` → 写回项目目录<br>② 创建角色卡、场景卡、镜头列表<br>③ 运行 `--mode auto` 启动流水线 |\r\n| `\"从这篇文章生成视频\"` + 贴 URL | ① WebFetch 读取文章内容<br>② 分析角色/场景/情绪 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"从这份文档生成视频\"` + 上传文件 | ① Read 读取文档内容<br>② 提取关键信息 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"帮我优化这个脚本\"` + 贴 JSON | ① 读取当前 `script.json`<br>② 运行 `optimize` 命令（OptimizerV2）做 12 维叙事修复<br>③ 输出修复报告 |\r\n| `\"修一下 shot_05 的运镜问题\"` | ① 定位问题<br>② 修改 `script.json`<br>③ 通知验证结果 |\r\n\r\n### Agent 脚本生成规则（重要）\r\n\r\n当 Agent 为你生成 `script.json` 时，遵循以下标准：\r\n\r\n```\r\n📋 角色卡要求:\r\n  - 每个角色必须有 name / title / appearance（clothing/physique/face/features）\r\n  - appearance 要细化到发型、脸型、瞳色、肤色、体态、着装\r\n  - 每个角色至少 front + face 两个视图，主角加 side + back\r\n  - asset_background 固定为 \"white\"\r\n\r\n📋 场景卡要求:\r\n  - 每个场景有 name / description / views（广角/中景/特写）\r\n  - description 描述环境氛围（光线/色调/空间感/情绪）\r\n\r\n📋 镜头要求（最重要）:\r\n  - 每个镜头有 id / description / duration\r\n  - voice_over（旁白）和 dialogue（对白）根据以下规则填写：\r\n\r\n    voice_over 旁白（TTS 音频 + 字幕）:\r\n    ── 谁在说话: 非角色，解说/叙事者/内心独白\r\n    ── 适用 shot_type: 远景/广角/空镜/建立/转场/过渡\r\n    ── 视频是否自带声音: ❌ 不包含，需 TTS 生成\r\n    ── 写作要求: 用人类叙事语言，不能直接照搬 description\r\n        正确: \"硝烟弥漫的废墟战场上，周戎站在高处俯视着远方。\"\r\n        错误: \"周戎在画面远处，突然，废墟战场全景，硝烟弥漫，断壁残垣中周戎站在废墟高处俯视战场，广角远景\"\r\n    ── 生成后自检: voice_over 中不能有景别（中景/远景/特写/广角）、拍摄指令（俯拍/仰拍）、角色定位（\"在画面远处\"）\r\n    ── 标点规则: 用空格代替所有标点符号（逗号/句号/感叹号等），但需保证断句合理，方便 TTS 自然停顿\r\n        断句规则:\r\n        - 每个空格代表一次自然停顿，每段 5~10 个汉字为宜，便于 TTS 一口气读完\r\n        - 在完整语义单位后断句：场景描述后 / 动作完成后 / 人物出现后\r\n        - 禁止在修饰语和中心语之间断开（\"硝烟弥漫的\"和\"废墟战场\"之间不能断）\r\n        - 主语和谓语不断开（\"周戎站在高处\"不能断为\"周戎 站在高处\"）\r\n        - 动词和宾语不断开（\"俯瞰着整片战场\"不能断为\"俯瞰着 整片战场\"）\r\n        正确: \"硝烟弥漫的废墟战场上 断壁残垣间 周戎站在高处俯瞰着整片战场\"\r\n        错误: \"硝烟弥漫的 废墟战场上 断壁残垣间 周戎 站在 高处 俯瞰着 整片战场\"\r\n\r\n    dialogue 对白（仅字幕，视频已自带声音）:\r\n    ── 谁在说话: 屏幕上的角色在对话/独白/回应\r\n    ── 适用 shot_type: 中景/双人/过肩/反应/独白/近景\r\n    ── 视频是否自带声音: ✅ Agnes 视频已包含角色对话声\r\n\r\n    两者可共存: voice_over 放旁白，dialogue 放对白\r\n    两者都无: 纯画面镜头（动作/追逐/环境），无台词\r\n\r\n  - 每个镜头生成后必须做三选一检查：是否决定好了 voice_over / dialogue / 两者皆无\r\n  - 不允许出现: 镜头 ≥5 秒且 voice_over/dialogue 都为空，且 description 未描述动作/追逐内容\r\n\r\n  - description 包含: 景别 + 运镜 + 人物动作 + 环境 + 情绪\r\n  - ⚠️ **description 中涉及角色的地方必须使用角色卡中的全名或实词（如「君无烬（奶牛猫）」或「君无烬」），禁止使用「猫」「狗」「他」「她」「男子」「女子」「老人」等泛称代词。**\r\n  - 反例: 「猫吃得太急 不小心打了一个响亮的嗝」（「猫」是泛称，optimizer 无法匹配到具体角色）\r\n  - 正例: 「君无烬（奶牛猫）吃得太急 不小心打了一个响亮的嗝」\r\n  - 理由: optimizer 的 `_fix_shots` 靠文本匹配补全 characters 字段，泛称会绕过全部四种匹配规则（全名/实词/括号内容/逐字），导致角色缺失不被发现\r\n  - duration 3-8 秒，总时长控制在 60-120 秒\r\n  - 前 3 个镜头要有钩子（冲突/悬念/意外）\r\n  - 高潮镜头放在总时长的 70-85% 处\r\n  - 收尾镜头要有结局感\r\n\r\n📋 叙事结构:\r\n  - 开头抓人 → 展开 → 冲突升级 → 高潮 → 收尾\r\n  - 运镜要变化（不要连续 3+ 镜头同运镜）\r\n  - 情绪要有起伏（不要从欢快跳到悲伤）\r\n  - 对话和动作镜头比例合理（各不超过 70%）\r\n\r\n📋 流水线触发:\r\n  - script.json 写完后，自动执行 `pipeline.py --mode auto`\r\n  - 如果项目已有 task_tracker 且部分完成，auto 会自动从断点继续\r\n```\r\n\r\n### 快速命令\r\n\r\n```bash\r\n# Agent 一键出片（在对话中描述需求即可）\r\n# 上述步骤全部由 AI Agent 自动完成\r\n\r\n# 如果你需要手动查状态\r\ntail -f auto.log          # 查看流水线进度\r\n```\r\n\r\n---\r\n\r\n<h2 id=\"architecture\">🏗️ 流水线架构</h2>\r\n\r\n```\r\nAI Agent（你） → script.json → 9 阶段全自动流水线 → final.mp4\r\n\r\n阶段 0:   脚本优化（含 12 维叙事结构修复）\r\n阶段 1:   构建资产 prompt 文件\r\n阶段 2:   角色资产生成 + 6 维质量验证（55 分制）\r\n阶段 3:   辅助资产生成 + 质量验证\r\n阶段 4:   场景资产生成 + 人脸检测 + 风格检测\r\n阶段 5:   初始化首帧图\r\n阶段 6:   首帧图生成 + 50 分制验证\r\n阶段 7:   提交视频任务 + 验证 prompt\r\n阶段 8:   轮询完成 + 55 分制视频验证 + 拼接 + 音频 + 字幕\r\n\r\n全部阶段支持断点续跑。\r\n```\r\n\r\n<h2 id=\"verification\">🔍 验证体系</h2>\r\n\r\n| 资产 | 检查项 | 评分 |\r\n|------|--------|------|\r\n| 角色图 | 文件+模糊+人物=1+背景+全身+风格 | 55 分 |\r\n| 场景图 | Haar 人脸检测 + Canny 风格匹配 | pass/fail |\r\n| 首帧图 | 文件+比例+模糊+HOG人数+色彩 | 50 分 |\r\n| 视频 | 时长+比例+黑帧+光流运镜+情绪匹配 | 55 分 |\r\n\r\n<h2 id=\"self-healing\">🩹 自愈机制</h2>\r\n\r\n```\r\nfail → classify(5 categories) → strategy(soften/switch/backoff/regen) → capped retry(max 10)\r\n```\r\n\r\n<h2 id=\"cli\">🛠️ 流水线 CLI</h2>\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode setup       # 环境检测 + 自动装依赖 + 复制 Key 模板\r\npython skills/project-generate/scripts/pipeline.py --mode auto         # 全自动流水线（从中断继续）\r\npython skills/project-generate/scripts/pipeline.py --mode validate     # 预检（只验证不生成）\r\npython skills/project-generate/scripts/pipeline.py --mode demo         # 快速尝鲜（30 秒，无需 API Key）\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached  # 仅轮询\r\n\r\n# 项目级子命令（project_generate.py）\r\npython skills/project-generate/scripts/project_generate.py --project . status        # 结构化状态（默认 JSON，--text 人类可读）\r\npython skills/project-generate/scripts/project_generate.py --project . stitch --tracker local  # 单独跑拼接（不重新提交/轮询）\r\n```\r\n\r\n---\r\n\r\n## 参考文档\r\n\r\n- [端到端案例](references/e2e-walkthrough.md) — 从飞书文档到成片的完整流程\r\n- [脚本生成检查清单](references/script-json-checklist.md)\r\n- [Provider 配置](references/provider-config.md)\r\n- [景别设计](references/shot-scales.md)\r\n- [剪辑与包装](references/editing-specs.md)\r\n- [节奏与叙事结构](references/pacing-narrative.md)\r\n- [Prompt 工程规则](references/prompt-rules.md)\r\n- [视频生成模式](references/video-modes.md)\r\n- [环境搭建](references/setup-guide.md)\r\n- [流水线排错](references/troubleshooting.md)\r\n- [Segment 合并设计](references/segment-design.md) — 仅小云雀(xiaoyunqiao) Provider 需要\r\n\r\n---\r\n\r\n## English Quick Start\r\n\r\n> **AI video auto pipeline: from idea to final video, one command.**\r\n\r\n### How it works\r\n\r\nLoad this skill in WorkBuddy, then tell the AI agent what you want:\r\n\r\n```\r\n\"Create a short video about an ancient general waking up in a modern city\"\r\n\"Generate a video from this article\" + paste URL\r\n\"Turn this document into a video\" + upload file\r\n```\r\n\r\nThe agent will:\r\n1. Read and analyze your input\r\n2. Generate a complete `script.json` (characters, scenes, shots)\r\n3. Run `pipeline.py --mode auto` — fully automated pipeline\r\n4. Notify you when `final.mp4` is ready\r\n\r\n### Pipeline stages\r\n\r\n| Stage | Description |\r\n|-------|-------------|\r\n| 0 | Script optimization (incl. 12-dim narrative auto repair: hook/pacing/camera/emotion/closure) |\r\n| 1 | Build asset prompt files |\r\n| 2 | Character asset generation + 6-dim quality verification (55pt) |\r\n| 3 | Troop asset generation + verification |\r\n| 4 | Scene asset generation + face detection + style check |\r\n| 5 | Initialize first frames |\r\n| 6 | First frame generation + 50pt verification |\r\n| 7 | Submit video tasks + prompt verification |\r\n| 8 | Poll completion + 55pt video verification (camera motion/mood/black frames) + stitch + audio + subtitles |\r\n\r\nAll stages support resume from checkpoint (Ctrl+C / crash / shutdown).\r\n\r\n### CLI reference\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode setup       # Auto-install dependencies + copy API key template\r\npython skills/project-generate/scripts/pipeline.py --mode auto         # Full pipeline (resume from checkpoint)\r\npython skills/project-generate/scripts/pipeline.py --mode validate     # Pre-flight check (no generation)\r\npython skills/project-generate/scripts/pipeline.py --mode demo         # 30s preview, no API key needed\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached  # Poll only\r\n```\r\n\r\n### Known limitations\r\n\r\n- Requires API Key for AI generation (default: Agnes AI, free unlimited tier)\r\n- Windows prioritized (macOS/Linux not fully tested)\r\n- OpenCV ~50MB dependency (auto-installed via `--mode setup`)\r\n- No real-time progress bar (logs written to file in detach mode)\r\n\r\n### Reference docs\r\n\r\n- [Provider config](references/provider-config.md)\r\n- [Shot scales](references/shot-scales.md) (Chinese)\r\n- [Prompt rules](references/prompt-rules.md) (Chinese)\r\n- [Troubleshooting](references/troubleshooting.md) (Chinese)\n\nFile v2.7.1:skills/agnes-ai/SKILL.md\n\n---\r\nname: agnes-ai\r\nversion: 2.7.0\r\ndescription: >\r\n  纯生成层 skill。调用 Agnes AI 免费 API 生成图片和视频。\r\n  脚本路径为 `skills/agnes-ai/scripts/generate_image.py`\r\n  和 `skills/agnes-ai/scripts/generate_video.py`（相对于主 skill 根目录）。\r\n---\r\n\r\n# Agnes AI 纯生成 Skill\r\n\r\n通过 `scripts/generate_image.py` 生成图片、`scripts/generate_video.py` 生成视频。\r\n\r\n> 本 skill 是 `ai-video-auto-generator` 的子 skill。项目级编排命令在 `project-generate` 子 skill 中。\r\n\r\n---\r\n\r\n## 🚀 高频命令\r\n\r\n```bash\r\n# 文生图\r\npython3 scripts/generate_image.py \"一只猫\" --size \"1024x1024\" -o ./output\r\n\r\n# 图生图\r\npython3 scripts/generate_image.py \"描述提示词\" --ref-image /path/to/ref.png\r\n\r\n# 文生视频\r\npython3 scripts/generate_video.py \"古风战场\" --size \"9:16\" --duration 5s\r\n\r\n# 图生视频\r\npython3 scripts/generate_video.py \"缓慢推进\" --ref-image input.png --duration 5s\r\n```\r\n\r\n## 前置条件\r\n\r\n1. **注册获取 API Key**（免费无限制）：\r\n   - 访问 https://platform.agnes-ai.com 注册\r\n   - 登录后在后台创建 API Key\r\n   - 将 Key 写入 `~/.agnes-api-key`，或设环境变量 `AGNES_API_KEY`\r\n\r\n2. **Python 3** — 标准库即可，无需额外依赖。\r\n\r\n## 两个模型的分工\r\n\r\n| 模型 | 本质 | 适用场景 | 翻车点 |\r\n|-----|------|---------|-------|\r\n| **2.0 Flash**（多图合成） | 多张图融合成一张新画面 | 单角色静态、双角色无互动、特写、环境合成 | 可能脑补多余元素（凭空加人） |\r\n| **2.1 Flash**（参考图编辑） | 以第一张图为基底添加元素 | 需保留场景结构、精确动作控制、有交互 | 过于忠实原图 |\r\n\r\n### 选择规则\r\n- 单角色静态/特写 → **2.0 Flash**\r\n- 单角色精确动作（掀帘、推门） → **2.1 Flash**\r\n- 双角色无互动（背对、行礼、跪拜） → **2.0 Flash**\r\n- 双角色有互动（对视、对话、肢体接触） → **2.1 Flash**\r\n- **2.0 Flash 图生图不需要传 `tags: [\"img2img\"]`**\r\n\r\n### 实战验证\r\n| 场景 | 2.0 结果 | 2.1 结果 | 建议 |\r\n|------|---------|---------|------|\r\n| 墨雪站窗边 | ✅ 1人 | — | 2.0 |\r\n| 墨将推门 | ✅ 1人 | — | 2.0 |\r\n| 双角色同框 | ✅ 2人 | — | 2.0 |\r\n| 面部特写 | ✅ 1人 | — | 2.0 |\r\n| 掀帘子 | ❌ 变2人 | ✅ 1人 | 2.1 |\r\n| 互踢（互动） | — | ✅ | 2.1 |\r\n| 城墙眺望 | ❌ 场景错 | ✅ 正确 | 2.1 |\r\n\r\n## 图片生成 — 使用方法\r\n\r\n### 快速入门（单张图片生成）\r\n\r\n`generate_image.py` 是一个独立的单张图片生成工具，批量生成请走 `project-generate`：\r\n\r\n```bash\r\n# 单张图生图\r\npython3 scripts/generate_image.py \"提示词\" --ref-image \"参考图.png\" -o \"images/characters/\" --output-name \"角色名_front.png\"\r\n\r\n# 批量首帧图 → 请使用 project-generate\r\npython3 ../ai-video-auto-generator/skills/project-generate/scripts/project_generate.py --project . gi\r\n```\r\n\r\n### 完整参数\r\n\r\n**图片参数（`scripts/generate_image.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `prompt`（必填） | 图片描述提示词 |\r\n| `--model` | 默认 `agnes-image-2.1-flash` |\r\n| `--size` | 默认 `720x1280`，自动从 aspect_ratio 映射 |\r\n| `--n` | 数量（1-4） |\r\n| `--quality` | `standard` 或 `hd` |\r\n| `--output-dir` / `-o` | 保存目录 |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-images` | 多张参考图（空格分隔）|\r\n| `--output-name` | 输出文件名 |\r\n| `--seed` | 固定随机种子 |\r\n| `--negative-prompt` | 负面提示词 |\r\n| `--api-key` | API Key 文件路径 |\r\n| `--shot-id` | 从 script.json 的 first_frame 块解析参数，生成该 shot 的首帧图 |\r\n| `--project` | 项目根目录（--shot-id 模式需要）|\r\n| `--force` | 强制重新生成已存在的 first_frame 和模板 |\r\n| `--parallel` | 并发生成数（默认 auto）|\r\n\r\n**视频参数（`scripts/generate_video.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `--model` | 默认 `agnes-video-v2.0` |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-image-list` | 多张参考图路径 |\r\n| `--ref-image-urls` | 已上传的公网 URL |\r\n| `--num-frames` | 总帧数（8n+1，≤441），默认 121 |\r\n| `--frame-rate` | 帧率（1-60），默认 24 |\r\n| `--size` | 分辨率，默认 `1152x768` |\r\n| `--seed` | 固定种子 |\r\n| `--output-name` | 输出文件名 |\r\n| `--output-dir` / `-o` | 保存目录 |\r\n| `--api-key` | API Key 文件路径 |\r\n| `--mode` | 生成模式：standard / keyframes / multi-image / auto |\r\n| `--duration` | 目标时长（如 `5s`）|\r\n| `--poll-interval` | 轮询间隔（默认 15s）|\r\n| `--timeout` | 超时时间（默认 600s）|\r\n| `--submit-only` | 仅创建任务，打印 task_id 后退出 |\r\n| `--query-task` | 查询已有任务，若完成则下载 |\r\n\r\n### 两步工作流\r\n\r\n**第 1 步 — 初始化：**\r\n```bash\r\npython3 scripts/generate_image.py --project . --build-first-frames\r\n# 或强制重新生成\r\npython3 scripts/generate_image.py --project . --build-first-frames --force\r\n```\r\n自动完成：\r\n- 遍历所有 shot，从 `generation.reference_images` 解析参考图路径\r\n- 根据 shot 描述自动推荐模型（2.0 Flash / 2.1 Flash）\r\n- 写入 `first_frame` 块到 script.json\r\n- 对每个 shot 生成六段式提示词模板\r\n- **multi-image 模式**（如 shot_01）自动跳过\r\n- 已有 `first_frame` 的 shot 默认跳过（`--force` 覆盖）\r\n\r\n**第 2 步 — 单 shot 或批量生成：**\r\n```bash\r\n# 单 shot\r\npython3 scripts/generate_image.py --project . --shot-id 4\r\n\r\n# 批量\r\npython3 scripts/generate_image.py --project . --batch-generate\r\n\r\n# 指定范围\r\npython3 scripts/generate_image.py --project . --batch-generate --batch-shots \"2-9\"\r\n```\r\n\r\n### 基本调用\r\n\r\n```bash\r\npython3 scripts/generate_image.py \"描述提示词，保留角色特征\" \\\r\n  --ref-image \"/path/to/墨雪_front.png\" \\\r\n  --size \"1024x1024\" \\\r\n  -o \"/path/to/output\" \\\r\n  --output-name \"墨雪_表情.png\"\r\n```\r\n\r\n## 提示词结构（六段式）\r\n\r\n适用于 2.0 Flash / 2.1 Flash 图生图：\r\n\r\n```\r\n将N张参考图合成一张完整画面。\r\n\r\n[编辑指令] 参考图1为XX（场景基底）。参考图2为XX（角色A样式）。\r\n以图1为基底，在场景中加入角色A（位置/方向参考图2）。明确写\"无交互无对视\"。\r\n\r\n[保留元素] 完全保持：图2的服装颜色、发型。\r\n\r\n[目标风格/场景] 每个角色的位置、动作、服装颜色、环境布局。\r\n\r\n[光照] 光源方向、冷暖对比。\r\n\r\n[构图] 画幅、景别、空间位置（谁高位谁低位）。\r\n\r\n[画质要求] 电影级写实，关键细节，氛围情绪。\r\n```\r\n\r\n### 关键技巧\r\n- ❌ **不要用** \"在图1场景中加入墨雪\" → 模型可能把参考图里\"旁边的人\"也取过来\r\n- ✅ **要用** \"场景中墨雪一个人站在门口掀帘\"\r\n- 2.1 Flash 在[编辑指令]里写清交互动作（\"推门走进来、望向\"）\r\n- 首次抽卡用最简 prompt，每轮只改 1-2 个点\r\n- 同参数连抽 ≤3 轮，不改善换策略\r\n\r\n## 常见问题\r\n\r\n### 文化手势无法精确控制\r\n模型无法生成\"左手抱右拳\"等特定手势。手抬至胸前已是极限。\r\n\r\n### 人物数量不对\r\n- 2.0 Flash 可能脑补多余人物 → 换 2.1 Flash\r\n- 不要用\"加入/插入/放入角色\"指令式措辞\r\n- 明确写\"只有一个人\"\r\n\r\n### 参考图比例\r\n手动合成参考板时，比例必须与输出一致。\r\n\r\n## 首帧图 Prompt 组装规则（重要）\r\n\r\n`generate_image.py` 在 `_clean_prompt()` 中实现了**段提取拼接机制**，从 `prompts/storyboard/shotXX_image.md` 文件中按 [xxx] 标签提取指定段的内容，去掉标签后按指定顺序拼接成最终 API prompt。\r\n\r\n### 动态段提取\r\n通过 `segments` 参数指定需要提取的段名列表，按顺序拼接：\r\n```python\r\nprompt = _clean_prompt(f.read().strip(),\r\n    segments=[\"编辑指令\",\"目标风格/场景\",\"光照\",\"构图\",\"画质要求\"])\r\n```\r\n\r\n### 可用段列表（按顺序）\r\n| 段名 | 用途 | 是否推荐 |\r\n|------|------|---------|\r\n| `[编辑指令]` | 描述参考图用途和角色空间关系 | ✅ 必须 |\r\n| `[保留元素]` | 指定参考图中需要保持的特征 | ⚠️ 谨慎（见下方说明）|\r\n| `[目标风格/场景]` | 最终画面描述 | ✅ 必须 |\r\n| `[光照]` | 光源方向和氛围 | ✅ 推荐 |\r\n| `[构图]` | 画面布局和角色位置 | ✅ 推荐 |\r\n| `[画质要求]` | 质量关键词+负面提示 | ✅ 推荐 |\r\n\r\n### ⚠️ [保留元素] 的关键陷阱\r\n2.0 Flash 多图合成模式下，`[保留元素]` 会让模型**保持参考图的整体特征（含朝向/姿态）**，覆盖文字指令中的空间描述。\r\n\r\n例如：参考图为 `墨雪_side.png`（侧身），`[保留元素]` 写\"完全保持图2墨雪的特征\" → 模型理解\"保持图2的所有包括朝向\" → 墨雪面向镜头方向而非文字指定的\"侧身望向窗外\"。\r\n\r\n**规则**：3张参考图（场景+双角色）时**不要加 `[保留元素]`**，角色朝向全靠文字指令描述。仅单角色+场景（2张图）时可以加。\r\n\r\n### 双角色首帧图推荐方案\r\n| 要素 | 推荐设置 |\r\n|------|---------|\r\n| 模型 | **2.0 Flash**（多图合成） |\r\n| 参考图 | 场景 + 墨雪_side + 墨将_front（**3张独立**，不合成参考板）|\r\n| 提示词段 | `[编辑指令]` + `[目标风格/场景]` + `[光照]` + `[构图]` + `[画质要求]` |\r\n| 墨雪参考 | 用 `墨雪_side.png`（侧身）而非 `墨雪_front.png`（正面），减少正面朝向的\"拉力\" |\r\n| 排除段 | **不加** `[保留元素]`（会导致角色面朝镜头方向） |\r\n\r\n### ⚠️ 参考图选型：`front`（全身）优于 `face`（面部特写）\r\n首帧图参考图**优先选用全身正面图 `_front`**，而非面部特写 `_face`：\r\n\r\n| 对比维度 | `_front`（全身正面） | `_face`（面部特写） |\r\n|---------|-------------------|-------------------|\r\n| 甲胄颜色 | ✅ 保留正确的颜色和样式 | ❌ 颜色偏差（特写区域太小，模型无法定位颜色）|\r\n| 面部特征 | ✅ 模型自然继承 | ✅ 保留 |\r\n| 服装细节 | ✅ 完整保留 | ❌ 无法获取全局颜色信息 |\r\n\r\n**实战案例**：`墨将_front` → 银灰轻甲（正确）；`墨将_face` → 深褐色玄铁甲（错误，被特写图领口小面积颜色误导）。\r\n\r\n**规则**：即使是面部特写镜头，参考图也用 `_front` 全身图，面部特征模型会自动继承。\r\n\r\n### 代码实现说明\r\n`generate_image.py` 中的 `_clean_prompt(text, segments)` 函数实现段提取：\r\n- `segments=None` → 全量模式（保留所有非标签内容，向后兼容）\r\n- `segments=[...]` → 段模式：仅提取指定 [xxx] 段的内容，按列表顺序拼接\r\n- 可配置在 `script.json` 中每个 shot 的 `first_frame.segments` 字段，无配置时 fallback 到默认列表\r\n\r\n## 调用方式（务必遵守）\r\n\r\n本 skill 已作为子技能打包在主 skill 的 `skills/agnes-ai/` 目录下。\r\n\r\n**🔥 硬性规则**：调用 `generate_*.py` 必须使用子 skill 路径（相对于主 skill 根目录）。\r\n\r\n```bash\r\n# ✅ 正确：子 skill 路径（在主 skill 根目录执行）\r\npython3 skills/agnes-ai/scripts/generate_image.py \\\r\n  \"prompt\" --project . --shot-id 4\r\n\r\n# ✅ 通过项目 scripts/generate_image.py 快捷入口（推荐）\r\npython3 scripts/generate_image.py \"prompt\" --size \"1024x1536\"\r\n```\r\n\r\n> 子 skill 是修改入口，此目录已在主 skill 的 `skills/agnes-ai/` 下，无需额外同步。\r\n\r\n---\r\n\r\n## 视频生成（Agnes Video V2.0）\r\n\r\n本 skill 也封装了视频生成能力，通过 `scripts/generate_video.py` 调用：\r\n\r\n```bash\r\n# 文生视频\r\npython3 scripts/generate_video.py \"古风战场，阴天低沉光线，硝烟弥漫\" \\\r\n  --size \"768x1152\" \\    # 9:16竖版\r\n  --num-frames 121 \\     # ≈5秒@24fps\r\n  --frame-rate 24 \\\r\n  -o \"./videos\" \\\r\n  --output-name \"shot_01.mp4\"\r\n\r\n# 图生视频（以分镜首帧图为参考）\r\npython3 scripts/generate_video.py \"缓慢推进的镜头，战场上残旗飘动\" \\\r\n  --ref-image \"./images/storyboard/shot_01_first_frame.png\" \\\r\n  --size \"768x1152\" \\\r\n  -o \"./videos\" \\\r\n  --output-name \"shot_01.mp4\"\r\n```\r\n\r\n### 时长参数\r\n\r\n| 目标时长 | --duration | 实际参数 |\r\n|---------|-----------|---------|\r\n| 约 3 秒 | `--duration 3s` | `--num-frames 81 --frame-rate 24` |\r\n| 约 5 秒 | `--duration 5s` | `--num-frames 121 --frame-rate 24` |\r\n| 约 10 秒 | `--duration 10s` | `--num-frames 241 --frame-rate 24` |\r\n| 约 18 秒 | `--duration 18s` | `--num-frames 441 --frame-rate 24` |\r\n\r\n也可直接用 `--num-frames` 和 `--frame-rate` 精细控制。num_frames 合法值：8n+1，≤441。\r\n\r\n### 分辨率参数\r\n\r\n`--size` 支持宽x高格式和比例别名：\r\n\r\n- `--size 9:16` → 720x1280（竖屏短视频）\r\n- `--size 16:9` → 1280x720（横屏）\r\n- `--size 1:1`  → 1024x1024（正方形）\r\n- `--size 1920x1080` → 自定义分辨率\r\n\r\n### 生成模式（--mode）\r\n\r\n脚本支持三种生成模式，通过 `--mode` 选择：\r\n\r\n**standard（默认）**\r\n```bash\r\n# 文生视频（无参考图）\r\npython generate_video.py \"prompt\" --duration 5s --size 9:16 --submit-only\r\n\r\n# 图生视频（1 张参考图）\r\npython generate_video.py \"prompt\" --ref-image input.png --duration 5s --size 9:16\r\n```\r\n\r\n**multi-image（多图视频）**\r\n```bash\r\npython generate_video.py \"prompt\" \\\r\n  --mode multi-image \\\r\n  --ref-image-list img1.png img2.png ... \\\r\n  --duration 5s --size 9:16 --submit-only\r\n```\r\n\r\n**keyframes（关键帧动画）**\r\n```bash\r\npython generate_video.py \"prompt\" \\\r\n  --mode keyframes \\\r\n  --ref-image-list kf1.png kf2.png ... \\\r\n  --duration 5s --size 9:16 --submit-only\r\n```\r\n\r\n### 模式选择决策指南\r\n\r\n根据镜头素材和描述自动选择模式（内置在 `video_api.py` 的 `_select_mode()`）：\r\n\r\n```\r\n只有 1 张参考图 ────────→ standard（最常用）\r\n        │\r\n有 2+ 张参考图 ─┬─ 描述含 before/after/对比/转变 → multi-image\r\n                ├─ 描述含 多人/关键帧/转场/复杂场景 → keyframes\r\n                └─ 其他 → standard\r\n```\r\n\r\n### 参考图来源优先级\r\n\r\n`generate_video.py` 接受三种形式的参考图，按以下优先级处理：\r\n\r\n| 优先级 | 参数 | 来源 | 适用场景 |\r\n|--------|------|------|---------|\r\n| 1 (最高) | `--ref-image-urls` | 已上传的公网 URL | 重试/多图 cache 回放 |\r\n| 2 | `--ref-image-list` | 本地多张图片路径 | 首次提交多图/keyframes |\r\n| 3 | `--ref-image` | 本地单张图片路径 | 首次提交 standard 模式 |\r\n\r\n### 视频参数一览\r\n\r\n| 参数 | 默认 | 说明 |\r\n|------|------|------|\r\n| `--model` | `agnes-video-v2.0` | 视频模型名 |\r\n| `--ref-image` | 无 | 参考图路径（图生视频模式） |\r\n| `--num-frames` | `121` | 总帧数，必须为 8n+1（≤441） |\r\n| `--frame-rate` | `24` | 帧率，1-60 |\r\n| `--size` | `1152x768` | 分辨率 宽x高（短剧用 768x1152） |\r\n| `--seed` | 随机 | 固定种子可复现结果 |\r\n| `--output-name` | 自动生成 | 指定文件名 |\r\n\r\n## Prompt 最佳实践（视频）\r\n\r\n### 各模式 Prompt 写作模板\r\n\r\n**standard（单图生视频）** — 描述哪些动、哪些不动：\r\n```\r\n{角色/元素} + {运动描述} + {场景/光照} + {保持稳定的元素}\r\n```\r\n\r\n**multi-image（多图过渡）** — 描述图片之间的关系和过渡方式：\r\n```\r\n从第1张图到第2张图 + {过渡描述} + {什么需要保持一致}\r\n```\r\n\r\n**keyframes（关键帧插值）** — 描述关键帧之间的插值风格：\r\n```\r\n在关键帧之间 + {过渡描述} + {角色/场景一致性要求} + {镜头风格}\r\n```\r\n\r\n---\r\n\r\n## API 说明\r\n\r\n### 图片 API 的 image 字段格式\r\n实测 `image` 在 `extra_body` 内才生效（顶层不生效）：\r\n\r\n```json\r\n{\r\n  \"model\": \"agnes-image-2.0-flash\",\r\n  \"prompt\": \"...\",\r\n  \"size\": \"1024x1792\",\r\n  \"extra_body\": {\r\n    \"image\": [\"url1\", \"url2\"],\r\n    \"response_format\": \"url\"\r\n  }\r\n}\r\n```\r\n\r\n两模型区别：\r\n| 对比维度 | 2.0 Flash | 2.1 Flash |\r\n|---------|-----------|-----------|\r\n| `image` 位置 | `extra_body` 内 | `extra_body` 内 |\r\n| `tags` 参数 | 不需要 | 不需要 |\r\n\r\n### 图片 vs 视频 API\r\n| 能力 | 图片 API | 视频 API |\r\n|------|---------|---------|\r\n| `image` 字段位置 | `extra_body` 内 | `extra_body` 内 |\r\n| 多图支持 | 数组 | 数组 |\r\n\r\n### 视频 API 补充说明\r\n- 三种模式：\r\n  - `standard`：传单张 URL 到顶层 `image`，不加 `extra_body.image`\r\n  - `multi-image`（pipeline 内部模式名）：传 `extra_body.image` 数组，**不加 `mode` 参数**\r\n  - `keyframes`：传 `extra_body.image` 数组 + `extra_body.mode=keyframes`\r\n- 多图参考时所有参考图尺寸建议统一（如均为 720×1280），避免模型根据输入图自适应调整输出分辨率。\r\n\r\n## 注意事项\r\n\r\n- **API 完全免费**，无调用次数限制、无限期。但建议合理使用避免滥用。\r\n- **支持图生图**：用 `--ref-image` 参数传入本地图片路径作为参考图。\r\n- **支持图生视频**：通过 `generate_video.py --ref-image` 传入参考图。\r\n- **纯中文提示词**：Agnes AI 对纯中文提示词理解准确，生图效果优于中英混用。\r\n- 生成成功后，脚本会返回本地文件路径列表。通过 `--output-name` 参数指定文件名，替代了旧的 asset_map.json 映射方式。\r\n## 基础设施与容错（2026-07 修复）\r\n\r\n_新项目自动继承以下代码层修复（在 modules/ 中），但了解其原理可帮助诊断类似问题。_\r\n\r\n### GitHub PAT 管理\r\n\r\n- **PAT 类型**：代码读取 `~/.github-pat` 文件。支持 Classic PAT 和 Fine-grained PAT。\r\n- **过期风险**：Fine-grained PAT（`github_pat_` 前缀）有强制过期时间（30/90/365天）。Classic PAT 可设 \"No expiration\"，推荐用于持续运行的流水线。\r\n- **创建新 PAT**：访问 https://github.com/settings/tokens\r\n  - 推荐：Classic → `repo` scope → No expiration → 写入 `~/.github-pat`\r\n- **故障特征**：GitHub 上传返回 HTTP 401 \"Bad credentials\" → `upload_to_url` 抛出 `ValueError(\"GitHub PAT 无效或已过期\")`，流水线立即标记 shot 失败而非死循环。\r\n\r\n### 参考图托管优化（skip-if-exists）\r\n\r\n**问题**：Agnes API 服务器从 `raw.githubusercontent.com` 下载大图时，国内网络访问 GitHub raw 偶发超时 → 返回 `400 Invalid image`，被误判为内容审核。\r\n\r\n**修复**（默认 Agnes Provider 走 `image_api.py upload_to_url`）：改为「先查后传」：\r\n- 上传前先 `GET` 查 GitHub 同名文件的 `sha`；若已存在，直接返回已有 raw 直链，**跳过 PUT**（1 次 API 调用而非 2 次）。\r\n- **不压缩**：早期版本用 PIL 压缩首帧图（quality 70 / 1280px）已被移除——Agnes 对原图尺寸兼容性更好，压缩反而可能触发审核。GitHub 上传分支始终上传原图；仅当**未配置 PAT** 时走 data-URI 兜底才压缩为 JPEG quality 85，正常流水线走不到。\r\n- 故障特征与重试语义见下方「重试架构」表（`image_api.py upload_to_url` 行）。\r\n\r\n> 小云雀 Provider 走另一条上传路径 `img_host.py upload_image`，重试语义更温和（见重试表最后一行）。\r\n\r\n**效果**：同图重复上传几乎零成本，降低 GitHub 限流（429）与 abuse detection 风险。\r\n\r\n### 重试架构\r\n\r\n所有 `while True` 无限重试已封顶，避免单点故障拖垮整轮轮询：\r\n\r\n| 位置 | 封顶值 | 4xx（非429） | 429/5xx/网络 | 耗尽后 |\r\n|------|--------|-------------|-------------|--------|\r\n| `agnes_provider.py generate_character` / `generate_scene`（角色图/场景图） | max_attempts=5 | 耗尽后 `return None`（4xx 非429 经 `apply_image_strategy` 调整提示词后重试，不立即中断） | 仅 rate_limit 时固定 sleep 30s（其余类别不 sleep） | `return None` |\r\n| `image_api.py upload_to_url`（默认 Agnes 上传） | MAX_UPLOAD_RETRY=4 | 401/403→`raise ValueError`（立即失败） | 退避 `min(10×attempt,60)` → 10s→20s→30s→40s（共 4 次，60s 仅在 attempt≥6 才触及） | `raise RuntimeError` |\r\n| `img_host.py upload_image`（小云雀 Provider） | MAX_RETRIES=3 | 401/403→`return None`（不重试） | 固定 2s（仅 429/500/502/503 重试） | `return None` |\r\n\r\n### 错误分类策略 `_classify_failure()`\r\n\r\n`error_utils.classify()`（在 `agnes_provider.py` / `video_utils.py` 中 import 为 `_classify_failure`）从 Agnes API 的 raw error 提取分类：\r\n\r\n| 分类 | 匹配规则 | 策略 |\r\n|------|---------|------|\r\n| `rate_limit` | 429 / rate_limit | 本轮跳过，等待下轮轮询（不退避原帧） |\r\n| `invalid_image` | 400 / invalid_image / unsafe / moderation | **重建首帧**（`_resubmit_shot(regen_first_frame=True)` 经 Provider 重新生成首帧图）+ 重提 |\r\n| `transient` | remoteclosed / timeout / 5xx | 原样重提（瞬时网络抖动） |\r\n| `bad_request` | 其他 4xx | 重建首帧后重提（可能图片格式问题） |\r\n| `unknown` | 不匹配任何规则 | 原样重提（保守策略） |\r\n\r\n### 首帧重建机制\r\n\r\n`invalid_image`/`bad_request` 错误通过 `video_utils.py:_resubmit_shot(project, sid, script, provider, retry_count=0, regen_first_frame=True)` 处理：\r\n\r\n- 调用 `provider.generate_first_frame(project, shot, script_data)` 重新生成首帧图（通过 `build_first_frame` 构建提示词 → `generate_image` API 调用）\r\n- 重建使用 `ThreadPoolExecutor` + 240s 超时保护：\r\n  - 超时前成功 → `shutil.copyfile` 覆盖到 first_frame.final 路径\r\n  - 超时或异常 → 返回 False，不提交旧被拒帧（避免重复 400 自旋）\r\n- 若 regen 失败 → `_resubmit_shot` 标记 shot 为 failed，等下一轮轮询重试\r\n\r\n### 新项目自查清单\r\n\r\n启动新项目后，检查以下基础设施是否正常：\r\n\r\n1. **GitHub PAT**：`curl -H \"Authorization: token $(cat ~/.github-pat)\" https://api.github.com/repos/JinXuchen2020/video-images/contents/` → HTTP 200\r\n2. **参考图**：首帧图尺寸建议 ≤ 1280px 边长（GitHub 上传分支上传**原图不压缩**；仅未配置 PAT 的 data-URI 兜底才压缩为 JPEG quality 85，正常流水线走不到）\r\n3. **轮询超时**：`pipeline.py` 的 `_run_poll` 子进程 timeout=1800s 已覆盖最坏情况（retry 5次×~100s 但实际压缩后 30s-2min 应返回）\r\n4. **日志**：若 shot 持续 pending，检查 `poll_only.log` 的 GitHub 上传日志和 Agnes 返回的原始错误\r\n\r\n<!-- skill ends here -->\n\nFile v2.7.1:skills/project-generate/SKILL.md\n\n---\r\nname: project-generate\r\nversion: 2.7.0\r\ndescription: \"项目编排层 — 首帧图生成、视频提交/轮询/拼接、状态查看/导出。提供 project_generate.py 作为统一入口，所有命令为子命令形式。图片生成走 Agnes AI（agnes-ai 子 skill），视频生成通过 Provider 路由（支持 Agnes / 小云雀 / LibTV 等）。\"\r\n---\r\n\r\n# project-generate — 项目编排层\r\n\r\n作为 `ai-video-auto-generator` 的子 skill，提供项目级的生成、提交、轮询、拼接全流程编排。\r\n\r\n> **项目创建**请使用 `ai-video-auto-generator` 的 `create_project.py`（在 skill 根目录执行）：\r\n> ```bash\r\n> python3 scripts/create_project.py \\\r\n>   --project <路径> --template short_drama\r\n> ```\r\n> 创建完成后，本 skill 的所有命令都要求项目目录已存在并包含 `script.json`。\r\n\r\n## 统一入口\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython3 skills/project-generate/scripts/project_generate.py\r\n```\r\n\r\n## 命令列表\r\n\r\n所有命令通过子命令（subcommand）调用，`--project` 为全局必选参数：\r\n\r\n```bash\r\nproject_generate.py --project <项目目录> <命令> [选项]\r\n```\r\n\r\n### 资产生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `generate-characters` | `gc` | 读 `character_cards`，批量生成角色资产图（front/face/side/back/action/pose 多视图） |\r\n| `generate-scenes` | `gs` | 读 `scene_cards`，批量生成场景资产图（广角/中景/特写 3 视角） |\r\n| `generate-troops` | `gt` | 读 `troop_cards`，批量生成辅助资产图（白背景全身展示） |\r\n\r\n### 首帧图生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `build-first-frames` | `bff` | 读取 script.json，生成各 shot 的 first_frame 配置和 prompt 模板文件（不调 API）。生成后自动验证六段式格式 |\r\n| `generate-images` | `gi` | 调 API 批量生成首帧图。对失败的首帧图自动重试（L1→L3 降敏），单次 API 调用 180s 超时保护 |\r\n| `verify` | — | 用 Haar Cascade 验证首帧图质量 |\r\n| `verify-scenes` | `ve-scenes` | 验证场景图是否包含人物 |\r\n\r\n### 后台运行\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `bg <子命令>` | 后台启动子命令。用 `subprocess.STARTUPINFO(wShowWindow=0)` 隐藏 `python.exe` 的控制台窗口，进程完全脱离当前控制台，不会被 WorkBuddy 断开连接杀死。**不通过 cmd.exe /c 中转**（中文路径重定向会报错）。stdout 直接重定向到 `pipeline.log`。示例：`project_generate.py --project . bg auto` |\r\n\r\n### 视频流水线\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `submit [--force [id...]]` | 提交视频任务。`--tracker local`（默认）用本地 JSON 记录，`--tracker feishu` 用飞书 Base |\r\n| `poll` | 轮询视频完成状态 + 自动下载 + 全部完成后触发拼接。**持续轮询**每 10 分钟检查一次（代码 `time.sleep(600)`），全部完成自动进行音频+字幕叠加 |\r\n| `stitch [--tracker local]` | **独立拼接子命令**：HF 无字幕渲染 → ffmpeg 烧录分段字幕(CRF18) → 叠加音频/BGM → 输出 `final.mp4`。脱离 `poll` 单独跑，用于只改字幕/编码后重拼（不重新提交/轮询视频） |\r\n| `status` | 显示各 shot/segment 的视频状态 |\r\n| `auto` | 全自动流水线。9 阶段（0→8）：脚本优化（含叙事修复）→构建prompt→角色资产→辅助资产→场景资产→首帧图→提交视频→轮询+拼接+音频。全部阶段支持断点续跑。 |\r\n\r\n### BGM 管理\r\n\r\n- 自定义 BGM：`sounds/bgm_custom.mp3` → `generate_bgm()` 优先使用，跳过 FreeSound 搜索\r\n- 自动 BGM：`script.tone` 字段驱动 FreeSound 关键词搜索，按时长匹配最合适的音乐\r\n- 多段拼接：可用 ffmpeg 将多个音乐片段交叉淡入淡出合成一个 BGM，匹配视频的叙事段落\r\n- 详见 `references/prompt-rules.md §8 BGM 管理`\r\n\r\n### Windows 注意事项\r\n\r\n- **禁用 xfade 转场**：Windows 上 xfade + acrossfade 链式叠加有音视频漂移导致画面卡死，全部改用简单 concat\r\n- **必须指定 yuv420p**：subtitles 滤镜默认输出 yuv444p 部分播放器不兼容\r\n- **subtitles 中文路径**：libass 对中文路径支持不好，需复制到 ASCII 临时路径再引用\r\n- **音频采样率**：强制输出 48kHz 立体声（`-ar 48000 -ac 2`）\r\n- 详见 `references/prompt-rules.md §9 Windows ffmpeg 避坑`\r\n\r\n### 项目管理\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `preview` | — | 生成交互式 HTML 预览页（首帧图缩略图+视频状态+shot_groups 分组）|\r\n| `report` | — | 生成 HTML 统计报告（模型分布、首帧图完成率、视频状态等）|\r\n| `tracker-sync` | — | 从飞书 Base 反向同步任务进度到本地 task_tracker.json（仅 --tracker feishu 时有效）|\r\n\r\n### script 优化\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `optimize` | `opt` | 调用 `script-optimizer` 自动验证和优化 script.json（P0/P1/P2 分级）。支持 `--strict`、`--force`、`--dry-run`、`--report-only`、`--sync-type` |\r\n| `build-prompts` | `bp` | 从 script.json 生成所有资产 prompt 文件到 `prompts/` 目录（角色/场景/辅助资产/视频），含 YAML frontmatter |\r\n| `validate-script` | — | 验证 script.json 结构和关键字段完整性 |\r\n\r\n### 诊断与修复\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `diff --shot-id <id>` | — | 生成单个 shot 的首帧图新旧对比页（side-by-side + 滑块对比）|\r\n| `diff-all` | — | 扫描 `images/storyboard/backup/` 或 `*_old.png`，批量生成对比页 + 索引页，输出到 `output/diff_index.html` |\r\n| `repair` | — | 自动修复提示词文件：重建 assets prompts + 修复 first_frame/video 提示词 |\r\n| `reset-prompts` | — | 删除所有提示词文件并重新生成 |\r\n| `update-prompts <kv>` | — | 批量删除 prompt 文件中的指定段。格式: `段名:false` |\r\n\r\n### 修复策略\r\n\r\n生成结果不满足预期时，参考 [修复策略](../../references/repair-strategy.md) 判断改 script.json 还是改 prompt 文件。\r\n\r\n## 通用选项\r\n\r\n| 选项 | 说明 |\r\n|------|------|\r\n| `--project <path>` | 项目根目录（必选）|\r\n| `--tracker local/feishu` | 任务追踪后端：local（本地 JSON）或 feishu（飞书 Base）|\r\n| `--log-file <path>` | 日志文件路径（默认：`<project>/generate.log`），所有输出同时写入此文件 |\r\n| `--verbose` | 详细输出 |\r\n| `--quiet` | 静默模式 |\r\n\r\n## 架构\r\n\r\n```\r\nproject_generate.py            ← CLI 入口（子命令路由）\r\nmodules/\r\n  ├── project_commands/        ← 包（所有 _cmd_* 业务命令，实际位于 modules/ 下）\r\n  │     ├── __init__.py        ← 主入口 + 9 阶段流水线编排（状态持久化：__init__.py 内联）\r\n  │     ├── 图片: _cmd_build_first_frames(), _cmd_generate_images()\r\n  │     ├── 视频: _cmd_submit(), _cmd_poll(), _cmd_status()\r\n  │     └── 管理: _cmd_preview() 等\r\n  ├── provider_factory.py    ← Provider 工厂（按 script.json 选 Agnes/小云雀）\r\n  ├── base_provider.py       ← 抽象基类（定义接口契约）\r\n  ├── agnes_provider.py      ← Agnes AI Provider\r\n  ├── xiaoyunqiao_provider.py ← 小云雀 Provider（含 segment 自动合并）\r\n  ├── video_utils.py         ← 视频编排逻辑（批量提交/轮询/参考图解析）\r\n  ├── task_tracker.py        ← 任务追踪门面\r\n  ├── task_tracker_local.py  ← 本地 JSON 追踪\r\n  ├── task_tracker_feishu.py ← 飞书 Base 追踪\r\n  ├── config.py              ← 统一配置加载\r\n  ├── feishu.py              ← 飞书 API 封装\r\n  ├── stitch.py              ← ffmpeg 拼接\r\n  ├── project_preview.py     ← HTML 预览\r\n  ├── project_stats.py       ← HTML 统计\r\n  ├── project_verify.py      ← 首帧图质量验证\r\n  └── project_diff.py        ← 首帧图对比\r\n```\r\n\r\n## Provider 配置\r\n\r\n在 `script.json` 的 `script` 块中配置：\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"provider\": \"agnes\",              // 图片生成工具（默认 agnes）\r\n    \"video_provider\": \"xiaoyunqiao\"   // 视频生成工具（不设则同 provider）\r\n  }\r\n}\r\n```\r\n\r\n也支持从飞书文档标题自动检测：标题含\"小云雀视频\" → `video_provider: xiaoyunqiao`。\r\n\r\n## 任务追踪\r\n\r\n`--tracker` 参数选择后端：\r\n\r\n| tracker | 后端类 | 优点 |\r\n|---------|--------|------|\r\n| `local`（默认）| `LocalJsonTracker` | 无依赖，所有操作在本地 |\r\n| `feishu` | `FeishuTracker` | 可多人协作，Base 可视化 |\r\n\r\n## 小云雀 Segment 模式\r\n\r\n当 `video_provider==\"xiaoyunqiao\"` 时，`write-prompt-file` 会自动：\r\n1. 按场景分组合并 shot 为 segment（15~45s 每段）\r\n2. 生成 segment 级提示词文件\r\n3. 写入 `xiaoyunqiao_segments[]` 到 script.json\r\n\r\n`submit`/`poll` 自动检测 segments，切换为段级提交和轮询。\r\n`stitch` 自动检测 segments，按 segment 文件拼接。\r\n\r\n## 历史\r\n\r\n本 skill 由 `batch_generate.py` + `batch_project.py` 合并为 `project_generate.py`，\r\n目录名从 `batch-generate` 更名为 `project-generate`。\r\n视频 API 函数原为 `video_api.py`（在 agnes-ai 模块中）的模块函数，逐步重构为 Provider 模式。\r\n\r\n## 设计决策（bug 预防）\r\n\r\n### 1. `project` 参数必须传递\r\n所有资产生成函数（`generate_character`、`generate_scene`、`generate_image`）必须传递 `project` 参数。\r\n- 漏传 → `upload_to_url()` 退化为 \"default\" → 参考图传到错误目录\r\n- `upload_to_url()` 内部使用 `os.path.abspath(project)` 解析相对路径（如 `.` → 项目名）\r\n- `img_host.upload_image()` 同理\r\n\r\n### 2. API 重试封顶 + 错误感知修复\r\n`agnes_provider.py` 中图片/场景生成采用「错误感知重试」：循环上限 `max_attempts=5`（`generate_image` / `generate_scene` 各独立计数），失败后用 `_classify_failure()` 分类并应用修复策略（软化提示词 / 换模型 / 原样重试），**仅 `rate_limit` 时固定 `sleep 30s`**，其余类别不 sleep。4xx non-429 由策略处理，不进入退避死循环。设上限、不设无限重试——5 次失败后上层 `project_commands` 自愈循环（`max_attempts=10`）接管降敏修复。\r\n\r\n### 3. 场景验证不依赖激进 Haar 配置\r\n`project_verify.py` 使用 Haar Cascade 多配置检测人脸。`scaleFactor=1.05/minNeighbors=3` 配置过于激进，会从废墟/火焰纹理中误报人脸。已移除，只保留 `1.1/5`、`1.2/3` 和 profile face。\r\n\r\n### 4. 场景 prompt 模板必须 scene-aware\r\n`prompt_builder.py` 的中景/特写 `view_desc` 不能硬编码特定场景描述（如 \"cracked brickwork\" 废墟模板）。必须从 scene card 的 `description` 动态派生，否则丛林场景会生成废墟砖墙。\r\n\r\n### 5. agnes-ai 为唯一真相源（单副本）\r\n`agnes-ai` 子 skill 是唯一的代码源。独立副本 `~/.workbuddy/skills/agnes-ai/` 已删除，**不再需要双副本同步**。所有改动只需在 `skills/agnes-ai/` 中完成，无需同步到其他位置。\r\n\r\n### 6. bg 后台启动：STARTUPINFO + 直接 Popen，不用 cmd.exe\r\n`launch_background.py` 的实现要点：\r\n- 使用 `subprocess.STARTUPINFO(wShowWindow=0)` 隐藏 `python.exe` 的控制台窗口\r\n- 不通过 `cmd.exe /c` 中转，因为中文路径（如\"不死者\"）在 `>` 重定向时 cmd.exe 会报错\r\n- 直接用 `subprocess.Popen(cmd, stdout=open(log), startupinfo=si)` 启动\r\n- 永远不要用 `pythonw.exe`——GUI 子系统下脚本的 stdout 行为异常\r\n- 日志自动写入 `pipeline.log`\r\n\r\n### 7. 首帧图生成：存在→验证→跳过 / 超时→降敏→重试\r\n`generate-images` 的 `_generate_single_shot()` 实现如下自愈逻辑：\r\n\r\n```\r\n对每个 shot:\r\n  1. 检查 output 路径 → 如果文件存在\r\n     → 执行 verify_first_frame()\r\n     → 通过: 跳过（\"首帧图已存在，验证通过\"）\r\n     → 不通过: 记录问题，进入生成流程\r\n  \r\n  2. 生成流程（最多 4 次尝试 = 1 次初始 + 3 次重试）:\r\n     a. 调 API 生成（180s 超时包裹）\r\n        → 正常返回: 验证质量，通过则返回\r\n        → API 超时/错误: 保存错误信息 → 进入下一轮重试\r\n     \r\n     b. 重试时:\r\n        - 检测到 timeout / HTTP 400 / content_policy_violation\r\n          → error_utils.soften_prompt 逐级降敏（先经 error_utils.classify 分类错误）:\r\n            L1: 移除高风险动作词 + 武器关键词\r\n            L2: 强制静态人像\r\n            L3: 降级为空场景\r\n        - 持久化修复后的 prompt 到文件\r\n        - 继续下一轮 API 调用\r\n  \r\n  3. 4 次全部失败 → 标记为 ❌ 失败，汇总输出\r\n```\r\n\r\n关键点：\r\n- 180s 超时防止 Agnes API 调用（由 `agnes_provider.generate_image` / `image_api.generate_image` 处理）的重试阻塞单 shot 处理\r\n- `last_error` 在 except 中捕获并传递到下一轮重试的 auto_fix\r\n- auto_fix 识别 \"timeout\"、\"invalid input image\"（武器类内容的误导性错误码）和 content_policy_violation\r\n- 武器关键词（枪/手枪/步枪/瞄准/射击等）自动替换为中性描述\r\n- 修复后的 prompt 持久化到文件，下次生成直接用修复版\r\n\r\n### 8. HF 渲染：必须让 hyperframes 自动发现 headless shell，禁止注入浏览器 env var\r\n`hyperframes_stitch.py` 的渲染入口**绝不能**设置 `HYPERFRAMES_BROWSER_PATH` / `PUPPETEER_EXECUTABLE_PATH` 强制指向系统 Edge。原因（2026-07-15 实证）：\r\n- hyperframes 主渲染路径走 `resolveHeadlessShellPath`，自动发现 `~/.cache/puppeteer/chrome-headless-shell/*/chrome-headless-shell.exe`（puppeteer 自动化构建，专为 CI 沙箱优化，无需 GUI/COM）。\r\n- 一旦注入 Edge 路径，headed 浏览器发现链（`findFromEnv2`）会捕获它用于 GPU 探测 → 系统 Edge 单实例架构下新 msedge.exe 转交已运行实例后 Code:0 秒退 → GPU 探测失败 → worker 校准失败 → 渲染级联失败回退 ffmpeg。\r\n- **正确做法**：不设置这两个 env var，让 hyperframes 自动发现 headless shell（约 2.7min 渲染 18 镜头 2258 帧）。Edge 在本机因会被系统/用户自动重开，实际不可用于渲染。\r\n\r\n### 9. 字幕分段：按词边界（空格）切，绝不按时间/字数硬切\r\n`_split_long_subtitle()` 按**空格分隔的完整词**累积切分，保证一个词不被劈开。不要按时间（会造成一句话分两段）或纯字数硬切（可能从词中间截断）。长文本按完整词累积到 `max_chars`(默认 15 字/行) 后切段；若整段 < min_seg_dur 则合并到最后一段。\r\n\r\n### 10. 字幕字体/编码约定\r\n- 烧录滤镜 `force_style='FontName=Microsoft YaHei,FontSize=14,PrimaryColour=&H00FFFFFF,Outline=1,Shadow=1'`（14px 适配 720 宽视频）。\r\n- 必须指定 `yuv420p`（libass 默认 yuv444p 部分播放器不兼容）。\r\n- 字幕时间轴使用 `actual_durations`（ffprobe 探测真实视频时长），不使用 script 的 `duration_seconds` 计划值（逐镜头偏差 0.04–0.4s 累积会偏移后段字幕）。\r\n- 成片默认编码 `-crf 18`（高码率）。\r\n\r\n### 11. safe-delete 沙箱坑：os.remove / os.unlink 必须 try/except\r\n托管 Python 的 safe-delete 钩子在沙箱无回收站时会抛 `SAFE_DELETE_FAIL_CLOSED`。若直接调用 `os.remove(final_hf.mp4)` / `os.unlink(_temp.mp4)` 不上抛保护，异常会被 `run_first` 当成拼接致命错误 → 误报\"拼接失败\"（其实 final.mp4 已写好）。现已全部包 try/except，删不掉仅 `[warn]` 不致命。\n\nFile v2.7.1:skills/script-optimizer/SKILL.md\n\n# script-optimizer\r\n\r\n纯自动化脚本质量优化器。验证 `script.json` 质量，自动修复模板默认值、角色匹配、运镜兼容等已知问题。\r\n\r\n## 入口\r\n\r\n```bash\r\n# 方式 A：直接运行模块（推荐）\r\npython3 scripts/optimize/__init__.py --project <项目目录> [选项]\r\n\r\n# 方式 B：通过 project-generate 统一入口\r\npython3 scripts/project-generate/project_generate.py --project <项目目录> optimize\r\n```\r\n\r\n## 调用方式\r\n\r\n| 模式 | 命令 |\r\n|------|------|\r\n| 全自动 | `python3 scripts/optimize/__init__.py --project <项目目录>` |\r\n| strict + force | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --force` |\r\n| JSON 输出 | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --json` |\r\n| 预览 | `python3 scripts/optimize/__init__.py --project <项目目录> --dry-run` |\r\n| 仅报告 | `python3 scripts/optimize/__init__.py --project <项目目录> --report-only` |\r\n| 修复 prompt | `python3 scripts/optimize/__init__.py --project <项目目录> --fix-prompts` |\r\n| 同步类型配置 | `python3 scripts/optimize/__init__.py --project <项目目录> --sync-type` |\r\n\r\n## 修复清单\r\n\r\n| 修复项 | 说明 |\r\n|--------|------|\r\n| gender | 从 build/aura/personality 关键词推断 |\r\n| aesthetic_style | 从类型配置注入 |\r\n| distinctive_mark | 从 hair + face_details + color_scheme 自动构建 |\r\n| face_details | 从 face 文本中按关键词提取 |\r\n| camera_movement | 按 shot_type 填充默认运镜 |\r\n| description | 从 prompt 截取 |\r\n| duration_seconds | 字符串→int 类型修正 |\r\n| reference_images | 从 shot_groups + character_cards 重建 |\r\n| scene lighting/mood | 从 time_of_day 推断 |\r\n| shot_groups | 删除孤儿引用，未分组 shot 创建新组 |\r\n| characters 去重 | 独立检测并移除 characters 列表中的重复项 |\r\n| 全局字段 | 从类型 .md 注入缺失字段 |\r\n| 运镜兼容 | 清除互斥组合（仰+俯、拉+推等） |\r\n| 泛称代词 | 检测「猫」「狗」「他」「她」等并替换为角色名 |\r\n\r\n## 验证维度\r\n\r\nP0 — 阻塞资产生成（模板占位符残留、description 过短、必填字段缺失等）\r\nP1 — 建议修复（strict 模式下阻塞）\r\nP2 — 消息（camera_movement 未设置、face_details 默认值等）\r\n\r\n## 与 project-generate 集成\r\n\r\n```python\r\nfrom optimize import OptimizerV2\r\nopt = OptimizerV2(project, strict=True, json_mode=True)\r\nresult = opt.run()\r\n```\n\nFile v2.7.1:README.md\n\n# ai-video-auto-generator\r\n\r\nAI 短视频全自动流水线 — 从想法到成片，一键出视频。\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## Quick Start\r\n\r\n### 🔥 快速尝鲜（30 秒出预览，无需 API Key）\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n自动装依赖 → ffmpeg 本地合成预览视频 → 看到效果 → 引导下一步。\r\n\r\n### 💬 AI Agent 一键出片（推荐）\r\n\r\n加载本 skill 后，直接向 AI Agent 描述需求：\r\n\r\n```\r\n\"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n```\r\n\r\nAgent 会自动完成：\r\n1. 分析需求 → 生成完整 `script.json`（含角色卡/场景卡/镜头列表）\r\n2. 运行 `optimize` 命令（OptimizerV2）做 12 维叙事自动修复\r\n3. 调用 `--mode auto` 全自动流水线\r\n4. 完成后通知你\r\n\r\n> 支持多种输入：文本描述、URL、本地文件(.txt/.md/.docx)、飞书文档链接。直接发给 Agent 即可。\r\n\r\n### 安装\r\n\r\nskill 安装后会自动检测环境，缺失的依赖（opencv, edge-tts, PIL 等）会自动安装：\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --project . --mode setup\r\n```\r\n\r\n### 方式 1：从模板创建新项目\r\n\r\n```bash\r\n# 查看可用模板（在 skill 根目录执行）\r\npython scripts/create_project.py --list-types\r\n\r\n# 创建项目\r\npython scripts/create_project.py --project ./my_video --template short_drama\r\n\r\n# 一键出片\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 2：导入现有 `script.json`\r\n\r\n```bash\r\n# 在已有项目目录下\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 3：从飞书文档导入\r\n\r\n```bash\r\n# 在 skill 根目录执行，把飞书需求文档 URL 写入 script.json\r\npython scripts/create_project.py --project . --feishu-doc-url <feishu_doc_url>\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## 流水线概览\r\n\r\n```\r\nscript.json\r\n  ↓ 叙事 12 维自动修复（ID/时长/钩子/运镜/情绪/收尾...）\r\n  ↓ 角色资产生成 + 6 维质量验证\r\n  ↓ 场景资产生成 + 无人检测 + 风格检测\r\n  ↓ 首帧图生成 + 50 分制验证 + L1/L2/L3 降敏修复\r\n  ↓ 视频提交 → 轮询 → 下载 → 55 分制验证（含运镜+情绪）\r\n  ↓ 拼接（hyperframes / ffmpeg）\r\n  ↓ TTS 配音 + BGM + 环境音 + 音效 + ffmpeg 多轨混音\r\n  ↓ SRT 字幕\r\n  → final.mp4\r\n```\r\n\r\n## 命令速查\r\n\r\n```bash\r\n# 🎮 快速尝鲜（30 秒，无需 API Key）\r\npython skills/project-generate/scripts/pipeline.py --mode demo\r\n\r\n# 环境检测 + 自动安装\r\npython skills/project-generate/scripts/pipeline.py --mode setup\r\n\r\n# 💬 告诉 AI Agent 你的需求（推荐）\r\n#    在 WorkBuddy 中加载本 skill 后，直接描述需求即可\r\n#    示例: \"帮我做一个古代将军在现代城市醒来的短视频\"\r\n\r\n# 全自动流水线（已有 script.json 时）\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n\r\n# 预检（只验证不生成）\r\npython skills/project-generate/scripts/pipeline.py --mode validate\r\n\r\n# 仅轮询（已有 task 的项目续跑）\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached\r\n\r\n# 项目状态（默认 JSON 输出，--text 人类可读）\r\npython skills/project-generate/scripts/project_generate.py --project . status\r\n\r\n# 单独拼接（HF 无字幕渲染 → ffmpeg 烧录字幕 → 叠加音频/BGM → final.mp4）\r\npython skills/project-generate/scripts/project_generate.py --project . stitch --tracker local\r\n```\r\n\r\n## Provider 切换\r\n\r\n默认使用 Agnes AI。修改 `script.json` 中的 `script.provider` 即可切换：\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"provider\": \"xiaoyunqiao\",\r\n    \"video_provider\": \"xiaoyunqiao\"\r\n  }\r\n}\r\n```\r\n\r\n自定义 Provider：实现 `BaseProvider` 后通过 `register_provider()` 注册。\r\n\r\n## 已知限制\r\n\r\n| 限制 | 说明 |\r\n|------|------|\r\n| 需 API Key | 默认使用 Agnes AI，需配置 `~/.agnes-api-key`（免费无限额度）。也可切换其他 Provider。 |\r\n| Windows 优先 | 路径处理、asyncio 事件循环针对 Windows 设计。macOS / Linux 未完整测试。 |\r\n| OpenCV 依赖 | 视觉验证需要 `opencv-python-headless`（~50MB），`--mode setup` 会自动安装。 |\r\n| 无实时进度条 | `auto` 模式 detach 后日志写入文件，无终端进度条。用 `tail -f auto.log` 查看。 |\r\n\r\n## 验证体系\r\n\r\n| 资产类型 | 检查内容 | 分值 |\r\n|---------|---------|------|\r\n| 角色图 | 文件+模糊+人物数量+背景+全身照+风格 | 55 分 |\r\n| 场景图 | 人脸检测+风格检测 | pass/fail |\r\n| 首帧图 | 文件+尺寸+模糊+人物数量+色彩 | 50 分 |\r\n| 视频 | 时长+比例+帧质量+运镜+情绪 | 55 分 |\r\n| 脚本 | 12 维叙事结构 | P0/P1/P2 |\r\n\r\n## 文档\r\n\r\n- [流水线排错指南](references/troubleshooting.md)\r\n- [环境搭建指南](references/setup-guide.md)\r\n- [Provider 配置参考](references/provider-config.md)\r\n- [script.json 生成检查清单](references/script-json-checklist.md)\r\n\r\n## License\r\n\r\nMIT\n\nFile v2.7.1:sample/README.md\n\n# Sample: Quick Experience Video\r\n\r\nA minimal 5-shot short video script for testing the pipeline.\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# 0. Quick demo (30 seconds, no API key needed)\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode demo\r\n\r\n# 1. Setup environment (auto-install missing deps)\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode setup\r\n\r\n# 2. Run the full pipeline\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode auto\r\n```\r\n\r\n## What It Does\r\n\r\nThis sample contains a 15-second drama scene:\r\n- 1 character (小墨)\r\n- 1 scene (天台 rooftop)\r\n- 5 shots with camera movement variety (dolly-in, closeup, tilt-up, static, wide)\r\n- Emotional arc: calm → reflective → tense → resolved\r\n\r\n## Notes\r\n\r\n- Requires Agnes AI API Key (`~/.agnes-api-key` or configured in `script.json`)\r\n- First run will auto-install Python dependencies (opencv, edge-tts, etc.)\r\n- The auto pipeline will validate and auto-fix the script's narrative structure\n\nFile v2.7.1:_meta.json\n\n{\n  \"ownerId\": \"kn7ejvrxyqc214x7gvae89m3nd8a42ye\",\n  \"slug\": \"ai-video-auto-generator\",\n  \"version\": \"2.7.1\",\n  \"publishedAt\": 1784188331271\n}\n\nFile v2.7.1:references/asset-generation.md\n\n# 资产生成参考\r\n\r\n> 从主 SKILL.md §5.4 抽取的完整资产生成规则。\r\n\r\n---\r\n\r\n#### 5.4.2 角色资产生成（强制）\r\n\r\n> 📌 本节较长（~200 行），覆盖 8 类必须资产的完整生成策略（标准共 11 个文件，见 §5.4.2 资产类别表）。\r\n> 新手建议先读概要（策略一~五），熟悉后按需查阅具体资产类型。\r\n\r\n对于视频中出现的每个角色：\r\n\r\n**⚠️ 角色/兵种一致性核心规则（Critical）**\r\n\r\n图片生成工具（agnes-ai）每次调用完全独立，**模型不认识任何自定义名字**。如果提示词里只写名字（如 `墨雪` / `墨将` / `明军` / `蛮兵`），每次生成都会随机出不同的人或装束。\r\n\r\n**规则：所有图片提示词中，涉及角色的名字必须替换为 `character_cards[].base_prompt_cn` 中的完整外观描述；涉及兵种的名字必须替换为 `troop_cards[].base_prompt_cn` 中的完整装束描述。**\r\n\r\n> ⚠️ **完整描述包括三项**：`base_prompt_cn`（外观）+ `color_scheme`（配色）+ `style_keywords`（风格词），三者缺一不可。仅用 `base_prompt_cn` 会导致铠甲颜色/纹理在不同镜头间漂移。\r\n\r\n反例（只写名字，模型不认识）：\r\n```\r\n\"明军与蛮兵激战，明军士兵接连倒地\"\r\n```\r\n\r\n正例（嵌入外观描述，模型有参照）：\r\n```\r\n\"明军士兵身着制式铁甲外罩暗红战袍持长枪腰刀制式头盔，蛮兵身着兽皮皮甲骨甲部分上身裸露可见战纹纹身持弯刀狼牙棒，两军激战刀剑交错\"\r\n```\r\n\r\n> `generation.reference_images` 字段标明该镜头引用了哪些卡，生成 prompt 时应从中提取对应描述注入。\r\n\r\n**五个关键优化策略，必须全部执行：**\r\n\r\n---\r\n\r\n**策略一：关闭提示词自动改写（agnes-ai 无此参数，提示词原样发送）** ⭐\r\n\r\nagnes-ai 的图片模型不会自动改写提示词，无需特殊设置。\r\n\r\n```yaml\r\n# agnes-ai 调用（首选）— 不需要 revise 参数\r\ntool: agnes-ai\r\nparams:\r\n  prompt: \"国风古典美人，鹅蛋脸型，丹凤眼冷冽锐利，剑眉英气，樱唇微抿，墨黑长发束成高马尾...\"\r\n  output_name: \"墨雪_front.png\"\r\n  output_dir: \"$HOME/WorkBuddy/锈甲天凤/images/characters\"\r\n```\r\n\r\n---\r\n\r\n**策略二：提示词结构化分层（核心锚定优先）**\r\n\r\n所有角色资产的提示词必须以 `character_cards.appearance` 的完整描述作为前缀，但按**资产类型**调整核心锚定的内容，避免过度联想：\r\n\r\n| 资产类型 | 🔴 核心锚定（必须） | 🟡 可选补充 | Framing 限制词 |\r\n|---------|-------------------|-----------|---------------|\r\n| **全身照** (front/3quarter/side/back) | 发型 + 完整铠甲/服装 + 脸型 | 气场+纹样+披风 | `full body from head to toe including boots` |\r\n| **面部特写** (face) | **发型 + 脸型/眉目 only**（**去掉铠甲**） | 眼神+表情 | `face only, tight face crop, no body, no armor visible, only face from forehead to chin` |\r\n| **头部多角度** (head_angles) | 发型 + 脸型（铠甲边缘隐约可见即可） | 眼神 | `head and neck only, shoulders barely visible` |\r\n| **五官特写** (face_details) | **发型 + 脸型 only**（**去掉铠甲**），用方案F生成4张独立部位特写+脚本拼接（详见第6条） | 皮肤质感+五官细节 | `face detail close-up, [specific feature] area only, no armor visible, no clothing` |\r\n| **表情研究** (expressions) | 发型 + 脸型（铠甲边缘隐约可见） | 多种表情 | `face and upper shoulders, headshot framing` |\r\n| **手脚姿态** (hands_feet_gestures) | 完整铠甲/服装 + 体型 | 武器/配饰 | `hand and foot poses, body partial visible` |\r\n| **参考板** (reference) | 完整全部 | 全部 | 无（全身到特写都有） |\r\n| **配饰道具** (props) | 标志性纹样 + 武器特征 | 材质光照 | `props isolated on neutral background` |\r\n\r\n> 以上 8 个类别覆盖 **11 个文件**（标准基数）：全身照类别产出 4 个文件（front/side/back/3quarter），其余类别各产出 1 个文件。含动态持械/动作视图时，每个角色产出的文件数会更多。详见 §5.4.5 资产库目录结构。\r\n\r\n⚠️ **关键原则**：\r\n- 全身照/参考板：**不能省略铠甲**，否则模型可能脑补不同服装\r\n- **面部特写/五官特写：必须去掉铠甲描述**，否则混元会将\"女武将\"身份与\"全身铠甲\"强关联，导致脸周围出现肩甲胸甲\r\n- 面部特写保留**发型+脸型**已足够锚定身份，发型比铠甲更具辨识度\r\n- **审美风格由项目决定**：读取 `script.json` 的 `aesthetic_style` 字段——`\"eastern\"` 选中文古典审美词汇，`\"western\"` 选英文词汇。**不可写死某一种审美，由 target_audience 决定**\r\n\r\n提示词结构模板：\r\n```\r\n# 全身照\r\n[🔴核心锚定：发型+完整铠甲+脸型], [🟡重要：气场+纹样], [🟢增强：光照+质量], [具体资产类型要求]\r\n\r\n# 面部特写（⚠️ 去掉铠甲，只留发型+脸型）\r\n[🔴核心锚定：发型+脸型], [🟡重要：眼神+表情], [🟢增强：光照+质量], [framing限制：face only no body no armor], [具体资产类型要求]\r\n```\r\n\r\n**策略三：使用固定 seed 保持跨图片一致性** ⭐\r\n\r\n`generate_image.py` 支持 `--seed <int>` 参数固定随机种子。同一角色在同一次会话中多次生成时，使用相同 seed 可显著提高面容一致性。\r\n\r\n```yaml\r\n# 同一角色的多张资产使用相同 seed\r\ntool: agnes-ai generate_image.py\r\nparams:\r\n  prompt: \"国风古典美人，鹅蛋脸型，丹凤眼冷冽锐利...\"\r\n  seed: 42  # 固定种子，确保多次生成的面容一致\r\n  output_name: \"墨雪_front.png\"\r\n```\r\n\r\n建议：每个角色分配一个固定 seed（如墨雪=42，墨将=43），该角色的所有资产图都使用这个 seed 生成。\r\n\r\n---\r\n\r\n**策略四：提示词语言策略（按 `aesthetic_style` 选择，覆盖全部资产类型）**\r\n\r\n所有资产类型（角色、场景、道具、分镜图）的提示词语言由 `script.json` 的 `aesthetic_style` 决定：\r\n\r\n- `\"eastern\"` → **纯中文**（不加英文），使用 `image_prompt_cn` / `scene_prompt_cn`\r\n- `\"western\"` → **英文**（古风词可保留中文），使用 `image_prompt` / 自写英文\r\n\r\n> 详见主 SKILL.md §5.5（审美风格配置）和 §6.2-§6.4（完整示例）。\r\n\r\n---\r\n\r\n**策略五：冗余生成 + 选优（针对高不一致资产）**\r\n\r\n对于最容易出现不一致的资产类型（面部特写/头部多角度/表情研究），一次生成 **2 张候选图**，选最接近的一张保留，另一张删除或重命名加 `_candidate` 后缀。\r\n\r\n---\r\n\r\n\r\n#### 5.4.3 场景资产生成（强制）\r\n\r\n对于视频中的每个关键场景：\r\n\r\n1. **画幅规则**：场景空镜头必须是 **16:9 横版**（1792x1024 或 1920x1080），展现环境广度。9:16 竖屏只用于角色全身照和分镜图。\r\n2. **内容规则**：场景空镜头中**不得出现任何人物**（包括小兵、路人）。可包含道具（旗帜、兵器、家具等）。如需士兵的三视图，单独生成。\r\n   - **实现方式**：`agnes_provider.py` 的 `generate_scene()` 已自动注入 `negative_prompt=\"人物, 人, 行人, 角色, 人类, 人群, 面部, 身体, 人体, 人物剪影, 生物, 动物, 活物, 多余的物体\"`，API 层面强制禁止人物出现。\r\n     仅靠 prompt 正文写\"画面中不应该有任何人物\"不够——AI 模型容易在长 prompt 中忽略正面描述，必须通过 `negative_prompt` 独立参数约束。\r\n   - **根因与修复**（2026-06-30）：`negative_prompt` 还不够——场景名/描述中的人物暗示词（如\"播客录音室\"→暗示有人播客、\"谈话氛围\"→暗示有人交谈、\"主播\"→暗示主持人）会**压倒 negative_prompt**，模型训练数据中这些词与人物强关联。\r\n     - `generate_scene()` 在构建 prompt 前**自动净化**场景描述：去掉\"播客\"、\"谈话\"、\"主播\"等暗示人物的词\r\n     - prompt 结构改为：**开头**强约束「室内空镜无人物」→ **中间**净化后的场景描述 → **结尾**再次约束「绝对不能出现人物」\r\n     - `negative_prompt` 增加\"主播、主持人、演讲者、人像、肖像\"等术语\r\n     - **重要**：不修改 `script.json` 的场景卡数据，只在 prompt 构建层做词法净化\r\n   - **验证**：`project_generate.py verify-scenes` 命令使用 Haar Cascade 人脸检测验证场景图是否含人物。\r\n\r\n3. **跨镜头角色一致性（强制）**（2026-06-30 新增）：\r\n   - **问题**：参考图（如 `小段_front.png`）有围巾/眼镜/发型等标志性特征，但 `character_cards` 的 `distinctive_mark`/`armor/clothing` 没写 → 后续 shot 的 prompt 不提这些特征 → AI 忽视参考图的标志性细节 → 角色一致性丢失（典型症状：shot_01 有围巾、shot_02 没有）\r\n   - **根因**：手动在某个 shot 的 prompt 临时加的\"橙色围巾\"没存回 `character_cards`，导致只有该 shot 的 prompt 有围巾\r\n   - **实现方式**（已编码到 `_generate_prompt_template`）：\r\n     - 自动从 `script.character_cards[]` 提取每个角色的 `distinctive_mark` + `style_keywords`\r\n     - 拼接到每个 shot 的 `[目标风格/场景]` 段末尾（用逗号分隔）\r\n     - 效果：修改 `character_cards[].distinctive_mark` 后，`build-first-frames --force` 一键同步所有 shot 的 prompt\r\n   - **强制规则**：\r\n     - **标志性特征（围巾、眼镜、发型、配饰）必须写入 `character_cards[].distinctive_mark`**\r\n     - 不能只在某个 shot 的 prompt 里手动加\r\n     - 任何\"参考图有但 prompt 没\"的特征都会被 AI 忽略\r\n   - **示例**：\r\n     ```json\r\n     \"character_cards\": [{\r\n       \"name\": \"小段\",\r\n       \"distinctive_mark\": \"戴一副圆框眼镜，佩戴一条橙色围巾，笑容有感染力，微卷短发\",\r\n       \"appearance\": {\r\n         \"armor/clothing\": \"米白色针织毛衣外套浅棕色休闲开衫，领口搭一条橙色围巾\"\r\n       }\r\n     }]\r\n     ```\r\n4. **单角色 shot 防双人脑补（强制）**（2026-06-30 新增）：\r\n   - **问题**：单角色镜头的参考图只有 `小段_front.png`，但 `agnes-image-2.0-flash` 的编辑指令写\"在场景中加入**各角色**\"（复数），AI 会脑补出第二个人（如 shot_05/07 出现两人）\r\n   - **修复**：`_generate_prompt_template` 根据角色参考图数量动态生成指令\r\n     - 单角色参考图 → \"加入**该角色**\" + \"只出现一位角色，禁止出现第二个人或倒影\"\r\n     - 多角色参考图 → \"加入**各角色**\" + 空间关系约束\r\n   - **强制规则**：所有单角色 shot 的 `[编辑指令]` 段必须显式禁止出现第二人\r\n5. **定义场景卡** — 在 `script.json` 的 `scene_cards` 中为每个场景定义光照、氛围、配色、关键元素等属性，与 `character_cards` 形成对称\r\n   - `scene_cards[].style_keywords` 自动注入到场景 `image_prompt` / `video_prompt` 中\r\n   - 场景角度由生成流程统一约定（使用中文命名）：`广角建立` / `中景细节` / `特写元素`\r\n   - 光照变体由生成流程统一约定（使用中文命名）：`白天` / `黄金时刻`，至少生成 2 个变体\r\n\r\n4. **多角度场景图** - 从不同景别生成同一场景\r\n   - 至少生成2-3个角度：远景建立、中景细节、特写元素\r\n   - 保存为：`images/scenes/<场景名>_广角.png`, `<场景名>_中景.png`, `<场景名>_特写.png`\r\n\r\n5. **场景光照变体** - 生成不同光照条件下的同一场景\r\n   - 默认：白天 + 黄金时刻（至少2个变体）\r\n   - 保存为：`images/scenes/<场景名>_白天.png`, `<场景名>_黄金时刻.png`\r\n\r\n**场景资产提示词示例**（按 `aesthetic_style` 选择语言，以下示 eastern 用纯中文）：\r\n\r\n```\r\n\"龙南客家围屋远景，黄金时刻阳光，雄伟山脉背景，文化遗产，高度细致，电影感，4K\"\r\n\"龙南客家围屋中景，主入口，精美石雕可见，温暖光线，建筑细节，4K\"\r\n\"龙南客家围屋特写，风化墙面纹理，苔藓和石头细节，微距镜头，历史质感，4K\"\r\n```\r\n\r\nwestern 风格时用英文，如 `\"Ancient Chinese courtyard house, golden hour sunlight, majestic mountain background...\"`\r\n\r\n#### 5.4.4 风格一致性规则\r\n\r\n所有生成的资产必须共享统一的视觉风格：\r\n\r\n1. **色彩统一** - 所有角色和场景资产使用相同的调色板\r\n   - 参考：脚本JSON中的 `asset_inventory.style_reference`\r\n   - 一致地应用色彩关键词（如\"温暖复古\"、\"电影感\"、\"纪录片风格\"）\r\n\r\n2. **光照统一** - 保持每个场景组的光照情绪一致\r\n   - 历史场景：\"温暖复古胶片颗粒光照\"\r\n   - 现代场景：\"锐利自然光，略微饱和\"\r\n\r\n3. **质感统一** - 使用一致的质量关键词\r\n   - 基础：\"高度细致，照片级真实，电影感，4K\"\r\n   - 风格化：\"艺术感，插画风格，一致的线条工作，[特定风格]\"\r\n\r\n4. **角色一致性** - 当同一角色出现在多个镜头中\r\n   - 在每个提示词中始终包含识别特征（面部特征、服装、关键道具）\r\n   - 对该角色的所有提示词使用相同的风格关键词\r\n\r\n#### 5.4.5 资产库组织\r\n\r\n所有资产放入 **$HOME/WorkBuddy/\\<项目名\\>/** 的 `images/` 子文件夹，结构如下：\r\n\r\n```\r\n$HOME/WorkBuddy/<项目名>/\r\n├── script.json\r\n├── images/\r\n│   ├── characters/\r\n│   │   ├── 名称_front.png           (正面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_side.png            (侧面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_back.png            (背面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_3quarter.png        (3/4侧面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_face.png            (面部极致特写)\r\n│   │   ├── 名称_head_angles.png     (头部多角度参考)\r\n│   │   ├── 名称_hands_feet_gestures.png  (手脚姿态研究)\r\n│   │   ├── 名称_reference.png       (角色设定参考板)\r\n│   │   ├── 名称_expressions.png     (表情研究表)\r\n│   │   ├── 名称_props.png           (配饰与道具特写)\r\n│   │   └── 名称_face_details.png    (面部五官特写)\r\n│   ├── scenes/\r\n│   │   ├── 场景名_广角.png   (广角空镜头，16:9，无人物)\r\n│   │   ├── 场景名_中景.png    (中景空镜头，16:9，无人物)\r\n│   │   ├── 场景名_特写.png (细节空镜头，16:9，无人物)\r\n│   │   ├── 场景名_白天.png   (白天光照变体)\r\n│   │   ├── 场景名_黄金时刻.png (黄金时刻光照变体)\r\n│   │   └── ...\r\n│   ├── props/\r\n│   │   ├── 道具名_01.png      (道具多角度)\r\n│   │   └── ...\r\n│   ├── style/\r\n│   │   ├── color_palette.png   (调色板参考卡)\r\n│   │   └── first_frame.png    (视频首帧合成图，含人物+场景+道具)\r\n│   └── storyboard/            ← 分镜首帧参考图，用于图生视频\r\n│       ├── shot_01_first_frame.png  (分镜1)\r\n│       ├── shot_02_first_frame.png  (分镜2)\r\n│       └── ...\r\n├── videos/\r\n├── output/\r\n└── ...\r\n```\r\n\r\n**关键规则**：\r\n\r\n1. **角色资产**（共11种必须生成）：\r\n\r\n   **基础全身照（4种，必须生成）**：\r\n   - `名称_front.png` - **正面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_side.png` - **侧面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_back.png` - **背面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_3quarter.png` - **3/4侧面全身照**（介于正面和侧面之间），**白色纯色背景**，**必须从头到脚完整（含靴子）**，展示角色立体感\r\n\r\n   **面部与细节（3种，必须生成）**\r\n   - `名称_face.png` - **面部极致特写**，展示五官细节（9:16），表情需符合角色性格\r\n   - `名称_head_angles.png` - **头部多角度参考**（方形或16:9），展示6个角度（正面、3/4、侧面、背面、仰视、俯视），确保3D建模/AI生成一致性\r\n   - `名称_hands_feet_gestures.png` - **手脚姿态研究**（方形或16:9），展示10种手部姿态和8种脚部/走路姿态，确保角色动作一致性\r\n\r\n   **角色设定与扩展（4种，必须生成）**：\r\n   - `名称_reference.png` - **角色设定参考板**（16:9或方形），**不透明背景**，参考专业角色设计参考板（含全身视图、头部多角度、表情研究、面部特写、服饰细节、配饰道具、手脚姿态），**一次性生成，用于角色一致性参考**\r\n   - `名称_expressions.png` - **表情研究表**（方形或16:9），展示10种表情（开心、惊讶、愤怒、悲伤、困惑、大笑、皱眉、思考、痛苦、疑惑）\r\n   - `名称_props.png` - **配饰与道具特写**（方形或16:9），展示武器、发簪、披风扣、腰带、靴子等道具细节\r\n   - `名称_face_details.png` - **面部五官特写**（方形，1024×1024），展示眼部/鼻部/唇部/耳部四部位特写拼图。用方案F生成（4张独立部位特写→PIL脚本拼接）\r\n\r\n   **全身照关键规则**：prompt中必须包含 `from head to toe` / `complete full body including feet` 等关键词，确保构图完整；表情需符合角色性格定位（如\"冷艳中带温情\"而非\"愤怒\"）\r\n\r\n2. **场景资产**（必须是空镜头，无人物）：\r\n   - 生成**多角度场景图**（广角/中景/特写）\r\n   - 可以是 **16:9 横向**，突出环境细节和空间感\r\n   - 每个场景至少生成 2-3 张（广角/中景/特写）\r\n   - 光照变体至少 2 种（白天/黄金时刻）\r\n   - 文件命名：`images/scenes/<场景名>_广角.png`、`<场景名>_中景.png`、`<场景名>_白天.png` 等\r\n\r\n3. **辅助资产**（当脚本需要除了主角之外的批量/群体角色时，为其生成三视图作为参考）：\r\n   - 典型场景：**两军对垒**（明军vs蛮兵）、**卫兵/随从**、**特定道具/装备**等\r\n   - 每类辅助资产生成 front / side / back 三视角，白色纯色背景，768×768\r\n   - 生成方式：**文生图**（无参考图，纯文字提示词）\r\n   - 提示词结构：`[时代] [类别] [视图] 全身视图，[装备描述]，[姿态]，完整全身从头到脚包括靴子，白色纯色背景，古风写实`\r\n   - 文件命名：`images/troops/<类别名>_front.png`、`<类别名>_side.png`、`<类别名>_back.png`\r\n   - 在 `script.json` 中增加相应的 `xxx_cards` 字段（如 `troop_cards`）描述特征和提示词\r\n   - 分镜首帧图涉及辅助资产时，将其与场景图、角色图合并为一张参考板使用\r\n\r\n4. **首帧合成图（全局风格参考）**：\r\n   - 视频的**首帧合成图**（first frame）是人物、场景、道具的合成图\r\n   - 用于确定整体视觉风格和色调\r\n   - 保存在 `images/style/first_frame.png`\r\n\r\n5. **分镜首帧图（分镜级，用于图生视频）**：\r\n   - **每个镜头**生成一张独立的**分镜首帧图**，作为该镜头视频生成的参考图\r\n   - 分镜图 = **场景 + 主要人物 + 次要人物 + 道具**的合成图，构图与 `image_prompt` 一致\r\n   - **比例**：由 `script.json` 的 `aspect_ratio` 和项目需求决定（如竖屏 9:16 对应 720×1280，横屏 16:9 对应 1280×720 等），匹配视频输出尺寸\r\n   - **参考图策略**（⚠️ 重要：不要只传角色 front 照做 ref-image）：\r\n     - 以**场景图**为主要 `--ref-image`（保证场景氛围/色调/光照不被白色背景覆盖）\r\n     - 角色一致性通过 **拼图参考板法** 或 prompt 文字描述实现\r\n   - **拼图参考板法**（多张参考图时的标准方案）：\r\n     - 当镜头需要参考**场景 + 多角色 + 辅助资产**时，先用 Python PIL 将所有参考图合并为一张\r\n     - 布局示例：场景图占左侧 2/3，角色/辅助资产图排列在右侧\r\n     - 合并后的单张图约 3-4MB，GitHub raw 上传不受限制\r\n     - 参考脚本：`scripts/make_ref_board.py`（通用模板，改路径即可复用）\r\n   - **多角色同框 Prompt 技巧**：\r\n     - 每个角色名称后紧跟 `(角色特征括号注释)`，如 `女性将军墨雪(国风古典美人鹅蛋脸丹凤眼鸳鸯暗纹玄铁铠甲)`\r\n     - 次要角色描述比主要角色简短，放在动作描述中自然带出\r\n     - ⚠️ **武器、装备、动作细节不要放进括号内**，括号内容容易被模型视为弱权重注释。应该写成自然语句：✅ `\"明军士兵持长枪突刺、拔腰刀近身格斗\"` ❌ `\"明军士兵（持长枪腰刀）\"`\r\n   - 生成方式：**图生图**，以合并后的单张参考板为 `--ref-image`\r\n   - 提示词中用 `image_prompt_cn`（eastern）或 `image_prompt`（western），并补充角色特征描述\r\n   - 命名规则：`images/storyboard/shot_<镜头编号>_first_frame.png`\r\n   - 示例：`images/storyboard/shot_01_first_frame.png`（分镜1）\r\n   - 该镜头后续视频生成时，以 storyboard 图为第一帧参考 + `video_prompt` 图生视频\r\n\r\n> `scripts/` 目录下提供辅助工具脚本：`make_ref_board.py`（合成参考板）、`stitch_face_details.py`（拼接面部细节图）。\r\n\r\n6. **风格统一**：\r\n   - 所有资产（角色、场景、道具）必须**风格统一**\r\n   - 遵循 `script.json` 中的 `tone` 和 `visual_thread` 设定\r\n   - 调色板参考 `images/style/color_palette.png`\r\n\r\n7. **文件位置**：\r\n   - 角色图、场景图必须保存在**项目文件夹下的 `images/`**，不要保存到 `generated-images/` 或其他全局文件夹\r\n   - 每个视频项目有独立的资产库，确保资产和脚本的对应关系清晰\r\n\r\n8. **生成顺序（优先图生图策略）**：\r\n   - 第一步：生成**全身照4种**（front / side / back / 3quarter）\r\n     - 使用 **文生图**（白色纯色背景，全身从头到脚含靴子）\r\n     - 优先用 Agnes AI\r\n   - 第二步：以4种全身照为参考图，**图生图**生成剩余7种资产：\r\n     - **face / face_details**：用 text-only 生成（img2img 会继承参考图背景/铠甲，纯脸图不适合）\r\n     - **head_angles / expressions**：以 front 图为参考，图生图\r\n     - **hands_feet / props**：以 front + side 图为参考，图生图\r\n     - **reference**：以全部4张为参考，图生图\r\n   - 第三步：生成场景空镜头（多角度）\r\n   - 第四步：生成首帧合成图（确定整体风格）\r\n   - 第五步：为**每个镜头**生成分镜首帧图，保存到 `images/storyboard/`\r\n   - 第六步：以 storyboard 图为参考图 + `video_prompt`，逐镜头图生视频\r\n\r\n   > 图生图使用 `project-generate` skill 自动上传到 GitHub raw 获取公网直链。\n\nFile v2.7.1:references/e2e-walkthrough.md\n\n# 端到端案例：锈甲天凤（34秒古风短剧）\r\n\r\n本文档展示 AI 视频流水线从飞书文档输入到最终成片的完整流程，以 **锈甲天凤** 项目为真实案例。\r\n\r\n> **路径说明**：本文档使用 `<skill-root>` 作为 skill 安装根目录的占位符（含 `SKILL.md` 的目录）。\r\n> 实际使用时，在 skill 根目录执行可省略前缀（如 `python3 scripts/create_project.py ...`），\r\n> 或在项目目录下使用完整路径（如 `python3 <skill-root>/skills/project-generate/scripts/project_generate.py ...`）。\r\n> 详情参见 `scripts/_paths.py` 的三层路径模型。\r\n\r\n---\r\n\r\n## 第 1 步：飞书文档输入\r\n\r\n用户在飞书写需求文档，标题格式：`【AI视频】【短剧】锈甲天凤`\r\n\r\n文档内容（精简版）：\r\n```\r\n标题：锈甲天凤\r\n类型：古风短剧\r\n时长：34秒\r\n画幅：9:16（竖屏）\r\n角色：\r\n  - 墨雪（明龙国女元帅，冷冽沉稳）\r\n  - 墨将（年轻副将，忠诚活泼）\r\n场景：龙南战场、城楼议事堂、城墙之上\r\n剧情：敌军压境，墨雪与墨将在议事堂密议破敌之策...\r\n```\r\n\r\n## 第 2 步：视频类型路由\r\n\r\nAI 视频流水线检测到文档标题包含 `【AI视频】【短剧】`：\r\n\r\n```json\r\n{\r\n  \"type\": \"短剧\",\r\n  \"project_name\": \"锈甲天凤\",\r\n  \"project_dir\": \"$HOME/WorkBuddy/锈甲天凤/\"\r\n}\r\n```\r\n\r\n加载 `references/types/短剧.md` 中的类型规则。\r\n\r\n## 第 3 步：创建项目目录\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython3 scripts/create_project.py \\\r\n  --project \"$HOME/WorkBuddy/锈甲天凤\" --template short_drama\r\n```\r\n\r\n自动创建 13 个标准目录并写入 `script.json` 模板。\r\n\r\n创建后的结构：\r\n```\r\n$HOME/WorkBuddy/锈甲天凤/\r\n├── script.json          (模板)\r\n├── images/characters/   (角色资产)\r\n├── images/scenes/       (场景资产)\r\n├── images/storyboard/   (分镜首帧图)\r\n├── images/style/        (风格参考)\r\n├── images/props/        (道具资产)\r\n├── videos/              (视频片段)\r\n├── output/              (最终输出)\r\n├── sounds/              (音效/配乐)\r\n├── assets/              (资产清单)\r\n├── prompts/             (提示词文件)\r\n├── references/          (原始需求)\r\n├── scripts/             (快捷入口)\r\n└── tasks/               (任务追踪)\r\n```\r\n\r\n## 第 4 步：生成脚本 JSON\r\n\r\nAI 视频流水线根据需求文档生成 `script.json`，包含角色卡、场景卡和分镜表。\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"title\": \"锈甲天凤\",\r\n    \"duration_seconds\": 34,\r\n    \"aspect_ratio\": \"9:16\",\r\n    \"type\": \"短剧\",\r\n    \"provider\": \"agnes\"\r\n  },\r\n  \"character_cards\": [ /* 墨雪 + 墨将 */ ],\r\n  \"scene_cards\": [ /* 龙南战场 + 城楼议事堂 + 城墙之上 */ ],\r\n  \"shots\": [ /* 9 个镜头 */ ],\r\n  \"shot_groups\": [ /* 3 组镜头 */ ]\r\n}\r\n```\r\n\r\n## 第 5 步：生成角色资产\r\n\r\n```bash\r\ncd \"$HOME/WorkBuddy/锈甲天凤\"\r\n\r\n# 一键生成所有角色（标准 4 视图：正面全身 / 面部 / 侧面 / 背面；另按武器·动作动态生成持械与动作视图，数量随角色卡而定）\r\n# <skill-root> 为 skill 安装根目录（含 SKILL.md），请替换为实际路径\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-characters\r\n# 别名：gc\r\n```\r\n\r\n## 第 6 步：生成场景资产\r\n\r\n```bash\r\n# 每场景 3 张变体（广角/中景/特写）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-scenes\r\n# 别名：gs\r\n```\r\n\r\n## 第 7~8 步：生成首帧图\r\n\r\n```bash\r\n# 初始化各 shot 的 first_frame 配置和 prompt 模板（不调 API）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . build-first-frames\r\n# 别名：bff\r\n\r\n# 调 API 批量生成首帧图\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-images\r\n# 别名：gi\r\n```\r\n\r\n## 第 9 步：提交 + 轮询 + 拼接\r\n\r\n```bash\r\n# 提交所有 shot 视频任务（自动按 provider 路由：Agnes / 小云雀）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . submit\r\n\r\n# 轮询完成状态，全部完成后自动触发 ffmpeg 拼接\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . poll\r\n\r\n# 查看项目总状态\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . status\r\n```\r\n\r\n## 全自动模式\r\n\r\n以上第 5~9 步可合并为一条命令：\r\n\r\n```bash\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . auto\r\n\r\n# 本地追踪模式（不依赖飞书）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . auto --tracker local\r\n```\r\n\r\n`auto` 自动执行：角色资产 → 场景资产 → 首帧图 → 提交 → 轮询 → 拼接。\r\n\r\n---\r\n\r\n## 完整流程图\r\n\r\n```\r\n飞书需求文档\r\n    │\r\n    ▼\r\n[1] 类型路由 ── 检测【AI视频】【短剧】→ 加载短剧规则\r\n    │\r\n    ▼\r\n[2] 创建项目 ── create_project.py\r\n    │\r\n    ▼\r\n[3] 生成 script.json ── 角色卡 + 场景卡 + 分镜（AI 驱动）\r\n    │\r\n    ──── 切换到 project-generate 流水线 ────\r\n    │\r\n    ▼\r\n[4] 角色资产 ── gc（每角色视图数随角色卡而定）\r\n    │\r\n    ▼\r\n[5] 场景资产 ── gs（每场景 3 张）\r\n    │\r\n    ▼\r\n[6] 首帧配置 ── bff\r\n    │\r\n    ▼\r\n[7] 首帧图生成 ── gi\r\n    │\r\n    ▼\r\n[8] 视频提交 ── submit（按 provider 路由）\r\n    │\r\n    ▼\r\n[9] 轮询 + 拼接 ── poll（ffmpeg 自动拼接）\r\n    │\r\n    ▼\r\n[10] 交付 ── output/final.mp4\r\n```\r\n\r\n**快捷方式**：`create_project.py` → `auto`，2 个命令走完全流程。\n\nFile v2.7.1:references/editing-specs.md\n\n# 剪辑与包装规范\n\n本文件提供字幕、转场、片头片尾的完整规范，由主 SKILL §8 抽取而来。\n\n---\n\n## 字幕规范\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| **字体大小** | 36px（9:16竖屏）/ 28px（16:9横屏） | 对白主体，保证可读性 |\n| **情绪/标题字号** | 48px | 情绪字幕（如\"三年后\"\"三日后\"） |\n| **底部留白** | 距底部 60px | 不遮挡人物面部或关键视觉区域 |\n| **字体** | 思源黑体 / Noto Sans SC（粗体） | 中文字体，清晰无衬线 |\n| **字体颜色** | 白色 #FFFFFF | 带 0.3 透明度黑色描边保证在任何背景可读 |\n| **停留时间** | 朗读时间 + 0.5秒（缓冲） | 确保读完不抢切 |\n| **行数限制** | ≤ 2行（9:16竖屏）；≤ 3行（16:9横屏） | 避免画面被字幕遮挡过多 |\n| **最长单行** | ≤ 18字（9:16竖屏）；≤ 30字（16:9横屏） | 保证单行阅读舒适度 |\n\n- **对白字幕**：底部居中，不得遮挡面部表情\n- **情绪字幕**（如\"三年后\"）：可用艺术字，配合转场\n- **字幕入场动画**：淡入（默认 0.2s）→ 停留 → 淡出（默认 0.2s）\n\n---\n\n## 音效与转场\n\n| 转场 | 默认时长 | 用法 | 适用场景 |\n|------|---------|------|---------|\n| **硬切** | 0s | 标准叙事过渡 | 90%以上的转场 |\n| **叠化** | 0.3s（叙事）/ 0.5s（情绪过渡） | 时间跳转或情绪过渡 | 场景变换、记忆/闪回 |\n| **闪白** | 0.15s（闪回）/ 0.3s（强烈冲击） | 强烈情绪冲击或记忆 | 惊讶、顿悟、回忆切入 |\n| **黑场** | 0.5-1.0s | 悬念停顿 | 留给观众思考的空间 |\n\n**音画先行规则**：下一个镜头的音效/对白应提前 0.5s 进入当前镜头的尾部。\n\n**转场混合建议：**\n\n| 场景类型 | 推荐转场 | 备注 |\n|----------|---------|------|\n| 同场景同组间 | 硬切（0s） | 保持连续性 |\n| 场景切换 | 叠化（0.3s） | 让观众感知空间变化 |\n| 时间跳转 | 叠化（0.5s） | 较长的叠化暗示时间流逝 |\n| 记忆/梦境切入 | 闪白（0.15s） | 快速鲜明地切换语境 |\n| 悬念/高潮后 | 黑场（0.5s） | 给观众呼吸空间 |\n\n---\n\n## 片头/片尾\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| **钩子出现时间** | 前 3s 内 | 片头必须在此时间内出现核心冲突/反差/高能对白 |\n| **片头标题停留** | 1.5s | 标题字幕或LOGO动画的展示时间 |\n| **片头缓冲** | 0.3s（淡入） | 视频起始从黑场淡入到第一帧 |\n| **片尾停留** | 2.0s | 最后镜头结束后停留画面，叠加片尾字幕 |\n| **片尾缓冲** | 0.5s（淡出） | 画面淡出到黑场 |\n| **片尾钩子** | \"关注/续看引导\" 2.0s | 引导语或预告画面的停留时间 |\n\n- **片头**：3秒内出现核心冲突或钩子，不铺陈。建议用硬切入画或淡入+音效甩入\n- **片尾**：埋下钩子或情绪余韵，引导续看/互动。建议用叠化+尾声音乐淡出\n\nFile v2.7.1:references/pacing-narrative.md\n\n# 节奏控制与叙事结构参考\n\n本文件提供节奏曲线和叙事结构的完整参考，由主 SKILL §7.8-§7.9 抽取而来。\n\n---\n\n## 节奏控制曲线\n\n所有叙事类视频应遵循情绪节奏曲线。平淡、单调的节奏是常见的质量陷阱。\n\n**情绪曲线模板：**\n```\n情绪强度\n   ▲\n高 │      ╱╲  高潮/释放\n   │     ╱  ╲\n中 │────╱    ╲────  转折/冲突\n   │   ╱      ╲\n低 │──╱        ╲──  建置/解决\n   └──────────────────▶ 时间\n      建置  冲突  高潮  收尾\n```\n\n**阶段时长指南：**\n\n| 阶段 | 镜头节奏 | 情绪任务 | 时长占比 |\n|------|---------|---------|---------|\n| **建置/铺垫** | 舒缓，稍长镜头 | 建立世界，制造好奇/悬念 | 15-20% |\n| **转折/冲突** | 加快，短镜头交替 | 引入冲突，推动变化 | 10-15% |\n| **高潮** | 最紧凑，特写密集 | 情绪爆发，爽点/释放 | 20-25% |\n| **钩子** | 突然放缓/定格 | 制造好奇，引导续看 | 5-10% |\n| **收尾** | 舒缓收尾 | 情绪缓冲，余韵留白 | 5-10% |\n\n**应用曲线：**\n- 在 `script.json` 中，规划镜头时长以匹配曲线（不是所有5秒都相等）\n- 用 `\"is_climax\": true` 标记高情绪镜头\n- 在情绪峰值后插入0.5秒填充（`\"padding_after\": 0.5`）\n- 对于多组脚本，每组应有自己的迷你曲线\n\n---\n\n## 叙事结构指南\n\n不同视频类型使用不同的叙事结构。一般原则是**因果逻辑**（因为→所以）而不是**时间顺序**（然后→然后）。\n\n### 三幕式结构（适用于大多数叙事视频）\n\n| 幕 | 占比 | 功能 | 核心任务 |\n|---|------|------|---------|\n| **第一幕：建置** | ~25% | 建立世界、引入角色、埋下钩子 | 让观众\"想知道\" |\n| **第二幕：对抗** | ~50% | 升级冲突、角色挣扎、情绪积累 | 让观众\"感同身受\" |\n| **第三幕：解决** | ~25% | 高潮、反转、余韵 | 让观众\"意犹未尽\" |\n\n### 四幕式结构（适用于文旅/纪录片）\n\n| 幕 | 功能 | 节奏 |\n|----|------|------|\n| **开篇** | 引人入胜的建立，激发兴趣 | 舒缓 |\n| **展开** | 深入展示，旁白叙事驱动 | 中速 |\n| **体验** | 沉浸式展示，视听高潮 | 紧凑 |\n| **升华** | 情感升华，留有余韵 | 舒缓 |\n\n### 观众距离金字塔（情绪节奏框架）\n\n观众的沉浸感按以下层级递进：\n```\n        ▲ 爽点（情绪爆发/满足/反转）\n       ╱ ╲\n      ╱ 共鸣 ╲（与角色共情，代入情感）\n     ╱─────────╲\n    ╱   代入    ╲（进入角色视角，关心命运）\n   ╱───────────────╲\n  ╱     悬念        ╲（产生好奇心，想知道后续）\n ╱─────────────────────╲\n```\n\n**应用规则**：\n- 开场必须制造**悬念**（问题/冲突/反常）\n- 前1/3让观众**代入**角色处境\n- 中1/3建立**共鸣**，让观众与角色共情\n- 高潮和结尾提供**爽点**（反转/满足/释放）\n\n### 悬念推进机制\n\n悬念应层层递进，而不是一次性抛出：\n\n1. **设悬** — 提出问题或展示反常（\"她为什么哭？\"）\n2. **布疑** — 给出线索但引向歧途（\"看起来是他伤害了她\"）\n3. **加深** — 增加压力或时间限制（\"她发现真相后必须在两者之间抉择\"）\n4. **揭晓** — 反转或真相揭示（\"原来一切都是为保护她\"）\n5. **余波** — 释放后的情绪缓冲（0.5-1秒填充）\n\n---\n\n## 避坑原则（通用）\n\n| 坑 | 说明 | 避免方法 |\n|---|------|---------|\n| **工具人陷阱** | 只执行技术生成，不做审美判断 | 每个镜头问：这服务于什么情绪？ |\n| **信息过载** | 一个镜头塞入太多信息 | 一个镜头只传达一个核心信息 |\n| **节奏平铺** | 从头到尾一个速度 | 必须有快-慢-快的节奏变化 |\n| **景别单一** | 全是中景或全是特写 | 强制使用景别交替 |\n| **忽略留白** | 镜头之间没有气口 | 情绪高点后留0.5-1秒缓冲 |\n| **为了炫技** | 运镜花哨但干扰叙事 | 运镜必须服务于剧情，不抢戏 |\n\nFile v2.7.1:references/prompt-rules.md\n\n# Prompt 工程规则（实战踩坑）\n\n> **本文职责**：记录从实际生成中总结的**实战踩坑规则**——角色描述、背景控制、武器道具、一致性保障、错误模式等。\n> **模板结构**（6 段式、语言选择）→ 主 SKILL.md §6\n> **资产生成**（角色 11 视图的具体 prompt）→ `references/asset-generation.md`\n\n---\n\n## 1. 角色外貌描述\n\n### 1.1 头发/头饰\n\n- **必须具体**：不能写\"传统头巾\"\"经典发型\"——模型会自由发挥\n- **写法**：颜色 + 位置 + 系法/样式\n  - ✅ `\"额头缠绕客家蓝染头巾，在前额上方打结固定\"`\n  - ❌ `\"戴客家传统头巾\"`\n  - ✅ `\"灰蓝色红军八角帽，帽檐微微上翘，正中缀红五星\"`\n  - ❌ `\"红军帽\"`\n\n### 1.2 同一角色的外貌描述必须跨视图统一\n\n- `hair` 字段被 `_clothes` 变量共享 → 所有视图的服饰描述一致\n- `face` 视图的 prompt 不应包含 `_clothes`（含 body/build/color 等全身级描述），否则模型把面部特写画成全身照\n- face 视图应只含：`fd_str`（五官细节）+ `hair`（发型/头饰）+ `base`（身份）+ `face`（面容）+ `_white_bg`\n\n---\n\n## 2. 背景控制\n\n### 2.1 纯白背景\n\n- 背景指令必须放在 prompt **开头和末尾**双重强调\n  - 开头：`\"纯白色背景。{视图描述}...\"`\n  - 末尾：`\"...{_white_bg}\"`\n- `_white_bg` 内容：`\"纯白色背景(#FFFFFF)，没有任何颜色、纹理或环境元素，只有纯空白底。\"`\n- 负面提示词必须包含：`\"暖色背景, 灰色背景, 米色背景, 有颜色的背景, 背景光, 复杂背景, 渐变背景, 纹理背景, 环境元素, 场景, 天空, 地面\"`\n- 原因：模型倾向自动填充浅色背景（浅灰/米色），即使 prompt 写了纯白也可能忽略\n\n---\n\n## 3. 武器和道具控制\n\n### 3.1 标准视图禁止武器\n\n- front/face/side/back 四视图：必须包含 `_no_weapon` + `_neg_weapons`\n  - `_no_weapon`：`\"双手自然垂下，手中不持任何武器，不能有剑、枪、刀、弓、盾等任何武器道具。\"`\n  - `_neg_weapons`：`\"手中持剑, 手中持枪, 手持武器, 握剑, 握刀, 武器, 道具, ...\"`\n\n### 3.2 武器视图\n\n- action_xxx / pose_xxx 视图：**不能**包含 `_no_weapon`（与武器描述矛盾）\n- 武器视图也需共享 `_clothes` 以确保衣着一致\n\n---\n\n## 4. 一致性保障\n\n### 4.1 跨视图一致性\n\n| 规则 | 说明 |\n|------|------|\n| 衣着统一 | front/side/back 共享 `_clothes` 变量（face 不用，避免 body 侵入）|\n| 面部统一 | face/side/back 以 front（全身正面无武器白底图）为 ref_image |\n| 背景统一 | 所有标准视图 + 武器/动作视图统一用 `_white_bg` |\n| 武器统一 | 标准视图禁用武器，武器视图没有 `_no_weapon` |\n| 发型/头饰统一 | `hair` 字段跨视图共享，必须具体到颜色+位置+系法 |\n\n### 4.2 ref_image 的选择\n\n- face/side/back 的 ref_image = front（标准四视图使用前视图保持一致性）\n- 武器视图：不设 ref_image（free generation），因为 ref_image 是无武器白底图，与武器 intent 冲突\n- 避免路径通配符回退：**不要从目录级别的通配符读取 ref_image**，只使用本角色前视图的具体路径\n\n### 4.3 画质描述不硬编码铠甲\n\n- [画质要求] 段中的\"铠甲金属质感\"不能硬编码——项目可能是现代题材（无铠甲）\n- 代码中根据 `character_cards` 的 `armor/clothing` 字段自动检测：包含\"铠甲/铁甲/甲胄/战甲\"等关键词才追加\n- 无铠甲时默认只写：`\"电影级写实，服装材质细节，光影层次丰富，氛围情绪饱满。\"`\n\n### 4.4 纯场景镜头不要写\"加入各角色\"\n\n- **纯场景镜头（只有 1 张场景参考图）**：编辑指令不能写\"在场景中加入各角色\"——模型会脑补古人\n- 代码中根据 `ref_count` 自动判断：仅 1 张参考图时，编辑指令改为 `以图1为基础，{desc}`，去掉\"加入角色\"\n- 这个规则也影响了 [保留元素] 段——**已完全禁用 [保留元素]**（无论几张参考图都不加，因为会导致角色朝向被参考图锁定）\n\n### 4.5 构图必须指定角色空间位置\n\n- 含角色的镜头（尤其是多角色），description 必须描述 **前/中/背景 + 左/右位置**\n  - ✅ `\"客家老人坐在左侧长椅上看报，现代青年从右侧跑步经过\"`\n  - ❌ `\"青年与老人相视而笑\"`（模型不知道人放哪里）\n- 全景+人物镜头：前景=人物站位，中景=城市/场景，背景=天空/远景\n\n### 4.6 角色行为必须匹配身份\n\n- video_prompt 和首帧图 prompt 中角色行为必须符合其身份特征：\n  - ❌ 客家老人在城市公园看报（客家老人是传统文化守护者，不会出现在城市）\n  - ❌ 古代角色穿T恤、现代角色穿铠甲\n  - ❌ 老者做敏捷动作（除非角色卡明确写了）\n- 验证方法：写完 description 后，问自己\"这个角色真的会做这件事吗？\"\n\n---\n\n## 5. 常见错误模式\n\n| 错误 | 现象 | 根因 | 修复 |\n|------|------|------|------|\n| face 画成全身照 | face 视图是全身而非特写 | face prompt 末尾拼了 `_clothes`（含 body/build/color）覆盖了\"面部特写\"指令 | face 只用 `fd_str` + `hair` + `base` + `face`，不用 `_clothes` |\n| 背景不是纯白 | 浅灰/米色背景 | 背景描述在 prompt 中间权重不足，被前面气氛词覆盖 | 开头+末尾双重强调 + 增强负面词 |\n| 头饰不一致 | 不同视图显式不同头饰 | `hair` 字段模糊（如\"传统头巾\"），模型自由发挥 | 描述精确到颜色+位置+系法 |\n| 人物有武器 | 标准视图手持武器 | 武器描述在 armor 字段中，被错误引入标准视图 | `_armor_clean` 剥离武器关键词 + `_no_weapon` + `_neg_weapons` |\n| 脚部被截断 | 脚踝以下被裁切 | prompt 缺少明确的全身指示 | 加 `_full_body`：`\"包含鞋子的完整全身从头到脚，不能截断脚部。\"` |\n| feishu_doc_id 为空 | poll 显示\"无项目数据\" | `script.json` 没配 `feishu_doc_id`，飞书查询按空 doc_id 过滤 | `create_project.py` 已自动填充；手动创建时检查 `script.feishu_doc_id` 是否从 URL 提取 |\n\n---\n\n## 6. 生成模式选择\n\n### 6.1 默认使用 standard 模式\n\n- **所有视频生成默认使用 `standard` 模式**（首帧合成图作参考 + video_prompt 驱动的动态视频）\n- 流程：`bff`（构建首帧配置）→ `gi`（生成首帧合成图）→ `submit`（standard 模式提交视频）\n- 即使是多角色/场景+人组合，也应先生成合成首帧图（场景+角色合为一张），再用 `standard` 模式\n\n### 6.2 multi-image 模式的定位\n\n`multi-image` 模式是**多张参考图之间的过渡动画**，不是真正的场景视频合成。它只适用于纯视觉过渡效果，不适用于需要角色动作/剧情推进的场景。\n\n- ❌ 不用于常规视频生成（效果是\"图A渐变到图B\"的动画）\n- ✅ 仅用于特殊的纯过渡/风格变换场景\n\n### 6.3 参考图完整性\n\n- 如果使用了 `multi-image` 模式：至少需要 2 张参考图，否则提交失败\n- 参考图路径必须指向**实际存在的文件**\n- 三种资产类型的依赖关系：\n\n```\ncharacter_cards → auto阶段3 → images/characters/{name}_front.png\ntroop_cards     → auto阶段4 → images/troops/{name}_front.png\nscene_cards     → auto阶段5 → images/scenes/{name}_宽高.png\n```\n\n> `troop_cards` 是\"辅助资产卡\"——可包含道具、军队、武器、群众等。\n\n### 6.4 引用了就一定要生成\n\n- shot 的 `reference_images` 中用到的所有资产路径必须确保文件存在\n- 不会自动回退\n\n---\n\n## 7. 常见运行错误\n\n### 7.1 GitHub 图片缓存不更新\n\n- `image_api.upload_to_url()` 检测到文件在 GitHub 上已存在时，**不会比较 SHA**，直接返回旧 URL\n- 即使本地首帧图已重新生成，传给 Agnes API 的参考图 URL 还是旧的\n- 修复：比较本地 SHA 与远程 SHA，不同则上传新版本\n- **定性**：视频内容\"看起来一样\"时，优先检查 GitHub 上参考图 URL 指向的图片是否已更新\n\n### 7.2 模块 import 路径被覆盖\n\n- `audio.py` 用 `from config import get_freesound_key`，但 `sys.modules[\"config\"]` 可能已被 agnes-ai 的 config 模块覆盖（通过 `_agnes_mod()` 注入）\n- 此时 `from config import xxx` 会拿到 agnes-ai 的 config，缺少项目级 config 的函数\n- 修复：不用顶层 import，改为通过 `_shared_tools` 统一配置读取（走 Layer 2 优先级链）\n- **定性**：项目级模块（`project-generate/scripts/modules/`）不要用 `from config import`，改用 `from modules.config import` 或直接读取配置\n\n### 7.3 lark-cli 在 subprocess 中找不到\n\n- `feishu.py` 的 `_lark()` 通过 `subprocess.run` 调用 `lark-cli.cmd`\n- 在 Windows nohup 环境下，`.cmd` 批处理文件可能无法被 `subprocess.run` 正确执行\n- 手动在 Bash 中跑 `lark-cli` 能成功，但 Python `subprocess.run` 静默失败\n- **后果**：飞书 Base 写入（`upsert_task`）静默失败，poll 找不到记录，但提交者以为成功了\n- 修复：加 `shell=True` 或用 `\"cmd\" \"/c\"` 前缀（注意参数长度限制）\n- 变通：通过 Bash 工具手动执行 `lark-cli base +record-upsert` 插入记录\n\n### 7.4 轮询死循环：旧记录不删 + 新记录写不回\n\n这是 7.3 的连锁后果：\n\n```\n1. submit 创建新任务 → upsert_task(lark-cli) 失败 → 飞书无新记录\n2. 飞书里只有旧记录（有旧 task_id，已过期/HTTP 400）\n3. poll 轮询 → 按旧 task_id 查 Agnes API → 400 → 触发重试\n4. 重试提交新任务 → 新任务完成 ✅ 但 upsert_task 又失败了\n5. 回到步骤 3 → 死循环 🔄\n```\n\n**判断标准**：\n- poll log 持续显示 `🔴 重试提交成功` 但任务状态一直是\"queued\"\n- 飞书 Base 记录数不变（全是旧记录）\n- 手动查 Agnes API 发现新 task_id 其实已完成\n\n**修复**：\n1. 查 Agnes API 获取最新已完成的任务 ID\n2. 手动用 `lark-cli base +record-upsert` 插入正确记录\n3. 删掉旧记录\n4. 修复 lark-cli subprocess 问题（见 §7.3）\n\n### 7.5 FeishuTracker 本地缓存兜底\n\n- `FeishuTracker.upsert_task()` 始终**优先写入本地 JSON 缓存**（`tasks/task_tracker_fallback.json`），再写飞书 Base\n- 飞书写入失败时打印 `⚠️ 飞书写入失败` 日志，但数据不丢（本地缓存保底）\n- `list_tasks()` 读取飞书后，用本地缓存**覆盖** task_id 和 status\n- 即使飞书完全不可用，重试也不进死循环\n\n### 7.6 原子化重试流程\n\n重试视频任务的三步流程：\n\n| 步骤 | 操作 | 关键点 |\n|------|------|--------|\n| 1 | `upsert_task(\"\", \"pending\")` | 清空旧 task_id，状态→pending，写入本地缓存 |\n| 2 | `provider.submit_video(...)` | 提交新任务 |\n| 3 | `upsert_task(new_task, \"queued\")` | 写回新 task_id，状态→queued |\n\n即使步骤 1/3 飞书写入失败，本地缓存确保下次 poll 读到正确数据。\n\n---\n\n## 8. BGM 管理\n\n### 8.1 自定义 BGM 优先\n\n- `sounds/bgm_custom.mp3` 存在时**优先使用**，跳过 FreeSound 自动搜索\n- 不存在时回退到 FreeSound 搜索（按 `script.tone` → 关键词 → 搜索 → 下载预览）\n\n### 8.2 多段 BGM 拼接\n\n- 可用 ffmpeg 将多段音乐拼接成自定义 BGM，匹配视频的叙事段落\n- 每段用 `atrim` 截取所需长度，`acrossfade` 做交叉淡入淡出过渡\n- 示例（三段式：史诗→传统→希望）：\n  ```\n  [0:a]atrim=0:15[seg1];[1:a]atrim=0:10[seg2];[2:a]atrim=0:15[seg3]\n  [seg1][seg2]acrossfade=d=1.0[mix1];[mix1][seg3]acrossfade=d=1.0[final]\n  ```\n\n### 8.3 推荐套索来源\n\n| 来源 | 协议 | 说明 |\n|------|------|------|\n| FreeSound (freesound.org) | CC0/CC | 已内置 API 支持，自动搜索+下载 |\n| Pixabay Music | Pixabay License | 免费可商用，直接下载 MP3 |\n| FreePD (freepd.cn) | CC0 | 公共领域，无需署名 |\n\n---\n\n## 9. Windows ffmpeg 避坑\n\n### 9.1 禁用 xfade 转场\n\n- **Windows 上 xfade + acrossfade 链式叠加有音视频时间轴漂移问题**\n- 漂移随转场次数累积，7 段拼接时约在 27s 处出现画面卡死\n- 修复：禁用 xfade，全用简单 concat（`-f concat -safe 0 -c copy`）\n- 简单 concat 帧级精确，无漂移风险\n- `shot_durations()` 计算镜头开始/结束时间时**不加 xfade 重叠**\n\n### 9.2 像素格式必须指定\n\n- `subtitles` 滤镜或某些 filter graph 在 Windows 上默认输出 `yuv444p`\n- `yuv444p` 不被部分播放器支持 → 画面黑屏/无法播放\n- 修复：所有 ffmpeg 输出加 `-pix_fmt yuv420p`\n\n### 9.3 subtitles 滤镜中文路径问题\n\n- Windows 上 libass 对中文路径支持不好，`subtitles` 滤镜可能导致 ffmpeg 退出码 4294967274\n- 修复：复制 SRT 到纯 ASCII 临时路径（`C:\\Users\\...\\cb_xxxx\\subs.srt`），在 filter_complex 中引用\n- filter_complex 方式：在 filter_complex_script 末尾追加 `;[0:v]subtitles='path'[vsub]`，输出映射改为 `[vsub]`\n\n### 9.4 音频采样率冲突\n\n- FreeSound 预览 BGM 通常是 24000Hz mono，TTS 输出也是 24000Hz mono\n- amix 混合后默认输出可能保持 24000Hz，但视频标准是 48000Hz stereo\n- 修复：`-ar 48000 -ac 2` 强制输出 48kHz 立体声\n\n---\n\n## 10. TTS 与字幕\n\n### 10.1 edge-tts 不支持 SSML\n\n- `edge_tts.Communicate(ssml, voice)` 不解析 SSML 标签，直接**朗读 XML 标签内容**\n- 导致 TTS 时长飙升至 30s+（在念 \"speak version 1.0 xmlns\"）\n- 修复：始终使用纯文本调用 `edge_tts.Communicate(text, voice).save(path)`\n- 如需控制停顿，在原始文本中加入标点符号（edge-tts 会自然停顿）\n\n### 10.2 字幕时长与实际 TTS 同步\n\n- 字幕结束时间使用 `_wav_duration()` 读取 WAV 实际时长，而不是字符数估算\n- `_char_per_sec()` 作为回退（读取失败时使用）\n- 字幕文本去掉/替换标点符号为空格：\n  - 句末（。！？）→ 两个全角空格\n  - 句中（，、：；）→ 一个全角空格\n\nArchive v2.7.0: 81 files, 356147 bytes\n\nFiles: CHANGELOG.md (15441b), config/config.toml (950b), config/keys.example.env (1030b), pipeline-diagram.svg (6629b), README.md (5257b), references/asset-generation.md (23311b), references/e2e-walkthrough.md (5967b), references/editing-specs.md (2995b), references/pacing-narrative.md (4229b), references/prompt-rules.md (14080b), references/provider-config.md (2838b), references/repair-strategy.md (6104b), references/script-json-checklist.md (8375b), references/segment-design.md (7621b), references/setup-guide.md (5047b), references/shot-scales.md (9633b), references/templates.json (2058b), references/troubleshooting.md (7706b), references/types/default.md (2797b), references/types/文旅.md (8348b), references/types/电影级长剧.md (10432b), references/types/短剧.md (17793b), references/video-modes.md (3256b), requirements.txt (72b), sample/README.md (1122b), sample/script.json (1884b), scripts/_paths.py (9045b), scripts/_shared_tools.py (11192b), scripts/create_project.py (6567b), scripts/make_ref_board.py (5943b), scripts/stitch_face_details.py (3029b), skill-card.md (2914b), SKILL.md (14259b), skills/agnes-ai/scripts/generate_image.py (6085b), skills/agnes-ai/scripts/generate_video.py (5936b), skills/agnes-ai/scripts/modules/__init__.py (1031b), skills/agnes-ai/scripts/modules/api.py (428b), skills/agnes-ai/scripts/modules/config.py (1959b), skills/agnes-ai/scripts/modules/image_api.py (13789b), skills/agnes-ai/scripts/modules/prompt.py (18323b), skills/agnes-ai/scripts/modules/video_api.py (12860b), skills/agnes-ai/SKILL.md (22673b), skills/project-generate/scripts/modules/agnes_provider.py (21502b), skills/project-generate/scripts/modules/audio.py (13763b), skills/project-generate/scripts/modules/base_provider.py (11183b), skills/project-generate/scripts/modules/config.py (4116b), skills/project-generate/scripts/modules/data_validator.py (3640b), skills/project-generate/scripts/modules/error_utils.py (5241b), skills/project-generate/scripts/modules/extract_module.py (14484b), skills/project-generate/scripts/modules/feishu.py (20554b), skills/project-generate/scripts/modules/hyperframes_stitch.py (20499b), skills/project-generate/scripts/modules/img_host.py (5785b), skills/project-generate/scripts/modules/launch_background.py (2778b), skills/project-generate/scripts/modules/project_commands/__init__.py (33587b), skills/project-generate/scripts/modules/project_diff.py (4687b), skills/project-generate/scripts/modules/project_preview.py (9296b), skills/project-generate/scripts/modules/project_stats.py (8004b), skills/project-generate/scripts/modules/project_status.py (11636b), skills/project-generate/scripts/modules/project_verify.py (88343b), skills/project-generate/scripts/modules/provider_factory.py (6653b), skills/project-generate/scripts/modules/script_generator.py (19609b), skills/project-generate/scripts/modules/speech.py (11629b), skills/project-generate/scripts/modules/stitch_base.py (2117b), skills/project-generate/scripts/modules/stitch_ffmpeg.py (13456b), skills/project-generate/scripts/modules/stitch.py (1381b), skills/project-generate/scripts/modules/task_tracker_feishu.py (14341b), skills/project-generate/scripts/modules/task_tracker_local.py (5394b), skills/project-generate/scripts/modules/task_tracker.py (2654b), skills/project-generate/scripts/modules/type_registry.py (5338b), skills/project-generate/scripts/modules/video_utils.py (17621b), skills/project-generate/scripts/modules/vlm_qa.py (16316b), skills/project-generate/scripts/modules/xiaoyunqiao_provider.py (19364b), skills/project-generate/scripts/pipeline.py (15304b), skills/project-generate/scripts/project_generate.py (19645b), skills/project-generate/scripts/type_defs/military.json (540b), skills/project-generate/SKILL.md (15782b), skills/script-optimizer/scripts/optimize/__init__.py (159208b), skills/script-optimizer/scripts/optimize/rules.py (5021b), skills/script-optimizer/scripts/prompt_builder.py (63949b), skills/script-optimizer/SKILL.md (2497b)\n\nFile v2.7.0:SKILL.md\n\n---\r\nname: ai-video-auto-generator\r\nversion: 2.7.0\r\ndescription: \"AI 短视频全自动流水线：从想法到成片，一键出视频。脚本生成→自动修复→资产生成→视频→音频→字幕，全自动无人值守。| AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated.\"\r\ncategory: video-generation\r\nplatforms:\r\n  - WorkBuddy\r\n  - QClaw\r\n  - ima\r\n  - Claude Code\r\n  - Cursor\r\ntags:\r\n  - video\r\n  - ai-video\r\n  - pipeline\r\n  - automation\r\n  - short-video\r\n  - tts\r\n  - subtitle\r\n  - script-generation\r\n---\r\n\r\n> 📖 **README**: `README.md` | **CHANGELOG**: `CHANGELOG.md`\r\n\r\n# ai-video-auto-generator\r\n\r\n将书面需求转换为结构化视频脚本，用于AI视频生成流水线。\r\n\r\n**目录**\r\n- <a href=\"#agent-mode\">🤖 Agent 使用模式（核心工作流）</a>\r\n- <a href=\"#quick-start\">⚡ Quick Start（4 路径出片）</a>\r\n- <a href=\"#architecture\">🏗️ 流水线架构</a>\r\n- <a href=\"#verification\">🔍 验证体系</a>\r\n- <a href=\"#self-healing\">🩹 自愈机制</a>\r\n- <a href=\"#cli\">🛠️ 流水线 CLI</a>\r\n- **参考文档**\r\n  - [端到端案例](references/e2e-walkthrough.md)\r\n  - [脚本生成检查清单](references/script-json-checklist.md)\r\n  - [Provider 配置](references/provider-config.md)\r\n  - [景别设计](references/shot-scales.md)\r\n  - [剪辑与包装](references/editing-specs.md)\r\n  - [节奏与叙事结构](references/pacing-narrative.md)\r\n  - [Prompt 工程规则](references/prompt-rules.md)\r\n  - [视频生成模式](references/video-modes.md)\r\n  - [环境搭建](references/setup-guide.md)\r\n  - [流水线排错](references/troubleshooting.md)\r\n  - [Segment 合并设计](references/segment-design.md) — 仅小云雀 Provider\r\n\r\n---\r\n\r\n<h2 id=\"quick-start\">⚡ Quick Start（4 路径出片）</h2>\r\n\r\n**🔥 尝鲜（30 秒出预览，无需 API Key）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n**💬 一句话生成视频（推荐，通过 AI Agent）：**\r\n```bash\r\n# 1. 在 WorkBuddy 中加载 ai-video-auto-generator skill\r\n# 2. 直接告诉 AI Agent 你的需求，例如：\r\n#    \"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n# 3. Agent 会自动：分析需求 → 生成 script.json → 跑流水线 → 出片\r\n```\r\n\r\n> 📌 **脚本生成已由 AI Agent 接管。** 之前的 `--mode generate` / `--prompt` 命令已废弃，保留入口但不再执行脚本生成。所有脚本生成直接在对话中完成。\r\n\r\n**📄 从文档生成视频（通过 AI Agent）：**\r\n```bash\r\n# 直接把文件/URL/飞书链接发给 AI Agent\r\n# Agent 会自动读取内容 → 生成 script.json → 跑流水线\r\n```\r\n\r\n**📦 从模板创建（手动编辑）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython scripts/create_project.py --project \"$HOME/WorkBuddy/我的视频\" --template short_drama\r\ncd \"$HOME/WorkBuddy/我的视频\" && python skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n> 详细说明见 `README.md`。\r\n\r\n---\r\n\r\n<h2 id=\"agent-mode\">🤖 Agent 使用模式（核心工作流）</h2>\r\n\r\n> **你提供需求，AI Agent（当前对话）帮你搞定一切。** 不需要手动调命令，直接说就好。\r\n\r\n### 如何与 Agent 配合\r\n\r\n| 你的输入 | Agent 自动执行 |\r\n|---------|---------------|\r\n| `\"帮我做一个军事短剧，紧张氛围\"` | ① 解析需求 → 生成 `script.json` → 写回项目目录<br>② 创建角色卡、场景卡、镜头列表<br>③ 运行 `--mode auto` 启动流水线 |\r\n| `\"从这篇文章生成视频\"` + 贴 URL | ① WebFetch 读取文章内容<br>② 分析角色/场景/情绪 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"从这份文档生成视频\"` + 上传文件 | ① Read 读取文档内容<br>② 提取关键信息 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"帮我优化这个脚本\"` + 贴 JSON | ① 读取当前 `script.json`<br>② 运行 `optimize` 命令（OptimizerV2）做 12 维叙事修复<br>③ 输出修复报告 |\r\n| `\"修一下 shot_05 的运镜问题\"` | ① 定位问题<br>② 修改 `script.json`<br>③ 通知验证结果 |\r\n\r\n### Agent 脚本生成规则（重要）\r\n\r\n当 Agent 为你生成 `script.json` 时，遵循以下标准：\r\n\r\n```\r\n📋 角色卡要求:\r\n  - 每个角色必须有 name / title / appearance（clothing/physique/face/features）\r\n  - appearance 要细化到发型、脸型、瞳色、肤色、体态、着装\r\n  - 每个角色至少 front + face 两个视图，主角加 side + back\r\n  - asset_background 固定为 \"white\"\r\n\r\n📋 场景卡要求:\r\n  - 每个场景有 name / description / views（广角/中景/特写）\r\n  - description 描述环境氛围（光线/色调/空间感/情绪）\r\n\r\n📋 镜头要求（最重要）:\r\n  - 每个镜头有 id / description / duration\r\n  - voice_over（旁白）和 dialogue（对白）根据以下规则填写：\r\n\r\n    voice_over 旁白（TTS 音频 + 字幕）:\r\n    ── 谁在说话: 非角色，解说/叙事者/内心独白\r\n    ── 适用 shot_type: 远景/广角/空镜/建立/转场/过渡\r\n    ── 视频是否自带声音: ❌ 不包含，需 TTS 生成\r\n    ── 写作要求: 用人类叙事语言，不能直接照搬 description\r\n        正确: \"硝烟弥漫的废墟战场上，周戎站在高处俯视着远方。\"\r\n        错误: \"周戎在画面远处，突然，废墟战场全景，硝烟弥漫，断壁残垣中周戎站在废墟高处俯视战场，广角远景\"\r\n    ── 生成后自检: voice_over 中不能有景别（中景/远景/特写/广角）、拍摄指令（俯拍/仰拍）、角色定位（\"在画面远处\"）\r\n    ── 标点规则: 用空格代替所有标点符号（逗号/句号/感叹号等），但需保证断句合理，方便 TTS 自然停顿\r\n        断句规则:\r\n        - 每个空格代表一次自然停顿，每段 5~10 个汉字为宜，便于 TTS 一口气读完\r\n        - 在完整语义单位后断句：场景描述后 / 动作完成后 / 人物出现后\r\n        - 禁止在修饰语和中心语之间断开（\"硝烟弥漫的\"和\"废墟战场\"之间不能断）\r\n        - 主语和谓语不断开（\"周戎站在高处\"不能断为\"周戎 站在高处\"）\r\n        - 动词和宾语不断开（\"俯瞰着整片战场\"不能断为\"俯瞰着 整片战场\"）\r\n        正确: \"硝烟弥漫的废墟战场上 断壁残垣间 周戎站在高处俯瞰着整片战场\"\r\n        错误: \"硝烟弥漫的 废墟战场上 断壁残垣间 周戎 站在 高处 俯瞰着 整片战场\"\r\n\r\n    dialogue 对白（仅字幕，视频已自带声音）:\r\n    ── 谁在说话: 屏幕上的角色在对话/独白/回应\r\n    ── 适用 shot_type: 中景/双人/过肩/反应/独白/近景\r\n    ── 视频是否自带声音: ✅ Agnes 视频已包含角色对话声\r\n\r\n    两者可共存: voice_over 放旁白，dialogue 放对白\r\n    两者都无: 纯画面镜头（动作/追逐/环境），无台词\r\n\r\n  - 每个镜头生成后必须做三选一检查：是否决定好了 voice_over / dialogue / 两者皆无\r\n  - 不允许出现: 镜头 ≥5 秒且 voice_over/dialogue 都为空，且 description 未描述动作/追逐内容\r\n\r\n  - description 包含: 景别 + 运镜 + 人物动作 + 环境 + 情绪\r\n  - ⚠️ **description 中涉及角色的地方必须使用角色卡中的全名或实词（如「君无烬（奶牛猫）」或「君无烬」），禁止使用「猫」「狗」「他」「她」「男子」「女子」「老人」等泛称代词。**\r\n  - 反例: 「猫吃得太急 不小心打了一个响亮的嗝」（「猫」是泛称，optimizer 无法匹配到具体角色）\r\n  - 正例: 「君无烬（奶牛猫）吃得太急 不小心打了一个响亮的嗝」\r\n  - 理由: optimizer 的 `_fix_shots` 靠文本匹配补全 characters 字段，泛称会绕过全部四种匹配规则（全名/实词/括号内容/逐字），导致角色缺失不被发现\r\n  - duration 3-8 秒，总时长控制在 60-120 秒\r\n  - 前 3 个镜头要有钩子（冲突/悬念/意外）\r\n  - 高潮镜头放在总时长的 70-85% 处\r\n  - 收尾镜头要有结局感\r\n\r\n📋 叙事结构:\r\n  - 开头抓人 → 展开 → 冲突升级 → 高潮 → 收尾\r\n  - 运镜要变化（不要连续 3+ 镜头同运镜）\r\n  - 情绪要有起伏（不要从欢快跳到悲伤）\r\n  - 对话和动作镜头比例合理（各不超过 70%）\r\n\r\n📋 流水线触发:\r\n  - script.json 写完后，自动执行 `pipeline.py --mode auto`\r\n  - 如果项目已有 task_tracker 且部分完成，auto 会自动从断点继续\r\n```\r\n\r\n### 快速命令\r\n\r\n```bash\r\n# Agent 一键出片（在对话中描述需求即可）\r\n# 上述步骤全部由 AI Agent 自动完成\r\n\r\n# 如果你需要手动查状态\r\ntail -f auto.log          # 查看流水线进度\r\n```\r\n\r\n---\r\n\r\n<h2 id=\"architecture\">🏗️ 流水线架构</h2>\r\n\r\n```\r\nAI Agent（你） → script.json → 9 阶段全自动流水线 → final.mp4\r\n\r\n阶段 0:   脚本优化（含 12 维叙事结构修复）\r\n阶段 1:   构建资产 prompt 文件\r\n阶段 2:   角色资产生成 + 6 维质量验证（55 分制）\r\n阶段 3:   辅助资产生成 + 质量验证\r\n阶段 4:   场景资产生成 + 人脸检测 + 风格检测\r\n阶段 5:   初始化首帧图\r\n阶段 6:   首帧图生成 + 50 分制验证\r\n阶段 7:   提交视频任务 + 验证 prompt\r\n阶段 8:   轮询完成 + 55 分制视频验证 + 拼接 + 音频 + 字幕\r\n\r\n全部阶段支持断点续跑。\r\n```\r\n\r\n<h2 id=\"verification\">🔍 验证体系</h2>\r\n\r\n| 资产 | 检查项 | 评分 |\r\n|------|--------|------|\r\n| 角色图 | 文件+模糊+人物=1+背景+全身+风格 | 55 分 |\r\n| 场景图 | Haar 人脸检测 + Canny 风格匹配 | pass/fail |\r\n| 首帧图 | 文件+比例+模糊+HOG人数+色彩 | 50 分 |\r\n| 视频 | 时长+比例+黑帧+光流运镜+情绪匹配 | 55 分 |\r\n\r\n<h2 id=\"self-healing\">🩹 自愈机制</h2>\r\n\r\n```\r\nfail → classify(5 categories) → strategy(soften/switch/backoff/regen) → capped retry(max 10)\r\n```\r\n\r\n<h2 id=\"cli\">🛠️ 流水线 CLI</h2>\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode setup       # 环境检测 + 自动装依赖 + 复制 Key 模板\r\npython skills/project-generate/scripts/pipeline.py --mode auto         # 全自动流水线（从中断继续）\r\npython skills/project-generate/scripts/pipeline.py --mode validate     # 预检（只验证不生成）\r\npython skills/project-generate/scripts/pipeline.py --mode demo         # 快速尝鲜（30 秒，无需 API Key）\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached  # 仅轮询\r\n\r\n# 项目级子命令（project_generate.py）\r\npython skills/project-generate/scripts/project_generate.py --project . status        # 结构化状态（默认 JSON，--text 人类可读）\r\npython skills/project-generate/scripts/project_generate.py --project . stitch --tracker local  # 单独跑拼接（不重新提交/轮询）\r\n```\r\n\r\n---\r\n\r\n## 参考文档\r\n\r\n- [端到端案例](references/e2e-walkthrough.md) — 从飞书文档到成片的完整流程\r\n- [脚本生成检查清单](references/script-json-checklist.md)\r\n- [Provider 配置](references/provider-config.md)\r\n- [景别设计](references/shot-scales.md)\r\n- [剪辑与包装](references/editing-specs.md)\r\n- [节奏与叙事结构](references/pacing-narrative.md)\r\n- [Prompt 工程规则](references/prompt-rules.md)\r\n- [视频生成模式](references/video-modes.md)\r\n- [环境搭建](references/setup-guide.md)\r\n- [流水线排错](references/troubleshooting.md)\r\n- [Segment 合并设计](references/segment-design.md) — 仅小云雀(xiaoyunqiao) Provider 需要\r\n\r\n---\r\n\r\n## English Quick Start\r\n\r\n> **AI video auto pipeline: from idea to final video, one command.**\r\n\r\n### How it works\r\n\r\nLoad this skill in WorkBuddy, then tell the AI agent what you want:\r\n\r\n```\r\n\"Create a short video about an ancient general waking up in a modern city\"\r\n\"Generate a video from this article\" + paste URL\r\n\"Turn this document into a video\" + upload file\r\n```\r\n\r\nThe agent will:\r\n1. Read and analyze your input\r\n2. Generate a complete `script.json` (characters, scenes, shots)\r\n3. Run `pipeline.py --mode auto` — fully automated pipeline\r\n4. Notify you when `final.mp4` is ready\r\n\r\n### Pipeline stages\r\n\r\n| Stage | Description |\r\n|-------|-------------|\r\n| 0 | Script optimization (incl. 12-dim narrative auto repair: hook/pacing/camera/emotion/closure) |\r\n| 1 | Build asset prompt files |\r\n| 2 | Character asset generation + 6-dim quality verification (55pt) |\r\n| 3 | Troop asset generation + verification |\r\n| 4 | Scene asset generation + face detection + style check |\r\n| 5 | Initialize first frames |\r\n| 6 | First frame generation + 50pt verification |\r\n| 7 | Submit video tasks + prompt verification |\r\n| 8 | Poll completion + 55pt video verification (camera motion/mood/black frames) + stitch + audio + subtitles |\r\n\r\nAll stages support resume from checkpoint (Ctrl+C / crash / shutdown).\r\n\r\n### CLI reference\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode setup       # Auto-install dependencies + copy API key template\r\npython skills/project-generate/scripts/pipeline.py --mode auto         # Full pipeline (resume from checkpoint)\r\npython skills/project-generate/scripts/pipeline.py --mode validate     # Pre-flight check (no generation)\r\npython skills/project-generate/scripts/pipeline.py --mode demo         # 30s preview, no API key needed\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached  # Poll only\r\n```\r\n\r\n### Known limitations\r\n\r\n- Requires API Key for AI generation (default: Agnes AI, free unlimited tier)\r\n- Windows prioritized (macOS/Linux not fully tested)\r\n- OpenCV ~50MB dependency (auto-installed via `--mode setup`)\r\n- No real-time progress bar (logs written to file in detach mode)\r\n\r\n### Reference docs\r\n\r\n- [Provider config](references/provider-config.md)\r\n- [Shot scales](references/shot-scales.md) (Chinese)\r\n- [Prompt rules](references/prompt-rules.md) (Chinese)\r\n- [Troubleshooting](references/troubleshooting.md) (Chinese)\n\nFile v2.7.0:skills/agnes-ai/SKILL.md\n\n---\r\nname: agnes-ai\r\nversion: 2.7.0\r\ndescription: >\r\n  纯生成层 skill。调用 Agnes AI 免费 API 生成图片和视频。\r\n  脚本路径为 `skills/agnes-ai/scripts/generate_image.py`\r\n  和 `skills/agnes-ai/scripts/generate_video.py`（相对于主 skill 根目录）。\r\n---\r\n\r\n# Agnes AI 纯生成 Skill\r\n\r\n通过 `scripts/generate_image.py` 生成图片、`scripts/generate_video.py` 生成视频。\r\n\r\n> 本 skill 是 `ai-video-auto-generator` 的子 skill。项目级编排命令在 `project-generate` 子 skill 中。\r\n\r\n---\r\n\r\n## 🚀 高频命令\r\n\r\n```bash\r\n# 文生图\r\npython3 scripts/generate_image.py \"一只猫\" --size \"1024x1024\" -o ./output\r\n\r\n# 图生图\r\npython3 scripts/generate_image.py \"描述提示词\" --ref-image /path/to/ref.png\r\n\r\n# 文生视频\r\npython3 scripts/generate_video.py \"古风战场\" --size \"9:16\" --duration 5s\r\n\r\n# 图生视频\r\npython3 scripts/generate_video.py \"缓慢推进\" --ref-image input.png --duration 5s\r\n```\r\n\r\n## 前置条件\r\n\r\n1. **注册获取 API Key**（免费无限制）：\r\n   - 访问 https://platform.agnes-ai.com 注册\r\n   - 登录后在后台创建 API Key\r\n   - 将 Key 写入 `~/.agnes-api-key`，或设环境变量 `AGNES_API_KEY`\r\n\r\n2. **Python 3** — 标准库即可，无需额外依赖。\r\n\r\n## 两个模型的分工\r\n\r\n| 模型 | 本质 | 适用场景 | 翻车点 |\r\n|-----|------|---------|-------|\r\n| **2.0 Flash**（多图合成） | 多张图融合成一张新画面 | 单角色静态、双角色无互动、特写、环境合成 | 可能脑补多余元素（凭空加人） |\r\n| **2.1 Flash**（参考图编辑） | 以第一张图为基底添加元素 | 需保留场景结构、精确动作控制、有交互 | 过于忠实原图 |\r\n\r\n### 选择规则\r\n- 单角色静态/特写 → **2.0 Flash**\r\n- 单角色精确动作（掀帘、推门） → **2.1 Flash**\r\n- 双角色无互动（背对、行礼、跪拜） → **2.0 Flash**\r\n- 双角色有互动（对视、对话、肢体接触） → **2.1 Flash**\r\n- **2.0 Flash 图生图不需要传 `tags: [\"img2img\"]`**\r\n\r\n### 实战验证\r\n| 场景 | 2.0 结果 | 2.1 结果 | 建议 |\r\n|------|---------|---------|------|\r\n| 墨雪站窗边 | ✅ 1人 | — | 2.0 |\r\n| 墨将推门 | ✅ 1人 | — | 2.0 |\r\n| 双角色同框 | ✅ 2人 | — | 2.0 |\r\n| 面部特写 | ✅ 1人 | — | 2.0 |\r\n| 掀帘子 | ❌ 变2人 | ✅ 1人 | 2.1 |\r\n| 互踢（互动） | — | ✅ | 2.1 |\r\n| 城墙眺望 | ❌ 场景错 | ✅ 正确 | 2.1 |\r\n\r\n## 图片生成 — 使用方法\r\n\r\n### 快速入门（单张图片生成）\r\n\r\n`generate_image.py` 是一个独立的单张图片生成工具，批量生成请走 `project-generate`：\r\n\r\n```bash\r\n# 单张图生图\r\npython3 scripts/generate_image.py \"提示词\" --ref-image \"参考图.png\" -o \"images/characters/\" --output-name \"角色名_front.png\"\r\n\r\n# 批量首帧图 → 请使用 project-generate\r\npython3 ../ai-video-auto-generator/skills/project-generate/scripts/project_generate.py --project . gi\r\n```\r\n\r\n### 完整参数\r\n\r\n**图片参数（`scripts/generate_image.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `prompt`（必填） | 图片描述提示词 |\r\n| `--model` | 默认 `agnes-image-2.1-flash` |\r\n| `--size` | 默认 `720x1280`，自动从 aspect_ratio 映射 |\r\n| `--n` | 数量（1-4） |\r\n| `--quality` | `standard` 或 `hd` |\r\n| `--output-dir` / `-o` | 保存目录 |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-images` | 多张参考图（空格分隔）|\r\n| `--output-name` | 输出文件名 |\r\n| `--seed` | 固定随机种子 |\r\n| `--negative-prompt` | 负面提示词 |\r\n| `--api-key` | API Key 文件路径 |\r\n| `--shot-id` | 从 script.json 的 first_frame 块解析参数，生成该 shot 的首帧图 |\r\n| `--project` | 项目根目录（--shot-id 模式需要）|\r\n| `--force` | 强制重新生成已存在的 first_frame 和模板 |\r\n| `--parallel` | 并发生成数（默认 auto）|\r\n\r\n**视频参数（`scripts/generate_video.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `--model` | 默认 `agnes-video-v2.0` |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-image-list` | 多张参考图路径 |\r\n| `--ref-image-urls` | 已上传的公网 URL |\r\n| `--num-frames` | 总帧数（8n+1，≤441），默认 121 |\r\n| `--frame-rate` | 帧率（1-60），默认 24 |\r\n| `--size` | 分辨率，默认 `1152x768` |\r\n| `--seed` | 固定种子 |\r\n| `--output-name` | 输出文件名 |\r\n| `--output-dir` / `-o` | 保存目录 |\r\n| `--api-key` | API Key 文件路径 |\r\n| `--mode` | 生成模式：standard / keyframes / multi-image / auto |\r\n| `--duration` | 目标时长（如 `5s`）|\r\n| `--poll-interval` | 轮询间隔（默认 15s）|\r\n| `--timeout` | 超时时间（默认 600s）|\r\n| `--submit-only` | 仅创建任务，打印 task_id 后退出 |\r\n| `--query-task` | 查询已有任务，若完成则下载 |\r\n\r\n### 两步工作流\r\n\r\n**第 1 步 — 初始化：**\r\n```bash\r\npython3 scripts/generate_image.py --project . --build-first-frames\r\n# 或强制重新生成\r\npython3 scripts/generate_image.py --project . --build-first-frames --force\r\n```\r\n自动完成：\r\n- 遍历所有 shot，从 `generation.reference_images` 解析参考图路径\r\n- 根据 shot 描述自动推荐模型（2.0 Flash / 2.1 Flash）\r\n- 写入 `first_frame` 块到 script.json\r\n- 对每个 shot 生成六段式提示词模板\r\n- **multi-image 模式**（如 shot_01）自动跳过\r\n- 已有 `first_frame` 的 shot 默认跳过（`--force` 覆盖）\r\n\r\n**第 2 步 — 单 shot 或批量生成：**\r\n```bash\r\n# 单 shot\r\npython3 scripts/generate_image.py --project . --shot-id 4\r\n\r\n# 批量\r\npython3 scripts/generate_image.py --project . --batch-generate\r\n\r\n# 指定范围\r\npython3 scripts/generate_image.py --project . --batch-generate --batch-shots \"2-9\"\r\n```\r\n\r\n### 基本调用\r\n\r\n```bash\r\npython3 scripts/generate_image.py \"描述提示词，保留角色特征\" \\\r\n  --ref-image \"/path/to/墨雪_front.png\" \\\r\n  --size \"1024x1024\" \\\r\n  -o \"/path/to/output\" \\\r\n  --output-name \"墨雪_表情.png\"\r\n```\r\n\r\n## 提示词结构（六段式）\r\n\r\n适用于 2.0 Flash / 2.1 Flash 图生图：\r\n\r\n```\r\n将N张参考图合成一张完整画面。\r\n\r\n[编辑指令] 参考图1为XX（场景基底）。参考图2为XX（角色A样式）。\r\n以图1为基底，在场景中加入角色A（位置/方向参考图2）。明确写\"无交互无对视\"。\r\n\r\n[保留元素] 完全保持：图2的服装颜色、发型。\r\n\r\n[目标风格/场景] 每个角色的位置、动作、服装颜色、环境布局。\r\n\r\n[光照] 光源方向、冷暖对比。\r\n\r\n[构图] 画幅、景别、空间位置（谁高位谁低位）。\r\n\r\n[画质要求] 电影级写实，关键细节，氛围情绪。\r\n```\r\n\r\n### 关键技巧\r\n- ❌ **不要用** \"在图1场景中加入墨雪\" → 模型可能把参考图里\"旁边的人\"也取过来\r\n- ✅ **要用** \"场景中墨雪一个人站在门口掀帘\"\r\n- 2.1 Flash 在[编辑指令]里写清交互动作（\"推门走进来、望向\"）\r\n- 首次抽卡用最简 prompt，每轮只改 1-2 个点\r\n- 同参数连抽 ≤3 轮，不改善换策略\r\n\r\n## 常见问题\r\n\r\n### 文化手势无法精确控制\r\n模型无法生成\"左手抱右拳\"等特定手势。手抬至胸前已是极限。\r\n\r\n### 人物数量不对\r\n- 2.0 Flash 可能脑补多余人物 → 换 2.1 Flash\r\n- 不要用\"加入/插入/放入角色\"指令式措辞\r\n- 明确写\"只有一个人\"\r\n\r\n### 参考图比例\r\n手动合成参考板时，比例必须与输出一致。\r\n\r\n## 首帧图 Prompt 组装规则（重要）\r\n\r\n`generate_image.py` 在 `_clean_prompt()` 中实现了**段提取拼接机制**，从 `prompts/storyboard/shotXX_image.md` 文件中按 [xxx] 标签提取指定段的内容，去掉标签后按指定顺序拼接成最终 API prompt。\r\n\r\n### 动态段提取\r\n通过 `segments` 参数指定需要提取的段名列表，按顺序拼接：\r\n```python\r\nprompt = _clean_prompt(f.read().strip(),\r\n    segments=[\"编辑指令\",\"目标风格/场景\",\"光照\",\"构图\",\"画质要求\"])\r\n```\r\n\r\n### 可用段列表（按顺序）\r\n| 段名 | 用途 | 是否推荐 |\r\n|------|------|---------|\r\n| `[编辑指令]` | 描述参考图用途和角色空间关系 | ✅ 必须 |\r\n| `[保留元素]` | 指定参考图中需要保持的特征 | ⚠️ 谨慎（见下方说明）|\r\n| `[目标风格/场景]` | 最终画面描述 | ✅ 必须 |\r\n| `[光照]` | 光源方向和氛围 | ✅ 推荐 |\r\n| `[构图]` | 画面布局和角色位置 | ✅ 推荐 |\r\n| `[画质要求]` | 质量关键词+负面提示 | ✅ 推荐 |\r\n\r\n### ⚠️ [保留元素] 的关键陷阱\r\n2.0 Flash 多图合成模式下，`[保留元素]` 会让模型**保持参考图的整体特征（含朝向/姿态）**，覆盖文字指令中的空间描述。\r\n\r\n例如：参考图为 `墨雪_side.png`（侧身），`[保留元素]` 写\"完全保持图2墨雪的特征\" → 模型理解\"保持图2的所有包括朝向\" → 墨雪面向镜头方向而非文字指定的\"侧身望向窗外\"。\r\n\r\n**规则**：3张参考图（场景+双角色）时**不要加 `[保留元素]`**，角色朝向全靠文字指令描述。仅单角色+场景（2张图）时可以加。\r\n\r\n### 双角色首帧图推荐方案\r\n| 要素 | 推荐设置 |\r\n|------|---------|\r\n| 模型 | **2.0 Flash**（多图合成） |\r\n| 参考图 | 场景 + 墨雪_side + 墨将_front（**3张独立**，不合成参考板）|\r\n| 提示词段 | `[编辑指令]` + `[目标风格/场景]` + `[光照]` + `[构图]` + `[画质要求]` |\r\n| 墨雪参考 | 用 `墨雪_side.png`（侧身）而非 `墨雪_front.png`（正面），减少正面朝向的\"拉力\" |\r\n| 排除段 | **不加** `[保留元素]`（会导致角色面朝镜头方向） |\r\n\r\n### ⚠️ 参考图选型：`front`（全身）优于 `face`（面部特写）\r\n首帧图参考图**优先选用全身正面图 `_front`**，而非面部特写 `_face`：\r\n\r\n| 对比维度 | `_front`（全身正面） | `_face`（面部特写） |\r\n|---------|-------------------|-------------------|\r\n| 甲胄颜色 | ✅ 保留正确的颜色和样式 | ❌ 颜色偏差（特写区域太小，模型无法定位颜色）|\r\n| 面部特征 | ✅ 模型自然继承 | ✅ 保留 |\r\n| 服装细节 | ✅ 完整保留 | ❌ 无法获取全局颜色信息 |\r\n\r\n**实战案例**：`墨将_front` → 银灰轻甲（正确）；`墨将_face` → 深褐色玄铁甲（错误，被特写图领口小面积颜色误导）。\r\n\r\n**规则**：即使是面部特写镜头，参考图也用 `_front` 全身图，面部特征模型会自动继承。\r\n\r\n### 代码实现说明\r\n`generate_image.py` 中的 `_clean_prompt(text, segments)` 函数实现段提取：\r\n- `segments=None` → 全量模式（保留所有非标签内容，向后兼容）\r\n- `segments=[...]` → 段模式：仅提取指定 [xxx] 段的内容，按列表顺序拼接\r\n- 可配置在 `script.json` 中每个 shot 的 `first_frame.segments` 字段，无配置时 fallback 到默认列表\r\n\r\n## 调用方式（务必遵守）\r\n\r\n本 skill 已作为子技能打包在主 skill 的 `skills/agnes-ai/` 目录下。\r\n\r\n**🔥 硬性规则**：调用 `generate_*.py` 必须使用子 skill 路径（相对于主 skill 根目录）。\r\n\r\n```bash\r\n# ✅ 正确：子 skill 路径（在主 skill 根目录执行）\r\npython3 skills/agnes-ai/scripts/generate_image.py \\\r\n  \"prompt\" --project . --shot-id 4\r\n\r\n# ✅ 通过项目 scripts/generate_image.py 快捷入口（推荐）\r\npython3 scripts/generate_image.py \"prompt\" --size \"1024x1536\"\r\n```\r\n\r\n> 子 skill 是修改入口，此目录已在主 skill 的 `skills/agnes-ai/` 下，无需额外同步。\r\n\r\n---\r\n\r\n## 视频生成（Agnes Video V2.0）\r\n\r\n本 skill 也封装了视频生成能力，通过 `scripts/generate_video.py` 调用：\r\n\r\n```bash\r\n# 文生视频\r\npython3 scripts/generate_video.py \"古风战场，阴天低沉光线，硝烟弥漫\" \\\r\n  --size \"768x1152\" \\    # 9:16竖版\r\n  --num-frames 121 \\     # ≈5秒@24fps\r\n  --frame-rate 24 \\\r\n  -o \"./videos\" \\\r\n  --output-name \"shot_01.mp4\"\r\n\r\n# 图生视频（以分镜首帧图为参考）\r\npython3 scripts/generate_video.py \"缓慢推进的镜头，战场上残旗飘动\" \\\r\n  --ref-image \"./images/storyboard/shot_01_first_frame.png\" \\\r\n  --size \"768x1152\" \\\r\n  -o \"./videos\" \\\r\n  --output-name \"shot_01.mp4\"\r\n```\r\n\r\n### 时长参数\r\n\r\n| 目标时长 | --duration | 实际参数 |\r\n|---------|-----------|---------|\r\n| 约 3 秒 | `--duration 3s` | `--num-frames 81 --frame-rate 24` |\r\n| 约 5 秒 | `--duration 5s` | `--num-frames 121 --frame-rate 24` |\r\n| 约 10 秒 | `--duration 10s` | `--num-frames 241 --frame-rate 24` |\r\n| 约 18 秒 | `--duration 18s` | `--num-frames 441 --frame-rate 24` |\r\n\r\n也可直接用 `--num-frames` 和 `--frame-rate` 精细控制。num_frames 合法值：8n+1，≤441。\r\n\r\n### 分辨率参数\r\n\r\n`--size` 支持宽x高格式和比例别名：\r\n\r\n- `--size 9:16` → 720x1280（竖屏短视频）\r\n- `--size 16:9` → 1280x720（横屏）\r\n- `--size 1:1`  → 1024x1024（正方形）\r\n- `--size 1920x1080` → 自定义分辨率\r\n\r\n### 生成模式（--mode）\r\n\r\n脚本支持三种生成模式，通过 `--mode` 选择：\r\n\r\n**standard（默认）**\r\n```bash\r\n# 文生视频（无参考图）\r\npython generate_video.py \"prompt\" --duration 5s --size 9:16 --submit-only\r\n\r\n# 图生视频（1 张参考图）\r\npython generate_video.py \"prompt\" --ref-image input.png --duration 5s --size 9:16\r\n```\r\n\r\n**multi-image（多图视频）**\r\n```bash\r\npython generate_video.py \"prompt\" \\\r\n  --mode multi-image \\\r\n  --ref-image-list img1.png img2.png ... \\\r\n  --duration 5s --size 9:16 --submit-only\r\n```\r\n\r\n**keyframes（关键帧动画）**\r\n```bash\r\npython generate_video.py \"prompt\" \\\r\n  --mode keyframes \\\r\n  --ref-image-list kf1.png kf2.png ... \\\r\n  --duration 5s --size 9:16 --submit-only\r\n```\r\n\r\n### 模式选择决策指南\r\n\r\n根据镜头素材和描述自动选择模式（内置在 `video_api.py` 的 `_select_mode()`）：\r\n\r\n```\r\n只有 1 张参考图 ────────→ standard（最常用）\r\n        │\r\n有 2+ 张参考图 ─┬─ 描述含 before/after/对比/转变 → multi-image\r\n                ├─ 描述含 多人/关键帧/转场/复杂场景 → keyframes\r\n                └─ 其他 → standard\r\n```\r\n\r\n### 参考图来源优先级\r\n\r\n`generate_video.py` 接受三种形式的参考图，按以下优先级处理：\r\n\r\n| 优先级 | 参数 | 来源 | 适用场景 |\r\n|--------|------|------|---------|\r\n| 1 (最高) | `--ref-image-urls` | 已上传的公网 URL | 重试/多图 cache 回放 |\r\n| 2 | `--ref-image-list` | 本地多张图片路径 | 首次提交多图/keyframes |\r\n| 3 | `--ref-image` | 本地单张图片路径 | 首次提交 standard 模式 |\r\n\r\n### 视频参数一览\r\n\r\n| 参数 | 默认 | 说明 |\r\n|------|------|------|\r\n| `--model` | `agnes-video-v2.0` | 视频模型名 |\r\n| `--ref-image` | 无 | 参考图路径（图生视频模式） |\r\n| `--num-frames` | `121` | 总帧数，必须为 8n+1（≤441） |\r\n| `--frame-rate` | `24` | 帧率，1-60 |\r\n| `--size` | `1152x768` | 分辨率 宽x高（短剧用 768x1152） |\r\n| `--seed` | 随机 | 固定种子可复现结果 |\r\n| `--output-name` | 自动生成 | 指定文件名 |\r\n\r\n## Prompt 最佳实践（视频）\r\n\r\n### 各模式 Prompt 写作模板\r\n\r\n**standard（单图生视频）** — 描述哪些动、哪些不动：\r\n```\r\n{角色/元素} + {运动描述} + {场景/光照} + {保持稳定的元素}\r\n```\r\n\r\n**multi-image（多图过渡）** — 描述图片之间的关系和过渡方式：\r\n```\r\n从第1张图到第2张图 + {过渡描述} + {什么需要保持一致}\r\n```\r\n\r\n**keyframes（关键帧插值）** — 描述关键帧之间的插值风格：\r\n```\r\n在关键帧之间 + {过渡描述} + {角色/场景一致性要求} + {镜头风格}\r\n```\r\n\r\n---\r\n\r\n## API 说明\r\n\r\n### 图片 API 的 image 字段格式\r\n实测 `image` 在 `extra_body` 内才生效（顶层不生效）：\r\n\r\n```json\r\n{\r\n  \"model\": \"agnes-image-2.0-flash\",\r\n  \"prompt\": \"...\",\r\n  \"size\": \"1024x1792\",\r\n  \"extra_body\": {\r\n    \"image\": [\"url1\", \"url2\"],\r\n    \"response_format\": \"url\"\r\n  }\r\n}\r\n```\r\n\r\n两模型区别：\r\n| 对比维度 | 2.0 Flash | 2.1 Flash |\r\n|---------|-----------|-----------|\r\n| `image` 位置 | `extra_body` 内 | `extra_body` 内 |\r\n| `tags` 参数 | 不需要 | 不需要 |\r\n\r\n### 图片 vs 视频 API\r\n| 能力 | 图片 API | 视频 API |\r\n|------|---------|---------|\r\n| `image` 字段位置 | `extra_body` 内 | `extra_body` 内 |\r\n| 多图支持 | 数组 | 数组 |\r\n\r\n### 视频 API 补充说明\r\n- 三种模式：\r\n  - `standard`：传单张 URL 到顶层 `image`，不加 `extra_body.image`\r\n  - `multi-image`（pipeline 内部模式名）：传 `extra_body.image` 数组，**不加 `mode` 参数**\r\n  - `keyframes`：传 `extra_body.image` 数组 + `extra_body.mode=keyframes`\r\n- 多图参考时所有参考图尺寸建议统一（如均为 720×1280），避免模型根据输入图自适应调整输出分辨率。\r\n\r\n## 注意事项\r\n\r\n- **API 完全免费**，无调用次数限制、无限期。但建议合理使用避免滥用。\r\n- **支持图生图**：用 `--ref-image` 参数传入本地图片路径作为参考图。\r\n- **支持图生视频**：通过 `generate_video.py --ref-image` 传入参考图。\r\n- **纯中文提示词**：Agnes AI 对纯中文提示词理解准确，生图效果优于中英混用。\r\n- 生成成功后，脚本会返回本地文件路径列表。通过 `--output-name` 参数指定文件名，替代了旧的 asset_map.json 映射方式。\r\n## 基础设施与容错（2026-07 修复）\r\n\r\n_新项目自动继承以下代码层修复（在 modules/ 中），但了解其原理可帮助诊断类似问题。_\r\n\r\n### GitHub PAT 管理\r\n\r\n- **PAT 类型**：代码读取 `~/.github-pat` 文件。支持 Classic PAT 和 Fine-grained PAT。\r\n- **过期风险**：Fine-grained PAT（`github_pat_` 前缀）有强制过期时间（30/90/365天）。Classic PAT 可设 \"No expiration\"，推荐用于持续运行的流水线。\r\n- **创建新 PAT**：访问 https://github.com/settings/tokens\r\n  - 推荐：Classic → `repo` scope → No expiration → 写入 `~/.github-pat`\r\n- **故障特征**：GitHub 上传返回 HTTP 401 \"Bad credentials\" → `upload_to_url` 抛出 `ValueError(\"GitHub PAT 无效或已过期\")`，流水线立即标记 shot 失败而非死循环。\r\n\r\n### 参考图托管优化（skip-if-exists）\r\n\r\n**问题**：Agnes API 服务器从 `raw.githubusercontent.com` 下载大图时，国内网络访问 GitHub raw 偶发超时 → 返回 `400 Invalid image`，被误判为内容审核。\r\n\r\n**修复**（默认 Agnes Provider 走 `image_api.py upload_to_url`）：改为「先查后传」：\r\n- 上传前先 `GET` 查 GitHub 同名文件的 `sha`；若已存在，直接返回已有 raw 直链，**跳过 PUT**（1 次 API 调用而非 2 次）。\r\n- **不压缩**：早期版本用 PIL 压缩首帧图（quality 70 / 1280px）已被移除——Agnes 对原图尺寸兼容性更好，压缩反而可能触发审核。GitHub 上传分支始终上传原图；仅当**未配置 PAT** 时走 data-URI 兜底才压缩为 JPEG quality 85，正常流水线走不到。\r\n- 故障特征与重试语义见下方「重试架构」表（`image_api.py upload_to_url` 行）。\r\n\r\n> 小云雀 Provider 走另一条上传路径 `img_host.py upload_image`，重试语义更温和（见重试表最后一行）。\r\n\r\n**效果**：同图重复上传几乎零成本，降低 GitHub 限流（429）与 abuse detection 风险。\r\n\r\n### 重试架构\r\n\r\n所有 `while True` 无限重试已封顶，避免单点故障拖垮整轮轮询：\r\n\r\n| 位置 | 封顶值 | 4xx（非429） | 429/5xx/网络 | 耗尽后 |\r\n|------|--------|-------------|-------------|--------|\r\n| `agnes_provider.py generate_character` / `generate_scene`（角色图/场景图） | max_attempts=5 | 耗尽后 `return None`（4xx 非429 经 `apply_image_strategy` 调整提示词后重试，不立即中断） | 仅 rate_limit 时固定 sleep 30s（其余类别不 sleep） | `return None` |\r\n| `image_api.py upload_to_url`（默认 Agnes 上传） | MAX_UPLOAD_RETRY=4 | 401/403→`raise ValueError`（立即失败） | 退避 `min(10×attempt,60)` → 10s→20s→30s→40s（共 4 次，60s 仅在 attempt≥6 才触及） | `raise RuntimeError` |\r\n| `img_host.py upload_image`（小云雀 Provider） | MAX_RETRIES=3 | 401/403→`return None`（不重试） | 固定 2s（仅 429/500/502/503 重试） | `return None` |\r\n\r\n### 错误分类策略 `_classify_failure()`\r\n\r\n`error_utils.classify()`（在 `agnes_provider.py` / `video_utils.py` 中 import 为 `_classify_failure`）从 Agnes API 的 raw error 提取分类：\r\n\r\n| 分类 | 匹配规则 | 策略 |\r\n|------|---------|------|\r\n| `rate_limit` | 429 / rate_limit | 本轮跳过，等待下轮轮询（不退避原帧） |\r\n| `invalid_image` | 400 / invalid_image / unsafe / moderation | **重建首帧**（`_resubmit_shot(regen_first_frame=True)` 经 Provider 重新生成首帧图）+ 重提 |\r\n| `transient` | remoteclosed / timeout / 5xx | 原样重提（瞬时网络抖动） |\r\n| `bad_request` | 其他 4xx | 重建首帧后重提（可能图片格式问题） |\r\n| `unknown` | 不匹配任何规则 | 原样重提（保守策略） |\r\n\r\n### 首帧重建机制\r\n\r\n`invalid_image`/`bad_request` 错误通过 `video_utils.py:_resubmit_shot(project, sid, script, provider, retry_count=0, regen_first_frame=True)` 处理：\r\n\r\n- 调用 `provider.generate_first_frame(project, shot, script_data)` 重新生成首帧图（通过 `build_first_frame` 构建提示词 → `generate_image` API 调用）\r\n- 重建使用 `ThreadPoolExecutor` + 240s 超时保护：\r\n  - 超时前成功 → `shutil.copyfile` 覆盖到 first_frame.final 路径\r\n  - 超时或异常 → 返回 False，不提交旧被拒帧（避免重复 400 自旋）\r\n- 若 regen 失败 → `_resubmit_shot` 标记 shot 为 failed，等下一轮轮询重试\r\n\r\n### 新项目自查清单\r\n\r\n启动新项目后，检查以下基础设施是否正常：\r\n\r\n1. **GitHub PAT**：`curl -H \"Authorization: token $(cat ~/.github-pat)\" https://api.github.com/repos/JinXuchen2020/video-images/contents/` → HTTP 200\r\n2. **参考图**：首帧图尺寸建议 ≤ 1280px 边长（GitHub 上传分支上传**原图不压缩**；仅未配置 PAT 的 data-URI 兜底才压缩为 JPEG quality 85，正常流水线走不到）\r\n3. **轮询超时**：`pipeline.py` 的 `_run_poll` 子进程 timeout=1800s 已覆盖最坏情况（retry 5次×~100s 但实际压缩后 30s-2min 应返回）\r\n4. **日志**：若 shot 持续 pending，检查 `poll_only.log` 的 GitHub 上传日志和 Agnes 返回的原始错误\r\n\r\n<!-- skill ends here -->\n\nFile v2.7.0:skills/project-generate/SKILL.md\n\n---\r\nname: project-generate\r\nversion: 2.7.0\r\ndescription: \"项目编排层 — 首帧图生成、视频提交/轮询/拼接、状态查看/导出。提供 project_generate.py 作为统一入口，所有命令为子命令形式。图片生成走 Agnes AI（agnes-ai 子 skill），视频生成通过 Provider 路由（支持 Agnes / 小云雀 / LibTV 等）。\"\r\n---\r\n\r\n# project-generate — 项目编排层\r\n\r\n作为 `ai-video-auto-generator` 的子 skill，提供项目级的生成、提交、轮询、拼接全流程编排。\r\n\r\n> **项目创建**请使用 `ai-video-auto-generator` 的 `create_project.py`（在 skill 根目录执行）：\r\n> ```bash\r\n> python3 scripts/create_project.py \\\r\n>   --project <路径> --template short_drama\r\n> ```\r\n> 创建完成后，本 skill 的所有命令都要求项目目录已存在并包含 `script.json`。\r\n\r\n## 统一入口\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython3 skills/project-generate/scripts/project_generate.py\r\n```\r\n\r\n## 命令列表\r\n\r\n所有命令通过子命令（subcommand）调用，`--project` 为全局必选参数：\r\n\r\n```bash\r\nproject_generate.py --project <项目目录> <命令> [选项]\r\n```\r\n\r\n### 资产生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `generate-characters` | `gc` | 读 `character_cards`，批量生成角色资产图（front/face/side/back/action/pose 多视图） |\r\n| `generate-scenes` | `gs` | 读 `scene_cards`，批量生成场景资产图（广角/中景/特写 3 视角） |\r\n| `generate-troops` | `gt` | 读 `troop_cards`，批量生成辅助资产图（白背景全身展示） |\r\n\r\n### 首帧图生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `build-first-frames` | `bff` | 读取 script.json，生成各 shot 的 first_frame 配置和 prompt 模板文件（不调 API）。生成后自动验证六段式格式 |\r\n| `generate-images` | `gi` | 调 API 批量生成首帧图。对失败的首帧图自动重试（L1→L3 降敏），单次 API 调用 180s 超时保护 |\r\n| `verify` | — | 用 Haar Cascade 验证首帧图质量 |\r\n| `verify-scenes` | `ve-scenes` | 验证场景图是否包含人物 |\r\n\r\n### 后台运行\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `bg <子命令>` | 后台启动子命令。用 `subprocess.STARTUPINFO(wShowWindow=0)` 隐藏 `python.exe` 的控制台窗口，进程完全脱离当前控制台，不会被 WorkBuddy 断开连接杀死。**不通过 cmd.exe /c 中转**（中文路径重定向会报错）。stdout 直接重定向到 `pipeline.log`。示例：`project_generate.py --project . bg auto` |\r\n\r\n### 视频流水线\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `submit [--force [id...]]` | 提交视频任务。`--tracker local`（默认）用本地 JSON 记录，`--tracker feishu` 用飞书 Base |\r\n| `poll` | 轮询视频完成状态 + 自动下载 + 全部完成后触发拼接。**持续轮询**每 10 分钟检查一次（代码 `time.sleep(600)`），全部完成自动进行音频+字幕叠加 |\r\n| `stitch [--tracker local]` | **独立拼接子命令**：HF 无字幕渲染 → ffmpeg 烧录分段字幕(CRF18) → 叠加音频/BGM → 输出 `final.mp4`。脱离 `poll` 单独跑，用于只改字幕/编码后重拼（不重新提交/轮询视频） |\r\n| `status` | 显示各 shot/segment 的视频状态 |\r\n| `auto` | 全自动流水线。9 阶段（0→8）：脚本优化（含叙事修复）→构建prompt→角色资产→辅助资产→场景资产→首帧图→提交视频→轮询+拼接+音频。全部阶段支持断点续跑。 |\r\n\r\n### BGM 管理\r\n\r\n- 自定义 BGM：`sounds/bgm_custom.mp3` → `generate_bgm()` 优先使用，跳过 FreeSound 搜索\r\n- 自动 BGM：`script.tone` 字段驱动 FreeSound 关键词搜索，按时长匹配最合适的音乐\r\n- 多段拼接：可用 ffmpeg 将多个音乐片段交叉淡入淡出合成一个 BGM，匹配视频的叙事段落\r\n- 详见 `references/prompt-rules.md §8 BGM 管理`\r\n\r\n### Windows 注意事项\r\n\r\n- **禁用 xfade 转场**：Windows 上 xfade + acrossfade 链式叠加有音视频漂移导致画面卡死，全部改用简单 concat\r\n- **必须指定 yuv420p**：subtitles 滤镜默认输出 yuv444p 部分播放器不兼容\r\n- **subtitles 中文路径**：libass 对中文路径支持不好，需复制到 ASCII 临时路径再引用\r\n- **音频采样率**：强制输出 48kHz 立体声（`-ar 48000 -ac 2`）\r\n- 详见 `references/prompt-rules.md §9 Windows ffmpeg 避坑`\r\n\r\n### 项目管理\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `preview` | — | 生成交互式 HTML 预览页（首帧图缩略图+视频状态+shot_groups 分组）|\r\n| `report` | — | 生成 HTML 统计报告（模型分布、首帧图完成率、视频状态等）|\r\n| `tracker-sync` | — | 从飞书 Base 反向同步任务进度到本地 task_tracker.json（仅 --tracker feishu 时有效）|\r\n\r\n### script 优化\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `optimize` | `opt` | 调用 `script-optimizer` 自动验证和优化 script.json（P0/P1/P2 分级）。支持 `--strict`、`--force`、`--dry-run`、`--report-only`、`--sync-type` |\r\n| `build-prompts` | `bp` | 从 script.json 生成所有资产 prompt 文件到 `prompts/` 目录（角色/场景/辅助资产/视频），含 YAML frontmatter |\r\n| `validate-script` | — | 验证 script.json 结构和关键字段完整性 |\r\n\r\n### 诊断与修复\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `diff --shot-id <id>` | — | 生成单个 shot 的首帧图新旧对比页（side-by-side + 滑块对比）|\r\n| `diff-all` | — | 扫描 `images/storyboard/backup/` 或 `*_old.png`，批量生成对比页 + 索引页，输出到 `output/diff_index.html` |\r\n| `repair` | — | 自动修复提示词文件：重建 assets prompts + 修复 first_frame/video 提示词 |\r\n| `reset-prompts` | — | 删除所有提示词文件并重新生成 |\r\n| `update-prompts <kv>` | — | 批量删除 prompt 文件中的指定段。格式: `段名:false` |\r\n\r\n### 修复策略\r\n\r\n生成结果不满足预期时，参考 [修复策略](../../references/repair-strategy.md) 判断改 script.json 还是改 prompt 文件。\r\n\r\n## 通用选项\r\n\r\n| 选项 | 说明 |\r\n|------|------|\r\n| `--project <path>` | 项目根目录（必选）|\r\n| `--tracker local/feishu` | 任务追踪后端：local（本地 JSON）或 feishu（飞书 Base）|\r\n| `--log-file <path>` | 日志文件路径（默认：`<project>/generate.log`），所有输出同时写入此文件 |\r\n| `--verbose` | 详细输出 |\r\n| `--quiet` | 静默模式 |\r\n\r\n## 架构\r\n\r\n```\r\nproject_generate.py            ← CLI 入口（子命令路由）\r\nmodules/\r\n  ├── project_commands/        ← 包（所有 _cmd_* 业务命令，实际位于 modules/ 下）\r\n  │     ├── __init__.py        ← 主入口 + 9 阶段流水线编排（状态持久化：__init__.py 内联）\r\n  │     ├── 图片: _cmd_build_first_frames(), _cmd_generate_images()\r\n  │     ├── 视频: _cmd_submit(), _cmd_poll(), _cmd_status()\r\n  │     └── 管理: _cmd_preview() 等\r\n  ├── provider_factory.py    ← Provider 工厂（按 script.json 选 Agnes/小云雀）\r\n  ├── base_provider.py       ← 抽象基类（定义接口契约）\r\n  ├── agnes_provider.py      ← Agnes AI Provider\r\n  ├── xiaoyunqiao_provider.py ← 小云雀 Provider（含 segment 自动合并）\r\n  ├── video_utils.py         ← 视频编排逻辑（批量提交/轮询/参考图解析）\r\n  ├── task_tracker.py        ← 任务追踪门面\r\n  ├── task_tracker_local.py  ← 本地 JSON 追踪\r\n  ├── task_tracker_feishu.py ← 飞书 Base 追踪\r\n  ├── config.py              ← 统一配置加载\r\n  ├── feishu.py              ← 飞书 API 封装\r\n  ├── stitch.py              ← ffmpeg 拼接\r\n  ├── project_preview.py     ← HTML 预览\r\n  ├── project_stats.py       ← HTML 统计\r\n  ├── project_verify.py      ← 首帧图质量验证\r\n  └── project_diff.py        ← 首帧图对比\r\n```\r\n\r\n## Provider 配置\r\n\r\n在 `script.json` 的 `script` 块中配置：\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"provider\": \"agnes\",              // 图片生成工具（默认 agnes）\r\n    \"video_provider\": \"xiaoyunqiao\"   // 视频生成工具（不设则同 provider）\r\n  }\r\n}\r\n```\r\n\r\n也支持从飞书文档标题自动检测：标题含\"小云雀视频\" → `video_provider: xiaoyunqiao`。\r\n\r\n## 任务追踪\r\n\r\n`--tracker` 参数选择后端：\r\n\r\n| tracker | 后端类 | 优点 |\r\n|---------|--------|------|\r\n| `local`（默认）| `LocalJsonTracker` | 无依赖，所有操作在本地 |\r\n| `feishu` | `FeishuTracker` | 可多人协作，Base 可视化 |\r\n\r\n## 小云雀 Segment 模式\r\n\r\n当 `video_provider==\"xiaoyunqiao\"` 时，`write-prompt-file` 会自动：\r\n1. 按场景分组合并 shot 为 segment（15~45s 每段）\r\n2. 生成 segment 级提示词文件\r\n3. 写入 `xiaoyunqiao_segments[]` 到 script.json\r\n\r\n`submit`/`poll` 自动检测 segments，切换为段级提交和轮询。\r\n`stitch` 自动检测 segments，按 segment 文件拼接。\r\n\r\n## 历史\r\n\r\n本 skill 由 `batch_generate.py` + `batch_project.py` 合并为 `project_generate.py`，\r\n目录名从 `batch-generate` 更名为 `project-generate`。\r\n视频 API 函数原为 `video_api.py`（在 agnes-ai 模块中）的模块函数，逐步重构为 Provider 模式。\r\n\r\n## 设计决策（bug 预防）\r\n\r\n### 1. `project` 参数必须传递\r\n所有资产生成函数（`generate_character`、`generate_scene`、`generate_image`）必须传递 `project` 参数。\r\n- 漏传 → `upload_to_url()` 退化为 \"default\" → 参考图传到错误目录\r\n- `upload_to_url()` 内部使用 `os.path.abspath(project)` 解析相对路径（如 `.` → 项目名）\r\n- `img_host.upload_image()` 同理\r\n\r\n### 2. API 重试封顶 + 错误感知修复\r\n`agnes_provider.py` 中图片/场景生成采用「错误感知重试」：循环上限 `max_attempts=5`（`generate_image` / `generate_scene` 各独立计数），失败后用 `_classify_failure()` 分类并应用修复策略（软化提示词 / 换模型 / 原样重试），**仅 `rate_limit` 时固定 `sleep 30s`**，其余类别不 sleep。4xx non-429 由策略处理，不进入退避死循环。设上限、不设无限重试——5 次失败后上层 `project_commands` 自愈循环（`max_attempts=10`）接管降敏修复。\r\n\r\n### 3. 场景验证不依赖激进 Haar 配置\r\n`project_verify.py` 使用 Haar Cascade 多配置检测人脸。`scaleFactor=1.05/minNeighbors=3` 配置过于激进，会从废墟/火焰纹理中误报人脸。已移除，只保留 `1.1/5`、`1.2/3` 和 profile face。\r\n\r\n### 4. 场景 prompt 模板必须 scene-aware\r\n`prompt_builder.py` 的中景/特写 `view_desc` 不能硬编码特定场景描述（如 \"cracked brickwork\" 废墟模板）。必须从 scene card 的 `description` 动态派生，否则丛林场景会生成废墟砖墙。\r\n\r\n### 5. agnes-ai 为唯一真相源（单副本）\r\n`agnes-ai` 子 skill 是唯一的代码源。独立副本 `~/.workbuddy/skills/agnes-ai/` 已删除，**不再需要双副本同步**。所有改动只需在 `skills/agnes-ai/` 中完成，无需同步到其他位置。\r\n\r\n### 6. bg 后台启动：STARTUPINFO + 直接 Popen，不用 cmd.exe\r\n`launch_background.py` 的实现要点：\r\n- 使用 `subprocess.STARTUPINFO(wShowWindow=0)` 隐藏 `python.exe` 的控制台窗口\r\n- 不通过 `cmd.exe /c` 中转，因为中文路径（如\"不死者\"）在 `>` 重定向时 cmd.exe 会报错\r\n- 直接用 `subprocess.Popen(cmd, stdout=open(log), startupinfo=si)` 启动\r\n- 永远不要用 `pythonw.exe`——GUI 子系统下脚本的 stdout 行为异常\r\n- 日志自动写入 `pipeline.log`\r\n\r\n### 7. 首帧图生成：存在→验证→跳过 / 超时→降敏→重试\r\n`generate-images` 的 `_generate_single_shot()` 实现如下自愈逻辑：\r\n\r\n```\r\n对每个 shot:\r\n  1. 检查 output 路径 → 如果文件存在\r\n     → 执行 verify_first_frame()\r\n     → 通过: 跳过（\"首帧图已存在，验证通过\"）\r\n     → 不通过: 记录问题，进入生成流程\r\n  \r\n  2. 生成流程（最多 4 次尝试 = 1 次初始 + 3 次重试）:\r\n     a. 调 API 生成（180s 超时包裹）\r\n        → 正常返回: 验证质量，通过则返回\r\n        → API 超时/错误: 保存错误信息 → 进入下一轮重试\r\n     \r\n     b. 重试时:\r\n        - 检测到 timeout / HTTP 400 / content_policy_violation\r\n          → error_utils.soften_prompt 逐级降敏（先经 error_utils.classify 分类错误）:\r\n            L1: 移除高风险动作词 + 武器关键词\r\n            L2: 强制静态人像\r\n            L3: 降级为空场景\r\n        - 持久化修复后的 prompt 到文件\r\n        - 继续下一轮 API 调用\r\n  \r\n  3. 4 次全部失败 → 标记为 ❌ 失败，汇总输出\r\n```\r\n\r\n关键点：\r\n- 180s 超时防止 Agnes API 调用（由 `agnes_provider.generate_image` / `image_api.generate_image` 处理）的重试阻塞单 shot 处理\r\n- `last_error` 在 except 中捕获并传递到下一轮重试的 auto_fix\r\n- auto_fix 识别 \"timeout\"、\"invalid input image\"（武器类内容的误导性错误码）和 content_policy_violation\r\n- 武器关键词（枪/手枪/步枪/瞄准/射击等）自动替换为中性描述\r\n- 修复后的 prompt 持久化到文件，下次生成直接用修复版\r\n\r\n### 8. HF 渲染：必须让 hyperframes 自动发现 headless shell，禁止注入浏览器 env var\r\n`hyperframes_stitch.py` 的渲染入口**绝不能**设置 `HYPERFRAMES_BROWSER_PATH` / `PUPPETEER_EXECUTABLE_PATH` 强制指向系统 Edge。原因（2026-07-15 实证）：\r\n- hyperframes 主渲染路径走 `resolveHeadlessShellPath`，自动发现 `~/.cache/puppeteer/chrome-headless-shell/*/chrome-headless-shell.exe`（puppeteer 自动化构建，专为 CI 沙箱优化，无需 GUI/COM）。\r\n- 一旦注入 Edge 路径，headed 浏览器发现链（`findFromEnv2`）会捕获它用于 GPU 探测 → 系统 Edge 单实例架构下新 msedge.exe 转交已运行实例后 Code:0 秒退 → GPU 探测失败 → worker 校准失败 → 渲染级联失败回退 ffmpeg。\r\n- **正确做法**：不设置这两个 env var，让 hyperframes 自动发现 headless shell（约 2.7min 渲染 18 镜头 2258 帧）。Edge 在本机因会被系统/用户自动重开，实际不可用于渲染。\r\n\r\n### 9. 字幕分段：按词边界（空格）切，绝不按时间/字数硬切\r\n`_split_long_subtitle()` 按**空格分隔的完整词**累积切分，保证一个词不被劈开。不要按时间（会造成一句话分两段）或纯字数硬切（可能从词中间截断）。长文本按完整词累积到 `max_chars`(默认 15 字/行) 后切段；若整段 < min_seg_dur 则合并到最后一段。\r\n\r\n### 10. 字幕字体/编码约定\r\n- 烧录滤镜 `force_style='FontName=Microsoft YaHei,FontSize=14,PrimaryColour=&H00FFFFFF,Outline=1,Shadow=1'`（14px 适配 720 宽视频）。\r\n- 必须指定 `yuv420p`（libass 默认 yuv444p 部分播放器不兼容）。\r\n- 字幕时间轴使用 `actual_durations`（ffprobe 探测真实视频时长），不使用 script 的 `duration_seconds` 计划值（逐镜头偏差 0.04–0.4s 累积会偏移后段字幕）。\r\n- 成片默认编码 `-crf 18`（高码率）。\r\n\r\n### 11. safe-delete 沙箱坑：os.remove / os.unlink 必须 try/except\r\n托管 Python 的 safe-delete 钩子在沙箱无回收站时会抛 `SAFE_DELETE_FAIL_CLOSED`。若直接调用 `os.remove(final_hf.mp4)` / `os.unlink(_temp.mp4)` 不上抛保护，异常会被 `run_first` 当成拼接致命错误 → 误报\"拼接失败\"（其实 final.mp4 已写好）。现已全部包 try/except，删不掉仅 `[warn]` 不致命。\n\nFile v2.7.0:skills/script-optimizer/SKILL.md\n\n# script-optimizer\r\n\r\n纯自动化脚本质量优化器。验证 `script.json` 质量，自动修复模板默认值、角色匹配、运镜兼容等已知问题。\r\n\r\n## 入口\r\n\r\n```bash\r\n# 方式 A：直接运行模块（推荐）\r\npython3 scripts/optimize/__init__.py --project <项目目录> [选项]\r\n\r\n# 方式 B：通过 project-generate 统一入口\r\npython3 scripts/project-generate/project_generate.py --project <项目目录> optimize\r\n```\r\n\r\n## 调用方式\r\n\r\n| 模式 | 命令 |\r\n|------|------|\r\n| 全自动 | `python3 scripts/optimize/__init__.py --project <项目目录>` |\r\n| strict + force | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --force` |\r\n| JSON 输出 | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --json` |\r\n| 预览 | `python3 scripts/optimize/__init__.py --project <项目目录> --dry-run` |\r\n| 仅报告 | `python3 scripts/optimize/__init__.py --project <项目目录> --report-only` |\r\n| 修复 prompt | `python3 scripts/optimize/__init__.py --project <项目目录> --fix-prompts` |\r\n| 同步类型配置 | `python3 scripts/optimize/__init__.py --project <项目目录> --sync-type` |\r\n\r\n## 修复清单\r\n\r\n| 修复项 | 说明 |\r\n|--------|------|\r\n| gender | 从 build/aura/personality 关键词推断 |\r\n| aesthetic_style | 从类型配置注入 |\r\n| distinctive_mark | 从 hair + face_details + color_scheme 自动构建 |\r\n| face_details | 从 face 文本中按关键词提取 |\r\n| camera_movement | 按 shot_type 填充默认运镜 |\r\n| description | 从 prompt 截取 |\r\n| duration_seconds | 字符串→int 类型修正 |\r\n| reference_images | 从 shot_groups + character_cards 重建 |\r\n| scene lighting/mood | 从 time_of_day 推断 |\r\n| shot_groups | 删除孤儿引用，未分组 shot 创建新组 |\r\n| characters 去重 | 独立检测并移除 characters 列表中的重复项 |\r\n| 全局字段 | 从类型 .md 注入缺失字段 |\r\n| 运镜兼容 | 清除互斥组合（仰+俯、拉+推等） |\r\n| 泛称代词 | 检测「猫」「狗」「他」「她」等并替换为角色名 |\r\n\r\n## 验证维度\r\n\r\nP0 — 阻塞资产生成（模板占位符残留、description 过短、必填字段缺失等）\r\nP1 — 建议修复（strict 模式下阻塞）\r\nP2 — 消息（camera_movement 未设置、face_details 默认值等）\r\n\r\n## 与 project-generate 集成\r\n\r\n```python\r\nfrom optimize import OptimizerV2\r\nopt = OptimizerV2(project, strict=True, json_mode=True)\r\nresult = opt.run()\r\n```\n\nFile v2.7.0:README.md\n\n# ai-video-auto-generator\r\n\r\nAI 短视频全自动流水线 — 从想法到成片，一键出视频。\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## Quick Start\r\n\r\n### 🔥 快速尝鲜（30 秒出预览，无需 API Key）\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n自动装依赖 → ffmpeg 本地合成预览视频 → 看到效果 → 引导下一步。\r\n\r\n### 💬 AI Agent 一键出片（推荐）\r\n\r\n加载本 skill 后，直接向 AI Agent 描述需求：\r\n\r\n```\r\n\"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n```\r\n\r\nAgent 会自动完成：\r\n1. 分析需求 → 生成完整 `script.json`（含角色卡/场景卡/镜头列表）\r\n2. 运行 `optimize` 命令（OptimizerV2）做 12 维叙事自动修复\r\n3. 调用 `--mode auto` 全自动流水线\r\n4. 完成后通知你\r\n\r\n> 支持多种输入：文本描述、URL、本地文件(.txt/.md/.docx)、飞书文档链接。直接发给 Agent 即可。\r\n\r\n### 安装\r\n\r\nskill 安装后会自动检测环境，缺失的依赖（opencv, edge-tts, PIL 等）会自动安装：\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --project . --mode setup\r\n```\r\n\r\n### 方式 1：从模板创建新项目\r\n\r\n```bash\r\n# 查看可用模板（在 skill 根目录执行）\r\npython scripts/create_project.py --list-types\r\n\r\n# 创建项目\r\npython scripts/create_project.py --project ./my_video --template short_drama\r\n\r\n# 一键出片\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 2：导入现有 `script.json`\r\n\r\n```bash\r\n# 在已有项目目录下\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 3：从飞书文档导入\r\n\r\n```bash\r\n# 在 skill 根目录执行，把飞书需求文档 URL 写入 script.json\r\npython scripts/create_project.py --project . --feishu-doc-url <feishu_doc_url>\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## 流水线概览\r\n\r\n```\r\nscript.json\r\n  ↓ 叙事 12 维自动修复（ID/时长/钩子/运镜/情绪/收尾...）\r\n  ↓ 角色资产生成 + 6 维质量验证\r\n  ↓ 场景资产生成 + 无人检测 + 风格检测\r\n  ↓ 首帧图生成 + 50 分制验证 + L1/L2/L3 降敏修复\r\n  ↓ 视频提交 → 轮询 → 下载 → 55 分制验证（含运镜+情绪）\r\n  ↓ 拼接（hyperframes / ffmpeg）\r\n  ↓ TTS 配音 + BGM + 环境音 + 音效 + ffmpeg 多轨混音\r\n  ↓ SRT 字幕\r\n  → final.mp4\r\n```\r\n\r\n## 命令速查\r\n\r\n```bash\r\n# 🎮 快速尝鲜（30 秒，无需 API Key）\r\npython skills/project-generate/scripts/pipeline.py --mode demo\r\n\r\n# 环境检测 + 自动安装\r\npython skills/project-generate/scripts/pipeline.py --mode setup\r\n\r\n# 💬 告诉 AI Agent 你的需求（推荐）\r\n#    在 WorkBuddy 中加载本 skill 后，直接描述需求即可\r\n#    示例: \"帮我做一个古代将军在现代城市醒来的短视频\"\r\n\r\n# 全自动流水线（已有 script.json 时）\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n\r\n# 预检（只验证不生成）\r\npython skills/project-generate/scripts/pipeline.py --mode validate\r\n\r\n# 仅轮询（已有 task 的项目续跑）\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached\r\n\r\n# 项目状态（默认 JSON 输出，--text 人类可读）\r\npython skills/project-generate/scripts/project_generate.py --project . status\r\n\r\n# 单独拼接（HF 无字幕渲染 → ffmpeg 烧录字幕 → 叠加音频/BGM → final.mp4）\r\npython skills/project-generate/scripts/project_generate.py --project . stitch --tracker local\r\n```\r\n\r\n## Provider 切换\r\n\r\n默认使用 Agnes AI。修改 `script.json` 中的 `script.provider` 即可切换：\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"provider\": \"xiaoyunqiao\",\r\n    \"video_provider\": \"xiaoyunqiao\"\r\n  }\r\n}\r\n```\r\n\r\n自定义 Provider：实现 `BaseProvider` 后通过 `register_provider()` 注册。\r\n\r\n## 已知限制\r\n\r\n| 限制 | 说明 |\r\n|------|------|\r\n| 需 API Key | 默认使用 Agnes AI，需配置 `~/.agnes-api-key`（免费无限额度）。也可切换其他 Provider。 |\r\n| Windows 优先 | 路径处理、asyncio 事件循环针对 Windows 设计。macOS / Linux 未完整测试。 |\r\n| OpenCV 依赖 | 视觉验证需要 `opencv-python-headless`（~50MB），`--mode setup` 会自动安装。 |\r\n| 无实时进度条 | `auto` 模式 detach 后日志写入文件，无终端进度条。用 `tail -f auto.log` 查看。 |\r\n\r\n## 验证体系\r\n\r\n| 资产类型 | 检查内容 | 分值 |\r\n|---------|---------|------|\r\n| 角色图 | 文件+模糊+人物数量+背景+全身照+风格 | 55 分 |\r\n| 场景图 | 人脸检测+风格检测 | pass/fail |\r\n| 首帧图 | 文件+尺寸+模糊+人物数量+色彩 | 50 分 |\r\n| 视频 | 时长+比例+帧质量+运镜+情绪 | 55 分 |\r\n| 脚本 | 12 维叙事结构 | P0/P1/P2 |\r\n\r\n## 文档\r\n\r\n- [流水线排错指南](references/troubleshooting.md)\r\n- [环境搭建指南](references/setup-guide.md)\r\n- [Provider 配置参考](references/provider-config.md)\r\n- [script.json 生成检查清单](references/script-json-checklist.md)\r\n\r\n## License\r\n\r\nMIT\n\nFile v2.7.0:sample/README.md\n\n# Sample: Quick Experience Video\r\n\r\nA minimal 5-shot short video script for testing the pipeline.\r\n\r\n## Quick Start\r\n\r\n```bash\r\n# 0. Quick demo (30 seconds, no API key needed)\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode demo\r\n\r\n# 1. Setup environment (auto-install missing deps)\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode setup\r\n\r\n# 2. Run the full pipeline\r\n#    在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project sample --mode auto\r\n```\r\n\r\n## What It Does\r\n\r\nThis sample contains a 15-second drama scene:\r\n- 1 character (小墨)\r\n- 1 scene (天台 rooftop)\r\n- 5 shots with camera movement variety (dolly-in, closeup, tilt-up, static, wide)\r\n- Emotional arc: calm → reflective → tense → resolved\r\n\r\n## Notes\r\n\r\n- Requires Agnes AI API Key (`~/.agnes-api-key` or configured in `script.json`)\r\n- First run will auto-install Python dependencies (opencv, edge-tts, etc.)\r\n- The auto pipeline will validate and auto-fix the script's narrative structure\n\nFile v2.7.0:_meta.json\n\n{\n  \"ownerId\": \"kn7ejvrxyqc214x7gvae89m3nd8a42ye\",\n  \"slug\": \"ai-video-auto-generator\",\n  \"version\": \"2.7.0\",\n  \"publishedAt\": 1784185601676\n}\n\nFile v2.7.0:references/asset-generation.md\n\n# 资产生成参考\r\n\r\n> 从主 SKILL.md §5.4 抽取的完整资产生成规则。\r\n\r\n---\r\n\r\n#### 5.4.2 角色资产生成（强制）\r\n\r\n> 📌 本节较长（~200 行），覆盖 8 类必须资产的完整生成策略（标准共 11 个文件，见 §5.4.2 资产类别表）。\r\n> 新手建议先读概要（策略一~五），熟悉后按需查阅具体资产类型。\r\n\r\n对于视频中出现的每个角色：\r\n\r\n**⚠️ 角色/兵种一致性核心规则（Critical）**\r\n\r\n图片生成工具（agnes-ai）每次调用完全独立，**模型不认识任何自定义名字**。如果提示词里只写名字（如 `墨雪` / `墨将` / `明军` / `蛮兵`），每次生成都会随机出不同的人或装束。\r\n\r\n**规则：所有图片提示词中，涉及角色的名字必须替换为 `character_cards[].base_prompt_cn` 中的完整外观描述；涉及兵种的名字必须替换为 `troop_cards[].base_prompt_cn` 中的完整装束描述。**\r\n\r\n> ⚠️ **完整描述包括三项**：`base_prompt_cn`（外观）+ `color_scheme`（配色）+ `style_keywords`（风格词），三者缺一不可。仅用 `base_prompt_cn` 会导致铠甲颜色/纹理在不同镜头间漂移。\r\n\r\n反例（只写名字，模型不认识）：\r\n```\r\n\"明军与蛮兵激战，明军士兵接连倒地\"\r\n```\r\n\r\n正例（嵌入外观描述，模型有参照）：\r\n```\r\n\"明军士兵身着制式铁甲外罩暗红战袍持长枪腰刀制式头盔，蛮兵身着兽皮皮甲骨甲部分上身裸露可见战纹纹身持弯刀狼牙棒，两军激战刀剑交错\"\r\n```\r\n\r\n> `generation.reference_images` 字段标明该镜头引用了哪些卡，生成 prompt 时应从中提取对应描述注入。\r\n\r\n**五个关键优化策略，必须全部执行：**\r\n\r\n---\r\n\r\n**策略一：关闭提示词自动改写（agnes-ai 无此参数，提示词原样发送）** ⭐\r\n\r\nagnes-ai 的图片模型不会自动改写提示词，无需特殊设置。\r\n\r\n```yaml\r\n# agnes-ai 调用（首选）— 不需要 revise 参数\r\ntool: agnes-ai\r\nparams:\r\n  prompt: \"国风古典美人，鹅蛋脸型，丹凤眼冷冽锐利，剑眉英气，樱唇微抿，墨黑长发束成高马尾...\"\r\n  output_name: \"墨雪_front.png\"\r\n  output_dir: \"$HOME/WorkBuddy/锈甲天凤/images/characters\"\r\n```\r\n\r\n---\r\n\r\n**策略二：提示词结构化分层（核心锚定优先）**\r\n\r\n所有角色资产的提示词必须以 `character_cards.appearance` 的完整描述作为前缀，但按**资产类型**调整核心锚定的内容，避免过度联想：\r\n\r\n| 资产类型 | 🔴 核心锚定（必须） | 🟡 可选补充 | Framing 限制词 |\r\n|---------|-------------------|-----------|---------------|\r\n| **全身照** (front/3quarter/side/back) | 发型 + 完整铠甲/服装 + 脸型 | 气场+纹样+披风 | `full body from head to toe including boots` |\r\n| **面部特写** (face) | **发型 + 脸型/眉目 only**（**去掉铠甲**） | 眼神+表情 | `face only, tight face crop, no body, no armor visible, only face from forehead to chin` |\r\n| **头部多角度** (head_angles) | 发型 + 脸型（铠甲边缘隐约可见即可） | 眼神 | `head and neck only, shoulders barely visible` |\r\n| **五官特写** (face_details) | **发型 + 脸型 only**（**去掉铠甲**），用方案F生成4张独立部位特写+脚本拼接（详见第6条） | 皮肤质感+五官细节 | `face detail close-up, [specific feature] area only, no armor visible, no clothing` |\r\n| **表情研究** (expressions) | 发型 + 脸型（铠甲边缘隐约可见） | 多种表情 | `face and upper shoulders, headshot framing` |\r\n| **手脚姿态** (hands_feet_gestures) | 完整铠甲/服装 + 体型 | 武器/配饰 | `hand and foot poses, body partial visible` |\r\n| **参考板** (reference) | 完整全部 | 全部 | 无（全身到特写都有） |\r\n| **配饰道具** (props) | 标志性纹样 + 武器特征 | 材质光照 | `props isolated on neutral background` |\r\n\r\n> 以上 8 个类别覆盖 **11 个文件**（标准基数）：全身照类别产出 4 个文件（front/side/back/3quarter），其余类别各产出 1 个文件。含动态持械/动作视图时，每个角色产出的文件数会更多。详见 §5.4.5 资产库目录结构。\r\n\r\n⚠️ **关键原则**：\r\n- 全身照/参考板：**不能省略铠甲**，否则模型可能脑补不同服装\r\n- **面部特写/五官特写：必须去掉铠甲描述**，否则混元会将\"女武将\"身份与\"全身铠甲\"强关联，导致脸周围出现肩甲胸甲\r\n- 面部特写保留**发型+脸型**已足够锚定身份，发型比铠甲更具辨识度\r\n- **审美风格由项目决定**：读取 `script.json` 的 `aesthetic_style` 字段——`\"eastern\"` 选中文古典审美词汇，`\"western\"` 选英文词汇。**不可写死某一种审美，由 target_audience 决定**\r\n\r\n提示词结构模板：\r\n```\r\n# 全身照\r\n[🔴核心锚定：发型+完整铠甲+脸型], [🟡重要：气场+纹样], [🟢增强：光照+质量], [具体资产类型要求]\r\n\r\n# 面部特写（⚠️ 去掉铠甲，只留发型+脸型）\r\n[🔴核心锚定：发型+脸型], [🟡重要：眼神+表情], [🟢增强：光照+质量], [framing限制：face only no body no armor], [具体资产类型要求]\r\n```\r\n\r\n**策略三：使用固定 seed 保持跨图片一致性** ⭐\r\n\r\n`generate_image.py` 支持 `--seed <int>` 参数固定随机种子。同一角色在同一次会话中多次生成时，使用相同 seed 可显著提高面容一致性。\r\n\r\n```yaml\r\n# 同一角色的多张资产使用相同 seed\r\ntool: agnes-ai generate_image.py\r\nparams:\r\n  prompt: \"国风古典美人，鹅蛋脸型，丹凤眼冷冽锐利...\"\r\n  seed: 42  # 固定种子，确保多次生成的面容一致\r\n  output_name: \"墨雪_front.png\"\r\n```\r\n\r\n建议：每个角色分配一个固定 seed（如墨雪=42，墨将=43），该角色的所有资产图都使用这个 seed 生成。\r\n\r\n---\r\n\r\n**策略四：提示词语言策略（按 `aesthetic_style` 选择，覆盖全部资产类型）**\r\n\r\n所有资产类型（角色、场景、道具、分镜图）的提示词语言由 `script.json` 的 `aesthetic_style` 决定：\r\n\r\n- `\"eastern\"` → **纯中文**（不加英文），使用 `image_prompt_cn` / `scene_prompt_cn`\r\n- `\"western\"` → **英文**（古风词可保留中文），使用 `image_prompt` / 自写英文\r\n\r\n> 详见主 SKILL.md §5.5（审美风格配置）和 §6.2-§6.4（完整示例）。\r\n\r\n---\r\n\r\n**策略五：冗余生成 + 选优（针对高不一致资产）**\r\n\r\n对于最容易出现不一致的资产类型（面部特写/头部多角度/表情研究），一次生成 **2 张候选图**，选最接近的一张保留，另一张删除或重命名加 `_candidate` 后缀。\r\n\r\n---\r\n\r\n\r\n#### 5.4.3 场景资产生成（强制）\r\n\r\n对于视频中的每个关键场景：\r\n\r\n1. **画幅规则**：场景空镜头必须是 **16:9 横版**（1792x1024 或 1920x1080），展现环境广度。9:16 竖屏只用于角色全身照和分镜图。\r\n2. **内容规则**：场景空镜头中**不得出现任何人物**（包括小兵、路人）。可包含道具（旗帜、兵器、家具等）。如需士兵的三视图，单独生成。\r\n   - **实现方式**：`agnes_provider.py` 的 `generate_scene()` 已自动注入 `negative_prompt=\"人物, 人, 行人, 角色, 人类, 人群, 面部, 身体, 人体, 人物剪影, 生物, 动物, 活物, 多余的物体\"`，API 层面强制禁止人物出现。\r\n     仅靠 prompt 正文写\"画面中不应该有任何人物\"不够——AI 模型容易在长 prompt 中忽略正面描述，必须通过 `negative_prompt` 独立参数约束。\r\n   - **根因与修复**（2026-06-30）：`negative_prompt` 还不够——场景名/描述中的人物暗示词（如\"播客录音室\"→暗示有人播客、\"谈话氛围\"→暗示有人交谈、\"主播\"→暗示主持人）会**压倒 negative_prompt**，模型训练数据中这些词与人物强关联。\r\n     - `generate_scene()` 在构建 prompt 前**自动净化**场景描述：去掉\"播客\"、\"谈话\"、\"主播\"等暗示人物的词\r\n     - prompt 结构改为：**开头**强约束「室内空镜无人物」→ **中间**净化后的场景描述 → **结尾**再次约束「绝对不能出现人物」\r\n     - `negative_prompt` 增加\"主播、主持人、演讲者、人像、肖像\"等术语\r\n     - **重要**：不修改 `script.json` 的场景卡数据，只在 prompt 构建层做词法净化\r\n   - **验证**：`project_generate.py verify-scenes` 命令使用 Haar Cascade 人脸检测验证场景图是否含人物。\r\n\r\n3. **跨镜头角色一致性（强制）**（2026-06-30 新增）：\r\n   - **问题**：参考图（如 `小段_front.png`）有围巾/眼镜/发型等标志性特征，但 `character_cards` 的 `distinctive_mark`/`armor/clothing` 没写 → 后续 shot 的 prompt 不提这些特征 → AI 忽视参考图的标志性细节 → 角色一致性丢失（典型症状：shot_01 有围巾、shot_02 没有）\r\n   - **根因**：手动在某个 shot 的 prompt 临时加的\"橙色围巾\"没存回 `character_cards`，导致只有该 shot 的 prompt 有围巾\r\n   - **实现方式**（已编码到 `_generate_prompt_template`）：\r\n     - 自动从 `script.character_cards[]` 提取每个角色的 `distinctive_mark` + `style_keywords`\r\n     - 拼接到每个 shot 的 `[目标风格/场景]` 段末尾（用逗号分隔）\r\n     - 效果：修改 `character_cards[].distinctive_mark` 后，`build-first-frames --force` 一键同步所有 shot 的 prompt\r\n   - **强制规则**：\r\n     - **标志性特征（围巾、眼镜、发型、配饰）必须写入 `character_cards[].distinctive_mark`**\r\n     - 不能只在某个 shot 的 prompt 里手动加\r\n     - 任何\"参考图有但 prompt 没\"的特征都会被 AI 忽略\r\n   - **示例**：\r\n     ```json\r\n     \"character_cards\": [{\r\n       \"name\": \"小段\",\r\n       \"distinctive_mark\": \"戴一副圆框眼镜，佩戴一条橙色围巾，笑容有感染力，微卷短发\",\r\n       \"appearance\": {\r\n         \"armor/clothing\": \"米白色针织毛衣外套浅棕色休闲开衫，领口搭一条橙色围巾\"\r\n       }\r\n     }]\r\n     ```\r\n4. **单角色 shot 防双人脑补（强制）**（2026-06-30 新增）：\r\n   - **问题**：单角色镜头的参考图只有 `小段_front.png`，但 `agnes-image-2.0-flash` 的编辑指令写\"在场景中加入**各角色**\"（复数），AI 会脑补出第二个人（如 shot_05/07 出现两人）\r\n   - **修复**：`_generate_prompt_template` 根据角色参考图数量动态生成指令\r\n     - 单角色参考图 → \"加入**该角色**\" + \"只出现一位角色，禁止出现第二个人或倒影\"\r\n     - 多角色参考图 → \"加入**各角色**\" + 空间关系约束\r\n   - **强制规则**：所有单角色 shot 的 `[编辑指令]` 段必须显式禁止出现第二人\r\n5. **定义场景卡** — 在 `script.json` 的 `scene_cards` 中为每个场景定义光照、氛围、配色、关键元素等属性，与 `character_cards` 形成对称\r\n   - `scene_cards[].style_keywords` 自动注入到场景 `image_prompt` / `video_prompt` 中\r\n   - 场景角度由生成流程统一约定（使用中文命名）：`广角建立` / `中景细节` / `特写元素`\r\n   - 光照变体由生成流程统一约定（使用中文命名）：`白天` / `黄金时刻`，至少生成 2 个变体\r\n\r\n4. **多角度场景图** - 从不同景别生成同一场景\r\n   - 至少生成2-3个角度：远景建立、中景细节、特写元素\r\n   - 保存为：`images/scenes/<场景名>_广角.png`, `<场景名>_中景.png`, `<场景名>_特写.png`\r\n\r\n5. **场景光照变体** - 生成不同光照条件下的同一场景\r\n   - 默认：白天 + 黄金时刻（至少2个变体）\r\n   - 保存为：`images/scenes/<场景名>_白天.png`, `<场景名>_黄金时刻.png`\r\n\r\n**场景资产提示词示例**（按 `aesthetic_style` 选择语言，以下示 eastern 用纯中文）：\r\n\r\n```\r\n\"龙南客家围屋远景，黄金时刻阳光，雄伟山脉背景，文化遗产，高度细致，电影感，4K\"\r\n\"龙南客家围屋中景，主入口，精美石雕可见，温暖光线，建筑细节，4K\"\r\n\"龙南客家围屋特写，风化墙面纹理，苔藓和石头细节，微距镜头，历史质感，4K\"\r\n```\r\n\r\nwestern 风格时用英文，如 `\"Ancient Chinese courtyard house, golden hour sunlight, majestic mountain background...\"`\r\n\r\n#### 5.4.4 风格一致性规则\r\n\r\n所有生成的资产必须共享统一的视觉风格：\r\n\r\n1. **色彩统一** - 所有角色和场景资产使用相同的调色板\r\n   - 参考：脚本JSON中的 `asset_inventory.style_reference`\r\n   - 一致地应用色彩关键词（如\"温暖复古\"、\"电影感\"、\"纪录片风格\"）\r\n\r\n2. **光照统一** - 保持每个场景组的光照情绪一致\r\n   - 历史场景：\"温暖复古胶片颗粒光照\"\r\n   - 现代场景：\"锐利自然光，略微饱和\"\r\n\r\n3. **质感统一** - 使用一致的质量关键词\r\n   - 基础：\"高度细致，照片级真实，电影感，4K\"\r\n   - 风格化：\"艺术感，插画风格，一致的线条工作，[特定风格]\"\r\n\r\n4. **角色一致性** - 当同一角色出现在多个镜头中\r\n   - 在每个提示词中始终包含识别特征（面部特征、服装、关键道具）\r\n   - 对该角色的所有提示词使用相同的风格关键词\r\n\r\n#### 5.4.5 资产库组织\r\n\r\n所有资产放入 **$HOME/WorkBuddy/\\<项目名\\>/** 的 `images/` 子文件夹，结构如下：\r\n\r\n```\r\n$HOME/WorkBuddy/<项目名>/\r\n├── script.json\r\n├── images/\r\n│   ├── characters/\r\n│   │   ├── 名称_front.png           (正面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_side.png            (侧面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_back.png            (背面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_3quarter.png        (3/4侧面全身照，白色纯色背景无环境元素)\r\n│   │   ├── 名称_face.png            (面部极致特写)\r\n│   │   ├── 名称_head_angles.png     (头部多角度参考)\r\n│   │   ├── 名称_hands_feet_gestures.png  (手脚姿态研究)\r\n│   │   ├── 名称_reference.png       (角色设定参考板)\r\n│   │   ├── 名称_expressions.png     (表情研究表)\r\n│   │   ├── 名称_props.png           (配饰与道具特写)\r\n│   │   └── 名称_face_details.png    (面部五官特写)\r\n│   ├── scenes/\r\n│   │   ├── 场景名_广角.png   (广角空镜头，16:9，无人物)\r\n│   │   ├── 场景名_中景.png    (中景空镜头，16:9，无人物)\r\n│   │   ├── 场景名_特写.png (细节空镜头，16:9，无人物)\r\n│   │   ├── 场景名_白天.png   (白天光照变体)\r\n│   │   ├── 场景名_黄金时刻.png (黄金时刻光照变体)\r\n│   │   └── ...\r\n│   ├── props/\r\n│   │   ├── 道具名_01.png      (道具多角度)\r\n│   │   └── ...\r\n│   ├── style/\r\n│   │   ├── color_palette.png   (调色板参考卡)\r\n│   │   └── first_frame.png    (视频首帧合成图，含人物+场景+道具)\r\n│   └── storyboard/            ← 分镜首帧参考图，用于图生视频\r\n│       ├── shot_01_first_frame.png  (分镜1)\r\n│       ├── shot_02_first_frame.png  (分镜2)\r\n│       └── ...\r\n├── videos/\r\n├── output/\r\n└── ...\r\n```\r\n\r\n**关键规则**：\r\n\r\n1. **角色资产**（共11种必须生成）：\r\n\r\n   **基础全身照（4种，必须生成）**：\r\n   - `名称_front.png` - **正面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_side.png` - **侧面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_back.png` - **背面全身照**（9:16或3:4），**白色纯色背景**，**必须从头到脚完整（含靴子）**\r\n   - `名称_3quarter.png` - **3/4侧面全身照**（介于正面和侧面之间），**白色纯色背景**，**必须从头到脚完整（含靴子）**，展示角色立体感\r\n\r\n   **面部与细节（3种，必须生成）**\r\n   - `名称_face.png` - **面部极致特写**，展示五官细节（9:16），表情需符合角色性格\r\n   - `名称_head_angles.png` - **头部多角度参考**（方形或16:9），展示6个角度（正面、3/4、侧面、背面、仰视、俯视），确保3D建模/AI生成一致性\r\n   - `名称_hands_feet_gestures.png` - **手脚姿态研究**（方形或16:9），展示10种手部姿态和8种脚部/走路姿态，确保角色动作一致性\r\n\r\n   **角色设定与扩展（4种，必须生成）**：\r\n   - `名称_reference.png` - **角色设定参考板**（16:9或方形），**不透明背景**，参考专业角色设计参考板（含全身视图、头部多角度、表情研究、面部特写、服饰细节、配饰道具、手脚姿态），**一次性生成，用于角色一致性参考**\r\n   - `名称_expressions.png` - **表情研究表**（方形或16:9），展示10种表情（开心、惊讶、愤怒、悲伤、困惑、大笑、皱眉、思考、痛苦、疑惑）\r\n   - `名称_props.png` - **配饰与道具特写**（方形或16:9），展示武器、发簪、披风扣、腰带、靴子等道具细节\r\n   - `名称_face_details.png` - **面部五官特写**（方形，1024×1024），展示眼部/鼻部/唇部/耳部四部位特写拼图。用方案F生成（4张独立部位特写→PIL脚本拼接）\r\n\r\n   **全身照关键规则**：prompt中必须包含 `from head to toe` / `complete full body including feet` 等关键词，确保构图完整；表情需符合角色性格定位（如\"冷艳中带温情\"而非\"愤怒\"）\r\n\r\n2. **场景资产**（必须是空镜头，无人物）：\r\n   - 生成**多角度场景图**（广角/中景/特写）\r\n   - 可以是 **16:9 横向**，突出环境细节和空间感\r\n   - 每个场景至少生成 2-3 张（广角/中景/特写）\r\n   - 光照变体至少 2 种（白天/黄金时刻）\r\n   - 文件命名：`images/scenes/<场景名>_广角.png`、`<场景名>_中景.png`、`<场景名>_白天.png` 等\r\n\r\n3. **辅助资产**（当脚本需要除了主角之外的批量/群体角色时，为其生成三视图作为参考）：\r\n   - 典型场景：**两军对垒**（明军vs蛮兵）、**卫兵/随从**、**特定道具/装备**等\r\n   - 每类辅助资产生成 front / side / back 三视角，白色纯色背景，768×768\r\n   - 生成方式：**文生图**（无参考图，纯文字提示词）\r\n   - 提示词结构：`[时代] [类别] [视图] 全身视图，[装备描述]，[姿态]，完整全身从头到脚包括靴子，白色纯色背景，古风写实`\r\n   - 文件命名：`images/troops/<类别名>_front.png`、`<类别名>_side.png`、`<类别名>_back.png`\r\n   - 在 `script.json` 中增加相应的 `xxx_cards` 字段（如 `troop_cards`）描述特征和提示词\r\n   - 分镜首帧图涉及辅助资产时，将其与场景图、角色图合并为一张参考板使用\r\n\r\n4. **首帧合成图（全局风格参考）**：\r\n   - 视频的**首帧合成图**（first frame）是人物、场景、道具的合成图\r\n   - 用于确定整体视觉风格和色调\r\n   - 保存在 `images/style/first_frame.png`\r\n\r\n5. **分镜首帧图（分镜级，用于图生视频）**：\r\n   - **每个镜头**生成一张独立的**分镜首帧图**，作为该镜头视频生成的参考图\r\n   - 分镜图 = **场景 + 主要人物 + 次要人物 + 道具**的合成图，构图与 `image_prompt` 一致\r\n   - **比例**：由 `script.json` 的 `aspect_ratio` 和项目需求决定（如竖屏 9:16 对应 720×1280，横屏 16:9 对应 1280×720 等），匹配视频输出尺寸\r\n   - **参考图策略**（⚠️ 重要：不要只传角色 front 照做 ref-image）：\r\n     - 以**场景图**为主要 `--ref-image`（保证场景氛围/色调/光照不被白色背景覆盖）\r\n     - 角色一致性通过 **拼图参考板法** 或 prompt 文字描述实现\r\n   - **拼图参考板法**（多张参考图时的标准方案）：\r\n     - 当镜头需要参考**场景 + 多角色 + 辅助资产**时，先用 Python PIL 将所有参考图合并为一张\r\n     - 布局示例：场景图占左侧 2/3，角色/辅助资产图排列在右侧\r\n     - 合并后的单张图约 3-4MB，GitHub raw 上传不受限制\r\n     - 参考脚本：`scripts/make_ref_board.py`（通用模板，改路径即可复用）\r\n   - **多角色同框 Prompt 技巧**：\r\n     - 每个角色名称后紧跟 `(角色特征括号注释)`，如 `女性将军墨雪(国风古典美人鹅蛋脸丹凤眼鸳鸯暗纹玄铁铠甲)`\r\n     - 次要角色描述比主要角色简短，放在动作描述中自然带出\r\n     - ⚠️ **武器、装备、动作细节不要放进括号内**，括号内容容易被模型视为弱权重注释。应该写成自然语句：✅ `\"明军士兵持长枪突刺、拔腰刀近身格斗\"` ❌ `\"明军士兵（持长枪腰刀）\"`\r\n   - 生成方式：**图生图**，以合并后的单张参考板为 `--ref-image`\r\n   - 提示词中用 `image_prompt_cn`（eastern）或 `image_prompt`（western），并补充角色特征描述\r\n   - 命名规则：`images/storyboard/shot_<镜头编号>_first_frame.png`\r\n   - 示例：`images/storyboard/shot_01_first_frame.png`（分镜1）\r\n   - 该镜头后续视频生成时，以 storyboard 图为第一帧参考 + `video_prompt` 图生视频\r\n\r\n> `scripts/` 目录下提供辅助工具脚本：`make_ref_board.py`（合成参考板）、`stitch_face_details.py`（拼接面部细节图）。\r\n\r\n6. **风格统一**：\r\n   - 所有资产（角色、场景、道具）必须**风格统一**\r\n   - 遵循 `script.json` 中的 `tone` 和 `visual_thread` 设定\r\n   - 调色板参考 `images/style/color_palette.png`\r\n\r\n7. **文件位置**：\r\n   - 角色图、场景图必须保存在**项目文件夹下的 `images/`**，不要保存到 `generated-images/` 或其他全局文件夹\r\n   - 每个视频项目有独立的资产库，确保资产和脚本的对应关系清晰\r\n\r\n8. **生成顺序（优先图生图策略）**：\r\n   - 第一步：生成**全身照4种**（front / side / back / 3quarter）\r\n     - 使用 **文生图**（白色纯色背景，全身从头到脚含靴子）\r\n     - 优先用 Agnes AI\r\n   - 第二步：以4种全身照为参考图，**图生图**生成剩余7种资产：\r\n     - **face / face_details**：用 text-only 生成（img2img 会继承参考图背景/铠甲，纯脸图不适合）\r\n     - **head_angles / expressions**：以 front 图为参考，图生图\r\n     - **hands_feet / props**：以 front + side 图为参考，图生图\r\n     - **reference**：以全部4张为参考，图生图\r\n   - 第三步：生成场景空镜头（多角度）\r\n   - 第四步：生成首帧合成图（确定整体风格）\r\n   - 第五步：为**每个镜头**生成分镜首帧图，保存到 `images/storyboard/`\r\n   - 第六步：以 storyboard 图为参考图 + `video_prompt`，逐镜头图生视频\r\n\r\n   > 图生图使用 `project-generate` skill 自动上传到 GitHub raw 获取公网直链。\n\nFile v2.7.0:references/e2e-walkthrough.md\n\n# 端到端案例：锈甲天凤（34秒古风短剧）\r\n\r\n本文档展示 AI 视频流水线从飞书文档输入到最终成片的完整流程，以 **锈甲天凤** 项目为真实案例。\r\n\r\n> **路径说明**：本文档使用 `<skill-root>` 作为 skill 安装根目录的占位符（含 `SKILL.md` 的目录）。\r\n> 实际使用时，在 skill 根目录执行可省略前缀（如 `python3 scripts/create_project.py ...`），\r\n> 或在项目目录下使用完整路径（如 `python3 <skill-root>/skills/project-generate/scripts/project_generate.py ...`）。\r\n> 详情参见 `scripts/_paths.py` 的三层路径模型。\r\n\r\n---\r\n\r\n## 第 1 步：飞书文档输入\r\n\r\n用户在飞书写需求文档，标题格式：`【AI视频】【短剧】锈甲天凤`\r\n\r\n文档内容（精简版）：\r\n```\r\n标题：锈甲天凤\r\n类型：古风短剧\r\n时长：34秒\r\n画幅：9:16（竖屏）\r\n角色：\r\n  - 墨雪（明龙国女元帅，冷冽沉稳）\r\n  - 墨将（年轻副将，忠诚活泼）\r\n场景：龙南战场、城楼议事堂、城墙之上\r\n剧情：敌军压境，墨雪与墨将在议事堂密议破敌之策...\r\n```\r\n\r\n## 第 2 步：视频类型路由\r\n\r\nAI 视频流水线检测到文档标题包含 `【AI视频】【短剧】`：\r\n\r\n```json\r\n{\r\n  \"type\": \"短剧\",\r\n  \"project_name\": \"锈甲天凤\",\r\n  \"project_dir\": \"$HOME/WorkBuddy/锈甲天凤/\"\r\n}\r\n```\r\n\r\n加载 `references/types/短剧.md` 中的类型规则。\r\n\r\n## 第 3 步：创建项目目录\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython3 scripts/create_project.py \\\r\n  --project \"$HOME/WorkBuddy/锈甲天凤\" --template short_drama\r\n```\r\n\r\n自动创建 13 个标准目录并写入 `script.json` 模板。\r\n\r\n创建后的结构：\r\n```\r\n$HOME/WorkBuddy/锈甲天凤/\r\n├── script.json          (模板)\r\n├── images/characters/   (角色资产)\r\n├── images/scenes/       (场景资产)\r\n├── images/storyboard/   (分镜首帧图)\r\n├── images/style/        (风格参考)\r\n├── images/props/        (道具资产)\r\n├── videos/              (视频片段)\r\n├── output/              (最终输出)\r\n├── sounds/              (音效/配乐)\r\n├── assets/              (资产清单)\r\n├── prompts/             (提示词文件)\r\n├── references/          (原始需求)\r\n├── scripts/             (快捷入口)\r\n└── tasks/               (任务追踪)\r\n```\r\n\r\n## 第 4 步：生成脚本 JSON\r\n\r\nAI 视频流水线根据需求文档生成 `script.json`，包含角色卡、场景卡和分镜表。\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"title\": \"锈甲天凤\",\r\n    \"duration_seconds\": 34,\r\n    \"aspect_ratio\": \"9:16\",\r\n    \"type\": \"短剧\",\r\n    \"provider\": \"agnes\"\r\n  },\r\n  \"character_cards\": [ /* 墨雪 + 墨将 */ ],\r\n  \"scene_cards\": [ /* 龙南战场 + 城楼议事堂 + 城墙之上 */ ],\r\n  \"shots\": [ /* 9 个镜头 */ ],\r\n  \"shot_groups\": [ /* 3 组镜头 */ ]\r\n}\r\n```\r\n\r\n## 第 5 步：生成角色资产\r\n\r\n```bash\r\ncd \"$HOME/WorkBuddy/锈甲天凤\"\r\n\r\n# 一键生成所有角色（标准 4 视图：正面全身 / 面部 / 侧面 / 背面；另按武器·动作动态生成持械与动作视图，数量随角色卡而定）\r\n# <skill-root> 为 skill 安装根目录（含 SKILL.md），请替换为实际路径\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-characters\r\n# 别名：gc\r\n```\r\n\r\n## 第 6 步：生成场景资产\r\n\r\n```bash\r\n# 每场景 3 张变体（广角/中景/特写）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-scenes\r\n# 别名：gs\r\n```\r\n\r\n## 第 7~8 步：生成首帧图\r\n\r\n```bash\r\n# 初始化各 shot 的 first_frame 配置和 prompt 模板（不调 API）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . build-first-frames\r\n# 别名：bff\r\n\r\n# 调 API 批量生成首帧图\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . generate-images\r\n# 别名：gi\r\n```\r\n\r\n## 第 9 步：提交 + 轮询 + 拼接\r\n\r\n```bash\r\n# 提交所有 shot 视频任务（自动按 provider 路由：Agnes / 小云雀）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . submit\r\n\r\n# 轮询完成状态，全部完成后自动触发 ffmpeg 拼接\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . poll\r\n\r\n# 查看项目总状态\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . status\r\n```\r\n\r\n## 全自动模式\r\n\r\n以上第 5~9 步可合并为一条命令：\r\n\r\n```bash\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . auto\r\n\r\n# 本地追踪模式（不依赖飞书）\r\npython3 <skill-root>/skills/project-generate/scripts/project_generate.py \\\r\n  --project . auto --tracker local\r\n```\r\n\r\n`auto` 自动执行：角色资产 → 场景资产 → 首帧图 → 提交 → 轮询 → 拼接。\r\n\r\n---\r\n\r\n## 完整流程图\r\n\r\n```\r\n飞书需求文档\r\n    │\r\n    ▼\r\n[1] 类型路由 ── 检测【AI视频】【短剧】→ 加载短剧规则\r\n    │\r\n    ▼\r\n[2] 创建项目 ── create_project.py\r\n    │\r\n    ▼\r\n[3] 生成 script.json ── 角色卡 + 场景卡 + 分镜（AI 驱动）\r\n    │\r\n    ──── 切换到 project-generate 流水线 ────\r\n    │\r\n    ▼\r\n[4] 角色资产 ── gc（每角色视图数随角色卡而定）\r\n    │\r\n    ▼\r\n[5] 场景资产 ── gs（每场景 3 张）\r\n    │\r\n    ▼\r\n[6] 首帧配置 ── bff\r\n    │\r\n    ▼\r\n[7] 首帧图生成 ── gi\r\n    │\r\n    ▼\r\n[8] 视频提交 ── submit（按 provider 路由）\r\n    │\r\n    ▼\r\n[9] 轮询 + 拼接 ── poll（ffmpeg 自动拼接）\r\n    │\r\n    ▼\r\n[10] 交付 ── output/final.mp4\r\n```\r\n\r\n**快捷方式**：`create_project.py` → `auto`，2 个命令走完全流程。\n\nFile v2.7.0:references/editing-specs.md\n\n# 剪辑与包装规范\n\n本文件提供字幕、转场、片头片尾的完整规范，由主 SKILL §8 抽取而来。\n\n---\n\n## 字幕规范\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| **字体大小** | 36px（9:16竖屏）/ 28px（16:9横屏） | 对白主体，保证可读性 |\n| **情绪/标题字号** | 48px | 情绪字幕（如\"三年后\"\"三日后\"） |\n| **底部留白** | 距底部 60px | 不遮挡人物面部或关键视觉区域 |\n| **字体** | 思源黑体 / Noto Sans SC（粗体） | 中文字体，清晰无衬线 |\n| **字体颜色** | 白色 #FFFFFF | 带 0.3 透明度黑色描边保证在任何背景可读 |\n| **停留时间** | 朗读时间 + 0.5秒（缓冲） | 确保读完不抢切 |\n| **行数限制** | ≤ 2行（9:16竖屏）；≤ 3行（16:9横屏） | 避免画面被字幕遮挡过多 |\n| **最长单行** | ≤ 18字（9:16竖屏）；≤ 30字（16:9横屏） | 保证单行阅读舒适度 |\n\n- **对白字幕**：底部居中，不得遮挡面部表情\n- **情绪字幕**（如\"三年后\"）：可用艺术字，配合转场\n- **字幕入场动画**：淡入（默认 0.2s）→ 停留 → 淡出（默认 0.2s）\n\n---\n\n## 音效与转场\n\n| 转场 | 默认时长 | 用法 | 适用场景 |\n|------|---------|------|---------|\n| **硬切** | 0s | 标准叙事过渡 | 90%以上的转场 |\n| **叠化** | 0.3s（叙事）/ 0.5s（情绪过渡） | 时间跳转或情绪过渡 | 场景变换、记忆/闪回 |\n| **闪白** | 0.15s（闪回）/ 0.3s（强烈冲击） | 强烈情绪冲击或记忆 | 惊讶、顿悟、回忆切入 |\n| **黑场** | 0.5-1.0s | 悬念停顿 | 留给观众思考的空间 |\n\n**音画先行规则**：下一个镜头的音效/对白应提前 0.5s 进入当前镜头的尾部。\n\n**转场混合建议：**\n\n| 场景类型 | 推荐转场 | 备注 |\n|----------|---------|------|\n| 同场景同组间 | 硬切（0s） | 保持连续性 |\n| 场景切换 | 叠化（0.3s） | 让观众感知空间变化 |\n| 时间跳转 | 叠化（0.5s） | 较长的叠化暗示时间流逝 |\n| 记忆/梦境切入 | 闪白（0.15s） | 快速鲜明地切换语境 |\n| 悬念/高潮后 | 黑场（0.5s） | 给观众呼吸空间 |\n\n---\n\n## 片头/片尾\n\n| 参数 | 默认值 | 说明 |\n|------|--------|------|\n| **钩子出现时间** | 前 3s 内 | 片头必须在此时间内出现核心冲突/反差/高能对白 |\n| **片头标题停留** | 1.5s | 标题字幕或LOGO动画的展示时间 |\n| **片头缓冲** | 0.3s（淡入） | 视频起始从黑场淡入到第一帧 |\n| **片尾停留** | 2.0s | 最后镜头结束后停留画面，叠加片尾字幕 |\n| **片尾缓冲** | 0.5s（淡出） | 画面淡出到黑场 |\n| **片尾钩子** | \"关注/续看引导\" 2.0s | 引导语或预告画面的停留时间 |\n\n- **片头**：3秒内出现核心冲突或钩子，不铺陈。建议用硬切入画或淡入+音效甩入\n- **片尾**：埋下钩子或情绪余韵，引导续看/互动。建议用叠化+尾声音乐淡出\n\nFile v2.7.0:references/pacing-narrative.md\n\n# 节奏控制与叙事结构参考\n\n本文件提供节奏曲线和叙事结构的完整参考，由主 SKILL §7.8-§7.9 抽取而来。\n\n---\n\n## 节奏控制曲线\n\n所有叙事类视频应遵循情绪节奏曲线。平淡、单调的节奏是常见的质量陷阱。\n\n**情绪曲线模板：**\n```\n情绪强度\n   ▲\n高 │      ╱╲  高潮/释放\n   │     ╱  ╲\n中 │────╱    ╲────  转折/冲突\n   │   ╱      ╲\n低 │──╱        ╲──  建置/解决\n   └──────────────────▶ 时间\n      建置  冲突  高潮  收尾\n```\n\n**阶段时长指南：**\n\n| 阶段 | 镜头节奏 | 情绪任务 | 时长占比 |\n|------|---------|---------|---------|\n| **建置/铺垫** | 舒缓，稍长镜头 | 建立世界，制造好奇/悬念 | 15-20% |\n| **转折/冲突** | 加快，短镜头交替 | 引入冲突，推动变化 | 10-15% |\n| **高潮** | 最紧凑，特写密集 | 情绪爆发，爽点/释放 | 20-25% |\n| **钩子** | 突然放缓/定格 | 制造好奇，引导续看 | 5-10% |\n| **收尾** | 舒缓收尾 | 情绪缓冲，余韵留白 | 5-10% |\n\n**应用曲线：**\n- 在 `script.json` 中，规划镜头时长以匹配曲线（不是所有5秒都相等）\n- 用 `\"is_climax\": true` 标记高情绪镜头\n- 在情绪峰值后插入0.5秒填充（`\"padding_after\": 0.5`）\n- 对于多组脚本，每组应有自己的迷你曲线\n\n---\n\n## 叙事结构指南\n\n不同视频类型使用不同的叙事结构。一般原则是**因果逻辑**（因为→所以）而不是**时间顺序**（然后→然后）。\n\n### 三幕式结构（适用于大多数叙事视频）\n\n| 幕 | 占比 | 功能 | 核心任务 |\n|---|------|------|---------|\n| **第一幕：建置** | ~25% | 建立世界、引入角色、埋下钩子 | 让观众\"想知道\" |\n| **第二幕：对抗** | ~50% | 升级冲突、角色挣扎、情绪积累 | 让观众\"感同身受\" |\n| **第三幕：解决** | ~25% | 高潮、反转、余韵 | 让观众\"意犹未尽\" |\n\n### 四幕式结构（适用于文旅/纪录片）\n\n| 幕 | 功能 | 节奏 |\n|----|------|------|\n| **开篇** | 引人入胜的建立，激发兴趣 | 舒缓 |\n| **展开** | 深入展示，旁白叙事驱动 | 中速 |\n| **体验** | 沉浸式展示，视听高潮 | 紧凑 |\n| **升华** | 情感升华，留有余韵 | 舒缓 |\n\n### 观众距离金字塔（情绪节奏框架）\n\n观众的沉浸感按以下层级递进：\n```\n        ▲ 爽点（情绪爆发/满足/反转）\n       ╱ ╲\n      ╱ 共鸣 ╲（与角色共情，代入情感）\n     ╱─────────╲\n    ╱   代入    ╲（进入角色视角，关心命运）\n   ╱───────────────╲\n  ╱     悬念        ╲（产生好奇心，想知道后续）\n ╱─────────────────────╲\n```\n\n**应用规则**：\n- 开场必须制造**悬念**（问题/冲突/反常）\n- 前1/3让观众**代入**角色处境\n- 中1/3建立**共鸣**，让观众与角色共情\n- 高潮和结尾提供**爽点**（反转/满足/释放）\n\n### 悬念推进机制\n\n悬念应层层递进，而不是一次性抛出：\n\n1. **设悬** — 提出问题或展示反常（\"她为什么哭？\"）\n2. **布疑** — 给出线索但引向歧途（\"看起来是他伤害了她\"）\n3. **加深** — 增加压力或时间限制（\"她发现真相后必须在两者之间抉择\"）\n4. **揭晓** — 反转或真相揭示（\"原来一切都是为保护她\"）\n5. **余波** — 释放后的情绪缓冲（0.5-1秒填充）\n\n---\n\n## 避坑原则（通用）\n\n| 坑 | 说明 | 避免方法 |\n|---|------|---------|\n| **工具人陷阱** | 只执行技术生成，不做审美判断 | 每个镜头问：这服务于什么情绪？ |\n| **信息过载** | 一个镜头塞入太多信息 | 一个镜头只传达一个核心信息 |\n| **节奏平铺** | 从头到尾一个速度 | 必须有快-慢-快的节奏变化 |\n| **景别单一** | 全是中景或全是特写 | 强制使用景别交替 |\n| **忽略留白** | 镜头之间没有气口 | 情绪高点后留0.5-1秒缓冲 |\n| **为了炫技** | 运镜花哨但干扰叙事 | 运镜必须服务于剧情，不抢戏 |\n\nFile v2.7.0:references/prompt-rules.md\n\n# Prompt 工程规则（实战踩坑）\n\n> **本文职责**：记录从实际生成中总结的**实战踩坑规则**——角色描述、背景控制、武器道具、一致性保障、错误模式等。\n> **模板结构**（6 段式、语言选择）→ 主 SKILL.md §6\n> **资产生成**（角色 11 视图的具体 prompt）→ `references/asset-generation.md`\n\n---\n\n## 1. 角色外貌描述\n\n### 1.1 头发/头饰\n\n- **必须具体**：不能写\"传统头巾\"\"经典发型\"——模型会自由发挥\n- **写法**：颜色 + 位置 + 系法/样式\n  - ✅ `\"额头缠绕客家蓝染头巾，在前额上方打结固定\"`\n  - ❌ `\"戴客家传统头巾\"`\n  - ✅ `\"灰蓝色红军八角帽，帽檐微微上翘，正中缀红五星\"`\n  - ❌ `\"红军帽\"`\n\n### 1.2 同一角色的外貌描述必须跨视图统一\n\n- `hair` 字段被 `_clothes` 变量共享 → 所有视图的服饰描述一致\n- `face` 视图的 prompt 不应包含 `_clothes`（含 body/build/color 等全身级描述），否则模型把面部特写画成全身照\n- face 视图应只含：`fd_str`（五官细节）+ `hair`（发型/头饰）+ `base`（身份）+ `face`（面容）+ `_white_bg`\n\n---\n\n## 2. 背景控制\n\n### 2.1 纯白背景\n\n- 背景指令必须放在 prompt **开头和末尾**双重强调\n  - 开头：`\"纯白色背景。{视图描述}...\"`\n  - 末尾：`\"...{_white_bg}\"`\n- `_white_bg` 内容：`\"纯白色背景(#FFFFFF)，没有任何颜色、纹理或环境元素，只有纯空白底。\"`\n- 负面提示词必须包含：`\"暖色背景, 灰色背景, 米色背景, 有颜色的背景, 背景光, 复杂背景, 渐变背景, 纹理背景, 环境元素, 场景, 天空, 地面\"`\n- 原因：模型倾向自动填充浅色背景（浅灰/米色），即使 prompt 写了纯白也可能忽略\n\n---\n\n## 3. 武器和道具控制\n\n### 3.1 标准视图禁止武器\n\n- front/face/side/back 四视图：必须包含 `_no_weapon` + `_neg_weapons`\n  - `_no_weapon`：`\"双手自然垂下，手中不持任何武器，不能有剑、枪、刀、弓、盾等任何武器道具。\"`\n  - `_neg_weapons`：`\"手中持剑, 手中持枪, 手持武器, 握剑, 握刀, 武器, 道具, ...\"`\n\n### 3.2 武器视图\n\n- action_xxx / pose_xxx 视图：**不能**包含 `_no_weapon`（与武器描述矛盾）\n- 武器视图也需共享 `_clothes` 以确保衣着一致\n\n---\n\n## 4. 一致性保障\n\n### 4.1 跨视图一致性\n\n| 规则 | 说明 |\n|------|------|\n| 衣着统一 | front/side/back 共享 `_clothes` 变量（face 不用，避免 body 侵入）|\n| 面部统一 | face/side/back 以 front（全身正面无武器白底图）为 ref_image |\n| 背景统一 | 所有标准视图 + 武器/动作视图统一用 `_white_bg` |\n| 武器统一 | 标准视图禁用武器，武器视图没有 `_no_weapon` |\n| 发型/头饰统一 | `hair` 字段跨视图共享，必须具体到颜色+位置+系法 |\n\n### 4.2 ref_image 的选择\n\n- face/side/back 的 ref_image = front（标准四视图使用前视图保持一致性）\n- 武器视图：不设 ref_image（free generation），因为 ref_image 是无武器白底图，与武器 intent 冲突\n- 避免路径通配符回退：**不要从目录级别的通配符读取 ref_image**，只使用本角色前视图的具体路径\n\n### 4.3 画质描述不硬编码铠甲\n\n- [画质要求] 段中的\"铠甲金属质感\"不能硬编码——项目可能是现代题材（无铠甲）\n- 代码中根据 `character_cards` 的 `armor/clothing` 字段自动检测：包含\"铠甲/铁甲/甲胄/战甲\"等关键词才追加\n- 无铠甲时默认只写：`\"电影级写实，服装材质细节，光影层次丰富，氛围情绪饱满。\"`\n\n### 4.4 纯场景镜头不要写\"加入各角色\"\n\n- **纯场景镜头（只有 1 张场景参考图）**：编辑指令不能写\"在场景中加入各角色\"——模型会脑补古人\n- 代码中根据 `ref_count` 自动判断：仅 1 张参考图时，编辑指令改为 `以图1为基础，{desc}`，去掉\"加入角色\"\n- 这个规则也影响了 [保留元素] 段——**已完全禁用 [保留元素]**（无论几张参考图都不加，因为会导致角色朝向被参考图锁定）\n\n### 4.5 构图必须指定角色空间位置\n\n- 含角色的镜头（尤其是多角色），description 必须描述 **前/中/背景 + 左/右位置**\n  - ✅ `\"客家老人坐在左侧长椅上看报，现代青年从右侧跑步经过\"`\n  - ❌ `\"青年与老人相视而笑\"`（模型不知道人放哪里）\n- 全景+人物镜头：前景=人物站位，中景=城市/场景，背景=天空/远景\n\n### 4.6 角色行为必须匹配身份\n\n- video_prompt 和首帧图 prompt 中角色行为必须符合其身份特征：\n  - ❌ 客家老人在城市公园看报（客家老人是传统文化守护者，不会出现在城市）\n  - ❌ 古代角色穿T恤、现代角色穿铠甲\n  - ❌ 老者做敏捷动作（除非角色卡明确写了）\n- 验证方法：写完 description 后，问自己\"这个角色真的会做这件事吗？\"\n\n---\n\n## 5. 常见错误模式\n\n| 错误 | 现象 | 根因 | 修复 |\n|------|------|------|------|\n| face 画成全身照 | face 视图是全身而非特写 | face prompt 末尾拼了 `_clothes`（含 body/build/color）覆盖了\"面部特写\"指令 | face 只用 `fd_str` + `hair` + `base` + `face`，不用 `_clothes` |\n| 背景不是纯白 | 浅灰/米色背景 | 背景描述在 prompt 中间权重不足，被前面气氛词覆盖 | 开头+末尾双重强调 + 增强负面词 |\n| 头饰不一致 | 不同视图显式不同头饰 | `hair` 字段模糊（如\"传统头巾\"），模型自由发挥 | 描述精确到颜色+位置+系法 |\n| 人物有武器 | 标准视图手持武器 | 武器描述在 armor 字段中，被错误引入标准视图 | `_armor_clean` 剥离武器关键词 + `_no_weapon` + `_neg_weapons` |\n| 脚部被截断 | 脚踝以下被裁切 | prompt 缺少明确的全身指示 | 加 `_full_body`：`\"包含鞋子的完整全身从头到脚，不能截断脚部。\"` |\n| feishu_doc_id 为空 | poll 显示\"无项目数据\" | `script.json` 没配 `feishu_doc_id`，飞书查询按空 doc_id 过滤 | `create_project.py` 已自动填充；手动创建时检查 `script.feishu_doc_id` 是否从 URL 提取 |\n\n---\n\n## 6. 生成模式选择\n\n### 6.1 默认使用 standard 模式\n\n- **所有视频生成默认使用 `standard` 模式**（首帧合成图作参考 + video_prompt 驱动的动态视频）\n- 流程：`bff`（构建首帧配置）→ `gi`（生成首帧合成图）→ `submit`（standard 模式提交视频）\n- 即使是多角色/场景+人组合，也应先生成合成首帧图（场景+角色合为一张），再用 `standard` 模式\n\n### 6.2 multi-image 模式的定位\n\n`multi-image` 模式是**多张参考图之间的过渡动画**，不是真正的场景视频合成。它只适用于纯视觉过渡效果，不适用于需要角色动作/剧情推进的场景。\n\n- ❌ 不用于常规视频生成（效果是\"图A渐变到图B\"的动画）\n- ✅ 仅用于特殊的纯过渡/风格变换场景\n\n### 6.3 参考图完整性\n\n- 如果使用了 `multi-image` 模式：至少需要 2 张参考图，否则提交失败\n- 参考图路径必须指向**实际存在的文件**\n- 三种资产类型的依赖关系：\n\n```\ncharacter_cards → auto阶段3 → images/characters/{name}_front.png\ntroop_cards     → auto阶段4 → images/troops/{name}_front.png\nscene_cards     → auto阶段5 → images/scenes/{name}_宽高.png\n```\n\n> `troop_cards` 是\"辅助资产卡\"——可包含道具、军队、武器、群众等。\n\n### 6.4 引用了就一定要生成\n\n- shot 的 `reference_images` 中用到的所有资产路径必须确保文件存在\n- 不会自动回退\n\n---\n\n## 7. 常见运行错误\n\n### 7.1 GitHub 图片缓存不更新\n\n- `image_api.upload_to_url()` 检测到文件在 GitHub 上已存在时，**不会比较 SHA**，直接返回旧 URL\n- 即使本地首帧图已重新生成，传给 Agnes API 的参考图 URL 还是旧的\n- 修复：比较本地 SHA 与远程 SHA，不同则上传新版本\n- **定性**：视频内容\"看起来一样\"时，优先检查 GitHub 上参考图 URL 指向的图片是否已更新\n\n### 7.2 模块 import 路径被覆盖\n\n- `audio.py` 用 `from config import get_freesound_key`，但 `sys.modules[\"config\"]` 可能已被 agnes-ai 的 config 模块覆盖（通过 `_agnes_mod()` 注入）\n- 此时 `from config import xxx` 会拿到 agnes-ai 的 config，缺少项目级 config 的函数\n- 修复：不用顶层 import，改为通过 `_shared_tools` 统一配置读取（走 Layer 2 优先级链）\n- **定性**：项目级模块（`project-generate/scripts/modules/`）不要用 `from config import`，改用 `from modules.config import` 或直接读取配置\n\n### 7.3 lark-cli 在 subprocess 中找不到\n\n- `feishu.py` 的 `_lark()` 通过 `subprocess.run` 调用 `lark-cli.cmd`\n- 在 Windows nohup 环境下，`.cmd` 批处理文件可能无法被 `subprocess.run` 正确执行\n- 手动在 Bash 中跑 `lark-cli` 能成功，但 Python `subprocess.run` 静默失败\n- **后果**：飞书 Base 写入（`upsert_task`）静默失败，poll 找不到记录，但提交者以为成功了\n- 修复：加 `shell=True` 或用 `\"cmd\" \"/c\"` 前缀（注意参数长度限制）\n- 变通：通过 Bash 工具手动执行 `lark-cli base +record-upsert` 插入记录\n\n### 7.4 轮询死循环：旧记录不删 + 新记录写不回\n\n这是 7.3 的连锁后果：\n\n```\n1. submit 创建新任务 → upsert_task(lark-cli) 失败 → 飞书无新记录\n2. 飞书里只有旧记录（有旧 task_id，已过期/HTTP 400）\n3. poll 轮询 → 按旧 task_id 查 Agnes API → 400 → 触发重试\n4. 重试提交新任务 → 新任务完成 ✅ 但 upsert_task 又失败了\n5. 回到步骤 3 → 死循环 🔄\n```\n\n**判断标准**：\n- poll log 持续显示 `🔴 重试提交成功` 但任务状态一直是\"queued\"\n- 飞书 Base 记录数不变（全是旧记录）\n- 手动查 Agnes API 发现新 task_id 其实已完成\n\n**修复**：\n1. 查 Agnes API 获取最新已完成的任务 ID\n2. 手动用 `lark-cli base +record-upsert` 插入正确记录\n3. 删掉旧记录\n4. 修复 lark-cli subprocess 问题（见 §7.3）\n\n### 7.5 FeishuTracker 本地缓存兜底\n\n- `FeishuTracker.upsert_task()` 始终**优先写入本地 JSON 缓存**（`tasks/task_tracker_fallback.json`），再写飞书 Base\n- 飞书写入失败时打印 `⚠️ 飞书写入失败` 日志，但数据不丢（本地缓存保底）\n- `list_tasks()` 读取飞书后，用本地缓存**覆盖** task_id 和 status\n- 即使飞书完全不可用，重试也不进死循环\n\n### 7.6 原子化重试流程\n\n重试视频任务的三步流程：\n\n| 步骤 | 操作 | 关键点 |\n|------|------|--------|\n| 1 | `upsert_task(\"\", \"pending\")` | 清空旧 task_id，状态→pending，写入本地缓存 |\n| 2 | `provider.submit_video(...)` | 提交新任务 |\n| 3 | `upsert_task(new_task, \"queued\")` | 写回新 task_id，状态→queued |\n\n即使步骤 1/3 飞书写入失败，本地缓存确保下次 poll 读到正确数据。\n\n---\n\n## 8. BGM 管理\n\n### 8.1 自定义 BGM 优先\n\n- `sounds/bgm_custom.mp3` 存在时**优先使用**，跳过 FreeSound 自动搜索\n- 不存在时回退到 FreeSound 搜索（按 `script.tone` → 关键词 → 搜索 → 下载预览）\n\n### 8.2 多段 BGM 拼接\n\n- 可用 ffmpeg 将多段音乐拼接成自定义 BGM，匹配视频的叙事段落\n- 每段用 `atrim` 截取所需长度，`acrossfade` 做交叉淡入淡出过渡\n- 示例（三段式：史诗→传统→希望）：\n  ```\n  [0:a]atrim=0:15[seg1];[1:a]atrim=0:10[seg2];[2:a]atrim=0:15[seg3]\n  [seg1][seg2]acrossfade=d=1.0[mix1];[mix1][seg3]acrossfade=d=1.0[final]\n  ```\n\n### 8.3 推荐套索来源\n\n| 来源 | 协议 | 说明 |\n|------|------|------|\n| FreeSound (freesound.org) | CC0/CC | 已内置 API 支持，自动搜索+下载 |\n| Pixabay Music | Pixabay License | 免费可商用，直接下载 MP3 |\n| FreePD (freepd.cn) | CC0 | 公共领域，无需署名 |\n\n---\n\n## 9. Windows ffmpeg 避坑\n\n### 9.1 禁用 xfade 转场\n\n- **Windows 上 xfade + acrossfade 链式叠加有音视频时间轴漂移问题**\n- 漂移随转场次数累积，7 段拼接时约在 27s 处出现画面卡死\n- 修复：禁用 xfade，全用简单 concat（`-f concat -safe 0 -c copy`）\n- 简单 concat 帧级精确，无漂移风险\n- `shot_durations()` 计算镜头开始/结束时间时**不加 xfade 重叠**\n\n### 9.2 像素格式必须指定\n\n- `subtitles` 滤镜或某些 filter graph 在 Windows 上默认输出 `yuv444p`\n- `yuv444p` 不被部分播放器支持 → 画面黑屏/无法播放\n- 修复：所有 ffmpeg 输出加 `-pix_fmt yuv420p`\n\n### 9.3 subtitles 滤镜中文路径问题\n\n- Windows 上 libass 对中文路径支持不好，`subtitles` 滤镜可能导致 ffmpeg 退出码 4294967274\n- 修复：复制 SRT 到纯 ASCII 临时路径（`C:\\Users\\...\\cb_xxxx\\subs.srt`），在 filter_complex 中引用\n- filter_complex 方式：在 filter_complex_script 末尾追加 `;[0:v]subtitles='path'[vsub]`，输出映射改为 `[vsub]`\n\n### 9.4 音频采样率冲突\n\n- FreeSound 预览 BGM 通常是 24000Hz mono，TTS 输出也是 24000Hz mono\n- amix 混合后默认输出可能保持 24000Hz，但视频标准是 48000Hz stereo\n- 修复：`-ar 48000 -ac 2` 强制输出 48kHz 立体声\n\n---\n\n## 10. TTS 与字幕\n\n### 10.1 edge-tts 不支持 SSML\n\n- `edge_tts.Communicate(ssml, voice)` 不解析 SSML 标签，直接**朗读 XML 标签内容**\n- 导致 TTS 时长飙升至 30s+（在念 \"speak version 1.0 xmlns\"）\n- 修复：始终使用纯文本调用 `edge_tts.Communicate(text, voice).save(path)`\n- 如需控制停顿，在原始文本中加入标点符号（edge-tts 会自然停顿）\n\n### 10.2 字幕时长与实际 TTS 同步\n\n- 字幕结束时间使用 `_wav_duration()` 读取 WAV 实际时长，而不是字符数估算\n- `_char_per_sec()` 作为回退（读取失败时使用）\n- 字幕文本去掉/替换标点符号为空格：\n  - 句末（。！？）→ 两个全角空格\n  - 句中（，、：；）→ 一个全角空格\n\nArchive v1.0.2: 74 files, 339195 bytes\n\nFiles: CHANGELOG.md (2046b), config/keys.example.env (1029b), pipeline-diagram.svg (6563b), README.md (5028b), references/asset-generation.md (23160b), references/e2e-walkthrough.md (5545b), references/editing-specs.md (2995b), references/pacing-narrative.md (4229b), references/prompt-rules.md (14063b), references/provider-config.md (2836b), references/repair-strategy.md (6104b), references/script-json-checklist.md (7834b), references/segment-design.md (7621b), references/setup-guide.md (3730b), references/shot-scales.md (9633b), references/templates.json (2058b), references/troubleshooting.md (6368b), references/types/default.md (2898b), references/types/文旅.md (8449b), references/types/电影级长剧.md (10533b), references/types/短剧.md (18293b), references/video-modes.md (3256b), requirements.txt (72b), sample/README.md (1101b), sample/script.json (1884b), scripts/create_project.py (5090b), scripts/make_ref_board.py (5943b), scripts/stitch_face_details.py (3029b), skill-card.md (2712b), SKILL.md (10677b), skills/agnes-ai/scripts/generate_image.py (6085b), skills/agnes-ai/scripts/generate_video.py (5936b), skills/agnes-ai/scripts/modules/__init__.py (933b), skills/agnes-ai/scripts/modules/api.py (428b), skills/agnes-ai/scripts/modules/config.py (8769b), skills/agnes-ai/scripts/modules/image_api.py (13729b), skills/agnes-ai/scripts/modules/prompt.py (13707b), skills/agnes-ai/scripts/modules/video_api.py (12779b), skills/agnes-ai/SKILL.md (22317b), skills/project-generate/scripts/modules/agnes_provider.py (17677b), skills/project-generate/scripts/modules/audio.py (14121b), skills/project-generate/scripts/modules/base_provider.py (9149b), skills/project-generate/scripts/modules/config.py (9594b), skills/project-generate/scripts/modules/data_validator.py (3640b), skills/project-generate/scripts/modules/error_utils.py (5241b), skills/project-generate/scripts/modules/feishu.py (17946b), skills/project-generate/scripts/modules/hyperframes_stitch.py (11058b), skills/project-generate/scripts/modules/img_host.py (5759b), skills/project-generate/scripts/modules/launch_background.py (2778b), skills/project-generate/scripts/modules/project_commands.py (124387b), skills/project-generate/scripts/modules/project_diff.py (4687b), skills/project-generate/scripts/modules/project_preview.py (9296b), skills/project-generate/scripts/modules/project_stats.py (8004b), skills/project-generate/scripts/modules/project_verify.py (83232b), skills/project-generate/scripts/modules/provider_factory.py (6653b), skills/project-generate/scripts/modules/script_generator.py (19609b), skills/project-generate/scripts/modules/speech.py (7176b), skills/project-generate/scripts/modules/stitch_base.py (2117b), skills/project-generate/scripts/modules/stitch_ffmpeg.py (16428b), skills/project-generate/scripts/modules/stitch.py (1341b), skills/project-generate/scripts/modules/task_tracker_feishu.py (14319b), skills/project-generate/scripts/modules/task_tracker_local.py (5225b), skills/project-generate/scripts/modules/task_tracker.py (1896b), skills/project-generate/scripts/modules/type_registry.py (5338b), skills/project-generate/scripts/modules/video_utils.py (55385b), skills/project-generate/scripts/modules/xiaoyunqiao_provider.py (19357b), skills/project-generate/scripts/pipeline.py (14990b), skills/project-generate/scripts/project_generate.py (17143b), skills/project-generate/scripts/type_defs/military.json (540b), skills/project-generate/SKILL.md (12618b), skills/script-optimizer/scripts/optimize.py (123219b), skills/script-optimizer/scripts/prompt_builder.py (52099b), skills/script-optimizer/SKILL.md (15182b), _meta.json (142b)\n\nFile v1.0.2:SKILL.md\n\n---\r\nname: ai-video-auto-generator\r\nversion: 2.3.0\r\ndescription: \"AI 短视频全自动流水线：从想法到成片，一键出视频。脚本生成→自动修复→资产生成→视频→音频→字幕，全自动无人值守。| AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → \n\nArchive v1.0.1: 73 files, 310332 bytes\n\nFiles: CHANGELOG.md (2891b), config/keys.example.env (1029b), pipeline-diagram.svg (6563b), README.md (5028b), references/asset-generation.md (23160b), references/e2e-walkthrough.md (5545b), references/editing-specs.md (2995b), references/pacing-narrative.md (4229b), references/prompt-rules.md (14063b), references/provider-config.md (2836b), references/script-json-checklist.md (7834b), references/segment-design.md (7621b), references/setup-guide.md (3730b), references/shot-scales.md (9633b), references/templates.json (2058b), references/troubleshooting.md (6368b), references/types/default.md (2898b), references/types/文旅.md (8449b), references/types/电影级长剧.md (10533b), references/types/短剧.md (18293b), references/video-modes.md (3256b), requirements.txt (72b), sample/README.md (1101b), sample/script.json (1884b), scripts/create_project.py (5090b), scripts/make_ref_board.py (5943b), scripts/stitch_face_details.py (3029b), skill-card.md (2880b), SKILL.md (10677b), skills/agnes-ai/scripts/generate_image.py (6085b), skills/agnes-ai/scripts/generate_video.py (5936b), skills/agnes-ai/scripts/modules/__init__.py (933b), skills/agnes-ai/scripts/modules/api.py (428b), skills/agnes-ai/scripts/modules/config.py (8769b), skills/agnes-ai/scripts/modules/image_api.py (13418b), skills/agnes-ai/scripts/modules/prompt.py (13696b), skills/agnes-ai/scripts/modules/video_api.py (12510b), skills/agnes-ai/SKILL.md (22306b), skills/project-generate/scripts/modules/agnes_provider.py (17677b), skills/project-generate/scripts/modules/audio.py (14113b), skills/project-generate/scripts/modules/base_provider.py (8554b), skills/project-generate/scripts/modules/config.py (9049b), skills/project-generate/scripts/modules/data_validator.py (3640b), skills/project-generate/scripts/modules/error_utils.py (5241b), skills/project-generate/scripts/modules/feishu.py (17946b), skills/project-generate/scripts/modules/hyperframes_stitch.py (11050b), skills/project-generate/scripts/modules/img_host.py (4893b), skills/project-generate/scripts/modules/launch_background.py (2778b), skills/project-generate/scripts/modules/project_commands.py (124602b), skills/project-generate/scripts/modules/project_diff.py (4687b), skills/project-generate/scripts/modules/project_preview.py (9296b), skills/project-generate/scripts/modules/project_stats.py (8004b), skills/project-generate/scripts/modules/project_verify.py (64279b), skills/project-generate/scripts/modules/provider_factory.py (6653b), skills/project-generate/scripts/modules/script_generator.py (19609b), skills/project-generate/scripts/modules/speech.py (7168b), skills/project-generate/scripts/modules/stitch_base.py (2117b), skills/project-generate/scripts/modules/stitch_ffmpeg.py (16420b), skills/project-generate/scripts/modules/stitch.py (1341b), skills/project-generate/scripts/modules/task_tracker_feishu.py (14319b), skills/project-generate/scripts/modules/task_tracker_local.py (5225b), skills/project-generate/scripts/modules/task_tracker.py (1896b), skills/project-generate/scripts/modules/type_registry.py (5338b), skills/project-generate/scripts/modules/video_utils.py (45303b), skills/project-generate/scripts/modules/xiaoyunqiao_provider.py (19349b), skills/project-generate/scripts/pipeline.py (14990b), skills/project...","readmeExcerpt":"Skill: AI video auto generator Owner: jinxuchen2020 Summary: AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Tags: latest:2.7.1 Version history: v2.7.1 | 2026-07-16T07:52:11.271Z | user ai-video-auto-generator 2.7.1 - Added new documentation and audit files for code and docs review, including detailed memory logs und","codeSnippets":[],"executableExamples":[{"language":"text","snippet":"File v2.7.1:README.md\n\n# ai-video-auto-generator\r\n\r\nAI 短视频全自动流水线 — 从想法到成片，一键出视频。"},{"language":"text","snippet":"情绪强度\n   ▲\n高 │      ╱╲  高潮/释放\n   │     ╱  ╲\n中 │────╱    ╲────  转折/冲突\n   │   ╱      ╲\n低 │──╱        ╲──  建置/解决\n   └──────────────────▶ 时间\n      建置  冲突  高潮  收尾"},{"language":"text","snippet":"▲ 爽点（情绪爆发/满足/反转）\n       ╱ ╲\n      ╱ 共鸣 ╲（与角色共情，代入情感）\n     ╱─────────╲\n    ╱   代入    ╲（进入角色视角，关心命运）\n   ╱───────────────╲\n  ╱     悬念        ╲（产生好奇心，想知道后续）\n ╱─────────────────────╲"},{"language":"text","snippet":"character_cards → auto阶段3 → images/characters/{name}_front.png\ntroop_cards     → auto阶段4 → images/troops/{name}_front.png\nscene_cards     → auto阶段5 → images/scenes/{name}_宽高.png"},{"language":"text","snippet":"1. submit 创建新任务 → upsert_task(lark-cli) 失败 → 飞书无新记录\n2. 飞书里只有旧记录（有旧 task_id，已过期/HTTP 400）\n3. poll 轮询 → 按旧 task_id 查 Agnes API → 400 → 触发重试\n4. 重试提交新任务 → 新任务完成 ✅ 但 upsert_task 又失败了\n5. 回到步骤 3 → 死循环 🔄"},{"language":"text","snippet":"[0:a]atrim=0:15[seg1];[1:a]atrim=0:10[seg2];[2:a]atrim=0:15[seg3]\n  [seg1][seg2]acrossfade=d=1.0[mix1];[mix1][seg3]acrossfade=d=1.0[final]"}],"parameters":null,"dependencies":[],"permissions":[],"extractedFiles":[{"path":"SKILL.md","content":"---\r\nname: ai-video-auto-generator\r\nversion: 2.7.0\r\ndescription: \"AI 短视频全自动流水线：从想法到成片，一键出视频。脚本生成→自动修复→资产生成→视频→音频→字幕，全自动无人值守。| AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated.\"\r\ncategory: video-generation\r\nplatforms:\r\n  - WorkBuddy\r\n  - QClaw\r\n  - ima\r\n  - Claude Code\r\n  - Cursor\r\ntags:\r\n  - video\r\n  - ai-video\r\n  - pipeline\r\n  - automation\r\n  - short-video\r\n  - tts\r\n  - subtitle\r\n  - script-generation\r\n---\r\n\r\n> 📖 **README**: `README.md` | **CHANGELOG**: `CHANGELOG.md`\r\n\r\n# ai-video-auto-generator\r\n\r\n将书面需求转换为结构化视频脚本，用于AI视频生成流水线。\r\n\r\n**目录**\r\n- <a href=\"#agent-mode\">🤖 Agent 使用模式（核心工作流）</a>\r\n- <a href=\"#quick-start\">⚡ Quick Start（4 路径出片）</a>\r\n- <a href=\"#architecture\">🏗️ 流水线架构</a>\r\n- <a href=\"#verification\">🔍 验证体系</a>\r\n- <a href=\"#self-healing\">🩹 自愈机制</a>\r\n- <a href=\"#cli\">🛠️ 流水线 CLI</a>\r\n- **参考文档**\r\n  - [端到端案例](references/e2e-walkthrough.md)\r\n  - [脚本生成检查清单](references/script-json-checklist.md)\r\n  - [Provider 配置](references/provider-config.md)\r\n  - [景别设计](references/shot-scales.md)\r\n  - [剪辑与包装](references/editing-specs.md)\r\n  - [节奏与叙事结构](references/pacing-narrative.md)\r\n  - [Prompt 工程规则](references/prompt-rules.md)\r\n  - [视频生成模式](references/video-modes.md)\r\n  - [环境搭建](references/setup-guide.md)\r\n  - [流水线排错](references/troubleshooting.md)\r\n  - [Segment 合并设计](references/segment-design.md) — 仅小云雀 Provider\r\n\r\n---\r\n\r\n<h2 id=\"quick-start\">⚡ Quick Start（4 路径出片）</h2>\r\n\r\n**🔥 尝鲜（30 秒出预览，无需 API Key）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n**💬 一句话生成视频（推荐，通过 AI Agent）：**\r\n```bash\r\n# 1. 在 WorkBuddy 中加载 ai-video-auto-generator skill\r\n# 2. 直接告诉 AI Agent 你的需求，例如：\r\n#    \"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n# 3. Agent 会自动：分析需求 → 生成 script.json → 跑流水线 → 出片\r\n```\r\n\r\n> 📌 **脚本生成已由 AI Agent 接管。** 之前的 `--mode generate` / `--prompt` 命令已废弃，保留入口但不再执行脚本生成。所有脚本生成直接在对话中完成。\r\n\r\n**📄 从文档生成视频（通过 AI Agent）：**\r\n```bash\r\n# 直接把文件/URL/飞书链接发给 AI Agent\r\n# Agent 会自动读取内容 → 生成 script.json → 跑流水线\r\n```\r\n\r\n**📦 从模板创建（手动编辑）：**\r\n```bash\r\n# 在 skill 根目录执行\r\npython scripts/create_project.py --project \"$HOME/WorkBuddy/我的视频\" --template short_drama\r\ncd \"$HOME/WorkBuddy/我的视频\" && python skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n> 详细说明见 `README.md`。\r\n\r\n---\r\n\r\n<h2 id=\"agent-mode\">🤖 Agent 使用模式（核心工作流）</h2>\r\n\r\n> **你提供需求，AI Agent（当前对话）帮你搞定一切。** 不需要手动调命令，直接说就好。\r\n\r\n### 如何与 Agent 配合\r\n\r\n| 你的输入 | Agent 自动执行 |\r\n|---------|---------------|\r\n| `\"帮我做一个军事短剧，紧张氛围\"` | ① 解析需求 → 生成 `script.json` → 写回项目目录<br>② 创建角色卡、场景卡、镜头列表<br>③ 运行 `--mode auto` 启动流水线 |\r\n| `\"从这篇文章生成视频\"` + 贴 URL | ① WebFetch 读取文章内容<br>② 分析角色/场景/情绪 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"从这份文档生成视频\"` + 上传文件 | ① Read 读取文档内容<br>② 提取关键信息 → 生成 `script.json`<br>③ 运行 `--mode auto` |\r\n| `\"帮我优化这个脚本\"` + 贴 JSON | ① 读取当前 `script.json`<br>② 运行 `optimize` 命令（OptimizerV2）做 12 维叙事修复<br>③ 输出修复报告 |\r\n| `\"修一下 shot_05 的运镜问题\"` | ① 定位问题<br>② 修改 `script.json`<br>③ 通知验证结果 |\r\n\r"},{"path":"skills/agnes-ai/SKILL.md","content":"---\r\nname: agnes-ai\r\nversion: 2.7.0\r\ndescription: >\r\n  纯生成层 skill。调用 Agnes AI 免费 API 生成图片和视频。\r\n  脚本路径为 `skills/agnes-ai/scripts/generate_image.py`\r\n  和 `skills/agnes-ai/scripts/generate_video.py`（相对于主 skill 根目录）。\r\n---\r\n\r\n# Agnes AI 纯生成 Skill\r\n\r\n通过 `scripts/generate_image.py` 生成图片、`scripts/generate_video.py` 生成视频。\r\n\r\n> 本 skill 是 `ai-video-auto-generator` 的子 skill。项目级编排命令在 `project-generate` 子 skill 中。\r\n\r\n---\r\n\r\n## 🚀 高频命令\r\n\r\n```bash\r\n# 文生图\r\npython3 scripts/generate_image.py \"一只猫\" --size \"1024x1024\" -o ./output\r\n\r\n# 图生图\r\npython3 scripts/generate_image.py \"描述提示词\" --ref-image /path/to/ref.png\r\n\r\n# 文生视频\r\npython3 scripts/generate_video.py \"古风战场\" --size \"9:16\" --duration 5s\r\n\r\n# 图生视频\r\npython3 scripts/generate_video.py \"缓慢推进\" --ref-image input.png --duration 5s\r\n```\r\n\r\n## 前置条件\r\n\r\n1. **注册获取 API Key**（免费无限制）：\r\n   - 访问 https://platform.agnes-ai.com 注册\r\n   - 登录后在后台创建 API Key\r\n   - 将 Key 写入 `~/.agnes-api-key`，或设环境变量 `AGNES_API_KEY`\r\n\r\n2. **Python 3** — 标准库即可，无需额外依赖。\r\n\r\n## 两个模型的分工\r\n\r\n| 模型 | 本质 | 适用场景 | 翻车点 |\r\n|-----|------|---------|-------|\r\n| **2.0 Flash**（多图合成） | 多张图融合成一张新画面 | 单角色静态、双角色无互动、特写、环境合成 | 可能脑补多余元素（凭空加人） |\r\n| **2.1 Flash**（参考图编辑） | 以第一张图为基底添加元素 | 需保留场景结构、精确动作控制、有交互 | 过于忠实原图 |\r\n\r\n### 选择规则\r\n- 单角色静态/特写 → **2.0 Flash**\r\n- 单角色精确动作（掀帘、推门） → **2.1 Flash**\r\n- 双角色无互动（背对、行礼、跪拜） → **2.0 Flash**\r\n- 双角色有互动（对视、对话、肢体接触） → **2.1 Flash**\r\n- **2.0 Flash 图生图不需要传 `tags: [\"img2img\"]`**\r\n\r\n### 实战验证\r\n| 场景 | 2.0 结果 | 2.1 结果 | 建议 |\r\n|------|---------|---------|------|\r\n| 墨雪站窗边 | ✅ 1人 | — | 2.0 |\r\n| 墨将推门 | ✅ 1人 | — | 2.0 |\r\n| 双角色同框 | ✅ 2人 | — | 2.0 |\r\n| 面部特写 | ✅ 1人 | — | 2.0 |\r\n| 掀帘子 | ❌ 变2人 | ✅ 1人 | 2.1 |\r\n| 互踢（互动） | — | ✅ | 2.1 |\r\n| 城墙眺望 | ❌ 场景错 | ✅ 正确 | 2.1 |\r\n\r\n## 图片生成 — 使用方法\r\n\r\n### 快速入门（单张图片生成）\r\n\r\n`generate_image.py` 是一个独立的单张图片生成工具，批量生成请走 `project-generate`：\r\n\r\n```bash\r\n# 单张图生图\r\npython3 scripts/generate_image.py \"提示词\" --ref-image \"参考图.png\" -o \"images/characters/\" --output-name \"角色名_front.png\"\r\n\r\n# 批量首帧图 → 请使用 project-generate\r\npython3 ../ai-video-auto-generator/skills/project-generate/scripts/project_generate.py --project . gi\r\n```\r\n\r\n### 完整参数\r\n\r\n**图片参数（`scripts/generate_image.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `prompt`（必填） | 图片描述提示词 |\r\n| `--model` | 默认 `agnes-image-2.1-flash` |\r\n| `--size` | 默认 `720x1280`，自动从 aspect_ratio 映射 |\r\n| `--n` | 数量（1-4） |\r\n| `--quality` | `standard` 或 `hd` |\r\n| `--output-dir` / `-o` | 保存目录 |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-images` | 多张参考图（空格分隔）|\r\n| `--output-name` | 输出文件名 |\r\n| `--seed` | 固定随机种子 |\r\n| `--negative-prompt` | 负面提示词 |\r\n| `--api-key` | API Key 文件路径 |\r\n| `--shot-id` | 从 script.json 的 first_frame 块解析参数，生成该 shot 的首帧图 |\r\n| `--project` | 项目根目录（--shot-id 模式需要）|\r\n| `--force` | 强制重新生成已存在的 first_frame 和模板 |\r\n| `--parallel` | 并发生成数（默认 auto）|\r\n\r\n**视频参数（`scripts/generate_video.py`）**\r\n| 参数 | 说明 |\r\n|------|------|\r\n| `--model` | 默认 `agnes-video-v2.0` |\r\n| `--ref-image` | 单张参考图路径 |\r\n| `--ref-image-list` | 多张参考图路径 |\r\n| `--ref-image-urls` | 已上传的公网 URL |\r\n| `--num-frames` | 总帧数（8n+1，≤441），默认 121 |\r\n| `--frame-rate` | 帧率（1-60），默认 24 |\r\n|"},{"path":"skills/project-generate/SKILL.md","content":"---\r\nname: project-generate\r\nversion: 2.7.0\r\ndescription: \"项目编排层 — 首帧图生成、视频提交/轮询/拼接、状态查看/导出。提供 project_generate.py 作为统一入口，所有命令为子命令形式。图片生成走 Agnes AI（agnes-ai 子 skill），视频生成通过 Provider 路由（支持 Agnes / 小云雀 / LibTV 等）。\"\r\n---\r\n\r\n# project-generate — 项目编排层\r\n\r\n作为 `ai-video-auto-generator` 的子 skill，提供项目级的生成、提交、轮询、拼接全流程编排。\r\n\r\n> **项目创建**请使用 `ai-video-auto-generator` 的 `create_project.py`（在 skill 根目录执行）：\r\n> ```bash\r\n> python3 scripts/create_project.py \\\r\n>   --project <路径> --template short_drama\r\n> ```\r\n> 创建完成后，本 skill 的所有命令都要求项目目录已存在并包含 `script.json`。\r\n\r\n## 统一入口\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython3 skills/project-generate/scripts/project_generate.py\r\n```\r\n\r\n## 命令列表\r\n\r\n所有命令通过子命令（subcommand）调用，`--project` 为全局必选参数：\r\n\r\n```bash\r\nproject_generate.py --project <项目目录> <命令> [选项]\r\n```\r\n\r\n### 资产生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `generate-characters` | `gc` | 读 `character_cards`，批量生成角色资产图（front/face/side/back/action/pose 多视图） |\r\n| `generate-scenes` | `gs` | 读 `scene_cards`，批量生成场景资产图（广角/中景/特写 3 视角） |\r\n| `generate-troops` | `gt` | 读 `troop_cards`，批量生成辅助资产图（白背景全身展示） |\r\n\r\n### 首帧图生成\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `build-first-frames` | `bff` | 读取 script.json，生成各 shot 的 first_frame 配置和 prompt 模板文件（不调 API）。生成后自动验证六段式格式 |\r\n| `generate-images` | `gi` | 调 API 批量生成首帧图。对失败的首帧图自动重试（L1→L3 降敏），单次 API 调用 180s 超时保护 |\r\n| `verify` | — | 用 Haar Cascade 验证首帧图质量 |\r\n| `verify-scenes` | `ve-scenes` | 验证场景图是否包含人物 |\r\n\r\n### 后台运行\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `bg <子命令>` | 后台启动子命令。用 `subprocess.STARTUPINFO(wShowWindow=0)` 隐藏 `python.exe` 的控制台窗口，进程完全脱离当前控制台，不会被 WorkBuddy 断开连接杀死。**不通过 cmd.exe /c 中转**（中文路径重定向会报错）。stdout 直接重定向到 `pipeline.log`。示例：`project_generate.py --project . bg auto` |\r\n\r\n### 视频流水线\r\n\r\n| 命令 | 说明 |\r\n|------|------|\r\n| `submit [--force [id...]]` | 提交视频任务。`--tracker local`（默认）用本地 JSON 记录，`--tracker feishu` 用飞书 Base |\r\n| `poll` | 轮询视频完成状态 + 自动下载 + 全部完成后触发拼接。**持续轮询**每 10 分钟检查一次（代码 `time.sleep(600)`），全部完成自动进行音频+字幕叠加 |\r\n| `stitch [--tracker local]` | **独立拼接子命令**：HF 无字幕渲染 → ffmpeg 烧录分段字幕(CRF18) → 叠加音频/BGM → 输出 `final.mp4`。脱离 `poll` 单独跑，用于只改字幕/编码后重拼（不重新提交/轮询视频） |\r\n| `status` | 显示各 shot/segment 的视频状态 |\r\n| `auto` | 全自动流水线。9 阶段（0→8）：脚本优化（含叙事修复）→构建prompt→角色资产→辅助资产→场景资产→首帧图→提交视频→轮询+拼接+音频。全部阶段支持断点续跑。 |\r\n\r\n### BGM 管理\r\n\r\n- 自定义 BGM：`sounds/bgm_custom.mp3` → `generate_bgm()` 优先使用，跳过 FreeSound 搜索\r\n- 自动 BGM：`script.tone` 字段驱动 FreeSound 关键词搜索，按时长匹配最合适的音乐\r\n- 多段拼接：可用 ffmpeg 将多个音乐片段交叉淡入淡出合成一个 BGM，匹配视频的叙事段落\r\n- 详见 `references/prompt-rules.md §8 BGM 管理`\r\n\r\n### Windows 注意事项\r\n\r\n- **禁用 xfade 转场**：Windows 上 xfade + acrossfade 链式叠加有音视频漂移导致画面卡死，全部改用简单 concat\r\n- **必须指定 yuv420p**：subtitles 滤镜默认输出 yuv444p 部分播放器不兼容\r\n- **subtitles 中文路径**：libass 对中文路径支持不好，需复制到 ASCII 临时路径再引用\r\n- **音频采样率**：强制输出 48kHz 立体声（`-ar 48000 -ac 2`）\r\n- 详见 `references/prompt-rules.md §9 Windows ffmpeg 避坑`\r\n\r\n### 项目管理\r\n\r\n| 命令 | 别名 | 说明 |\r\n|------|:----:|------|\r\n| `preview` | — | 生成交互式 HTML 预览页（首帧图缩略图+视频状态+shot_groups 分组）|\r\n| `report` | — | 生成 HTML 统计报告（模型分布、首帧图完成率、视频状态等）|\r\n| `tracker-sync` | — | 从飞书 Base 反向同步任务进度到本地 t"},{"path":"skills/script-optimizer/SKILL.md","content":"# script-optimizer\r\n\r\n纯自动化脚本质量优化器。验证 `script.json` 质量，自动修复模板默认值、角色匹配、运镜兼容等已知问题。\r\n\r\n## 入口\r\n\r\n```bash\r\n# 方式 A：直接运行模块（推荐）\r\npython3 scripts/optimize/__init__.py --project <项目目录> [选项]\r\n\r\n# 方式 B：通过 project-generate 统一入口\r\npython3 scripts/project-generate/project_generate.py --project <项目目录> optimize\r\n```\r\n\r\n## 调用方式\r\n\r\n| 模式 | 命令 |\r\n|------|------|\r\n| 全自动 | `python3 scripts/optimize/__init__.py --project <项目目录>` |\r\n| strict + force | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --force` |\r\n| JSON 输出 | `python3 scripts/optimize/__init__.py --project <项目目录> --strict --json` |\r\n| 预览 | `python3 scripts/optimize/__init__.py --project <项目目录> --dry-run` |\r\n| 仅报告 | `python3 scripts/optimize/__init__.py --project <项目目录> --report-only` |\r\n| 修复 prompt | `python3 scripts/optimize/__init__.py --project <项目目录> --fix-prompts` |\r\n| 同步类型配置 | `python3 scripts/optimize/__init__.py --project <项目目录> --sync-type` |\r\n\r\n## 修复清单\r\n\r\n| 修复项 | 说明 |\r\n|--------|------|\r\n| gender | 从 build/aura/personality 关键词推断 |\r\n| aesthetic_style | 从类型配置注入 |\r\n| distinctive_mark | 从 hair + face_details + color_scheme 自动构建 |\r\n| face_details | 从 face 文本中按关键词提取 |\r\n| camera_movement | 按 shot_type 填充默认运镜 |\r\n| description | 从 prompt 截取 |\r\n| duration_seconds | 字符串→int 类型修正 |\r\n| reference_images | 从 shot_groups + character_cards 重建 |\r\n| scene lighting/mood | 从 time_of_day 推断 |\r\n| shot_groups | 删除孤儿引用，未分组 shot 创建新组 |\r\n| characters 去重 | 独立检测并移除 characters 列表中的重复项 |\r\n| 全局字段 | 从类型 .md 注入缺失字段 |\r\n| 运镜兼容 | 清除互斥组合（仰+俯、拉+推等） |\r\n| 泛称代词 | 检测「猫」「狗」「他」「她」等并替换为角色名 |\r\n\r\n## 验证维度\r\n\r\nP0 — 阻塞资产生成（模板占位符残留、description 过短、必填字段缺失等）\r\nP1 — 建议修复（strict 模式下阻塞）\r\nP2 — 消息（camera_movement 未设置、face_details 默认值等）\r\n\r\n## 与 project-generate 集成\r\n\r\n```python\r\nfrom optimize import OptimizerV2\r\nopt = OptimizerV2(project, strict=True, json_mode=True)\r\nresult = opt.run()\r\n```"},{"path":"README.md","content":"# ai-video-auto-generator\r\n\r\nAI 短视频全自动流水线 — 从想法到成片，一键出视频。\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## Quick Start\r\n\r\n### 🔥 快速尝鲜（30 秒出预览，无需 API Key）\r\n\r\n```bash\r\n# 在 skill 根目录执行\r\npython skills/project-generate/scripts/pipeline.py --project ./sample --mode demo\r\n```\r\n\r\n自动装依赖 → ffmpeg 本地合成预览视频 → 看到效果 → 引导下一步。\r\n\r\n### 💬 AI Agent 一键出片（推荐）\r\n\r\n加载本 skill 后，直接向 AI Agent 描述需求：\r\n\r\n```\r\n\"帮我做一个古代将军在现代城市醒来的短视频，紧张氛围，约30秒\"\r\n```\r\n\r\nAgent 会自动完成：\r\n1. 分析需求 → 生成完整 `script.json`（含角色卡/场景卡/镜头列表）\r\n2. 运行 `optimize` 命令（OptimizerV2）做 12 维叙事自动修复\r\n3. 调用 `--mode auto` 全自动流水线\r\n4. 完成后通知你\r\n\r\n> 支持多种输入：文本描述、URL、本地文件(.txt/.md/.docx)、飞书文档链接。直接发给 Agent 即可。\r\n\r\n### 安装\r\n\r\nskill 安装后会自动检测环境，缺失的依赖（opencv, edge-tts, PIL 等）会自动安装：\r\n\r\n```bash\r\npython skills/project-generate/scripts/pipeline.py --project . --mode setup\r\n```\r\n\r\n### 方式 1：从模板创建新项目\r\n\r\n```bash\r\n# 查看可用模板（在 skill 根目录执行）\r\npython scripts/create_project.py --list-types\r\n\r\n# 创建项目\r\npython scripts/create_project.py --project ./my_video --template short_drama\r\n\r\n# 一键出片\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 2：导入现有 `script.json`\r\n\r\n```bash\r\n# 在已有项目目录下\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n### 方式 3：从飞书文档导入\r\n\r\n```bash\r\n# 在 skill 根目录执行，把飞书需求文档 URL 写入 script.json\r\npython scripts/create_project.py --project . --feishu-doc-url <feishu_doc_url>\r\ncd my_video\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n```\r\n\r\n## 流水线概览\r\n\r\n```\r\nscript.json\r\n  ↓ 叙事 12 维自动修复（ID/时长/钩子/运镜/情绪/收尾...）\r\n  ↓ 角色资产生成 + 6 维质量验证\r\n  ↓ 场景资产生成 + 无人检测 + 风格检测\r\n  ↓ 首帧图生成 + 50 分制验证 + L1/L2/L3 降敏修复\r\n  ↓ 视频提交 → 轮询 → 下载 → 55 分制验证（含运镜+情绪）\r\n  ↓ 拼接（hyperframes / ffmpeg）\r\n  ↓ TTS 配音 + BGM + 环境音 + 音效 + ffmpeg 多轨混音\r\n  ↓ SRT 字幕\r\n  → final.mp4\r\n```\r\n\r\n## 命令速查\r\n\r\n```bash\r\n# 🎮 快速尝鲜（30 秒，无需 API Key）\r\npython skills/project-generate/scripts/pipeline.py --mode demo\r\n\r\n# 环境检测 + 自动安装\r\npython skills/project-generate/scripts/pipeline.py --mode setup\r\n\r\n# 💬 告诉 AI Agent 你的需求（推荐）\r\n#    在 WorkBuddy 中加载本 skill 后，直接描述需求即可\r\n#    示例: \"帮我做一个古代将军在现代城市醒来的短视频\"\r\n\r\n# 全自动流水线（已有 script.json 时）\r\npython skills/project-generate/scripts/pipeline.py --mode auto\r\n\r\n# 预检（只验证不生成）\r\npython skills/project-generate/scripts/pipeline.py --mode validate\r\n\r\n# 仅轮询（已有 task 的项目续跑）\r\npython skills/project-generate/scripts/pipeline.py --mode poll --detached\r\n\r\n# 项目状态（默认 JSON 输出，--text 人类可读）\r\npython skills/project-generate/scripts/project_generate.py --project . status\r\n\r\n# 单独拼接（HF 无字幕渲染 → ffmpeg 烧录字幕 → 叠加音频/BGM → final.mp4）\r\npython skills/project-generate/scripts/project_generate.py --project . stitch --tracker local\r\n```\r\n\r\n## Provider 切换\r\n\r\n默认使用 Agnes AI。修改 `script.json` 中的 `script.provider` 即可切换：\r\n\r\n```json\r\n{\r\n  \"script\": {\r\n    \"provider\": \"xiaoyunqiao\",\r\n    \"video_provider\": \"xiaoyunqiao\"\r\n  }\r\n}\r\n```\r\n\r\n自定义 Provider：实现 `BaseProvider` 后通过 `register_provider()` 注册。\r\n\r\n## 已知限制\r\n\r\n| 限制 | 说明 |\r\n|------|------|\r\n| 需 API Key | 默认使用 Agnes AI，需配置 `~/.agnes-api-key`（免费无限额度）。也可切换其他 Provider。 |\r\n| Windo"}],"languages":[],"docsSourceLabel":"CLAWHUB","editorialOverview":"AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Skill: AI video auto generator Owner: jinxuchen2020 Summary: AI video auto pipeline: from idea to final video, one command. Script generation → auto repair → assets → video → audio → subtitles, fully automated. Tags: latest:2.7.1 Version history: v2.7.1 | 2026-07-16T07:52:11.271Z | user ai-video-auto-generator 2.7.1 - Added new documentation and audit files for code and docs review, including detailed memory logs und","editorialQuality":{"score":100,"threshold":65,"status":"ready","wordCount":1540,"uniquenessScore":46,"reasons":[]}},"media":{"evidence":{"source":"no-media","verified":false,"confidence":"low","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":"No screenshots, media assets, or demo links are available."},"primaryImageUrl":null,"mediaAssetCount":0,"assets":[],"demoUrl":null},"ownerResources":{"evidence":{"source":"unclaimed","verified":false,"confidence":"low","updatedAt":"2026-10-11T18:02:45.380Z","emptyReason":"This page has not been claimed by the agent owner."},"hasCustomPage":false,"customPageUpdatedAt":null,"customLinks":[],"structuredLinks":{"docsUrl":null,"demoUrl":null,"supportUrl":null,"pricingUrl":null,"statusUrl":null},"customPage":null},"relatedAgents":{"evidence":{"source":"protocol-neighbors","verified":false,"confidence":"medium","updatedAt":"2026-10-11T21:00:21.414Z","emptyReason":null},"items":[{"id":"8ebccd8e-3863-4187-8355-c3f14e1f9edf","entityType":"agent","canonicalPath":"/agent/iofficeai-aionui","slug":"iofficeai-aionui","name":"AionUi","description":"Free, local, open-source 24/7 Cowork app and OpenClaw for Gemini CLI, Claude Code, Codex, OpenCode, Qwen Code, Goose CLI, Auggie, and more | 🌟 Star if you like it!","url":"https://github.com/iOfficeAI/AionUi","homepage":"https://www.aionui.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-10-09T19:11:12.944Z","createdAt":"2026-02-25T03:38:16.584Z","downloads":null},{"id":"b917f68a-ebff-438e-84f8-3f4b2494c0bc","entityType":"agent","canonicalPath":"/agent/activepieces-activepieces","slug":"activepieces-activepieces","name":"activepieces","description":"AI Agents & MCPs & AI Workflow Automation • (~400 MCP servers for AI agents) • AI Automation / AI Agent with MCPs • AI Workflows & AI Agents • MCPs for AI Agents","url":"https://github.com/activepieces/activepieces","homepage":"https://www.activepieces.com","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-15T02:22:12.426Z","createdAt":"2026-02-25T03:38:12.412Z","downloads":null},{"id":"5cb26759-3a39-483f-94cf-276a98c13bb8","entityType":"agent","canonicalPath":"/agent/cherryhq-cherry-studio","slug":"cherryhq-cherry-studio","name":"cherry-studio","description":"AI productivity studio with smart chat, autonomous agents, and 300+ assistants. Unified access to frontier LLMs","url":"https://github.com/CherryHQ/cherry-studio","homepage":"https://cherry-ai.com","source":"GITHUB_REPOS","protocols":["MCP","OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-04-11T14:38:40.986Z","createdAt":"2026-02-25T03:38:19.379Z","downloads":null},{"id":"6f6582d0-5d76-4f0f-b81d-86520247950b","entityType":"agent","canonicalPath":"/agent/copilotkit-copilotkit","slug":"copilotkit-copilotkit","name":"CopilotKit","description":"The Frontend for Agents & Generative UI. React + Angular","url":"https://github.com/CopilotKit/CopilotKit","homepage":"https://docs.copilotkit.ai","source":"GITHUB_REPOS","protocols":["OPENCLAW"],"capabilities":[],"safetyScore":100,"overallRank":70,"updatedAt":"2026-03-25T09:50:57.846Z","createdAt":"2026-02-25T03:39:14.617Z","downloads":null}],"links":{"hub":"/agent","source":"/agent/source/clawhub","protocols":[{"label":"OpenClaw","href":"/agent/protocol/openclew"}]}}}