diff --git a/video-ai-system/outputs/review/ENV-002-V1-candidate-01-1440x2560.png b/video-ai-system/outputs/review/ENV-002-V1-candidate-01-1440x2560.png
new file mode 100644
index 0000000..da31cdf
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-002-V1-candidate-01-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-002-V1-candidate-02-1440x2560.png b/video-ai-system/outputs/review/ENV-002-V1-candidate-02-1440x2560.png
new file mode 100644
index 0000000..c8bc841
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-002-V1-candidate-02-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-002-V1-candidate-03-1440x2560.png b/video-ai-system/outputs/review/ENV-002-V1-candidate-03-1440x2560.png
new file mode 100644
index 0000000..101f26c
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-002-V1-candidate-03-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-002-V1-candidate-04-1440x2560.png b/video-ai-system/outputs/review/ENV-002-V1-candidate-04-1440x2560.png
new file mode 100644
index 0000000..fd6ed60
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-002-V1-candidate-04-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-003-V1-candidate-01-1440x2560.png b/video-ai-system/outputs/review/ENV-003-V1-candidate-01-1440x2560.png
new file mode 100644
index 0000000..6304157
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-003-V1-candidate-01-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-003-V1-candidate-02-1440x2560.png b/video-ai-system/outputs/review/ENV-003-V1-candidate-02-1440x2560.png
new file mode 100644
index 0000000..5328e43
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-003-V1-candidate-02-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-003-V1-candidate-03-1440x2560.png b/video-ai-system/outputs/review/ENV-003-V1-candidate-03-1440x2560.png
new file mode 100644
index 0000000..c03081e
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-003-V1-candidate-03-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-003-V1-candidate-04-1440x2560.png b/video-ai-system/outputs/review/ENV-003-V1-candidate-04-1440x2560.png
new file mode 100644
index 0000000..579b94b
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-003-V1-candidate-04-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-004-V1-candidate-01-1440x2560.png b/video-ai-system/outputs/review/ENV-004-V1-candidate-01-1440x2560.png
new file mode 100644
index 0000000..eff2fd3
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-004-V1-candidate-01-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-004-V1-candidate-02-1440x2560.png b/video-ai-system/outputs/review/ENV-004-V1-candidate-02-1440x2560.png
new file mode 100644
index 0000000..164d2e8
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-004-V1-candidate-02-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-004-V1-candidate-03-1440x2560.png b/video-ai-system/outputs/review/ENV-004-V1-candidate-03-1440x2560.png
new file mode 100644
index 0000000..0e1385f
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-004-V1-candidate-03-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/ENV-004-V1-candidate-04-1440x2560.png b/video-ai-system/outputs/review/ENV-004-V1-candidate-04-1440x2560.png
new file mode 100644
index 0000000..435b95c
Binary files /dev/null and b/video-ai-system/outputs/review/ENV-004-V1-candidate-04-1440x2560.png differ
diff --git a/video-ai-system/outputs/review/view.html b/video-ai-system/outputs/review/view.html
index 5f71072..bb76032 100644
--- a/video-ai-system/outputs/review/view.html
+++ b/video-ai-system/outputs/review/view.html
@@ -1,19 +1,39 @@
-
PROP-003 广告牌 V2 · 修仙世界升级
+场景 ENV-002/003/004 · 百宗会·天道宗·灵霄宗
-PROP-003 免费招徒广告牌 V2 · 修仙世界升级
-V1→V2: 石墙小巷→修仙百宗会·灵木A架·粗麻画布无字·仙雾·对齐苏白+牌匾
+ENV-002 百宗会广场高空俯瞰
+人山人海·宗门招牌·御剑流光·修仙盛会
-

候选01 · 正面A架·摊旁·粗麻画布无字·仙雾脚下·冷雅
-

候选02 · 微侧·画布微皱·百宗会远景·清冷光影
-

候选03 · 正面中景·A架主体留白·摊位桌旁·修仙氛围
-

候选04 · 半侧面·绳结清晰·画布粗糙·背景虚化·电影调色
-
+
候选01 · 高空俯瞰·人山人海·招牌阵列·御剑流光
+
候选02 · 云端俯视·万人集会·飞檐帐篷·仙鹤远山
+
候选03 · 高空全景·密集人流·各宗招牌灵气环绕
+
候选04 · 广角大远景·层叠宗门·人潮涌动·史诗构图
+
+
+ENV-003 天道宗摊位 · 角落破旧
+角落位置·杆挂牌匾+广告牌·灵木桌青布·冷寂清雅
+
+

候选01 · 破旧摊位·牌匾广告牌清晰·灵木桌青布·冷寂
+

候选02 · 角落摊位·牌匾广告牌左右·远焦豪华宗门对比
+

候选03 · 中近景·空灵木台·牌匾悬空·冷色调清寂
+

候选04 · 最角落·破败冷清·虚化豪华宗门·电影感
+
+
+ENV-004 灵霄宗摊位 · 气派华丽
+鎏金牌匾·豪华帐篷·修仙者排队·灵光流转
+
+

候选01 · 鎏金牌匾·丝绸帐篷·修仙者长队·灵光点缀
+

候选02 · 紫檀桌案灵石法器·排队人群·华贵灵光
+

候选03 · 黄金位置·鎏金招牌·豪华帐篷·人群涌动
+

候选04 · 灵光流转仙气浓郁·丝绸帷幕·队伍排长
+
+
diff --git a/video-ai-system/tools/env_batch_gen.py b/video-ai-system/tools/env_batch_gen.py
new file mode 100644
index 0000000..a4ed837
--- /dev/null
+++ b/video-ai-system/tools/env_batch_gen.py
@@ -0,0 +1,139 @@
+#!/usr/bin/env python3
+"""ENV-002/003/004 三场景批量生成 · 对齐苏白V3-R4风格 · 修仙世界"""
+import os, sys, json, time, subprocess
+from pathlib import Path
+
+ROOT = Path('D:/WorkBuddy/guanghulab/video-ai-system')
+env = {}
+for line in open(ROOT/".env"):
+ line = line.strip()
+ if not line or line.startswith("#"): continue
+ if "=" in line:
+ k, v = line.split("=", 1)
+ env[k.strip()] = v.strip()
+
+AK = env["JIMENG_API_KEY"]
+URL = env["JIMENG_BASE_URL"]
+MODEL = "doubao-seedream-4-0-250828"
+
+SCENES = {
+ "ENV-002": {
+ "name": "百宗会广场全景",
+ "prompt": """中国修仙世界百宗会广场高空俯瞰,大远景。
+从云端俯瞰修仙界盛大集会,巨大广场人山人海,数不清的修仙者如蚂蚁般穿梭其间。
+多个豪华宗门招牌林立——鎏金牌匾、灵气光环、飞檐楼阁帐篷,御剑飞行的修仙者化作流光划过天际。
+广场中央灵雾缭绕,远处群山环抱,仙鹤翱翔。
+场景宏大震撼,每个宗门摊位都有独特风格和招牌。
+3D真人向写实渲染,光影清冷自然,不良人硬核写实风格,与CHAR-003苏白V3-R4同一风格体系,电影级大场面。""",
+ "neg": """卡通渲染,赛璐璐,塑料感,游戏低模,廉价3D,页游风,光污染,浮夸光环,土味特效。
+现代城市,高楼大厦,现代建筑,水泥广场,柏油路,现代人群,西装革履。
+空无一人的广场,荒凉无人的场景,空旷寂寥。
+任何文字,汉字,标语。
+人物面部特写,单一人物占主体。
+白天正午艳阳,过曝,惨白,画面扁平无层次。
+黑暗阴森恐怖,末日废墟。
+这个场景是远景俯瞰,不要近景。""",
+ "variants": [
+ "高空俯瞰百宗会全景,人山人海修仙盛会,豪华宗门招牌阵列,御剑流光划过天空,仙雾缭绕宏大场面",
+ "云端俯视修仙广场,万人集会宗门林立,飞檐帐篷金碧辉煌,仙鹤翱翔远山环抱,电影级鸟瞰",
+ "百宗会广场高空全景,密集修仙者人流穿行,各宗招牌灵气环绕,御剑飞行轨迹优美,震撼修仙界盛况",
+ "俯瞰修仙界盛典,广角大远景,层叠宗门帐篷招牌如星罗棋布,人潮涌动灵雾飘渺,史诗级构图"
+ ]
+ },
+ "ENV-003": {
+ "name": "天道宗摊位近景",
+ "prompt": """中国修仙世界百宗会角落,天道宗简陋摊位中近景。
+角落位置破旧感强烈,一根仙木杆悬挂刻有天道宗的破旧木牌匾,旁边是绳系A架粗麻画布广告牌。
+摊位是粗糙灵木桌铺着淡青色粗布,桌面上空无一物十分简陋。
+与远处豪华宗门摊位形成鲜明对比——远处可见气派帐篷和排队人群。
+脚下淡淡仙雾缭绕,色调偏冷暗清寂,氛围孤独但不阴森。
+3D真人向写实渲染,不良人硬核写实风格,与CHAR-003苏白V3-R4同一风格体系,画面有电影感。""",
+ "neg": """卡通渲染,塑料感,游戏低模,廉价3D,页游风,光污染。
+现代建筑,水泥地,柏油路,现代家具,金属桌椅,塑料凳子。
+豪华摊位,气派装饰,金碧辉煌,华丽场景,热闹喜庆氛围。
+任何人,人物,角色,修行者,顾客,围观群众。
+任何文字(除天道宗),无关汉字,标语。
+晴天艳阳,高饱和度,暖黄色调,金色阳光,鲜艳色彩。
+过于黑暗,完全漆黑的角落,恐怖片氛围。""",
+ "variants": [
+ "天道宗破旧摊位中景,杆挂牌匾和广告牌清晰,灵木桌青布简陋,远处豪华摊位虚化,冷寂修仙氛围",
+ "角落天道宗摊位,破旧灵木桌铺青布,牌匾广告牌一左一右,脚下仙雾,远焦豪华宗门对比强烈",
+ "天道宗摊位中近景,简陋灵木台上空无一物,牌匾悬空广告牌旁立,冷色调清寂氛围,写实修仙场景",
+ "百宗会最角落的天道宗摊位,破败冷清,牌匾广告牌灵木桌青布,虚化远处的气派宗门摊位,电影感对比"
+ ]
+ },
+ "ENV-004": {
+ "name": "灵霄宗摊位近景",
+ "prompt": """中国修仙世界百宗会灵霄宗豪华摊位中近景。
+气派华丽摊位占据显眼位置,鎏金灵霄宗牌匾悬挂高处光芒流转,牌下豪华帐篷飞檐翘角。
+排队等候的修仙者队伍蜿蜒如龙,人群拥挤热闹非凡。
+摊位装饰奢华——丝绸帷幕、紫檀木桌案、灵石法器点缀其间,灵光流转仙气浓郁。
+与其他简陋摊位(如天道宗)形成强烈视觉对比。
+3D真人向写实渲染,光影清冷但有灵气光晕点缀,不良人硬核写实风格,与CHAR-003苏白V3-R4同一风格体系,电影级画面。""",
+ "neg": """卡通渲染,塑料感,游戏低模,廉价3D,页游风,光污染过度,土味光效特效。
+现代建筑,现代广告牌,LED灯箱,霓虹灯,现代排队栏杆,现代装修。
+简陋摊位,破旧摊位,寒酸场景,贫困感。
+任何文字(除灵霄宗),无关汉字,标语。
+空无一人,冷清寥落。
+过于鲜艳高饱和,过于金黄,暴发户土豪金,粗俗俗气装饰。
+过于黑暗阴森。""",
+ "variants": [
+ "灵霄宗豪华摊位中景,鎏金牌匾光芒流转,丝绸帐篷飞檐,修仙者长队蜿蜒,灵光点缀华丽场景",
+ "灵霄宗气派摊位,紫檀木桌案灵石法器,排队人群熙攘,华贵装饰灵光流转,与天道宗对比鲜明",
+ "百宗会黄金位置灵霄宗摊位,鎏金招牌醒目,豪华帐篷飞檐翘角,人群涌动络绎不绝,修仙界顶级摊位",
+ "灵霄宗摊位中近景,灵光流转仙气浓郁,丝绸帷幕豪华装饰,队伍排长修仙者众多,电影级光影"
+ ]
+ }
+}
+
+SEEDS = [777, 888, 999, 111]
+
+def gen(prompt, neg, seed):
+ body = json.dumps({"model": MODEL, "prompt": prompt, "negative_prompt": neg, "size": "1440x2560", "n": 1, "seed": seed})
+ r = subprocess.run(["curl", "-s", "-m", "120", "--noproxy", "*", "-X", "POST", f"{URL}/images/generations",
+ "-H", f"Authorization: Bearer {AK}", "-H", "Content-Type: application/json", "-d", body],
+ capture_output=True, text=True, timeout=130)
+ try:
+ return json.loads(r.stdout)["data"][0].get("url")
+ except:
+ print(f" API err: {r.stdout[:200]}")
+ return None
+
+def dl(url, dst):
+ Path(dst).parent.mkdir(parents=True, exist_ok=True)
+ subprocess.run(["curl", "-s", "-m", "120", "-L", "--noproxy", "*", "-o", dst, url], capture_output=True, timeout=130)
+ return os.path.exists(dst) and os.path.getsize(dst) > 1024
+
+ts = time.strftime("%Y%m%d-%H%M%S")
+all_meta = {}
+
+for env_id, cfg in SCENES.items():
+ print(f"\n{'='*40}\n{env_id} · {cfg['name']}\n{'='*40}")
+ OUT = ROOT / f"assets/candidates/D169-VA-05-001/{env_id}"
+ OUT.mkdir(parents=True, exist_ok=True)
+ results = []
+ for i, seed in enumerate(SEEDS):
+ var = cfg["variants"][i]
+ full = f"{cfg['prompt']} {var}"
+ print(f" [{i+1}/4] seed={seed}", flush=True)
+ url = gen(full, cfg["neg"], seed)
+ if not url:
+ results.append({"c": i+1, "ok": False, "err": "api"})
+ continue
+ dst = OUT / f"{env_id}-V1-candidate-{i+1:02d}-1440x2560.png"
+ if not dl(url, str(dst)):
+ results.append({"c": i+1, "ok": False, "err": "dl"})
+ continue
+ results.append({"c": i+1, "ok": True, "raw": str(dst), "seed": seed})
+ print(f" -> {dst.name}")
+ time.sleep(3)
+ ok = sum(1 for r in results if r["ok"])
+ print(f" {env_id} 完成: {ok}/4")
+ all_meta[env_id] = {"name": cfg["name"], "ok": ok, "results": results}
+ json.dump({"spec": f"VA-05-001-{env_id}-V1", "ts": ts, **all_meta[env_id], "model": MODEL, "engine": "Seedream"},
+ open(OUT/"generation-meta.json","w",encoding="utf-8"), ensure_ascii=False, indent=2)
+
+print(f"\n{'='*40}")
+for env_id, m in all_meta.items():
+ print(f" {env_id} · {m['name']}: {m['ok']}/4")
+print(f"{'='*40}")