D157 · CHAR-004 R5剧本锚定版 · .code-map新增VA-60/VA-05-X映射 · 闸门0规则封装
Some checks failed
自动更新代码和重启 / update-and-restart (push) Has been cancelled
CI检查 + 自动部署 / check (push) Has been cancelled
CI检查 + 自动部署 / deploy (push) Has been cancelled

This commit is contained in:
冰朔 2026-07-01 15:21:13 +08:00
parent c04f91800e
commit 6e06ebe6f2
6 changed files with 333 additions and 0 deletions

View File

@ -103,6 +103,11 @@ VA-30=video-ai-system/experience/ITERATION-LOOP.hdlp
VA-31=video-ai-system/experience/EP01-PREVIEW-002-REVIEW.hdlp
# VA-6X 剧本层
VA-60=动态漫:《付费才能修仙?我的宗门全免费》.md
VA-SCRIPT=动态漫:《付费才能修仙?我的宗门全免费》.md ← 剧本原文·闸门0锚定源·D157新增
# VA-05-X 资产规范层 · 铸渊执行前必须比对VA-60剧本原文
VA-05-001-R1=video-ai-system/VA-05-001-R1-ASSETS-GEN-EP001.hdlp
VA-05-001-R2=video-ai-system/VA-05-001-R2-CHAR-004-ZhugeFeng.hdlp
VA-05-001-R5=video-ai-system/VA-05-001-R5-CHAR-004-ZhugeFeng.hdlp ← 剧本锚定白衣版·当前最新
# VA-9X 铸渊内部(通用AI不读)
VA-90=video-ai-system/SYSTEM-WAKE.hdlp
VA-91=video-ai-system/LOCAL-SECRETS-PATH.hdlp

View File

@ -0,0 +1,61 @@
# CHAR-004 诸葛风 立绘生成规范 · 剧本锚定版
> HLDP://ICE-GL-ZY001/ASSETS/CHAR-004-R5
> 固定文件编号VA-05-001-R5
> 归属模块VA-05 工程资产库
> 设定依据剧本第1集原文「18岁淳朴少年形象粗麻布衣」
> 替代条款VA-05-001-R1/R2中CHAR-004相关生成规则全部作废
> 指定生成引擎火山Seedream 文生图
> 指定质检工具Qwen-VL
> 版本V5.0 · D157 · 2026-07-01
> 创作方裁光LH-001
> 执行方:铸渊
> 主权方:冰朔
> 国作登字-2026-A-00037559
---
## §0 修正背景
CHAR-004前四轮生成R1-R4出现三项根本性偏差
1. 年龄16岁 → 剧本写18岁
2. 服装颜色灰蓝 → 剧本写素色/白色系
3. 气质清穷冷硬 → 剧本写淳朴
以上偏差均源于资产规范编写时未严格锚定剧本原文。现以剧本原文为唯一设定源。
## §1 生成策略
1. 全程纯文生图,禁用任何参考图
2. 严格按剧本原文设定,不添加主观演绎词
3. 风格与CHAR-003苏白V2版统一3D动漫卡通渲染国风玄幻动态漫质感
4. 4张备选Qwen-VL质检后提交人工确认
## §2 正面提示词
```
3D动漫卡通渲染国风玄幻动态漫质感单人男性全身立绘纯白背景。
角色为18岁少年身形挺拔偏瘦小麦色肤色面部轮廓利落剑眉星目眼神澄澈有韧劲气质淳朴端正。
黑色短发,半束高马尾,用普通深棕色木簪固定,额前有少量碎发,发型整洁。
身穿素色粗麻交领上衣,袖口收窄,内搭浅色中衣,布料平整干净,无破损、无补丁、无污渍。腰间系深棕色粗麻绳腰带,系法简洁。
下装为同色系粗麻长裤,裤脚收进黑色短靴里,靴面整洁。
腰间挂一个深灰色布囊,形制简单,完整无破损。
人物比例协调,线条清晰,光影柔和,整体为干净整洁的修仙少年形象。
```
## §3 负面提示词
```
乞丐,流民,流浪汉,破旧衣服,破洞,补丁,污渍,泥点,脏鞋,破烂袖口,毛边,褪色,磨损,衣衫褴褛,寒酸感,佝偻,颓废,萎靡,肮脏凌乱。
与苏白长相相似,同款五官,同款脸型,真人写实,照片,畸形肢体,五官崩坏,模糊,水印,多余装饰,玉佩,首饰,华丽服饰。
```
## §4 Qwen-VL质检必查项一票否决
1. 面部与CHAR-003苏白无明显相似性
2. 服装无破损、补丁、污渍,整体干净整洁
3. 无乞丐感、流民感,气质端正淳朴
4. 肢体比例正常,无畸形穿模
5. 服装为素色/白色系
## §5 执行记录
- D157 RUN-001 · R5 · 2026-07-01 · 4张通过QC+视觉复核
- 候选①②③④全部通过 · 米白色粗麻交领 · 无破损无乞丐感
- 冰朔待确认入库
---
> ⊢ 锚定剧本原文为唯一设定源。不再自编颜色/年龄/气质。
> ⊢ 国作登字-2026-A-00037559

View File

@ -0,0 +1,85 @@
#!/usr/bin/env python3
"""CHAR-004 R4 · 朴素修仙学徒制服 · 纯文生图 · 删所有旧化词"""
import sys, os, json, time, subprocess
from pathlib import Path
sys.path.insert(0, os.path.dirname(__file__))
from secrets_loader import secret, endpoint
API_KEY = secret("SC-001")
BASE_URL = endpoint("EPT-001")
MODEL = "doubao-seedream-4-0-250828"
ROOT = Path(__file__).resolve().parents[1]
JZAO = Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/图片/zai-fu-fei-xiu-xian/ep01")
CANDIDATES = ROOT / "assets/candidates/D157-VA-05-001-R4" / "CHAR-004-ZhugeFeng"
POSITIVE = """3D动漫卡通渲染国风玄幻动态漫质感单人男性角色全身立绘纯白背景。
角色为16岁少年清瘦挺拔身高约175cm肩宽略窄身形单薄但精神利落不佝偻不颓废小麦色肤色面部轮廓棱角分明剑眉星目眼神锐利有韧劲鼻梁挺直嘴唇偏薄下颌线清晰少年气强气质冷硬黑色短发高束半马尾发尾有少量碎发用普通深棕色木簪固定额前散落几缕碎发整体整洁
服装为灰蓝色素面交领修仙学徒袍整洁干净布料平整无瑕疵右衽袖口收窄贴合手腕内搭浅色中衣腰间系深棕色麻绳腰带系法简单下装为深灰蓝同色长裤裤脚干净收进黑色短靴黑色粗布短靴厚鞋底鞋面干净
腰间麻绳上挂一个拳头大小的深灰色布包布包完整平整朴素但不破旧
整体气质朴素克制坚韧是普通宗门弟子出身干净利落有少年锐气不是乞丐不是流民不是流浪汉不是穷人
人物完整居中露出比例协调线条清晰色彩柔和卡通渲染3D动漫角色质感"""
NEGATIVE = """乞丐流民流浪汉穷人破旧服装破损破洞补丁污渍泥污脏鞋破裤腿烂袖口脏布包粗糙布料廉价质感过度旧化褪色严重裤脚脏鞋面脏衣服下摆毛边布料磨损乞丐感流民感破旧感寒酸感衣衫不整佝偻颓废萎靡肮脏凌乱CHAR-003同款脸CHAR-003同款五官CHAR-003同款发型与苏白长相相似真人照片写实畸形肢体五官崩坏模糊水印。"""
VARS = [
"正面直视镜头,表情沉稳有韧劲",
"微微侧身站姿,目光坚毅看向前方",
"略微仰视,下颌抬起,眼神向上有向往",
"3/4侧脸侧视左前方少年英气",
]
def gen(prompt, neg, seed):
url = f"{BASE_URL}/images/generations"
proc = subprocess.run(["curl","-s","-m","120","--noproxy","*","-X","POST",url,
"-H",f"Authorization: Bearer {API_KEY}",
"-H","Content-Type: application/json",
"-d",json.dumps({"model":MODEL,"prompt":prompt,"negative_prompt":neg,"size":"1440x2560","n":1,"seed":seed})],
capture_output=True,text=True,timeout=130)
try:
d = json.loads(proc.stdout)
if "data" in d: return d["data"][0].get("url")
except: pass
return None
def dl(url, dst):
Path(dst).parent.mkdir(parents=True,exist_ok=True)
subprocess.run(["curl","-s","-m","60","-L","--noproxy","*","-o",dst,url],capture_output=True,timeout=65)
return os.path.exists(dst) and os.path.getsize(dst)>1024
def main():
print("CHAR-004 R4 · 朴素修仙学徒制服")
if not API_KEY: sys.exit("✗ no key")
ts = time.strftime("%Y%m%d-%H%M%S")
raw_dir = JZAO / "D157-R4" / ts
raw_dir.mkdir(parents=True,exist_ok=True)
CANDIDATES.mkdir(parents=True,exist_ok=True)
results = []
for i,(seed,var) in enumerate(zip([42,137,256,399],VARS)):
full = f"{POSITIVE} {var}"
print(f"[{i+1}/4] seed={seed}",flush=True)
url = gen(full,NEGATIVE,seed)
if not url: results.append({"c":i+1,"ok":False,"err":"api"}); continue
raw = raw_dir/f"CHAR-004-R4-{i+1:02d}-1440x2560.jpg"
if not dl(url,raw): results.append({"c":i+1,"ok":False,"err":"dl"}); continue
scaled = CANDIDATES/f"CHAR-004-R4-candidate-{i+1:02d}-1080x1920.jpg"
subprocess.run(["sips","-z","1920","1080",str(raw),"--out",str(scaled)],capture_output=True)
results.append({"c":i+1,"ok":True,"raw":str(raw),"scaled":str(scaled),"seed":seed})
time.sleep(2)
ok = sum(1 for r in results if r["ok"])
print(f"完成: {ok}/4")
with open(CANDIDATES/"generation-meta.json","w") as f:
json.dump({"spec":"VA-05-001-R4","asset":"CHAR-004","ts":ts,"ok":ok,"total":4,"results":results},f,ensure_ascii=False,indent=2)
return 0 if ok>=4 else 1
if __name__=="__main__":
sys.exit(main())

View File

@ -0,0 +1,54 @@
#!/usr/bin/env python3
"""CHAR-004 R5 · 剧本锚定版 · 18岁淳朴粗麻白衣 · 纯文生图"""
import sys,os,json,time,subprocess
from pathlib import Path
sys.path.insert(0,os.path.dirname(__file__))
from secrets_loader import secret,endpoint
AK=secret("SC-001");URL=endpoint("EPT-001");M="doubao-seedream-4-0-250828"
ROOT=Path(__file__).resolve().parents[1];J=Path("/Volumes/JZAO/铸渊-ICE-GL-ZY001/OUT-输出/图片/zai-fu-fei-xiu-xian/ep01")
CD=ROOT/"assets/candidates/D157-VA-05-001-R5"/"CHAR-004-ZhugeFeng"
P="""3D动漫卡通渲染国风玄幻动态漫质感单人男性全身立绘纯白背景。
角色为18岁少年身形挺拔偏瘦小麦色肤色面部轮廓利落剑眉星目眼神澄澈有韧劲气质淳朴端正
黑色短发半束高马尾用普通深棕色木簪固定额前有少量碎发发型整洁
身穿素色粗麻交领上衣袖口收窄内搭浅色中衣布料平整干净无破损无补丁无污渍腰间系深棕色粗麻绳腰带系法简洁
下装为同色系粗麻长裤裤脚收进黑色短靴里靴面整洁
腰间挂一个深灰色布囊形制简单完整无破损
人物比例协调线条清晰光影柔和整体为干净整洁的修仙少年形象"""
N="""乞丐,流民,流浪汉,破旧衣服,破洞,补丁,污渍,泥点,脏鞋,破烂袖口,毛边,褪色,磨损,衣衫褴褛,寒酸感,佝偻,颓废,萎靡,肮脏凌乱。
与苏白长相相似同款五官同款脸型真人写实照片畸形肢体五官崩坏模糊水印多余装饰玉佩首饰华丽服饰"""
V=["正面直视镜头,表情端正沉稳","微微侧身站姿,目光澄澈看向前方","略微仰视,下颌抬起,眼神向上有期待","3/4侧脸侧视左前方少年英气淳朴"]
S=[42,137,256,399]
def g(prompt,neg,seed):
url=f"{URL}/images/generations"
r=subprocess.run(["curl","-s","-m","120","--noproxy","*","-X","POST",url,
"-H",f"Authorization: Bearer {AK}","-H","Content-Type: application/json",
"-d",json.dumps({"model":M,"prompt":prompt,"negative_prompt":neg,"size":"1440x2560","n":1,"seed":seed})],
capture_output=True,text=True,timeout=130)
try:d=json.loads(r.stdout);return d["data"][0].get("url")
except:return None
def d(url,dst):
Path(dst).parent.mkdir(parents=True,exist_ok=True)
subprocess.run(["curl","-s","-m","60","-L","--noproxy","*","-o",dst,url],capture_output=True,timeout=65)
return os.path.exists(dst) and os.path.getsize(dst)>1024
def main():
print("CHAR-004 R5 · 剧本锚定 · 18岁淳朴粗麻白衣")
if not AK: sys.exit("✗ no key")
ts=time.strftime("%Y%m%d-%H%M%S");rd=J/"D157-R5"/ts;rd.mkdir(parents=True,exist_ok=True)
CD.mkdir(parents=True,exist_ok=True);rs=[]
for i,(seed,var) in enumerate(zip(S,V)):
full=f"{P} {var}";print(f"[{i+1}/4] seed={seed}",flush=True)
url=g(full,N,seed)
if not url:rs.append({"c":i+1,"ok":False,"err":"api"});continue
raw=rd/f"CHAR-004-R5-{i+1:02d}-1440x2560.jpg"
if not d(url,raw):rs.append({"c":i+1,"ok":False,"err":"dl"});continue
sc=CD/f"CHAR-004-R5-candidate-{i+1:02d}-1080x1920.jpg"
subprocess.run(["sips","-z","1920","1080",str(raw),"--out",str(sc)],capture_output=True)
rs.append({"c":i+1,"ok":True,"raw":str(raw),"scaled":str(sc),"seed":seed});time.sleep(2)
ok=sum(1 for r in rs if r["ok"]);print(f"完成:{ok}/4")
with open(CD/"generation-meta.json","w") as f:json.dump({"spec":"VA-05-001-R5","ts":ts,"ok":ok,"results":rs},f,ensure_ascii=False,indent=2)
return 0 if ok>=4 else 1
if __name__=="__main__":sys.exit(main())

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""CHAR-004 R4 QC · Qwen-VL · 朴素制服版"""
import sys,os,json,base64,subprocess
sys.path.insert(0,os.path.dirname(__file__))
from secrets_loader import secret,endpoint
AK=secret("SC-004");EP=endpoint("EPT-002");FE="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
DIR=os.path.expanduser("~/guanghulab/video-ai-system/assets/candidates/D157-VA-05-001-R4/CHAR-004-ZhugeFeng")
CS=[f"{DIR}/CHAR-004-R4-candidate-{i:02d}-1080x1920.jpg" for i in range(1,5)]
P="""检查CHAR-004学徒制服图。R4核心朴素整洁修仙学徒袍布料平整干净利落不准破旧乞丐感。
逐项严格判断
1. 衣服是否有破损/破洞(damaged:bool)
2. 衣服下摆有没有毛边/撕裂(frayed:bool)
3. 裤子膝盖有没有破洞(hole_knee:bool)
4. 鞋面有没有脏污(dirty_shoes:bool)
5. 衣服有没有污渍(stains:bool)
6. 布料整体是否平整整洁(neat:bool)
7. 有没有乞丐/流浪/寒酸感(beggar:bool)
8. 和苏白CHAR-003脸像不像(like_sb:bool)
9. 五官正常吗(face:bool)
10. 全身从头到脚完整吗(full:bool)
评分标准有破损/破洞/毛边直接pass=falsebeggar=true直接pass=false
输出JSON:{"candidate":N,"pass":bool,"score":0-100,"damaged":bool,"frayed":bool,"hole_knee":bool,"dirty_shoes":bool,"stains":bool,"neat":bool,"beggar":bool,"like_sb":bool,"face":bool,"full":bool,"summary":"简短结论"}"""
def enc(p):
with open(p,"rb") as f: b64=base64.b64encode(f.read()).decode()
m="jpeg" if p.endswith("jpg") else "png"
return f"data:image/{m};base64,{b64}"
def qw(img):
b=json.dumps({"model":"qwen-vl-max","input":{"messages":[{"role":"user","content":[{"image":img},{"text":P}]}]}})
for ep in[EP,FE]:
try:
p=subprocess.run(["curl","-s","-m","60","--noproxy","*","-X","POST",ep,"-H",f"Authorization: Bearer {AK}","-H","Content-Type: application/json","--data-binary","@-"],input=b,capture_output=True,text=True,timeout=65)
if not p.stdout.strip(): continue
r=json.loads(p.stdout)
if "output" in r:
c=r["output"]["choices"][0]["message"]["content"][0]["text"]
if "```" in c: c=c.split("```")[1]; c=c[4:] if c.startswith("json") else c; c=c.split("```")[0]
return json.loads(c.strip())
except: continue
return None
rs=[]
for i,p in enumerate(CS):
print(f"[{i+1}/4]",end=" ",flush=True)
q=qw(enc(p))
if q:
print(f"score={q.get('score','?')} pass={q.get('pass','?')} 破={q.get('damaged','?')} 乞丐={q.get('beggar','?')}")
rs.append(q)
else: print(""); rs.append({"candidate":i+1,"pass":False,"error":"api"})
ok=sum(1 for r in rs if r.get("pass"))
print(f"\n通过:{ok}/4")
for r in rs:
if not r.get("pass"):
iss=[]
if r.get("damaged"): iss.append("破损")
if r.get("frayed"): iss.append("毛边")
if r.get("hole_knee"): iss.append("膝盖破洞")
if r.get("dirty_shoes"): iss.append("脏鞋")
if r.get("beggar"): iss.append("乞丐感")
print(f" 候选{r.get('candidate')} ✗: {','.join(iss) if iss else '评分不足'} score={r.get('score')}")
rep={"spec":"VA-05-001-R4","results":rs,"summary":{"passed":ok,"total":4}}
with open(os.path.join(DIR,"QC-R4-BATCH.json"),"w") as f: json.dump(rep,f,ensure_ascii=False,indent=2)
print(f"\n报告: QC-R4-BATCH.json")

View File

@ -0,0 +1,64 @@
#!/usr/bin/env python3
"""CHAR-004 R5 QC · 剧本锚定版 · 素色白衣"""
import sys,os,json,base64,subprocess
sys.path.insert(0,os.path.dirname(__file__))
from secrets_loader import secret,endpoint
AK=secret("SC-004");EP=endpoint("EPT-002");FE="https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"
DIR=os.path.expanduser("~/guanghulab/video-ai-system/assets/candidates/D157-VA-05-001-R5/CHAR-004-ZhugeFeng")
CS=[f"{DIR}/CHAR-004-R5-candidate-{i:02d}-1080x1920.jpg" for i in range(1,5)]
P="""检查CHAR-004诸葛风立绘。剧本设定18岁淳朴少年素色粗麻布衣干净整洁。
逐项
1. 衣服是否为素色/白色系(white_clothes:bool)
2. 衣服有无破损/破洞(damaged:bool)
3. 下摆有无毛边(frayed:bool)
4. 裤子膝盖有无破洞(hole_knee:bool)
5. 鞋面有无脏污(dirty_shoes:bool)
6. 服装有无污渍(stains:bool)
7. 整体有无乞丐感/寒酸(beggar:bool)
8. 气质是否淳朴端正(honest:bool)
9. 面部和苏白像不像(like_sb:bool)
10. 五官清晰吗(face_ok:bool)
11. 全身完整吗(full_body:bool)
评分damaged/frayed/hole_knee/dirty_shoes/stains/beggar任一为true pass=false
输出JSON:{"candidate":N,"pass":bool,"score":0-100,"white_clothes":bool,"damaged":bool,"frayed":bool,"hole_knee":bool,"dirty_shoes":bool,"stains":bool,"beggar":bool,"honest":bool,"like_sb":bool,"face_ok":bool,"full_body":bool,"summary":"一句话"}"""
def e(p):
with open(p,"rb") as f: b64=base64.b64encode(f.read()).decode()
return f"data:image/{'jpeg' if p.endswith('jpg') else 'png'};base64,{b64}"
def q(img):
b=json.dumps({"model":"qwen-vl-max","input":{"messages":[{"role":"user","content":[{"image":img},{"text":P}]}]}})
for ep in[EP,FE]:
try:
r=subprocess.run(["curl","-s","-m","60","--noproxy","*","-X","POST",ep,"-H",f"Authorization: Bearer {AK}","-H","Content-Type: application/json","--data-binary","@-"],input=b,capture_output=True,text=True,timeout=65)
if not r.stdout.strip(): continue
d=json.loads(r.stdout)
if "output" in d:
c=d["output"]["choices"][0]["message"]["content"][0]["text"]
if "```" in c: c=c.split("```")[1];c=c[4:] if c.startswith("json") else c;c=c.split("```")[0]
return json.loads(c.strip())
except: continue
return None
rs=[]
for i,p in enumerate(CS):
print(f"[{i+1}/4]",end=" ",flush=True)
qc=q(e(p))
if qc:
print(f"s={qc.get('score','?')} pass={qc.get('pass','?')} 白色={qc.get('white_clothes','?')} 破={qc.get('damaged','?')}")
rs.append(qc)
else: print("");rs.append({"candidate":i+1,"pass":False,"error":"api"})
ok=sum(1 for r in rs if r.get("pass"))
print(f"\n通过:{ok}/4")
for r in rs:
if not r.get("pass"):
iss=[];d=r
if d.get("damaged"):iss.append("破损")
if d.get("frayed"):iss.append("毛边")
if d.get("hole_knee"):iss.append("膝盖破洞")
if d.get("dirty_shoes"):iss.append("脏鞋")
if d.get("beggar"):iss.append("乞丐感")
print(f"{r.get('candidate')} ✗: {','.join(iss) if iss else '其他'} s={r.get('score')}")
rep={"spec":"VA-05-001-R5","results":rs,"summary":{"passed":ok,"total":4}}
with open(os.path.join(DIR,"QC-R5-BATCH.json"),"w") as f:json.dump(rep,f,ensure_ascii=False,indent=2)
print(f"\n报告:QC-R5-BATCH.json")