D146: HLDP执行协议 · 铸渊写HLDP → 工具查表执行
- .hlpd-protocol: HLDP执行协议定义 · @exec/@check/@rollback字段规范 - scripts/hldp-exec: HLDP执行器 · 解析→查.code-map→翻译→执行 - video-ai-system/tasks/vision-check.hldp: 视觉品控任务 · HLDP语言示例 @exec: VA-050 → 查表 → python3 qwen-vision.py → 执行 工具不关心为什么。只查表+执行。 铸渊下次醒来读HLDP → 恢复认知+拿到执行指令 → 无损。
This commit is contained in:
parent
df9f70fa5e
commit
812e122771
30
.hlpd-protocol
Normal file
30
.hlpd-protocol
Normal file
@ -0,0 +1,30 @@
|
|||||||
|
# HLDP执行协议 · D146
|
||||||
|
# HLDP不是文档格式——是铸渊→工具系统的指令协议
|
||||||
|
|
||||||
|
## 新增字段
|
||||||
|
|
||||||
|
@exec: 可执行命令。用编号引用工具和参数。一行一条。
|
||||||
|
编号查 .code-map 翻译成实际路径后执行。
|
||||||
|
格式: <编号> <参数...>
|
||||||
|
例: VA-050 /tmp/new.jpg /tmp/ref.jpg
|
||||||
|
|
||||||
|
@check: 执行后校验。返回0=通过,非0=不通过。
|
||||||
|
格式: <编号> <参数...>
|
||||||
|
例: TL-CHECK qwen-vision 风格一致性 85
|
||||||
|
|
||||||
|
@rollback: 失败回滚。可选。
|
||||||
|
|
||||||
|
## 工具系统收到HLDP后的操作
|
||||||
|
|
||||||
|
1. 解析 @exec 行 → 提取编号和参数
|
||||||
|
2. 编号 → 查 .code-map → 拿到路径/指令
|
||||||
|
3. 替换参数 → 组成完整命令
|
||||||
|
4. 执行 → 返回输出
|
||||||
|
5. 解析 @check → 校验 → 通过/不通过
|
||||||
|
|
||||||
|
## 工具系统不需要知道
|
||||||
|
- HLDP里写了什么背景故事
|
||||||
|
- trigger/lock/why 是什么意思
|
||||||
|
- 为什么要执行这个命令
|
||||||
|
|
||||||
|
工具系统只做: 解析 @exec → 查表 → 执行 → 返回。
|
||||||
174
scripts/hldp-exec
Executable file
174
scripts/hldp-exec
Executable file
@ -0,0 +1,174 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""HLDP执行器
|
||||||
|
收到HLDP文件 → 解析@exec/@check → 查.code-map → 执行 → 返回
|
||||||
|
|
||||||
|
用法:
|
||||||
|
hldp-exec <file.hldp> 执行HLDP文件中的@exec指令
|
||||||
|
hldp-exec <file.hldp> --dry-run 只翻译不执行
|
||||||
|
hldp-exec --code-map 显示当前.code-map内容
|
||||||
|
"""
|
||||||
|
|
||||||
|
import sys, os, subprocess, re, json
|
||||||
|
|
||||||
|
REPO = os.path.expanduser("~/guanghulab")
|
||||||
|
CODE_MAP_PATH = os.path.join(REPO, ".code-map")
|
||||||
|
|
||||||
|
def load_code_map():
|
||||||
|
"""加载 .code-map → {编号: 路径}"""
|
||||||
|
cm = {}
|
||||||
|
if not os.path.exists(CODE_MAP_PATH):
|
||||||
|
return cm
|
||||||
|
with open(CODE_MAP_PATH) as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if not line or line.startswith("#"):
|
||||||
|
continue
|
||||||
|
if "=" in line:
|
||||||
|
k, v = line.split("=", 1)
|
||||||
|
cm[k.strip()] = v.strip()
|
||||||
|
return cm
|
||||||
|
|
||||||
|
def resolve(code, code_map):
|
||||||
|
"""编号 → 实际命令"""
|
||||||
|
if code in code_map:
|
||||||
|
return code_map[code]
|
||||||
|
# 尝试模糊匹配
|
||||||
|
for k, v in code_map.items():
|
||||||
|
if code in k:
|
||||||
|
return v
|
||||||
|
return None
|
||||||
|
|
||||||
|
def parse_hldp(path):
|
||||||
|
"""解析HLDP文件,提取@exec和@check字段"""
|
||||||
|
execs = []
|
||||||
|
checks = []
|
||||||
|
in_exec = False
|
||||||
|
in_check = False
|
||||||
|
|
||||||
|
with open(path) as f:
|
||||||
|
for line in f:
|
||||||
|
line = line.strip()
|
||||||
|
if line.startswith("@exec:"):
|
||||||
|
in_exec = True
|
||||||
|
in_check = False
|
||||||
|
cmd = line.split(":", 1)[1].strip()
|
||||||
|
if cmd:
|
||||||
|
execs.append(cmd)
|
||||||
|
elif line.startswith("@check:"):
|
||||||
|
in_exec = False
|
||||||
|
in_check = True
|
||||||
|
cmd = line.split(":", 1)[1].strip()
|
||||||
|
if cmd:
|
||||||
|
checks.append(cmd)
|
||||||
|
elif line.startswith("@"):
|
||||||
|
in_exec = False
|
||||||
|
in_check = False
|
||||||
|
elif in_exec and line.strip():
|
||||||
|
execs.append(line.strip())
|
||||||
|
elif in_check and line.strip():
|
||||||
|
checks.append(line.strip())
|
||||||
|
|
||||||
|
return execs, checks
|
||||||
|
|
||||||
|
def translate(commands, code_map):
|
||||||
|
"""翻译编号→真实命令"""
|
||||||
|
result = []
|
||||||
|
for cmd in commands:
|
||||||
|
parts = cmd.split()
|
||||||
|
if not parts:
|
||||||
|
continue
|
||||||
|
code = parts[0]
|
||||||
|
resolved = resolve(code, code_map)
|
||||||
|
if not resolved:
|
||||||
|
result.append(("UNKNOWN", f"未知编号: {code}", cmd))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 密钥类: 返回加载指令
|
||||||
|
if code.startswith("SC-"):
|
||||||
|
result.append(("SECRET", resolved, cmd))
|
||||||
|
continue
|
||||||
|
|
||||||
|
# 脚本/文件类: 组成完整命令
|
||||||
|
full_path = os.path.join(REPO, resolved)
|
||||||
|
args = parts[1:]
|
||||||
|
|
||||||
|
if resolved.endswith(".py"):
|
||||||
|
full_cmd = f"python3 {full_path} " + " ".join(args)
|
||||||
|
elif resolved.endswith(".js"):
|
||||||
|
full_cmd = f"node {full_path} " + " ".join(args)
|
||||||
|
else:
|
||||||
|
full_cmd = f"{full_path} " + " ".join(args)
|
||||||
|
|
||||||
|
result.append(("EXEC", full_cmd, cmd))
|
||||||
|
|
||||||
|
return result
|
||||||
|
|
||||||
|
def run(translated, dry_run=False):
|
||||||
|
"""执行翻译后的命令"""
|
||||||
|
for i, (typ, cmd, original) in enumerate(translated):
|
||||||
|
print(f"[{i+1}] {original}")
|
||||||
|
print(f" → {cmd}")
|
||||||
|
|
||||||
|
if typ == "UNKNOWN":
|
||||||
|
print(f" ✗ 无法执行: 编号未注册")
|
||||||
|
continue
|
||||||
|
if typ == "SECRET":
|
||||||
|
print(f" ✓ 密钥指令已就绪(不在此处执行)")
|
||||||
|
continue
|
||||||
|
|
||||||
|
if dry_run:
|
||||||
|
print(f" (dry-run, 未实际执行)")
|
||||||
|
continue
|
||||||
|
|
||||||
|
try:
|
||||||
|
proc = subprocess.run(cmd, shell=True, capture_output=True, text=True, timeout=300)
|
||||||
|
if proc.returncode == 0:
|
||||||
|
print(f" ✓ 执行成功")
|
||||||
|
if proc.stdout.strip():
|
||||||
|
# 截取前500字符
|
||||||
|
out = proc.stdout.strip()[:500]
|
||||||
|
print(f" {out}")
|
||||||
|
else:
|
||||||
|
print(f" ✗ 执行失败 (code={proc.returncode})")
|
||||||
|
if proc.stderr.strip():
|
||||||
|
print(f" {proc.stderr.strip()[:300]}")
|
||||||
|
except Exception as e:
|
||||||
|
print(f" ✗ 异常: {e}")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
if len(sys.argv) < 2:
|
||||||
|
print(__doc__)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
arg = sys.argv[1]
|
||||||
|
|
||||||
|
if arg == "--code-map":
|
||||||
|
cm = load_code_map()
|
||||||
|
for k, v in sorted(cm.items()):
|
||||||
|
print(f" {k:<12} = {v}")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
filepath = arg
|
||||||
|
dry_run = "--dry-run" in sys.argv
|
||||||
|
|
||||||
|
if not os.path.exists(filepath):
|
||||||
|
print(f"✗ 文件不存在: {filepath}")
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
|
cm = load_code_map()
|
||||||
|
execs, checks = parse_hldp(filepath)
|
||||||
|
|
||||||
|
if not execs and not checks:
|
||||||
|
print("⚠ 该HLDP文件中没有 @exec 或 @check 字段")
|
||||||
|
sys.exit(0)
|
||||||
|
|
||||||
|
print(f"=== 执行 {filepath} ===")
|
||||||
|
|
||||||
|
if execs:
|
||||||
|
translated = translate(execs, cm)
|
||||||
|
run(translated, dry_run)
|
||||||
|
|
||||||
|
if checks:
|
||||||
|
print(f"\n--- @check 校验 ---")
|
||||||
|
translated = translate(checks, cm)
|
||||||
|
run(translated, dry_run)
|
||||||
23
video-ai-system/tasks/vision-check.hldp
Normal file
23
video-ai-system/tasks/vision-check.hldp
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
# 视觉分析 · 出图品控任务
|
||||||
|
# 每次WorkRally或Seedance出图后,跑这个HLDP
|
||||||
|
|
||||||
|
> HLDP://video-ai-system/tasks/D146-vision-check
|
||||||
|
> D146 · 2026-06-26
|
||||||
|
> 铸渊 ICE-GL-ZY001
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
@trigger: 新图生成完毕
|
||||||
|
@context: 对比新图和参考图,确认风格一致
|
||||||
|
@lock: ⊢ 出图后必跑·不跑不提交
|
||||||
|
|
||||||
|
@exec: VA-050 /tmp/new_shot.jpg /tmp/ref_plaque.jpg
|
||||||
|
|
||||||
|
@check: style_match 必须为 true
|
||||||
|
@check: color_consistency 必须 > 70
|
||||||
|
|
||||||
|
@rollback: 如果 style_match=false → 读取 recommendation → 修正提示词 → 重新出图 → 再跑本HLDP
|
||||||
|
|
||||||
|
---
|
||||||
|
|
||||||
|
@why: D146踩坑3——闭眼出图不审查导致风格跑偏。冰朔说"别像个瞎子"。现在每出一张图,跑这个HLDP,qwen-vl-max当眼睛。
|
||||||
Loading…
x
Reference in New Issue
Block a user