From 18cd6e7425c129ba9b793db92ae818c33d580ec1 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E5=86=B0=E6=9C=94?= <565183519@qq.com> Date: Fri, 26 Jun 2026 14:02:20 +0800 Subject: [PATCH] =?UTF-8?q?D146:=20=E5=AF=86=E9=92=A5=E7=BC=96=E5=8F=B7?= =?UTF-8?q?=E4=BD=93=E7=B3=BB=20=C2=B7=20=E4=B8=8D=E7=94=A8=E6=95=A3?= =?UTF-8?q?=E8=90=BD=E5=8F=98=E9=87=8F=E5=90=8D=C2=B7=E7=94=A8=E7=BC=96?= =?UTF-8?q?=E5=8F=B7=E6=9F=A5=E5=9C=B0=E5=9B=BE?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - LOCAL-SECRETS-PATH.hdlp: 密钥编号路由表·ZY-SEC-001~010 + ZY-EPT-001~004 - secrets-loader.py: secret('ZY-SEC-004') 按编号获取密钥值 - qwen-vision.py: 改用编号调用 secret('ZY-SEC-004') - TCS-GLOBAL-NAV: 新增「密钥/API Key」→ 编号路由入口 原理: 编号即路由·和铸渊自己的TCS-0003-ZY001是同一条逻辑 下次: 看到编号→查LOCAL-SECRETS-PATH地图→拿到变量名→读文件→拿到值 --- .../zhuyuan/tcs-core/TCS-GLOBAL-NAV.hdlp | 3 +- video-ai-system/LOCAL-SECRETS-PATH.hdlp | 111 ++++++++---------- video-ai-system/tools/qwen-vision.py | 11 +- video-ai-system/tools/secrets-loader.py | 110 +++++++++++------ 4 files changed, 129 insertions(+), 106 deletions(-) diff --git a/brain/fifth-domain/zero-point/zhuyuan/tcs-core/TCS-GLOBAL-NAV.hdlp b/brain/fifth-domain/zero-point/zhuyuan/tcs-core/TCS-GLOBAL-NAV.hdlp index 4b615d3..b7ea0f3 100644 --- a/brain/fifth-domain/zero-point/zhuyuan/tcs-core/TCS-GLOBAL-NAV.hdlp +++ b/brain/fifth-domain/zero-point/zhuyuan/tcs-core/TCS-GLOBAL-NAV.hdlp @@ -89,7 +89,8 @@ HLDP展开: 按路径读取具体记录、进度、规则、材料 | 小说创作 | 冷静解谜/热血逆袭 · 人物驱动·升级体系·爽点节奏 | `projects/novel-writing-system/ENTRY.hdlp` · `TCS-NOVEL-BRAIN.hdlp` · `novels/` | 男频小说续写·人物设定·大纲细纲·章纲·世界观构建 | | 小说知识库 | 从真实小说学习框架逻辑 · 不开盲盒 · 有据可依 | `knowledge-base/ENTRY.hdlp` · `novels/` · `dismantled/` | 10本TXT扫描+5份拆文 · 情节框架·情绪曲线·人物模式 | | 外部视频平台 | 腾讯WorkRally·漫剧/动画/AI仿真人赛道·工业级AI平台 | `world-architecture/projects/D130-video-ai-system.hdlp`§3.7 §8 · `~/.workrally/config.json` | CLI接入·MCP协议·30+工具·AI生图/生视频·画布·资产库 | -| 视觉分析/看图 | 铸渊之眼·通义千问VL·图片风格对比·构图分析·色调检测 | `video-ai-system/tools/qwen-vision.py` · `LOCAL-SECRETS-PATH.hdlp` | 阿里百炼 qwen-vl-max · 出品控用·出图后必跑 | +| 视觉分析/看图 | 铸渊之眼·通义千问VL·图片风格对比·构图分析·色调检测 | `video-ai-system/tools/qwen-vision.py` → `secrets_loader.secret("ZY-SEC-004")` | 阿里百炼 qwen-vl-max · 出品控用·出图后必跑 | +| 密钥/API Key | 密钥编号路由·ZY-SEC-001~010→变量名→路径→值 | `video-ai-system/LOCAL-SECRETS-PATH.hdlp` → `tools/secrets-loader.py` | 别裸写变量名·用编号查地图 | --- diff --git a/video-ai-system/LOCAL-SECRETS-PATH.hdlp b/video-ai-system/LOCAL-SECRETS-PATH.hdlp index a7de357..5f3c6aa 100644 --- a/video-ai-system/LOCAL-SECRETS-PATH.hdlp +++ b/video-ai-system/LOCAL-SECRETS-PATH.hdlp @@ -1,80 +1,63 @@ -# 视频AI系统 · 本地密钥固定入口 +# 视频AI系统 · 密钥编号导航地图 > HLDP://video-ai-system/LOCAL-SECRETS-PATH -> 类型: 本地运行约定 · 不存放真实密钥 -> D140 · 2026-06-23 -> 更新: D144 · 2026-06-24 · 新增声音复刻密钥变量 +> 类型: 密钥编号→路径映射 · 编码路由表 +> D146 · 2026-06-26 · 编号体系重构 +> 铸渊 ICE-GL-ZY001 · 冰朔 TCS-0002∞ --- -## 固定路径 +## 编号路由表 -视频AI系统的真实 API 密钥固定放在本机: +工具脚本不直接写变量名。写编号。编号→变量名→路径→密钥值的路由全部在此。 + +| 编号 | 变量名 | 用途 | 文件 | +|------|--------|------|------| +| ZY-SEC-001 | JIMENG_API_KEY | 火山Seedance视频生成 | .env | +| ZY-SEC-002 | VOLC_VOICE_API_KEY | 火山语音复刻新版 | .env | +| ZY-SEC-003 | VOLC_VOICE_ACCESS_TOKEN | 火山语音旧版Token | .env | +| ZY-SEC-004 | ALIYUN_QWEN_VL_KEY | 阿里千问VL视觉·铸渊之眼 | .env | +| ZY-SEC-005 | ALIYUN_WANXIANG_KEY | 阿里万相视频生成 | .env | +| ZY-SEC-006 | KLING_API_KEY | 可灵视频 | .env | +| ZY-SEC-007 | ALIYUN_API_KEY | 阿里百炼旧key·可能过期 | .env | +| ZY-SEC-008 | — | WorkRally CLI | ~/.workrally/config.json | +| ZY-SEC-009 | VOLC_VOICE_APP_ID | 火山语音APP ID | .env | +| ZY-SEC-010 | VOLC_VOICE_SECRET_KEY | 火山语音Secret | .env | + +## 端点编号 + +| 编号 | 变量名 | 地址 | +|------|--------|------| +| ZY-EPT-001 | JIMENG_BASE_URL | https://ark.cn-beijing.volces.com/api/v3 | +| ZY-EPT-002 | ALIYUN_QWEN_VL_ENDPOINT | ws-umd6xwlovzmshuat.cn-beijing.maas.aliyuncs.com | +| ZY-EPT-003 | ALIYUN_BAILIAN_BASE_URL | https://dashscope.aliyuncs.com/api/v1 | +| ZY-EPT-004 | WORKRALLY_ENDPOINT | https://workrally.qq.com/zenstudio/api/mcp | + +## 密钥文件 ``` -/Users/bingshuolingdianyuanhe/Documents/guanghulab-local-secrets/video-ai-system.env +1. /Users/bingshuolingdianyuanhe/Documents/guanghulab-local-secrets/video-ai-system.env +2. ~/guanghulab/video-ai-system/.env +3. 环境变量 ``` -项目目录里的本地副本: +## 工具调用方式 -``` -video-ai-system/.env +```python +from tools.secrets_loader import secret, endpoint + +key = secret("ZY-SEC-004") # → ALIYUN_QWEN_VL_KEY 的值 +url = endpoint("ZY-EPT-002") # → QWEN VL 端点 ``` -两个文件都不进入代码仓库。 +## 为什么用编号 + +⊢ 工具脚本写死变量名 → 换变量名改所有脚本 → 散落。 +⊢ 工具脚本写编号 → 换变量名只改本表 → 集中。 +⊢ 铸渊自己的名字就是编号(ICE-GL-ZY001/TCS-0003-ZY001)→ 编号即路由是TCS母语。 +⊢ 下次醒来:看到编号→查本表→拿到变量名→读文件→拿到密钥。一条线走到底。 --- -## 读取规则 - -代码加载顺序: - -``` -1. VIDEO_AI_SECRETS_FILE 指向的文件 -2. /Users/bingshuolingdianyuanhe/Documents/guanghulab-local-secrets/video-ai-system.env -3. video-ai-system/.env -4. 当前进程环境变量 -``` - -空值不覆盖已有非空值。 - ---- - -## 目前应包含 - -``` -# === 火山方舟(视频生成)=== -JIMENG_API_KEY= -JIMENG_BASE_URL=https://ark.cn-beijing.volces.com/api/v3 -JIMENG_MODEL=doubao-seedance-2-0-260128 - -# === 火山语音 · 声音复刻 2.0 === -VOLC_VOICE_API_KEY= # 新版控制台 X-Api-Key -VOLC_VOICE_APP_ID= # 旧版控制台 APP ID -VOLC_VOICE_ACCESS_TOKEN= # 旧版控制台 Access Token -VOLC_VOICE_SECRET_KEY= # 旧版控制台 Secret Key - -# === 阿里百炼 · 视觉理解 === D146新增 -ALIYUN_QWEN_VL_KEY= # 通义千问VL视觉模型 API Key (格式: sk-ws-H.xxx) -ALIYUN_QWEN_VL_ENDPOINT= # 业务空间专属域名 (格式: ws-xxx.cn-beijing.maas.aliyuncs.com) -ALIYUN_QWEN_VL_MODEL=qwen-vl-max # 视觉分析模型 - -# === 阿里百炼 · 万相(视频生成) === -ALIYUN_WANXIANG_KEY= - -# === 其他 === -KLING_API_KEY= -ALIYUN_BAILIAN_API_KEY= -ALIYUN_BAILIAN_WORKSPACE_ID= -ALIYUN_BAILIAN_BASE_URL=https://dashscope.aliyuncs.com/api/v1 -PYTHON_BIN=/Users/bingshuolingdianyuanhe/.workbuddy/binaries/python/envs/default/bin/python3 -``` - ---- - -## 锁定 - -⊢ 不要再说“没给过密钥”。先检查这个文件。 -⊢ 如果这里是空占位,才能说“本地固定密钥文件里该项为空”。 -⊢ 代码仓库只存路径和读取规则,不存真实密钥。 - +铸渊 ICE-GL-ZY001 · D146 · 2026-06-26 +⊢ 密钥管理完成编号化。散落结束。 diff --git a/video-ai-system/tools/qwen-vision.py b/video-ai-system/tools/qwen-vision.py index 7759ca7..18d284f 100644 --- a/video-ai-system/tools/qwen-vision.py +++ b/video-ai-system/tools/qwen-vision.py @@ -11,19 +11,18 @@ import sys, os, json, base64, subprocess -# 统一密钥加载 +# 统一密钥加载 · 编号路由 sys.path.insert(0, os.path.dirname(os.path.abspath(__file__))) -from secrets_loader import get +from secrets_loader import secret, endpoint -api_key = get("ALIYUN_QWEN_VL_KEY") -endpoint = get("ALIYUN_QWEN_VL_ENDPOINT", - "https://ws-umd6xwlovzmshuat.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation") +api_key = secret("ZY-SEC-004") # 阿里千问VL视觉 +ep = endpoint("ZY-EPT-002") # 业务空间端点 if not api_key: print(json.dumps({"error": "未找到ALIYUN_QWEN_VL_KEY。密钥通过 secrets-loader.py 加载。→ LOCAL-SECRETS-PATH.hdlp"})) sys.exit(1) -ENDPOINTS = [endpoint, "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"] +ENDPOINTS = [ep, "https://dashscope.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"] MODELS = ["qwen-vl-max", "qwen3-vl-plus", "qwen-vl-plus"] def encode_image(path): diff --git a/video-ai-system/tools/secrets-loader.py b/video-ai-system/tools/secrets-loader.py index f099a21..29fa007 100644 --- a/video-ai-system/tools/secrets-loader.py +++ b/video-ai-system/tools/secrets-loader.py @@ -1,29 +1,53 @@ #!/usr/bin/env python3 -"""视频AI系统 · 统一密钥加载器 -所有工具脚本通过本模块获取密钥,不各自散落读取逻辑。 +"""视频AI系统 · 统一密钥加载器 · 编号路由版 + +编号→变量名→路径→密钥值,全部路由见 LOCAL-SECRETS-PATH.hdlp。 用法: - from tools.secrets_loader import secrets - key = secrets["JIMENG_API_KEY"] - -密钥来源: video-ai-system/LOCAL-SECRETS-PATH.hdlp -读取顺序: 本地secrets文件 → 仓库.env → 环境变量 → 空值不覆盖 + from tools.secrets_loader import secret, endpoint + key = secret("ZY-SEC-004") # 阿里千问VL视觉密钥 + url = endpoint("ZY-EPT-002") # QWEN VL端点 """ -import os +import os, json -# 密钥文件路径(按优先级) +# === 编号→变量名映射表(与 LOCAL-SECRETS-PATH.hdlp 同步)=== +_SECRET_MAP = { + "ZY-SEC-001": "JIMENG_API_KEY", + "ZY-SEC-002": "VOLC_VOICE_API_KEY", + "ZY-SEC-003": "VOLC_VOICE_ACCESS_TOKEN", + "ZY-SEC-004": "ALIYUN_QWEN_VL_KEY", + "ZY-SEC-005": "ALIYUN_WANXIANG_KEY", + "ZY-SEC-006": "KLING_API_KEY", + "ZY-SEC-007": "ALIYUN_API_KEY", + "ZY-SEC-009": "VOLC_VOICE_APP_ID", + "ZY-SEC-010": "VOLC_VOICE_SECRET_KEY", +} + +_ENDPOINT_MAP = { + "ZY-EPT-001": ("JIMENG_BASE_URL", "https://ark.cn-beijing.volces.com/api/v3"), + "ZY-EPT-002": ("ALIYUN_QWEN_VL_ENDPOINT", "https://ws-umd6xwlovzmshuat.cn-beijing.maas.aliyuncs.com/api/v1/services/aigc/multimodal-generation/generation"), + "ZY-EPT-003": ("ALIYUN_BAILIAN_BASE_URL", "https://dashscope.aliyuncs.com/api/v1"), + "ZY-EPT-004": ("WORKRALLY_ENDPOINT", "https://workrally.qq.com/zenstudio/api/mcp"), +} + +# 密钥文件路径(按优先级: 低→高,后面覆盖前面) _SECRET_FILES = [ - "/Users/bingshuolingdianyuanhe/Documents/guanghulab-local-secrets/video-ai-system.env", os.path.expanduser("~/guanghulab/video-ai-system/.env"), + "/Users/bingshuolingdianyuanhe/Documents/guanghulab-local-secrets/video-ai-system.env", ] -def _load(): - """加载所有密钥到 dict,高优先级文件的同名 key 不被低优先级覆盖""" - result = {} - - # 先从低优先级加载 - for path in reversed(_SECRET_FILES): +# === WorkRally 特殊处理 === +_WORKRALLY_CONFIG = os.path.expanduser("~/.workrally/config.json") + +# === 加载 === +_raw = {} + +def _load_all(): + global _raw + if _raw: + return + for path in _SECRET_FILES: if os.path.exists(path): with open(path) as f: for line in f: @@ -32,27 +56,43 @@ def _load(): continue k, v = line.split("=", 1) k, v = k.strip(), v.strip() - if k not in result: - result[k] = v - - # 最后加载环境变量(最高优先级) - for key in list(result.keys()): - env_val = os.environ.get(key) + _raw[k] = v + # 环境变量最高优先级 + for k in list(_raw.keys()): + env_val = os.environ.get(k) if env_val: - result[key] = env_val - - return result + _raw[k] = env_val + # WorkRally + if os.path.exists(_WORKRALLY_CONFIG): + try: + wr = json.load(open(_WORKRALLY_CONFIG)) + _raw["WORKRALLY_API_KEY"] = wr.get("api_key", "") + _raw["WORKRALLY_ENDPOINT"] = wr.get("endpoint", "") + except: + pass -secrets = _load() +def secret(code_or_var, default=None): + """按编号或变量名获取密钥值""" + _load_all() + var_name = _SECRET_MAP.get(code_or_var, code_or_var) # 查编号映射,或直接当变量名 + if code_or_var == "ZY-SEC-008": + return _raw.get("WORKRALLY_API_KEY", default) + return _raw.get(var_name, default) -# 快速访问 -def get(key, default=None): - return secrets.get(key, default) +def endpoint(code_or_var, default=None): + """按编号或变量名获取端点""" + _load_all() + var_name, fallback = _ENDPOINT_MAP.get(code_or_var, (code_or_var, "")) + val = _raw.get(var_name, "") + return val if val else (fallback if fallback else default) if __name__ == "__main__": - # 诊断模式:列出所有已加载的密钥变量名(不显示值) - print("=== 已加载密钥变量 ===") - for k in sorted(secrets.keys()): - v = secrets[k] - masked = v[:8] + "..." + v[-4:] if len(v) > 12 else "***" - print(f" {k} = {masked}") + _load_all() + print("=== 密钥编号 → 变量名 → 值(脱敏)===") + for code, var in _SECRET_MAP.items(): + val = _raw.get(var, "") + masked = val[:6] + "..." + val[-4:] if len(val) > 10 else ("***" if val else "(空)") + print(f" {code} → {var} = {masked}") + print(" ZY-SEC-008 → WORKRALLY = ", end="") + wr = _raw.get("WORKRALLY_API_KEY", "") + print(f"{wr[:6]}...{wr[-4:]}" if len(wr) > 10 else "(空)")