D146: 密钥编号体系 · 不用散落变量名·用编号查地图
- 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地图→拿到变量名→读文件→拿到值
This commit is contained in:
parent
7c05b1da93
commit
18cd6e7425
@ -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` | 别裸写变量名·用编号查地图 |
|
||||
|
||||
---
|
||||
|
||||
|
||||
@ -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
|
||||
⊢ 密钥管理完成编号化。散落结束。
|
||||
|
||||
@ -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):
|
||||
|
||||
@ -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 "(空)")
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user