Files
digital-me-history/digital-me-backend/docs/talents/README.md
T
admin 0593ff7e62
nginx serve /uploads direct (audio speed) / patch-nginx (push) Failing after 1m34s
数字我 Digital Me:全量入库(大文件走 Git LFS)
2026-10-10 16:24:43 +08:00

4.9 KiB
Executable File
Raw Blame History

天赋系统契约(Talent System Contract)

天赋树 = Prompt + 模型行为的控制平面,不是游戏成长系统。

  • 主天赋(唯一) = 身份:决定 System Prompt / 是否走 RAG / 合规安全等级 / 默认模型。主天赋 就是 twin.profession,不另存一套 id。
  • 副天赋(≤N) = 风格软技能:后置改写,只碰成稿、绝不改事实。

实现见 ../../src/talents.js。本目录是与线上代码对齐的契约,也是将来搬 DB 的蓝本。

文件

Schema 描述 对应代码
main-talent.schema.json 主天赋身份节点 mainTalent(profId)
sub-talent.schema.json 副天赋注册表项 SUB_REGISTRY
user-talent-instance.schema.json 分身选定的天赋 twin.talents
talent-registry.schema.json 注册表整体 派生/静态表

派生关系(主天赋怎么来的)

不逐个职业手写主天赋,而是三张映射表交叉派生(talents.js):

profession(professions.js) ──cat──▶ ARCH_BY_CAT ──▶ arch ──▶ ARCH_BEHAVIOR(行为基线) + ARCH_MODEL(模型偏好)
                          └─compliance─▶ COMPLIANCE ──▶ safety_level + block_keywords + disclaimer + audit_required
  • cat → arch:content→creator, pro/health/biz/life/other→expert, edu→teacher, art→artist, sport→sport, craft→craft
  • compliance → 安全:none→{2,无} / soft→{5,软免责} / strict→{9,强免责+关键词+需审核}

新增一个职业只改 professions.js 一处;换某原型的行为只改 ARCH_BEHAVIOR 一处。

校验规则(服务端必须兜底,不信前端)

  1. 主天赋唯一:main_talent 必须 ∈ 职业表(getProfession),否则 400 unknown-main-talent;null/无 → general 兜底身份。
  2. 副天赋合法性:每个 id 必须 ∈ SUB_REGISTRY;去重;顺序保留。
  3. 副天赋槽位:数量 ≤ maxSubs(level) = min(3, 1 + level)(level 来自 computeSkillTree)。超出静默截断(validateSubs),不报错。
  4. 副天赋不改事实:所有 style/constraint 副天赋合并成一次后置改写,指令强约束"不改变任何事实/数字/结论/引用";hobby 型走前置注入。
  5. 审核门(软门):main.audit_required && !twin.verified → twin.talentAudit='pending',不拦截(分身仍可用),但运行时 Guardrail 强制免责。已 verified → 'approved'。
  6. Guardrail(运行时,输出前):
    • block_keywords 命中 → 软化替换;
    • safety_level >= 5 且回答未含免责 → 追加 disclaimer 到结尾。

运行时管线(services/twin.js → ask())

用户输入
  → 组装 System Prompt:身份(mainPromptBlock) + 前置注入(injectBlock) + 人设/记忆/RAG
  → (RAG 检索,main.rag)
  → LLM 主回答           chat(messages)                     ← 主天赋出稿
  → 副天赋后置改写        chat([restyleInstruction, draft])  ← 合并 1 次;无副天赋则跳过
  → Guardrail            guardrail(text, main)              ← 屏蔽词 + 免责
  → 输出

成本:每轮 1 次主调用 + 至多 1 次改写调用(不是每个副天赋一次)。

API 契约

GET /api/twins/:id/talents

返回(describeTalents):

{
  "main": { "id","name","emoji","entity","arch","compliance","safety_level",
            "rag_required","audit_required","audit_ok","behavior" },
  "subs": { "selected": ["humor"], "max": 1,
            "options": [{ "id","name","subtype","desc" }] },
  "growth": { "level": 0, "maxSubs": 1 }
}

PUT /api/twins/:id/talents

Body(两字段都可选,可单独改):

{ "main_talent": "lawyer",            // 可选:切身份(=profession),带 audit 门
  "sub_talents": ["humor","concise"] } // 可选:仅当为数组时才更新;截到 maxSubs

返回同 GET。

DB 化迁移(留了缝,MVP 不做)

  1. SUB_REGISTRY → 集合 talent_sub_registry(一项一文档)。
  2. 主天赋映射(ARCH_BEHAVIOR / COMPLIANCE / ARCH_MODEL)→ 集合 talent_main_config,或物化 talent_main_talents(一职业一行)。
  3. 每个节点加 talent-registry.schema.json#/$defs/versioning(version/active/gray_pct)→ 支持灰度放量 + 一键回滚。
  4. talents.js 的纯函数签名不变,只把三张 const 表换成带缓存的 DB 读取;describeTalents/resolveTalents/guardrail 全部复用。

留坑不做(架构留得住)

天赋升级 lv2/3(level 字段已在)· 冲突检测(医生+算命❌)· 天赋市场(官方/共创)· 会话级动态天赋 · 按天赋真路由模型/计量返佣(model_preference + chat(opts.model) 缝已在)。