Skip to content

WizardHeHeJun/Zero

Repository files navigation

Zero — 情感引擎驱动的 AI 数字人

让机器带着情绪说话。Zero 以一套情感引擎为内核、以 LLM 为语言外壳:每一句话先被读成情绪、在引擎里按人类情感动力学演化,再由语言与表情把这份情绪自然地漏出来——不是让模型"扮演"情绪,而是让情绪真实地参与生成。

情感引擎融合了五个学科的建模视角:

  • 数学 — 贝叶斯主动推断、动力系统、在线价值学习
  • 心理学 — OCC 评价理论、效价-唤醒环状模型、情绪调节、评价性条件作用
  • 生物学 — 面部动作单元(FACS)、自主神经生理反应
  • 神经科学 — 预测编码、全局工作空间点燃、显著网络门控、杏仁核多通路、多巴胺奖赏预测误差
  • 计算科学 — 多 Agent 编排(LangGraph)、多网络并行

情感引擎是怎么做的

把"人产生并表达情绪"的过程,建模成一条贝叶斯流水线——感知一句话、推断出此刻的情绪、让它随时间演化、再分两路外化为语言和表情。

情绪引擎框架图

1. 评价桥:把话读成情绪

每一句输入先经评价桥反推出效价-唤醒坐标 (v, a)——一句夸奖是正效价、一句挑衅是负效价高唤醒——作为刺激喂给引擎。

2. 情感引擎核心:贝叶斯主动推断 + 显著度门控工作空间

引擎不是简单地"查表给情绪",而是把多条并行的功能流竞争整合成一个全局情绪状态:

  • OCC 评价流 — 按目标契合度 / 标准符合度 / 对象吸引力给出情绪先验;
  • 价值流 — 在线的 TD 奖赏预测误差与精度(对惊喜、对确定性的敏感);
  • 生存流 — 快速、低精度的亚符号信号(突如其来的巨响先于"这是什么"就拉高唤醒);
  • 语义流 — 文本/语义读出的情绪作为一条独立、低精度的高阶先验汇入(语言是高阶皮层的 top-down 预测,与评价、感官流并列竞争而非互相覆盖);
  • 显著度门控点燃 — 各流各出一个 (均值, 精度),由显著网络打分,只有过阈的流被"点燃"广播进全局工作空间(全局工作空间理论的 ignition),其余停留局部、不空播;
  • 精度加权融合 + 后验采样 — 点燃的流按精度加权融合,采样出此刻的瞬时情绪 e*(随机性让同一刺激也有细微波动);读出也可切稳定模式(取后验均值而非单次采样),让情绪只跟刺激走、不被单样本噪声带得逐轮乱跳(见配置 ZERO_AFFECT_READOUT)。

工作空间点燃:并行流竞争 → 过阈广播 → 精度加权融合出 e*

3. 三时间尺度:情绪会退、态度会沉淀

人的情绪不是一锤子,而是多个时间尺度叠加

  • 瞬时 e* — 每个刺激当下采样出的情绪;
  • 快变 emotion — 短时情绪,被 e* 冲击后几轮内向基线衰退(怒火飙起后会回落;衰退太慢反而是病理性的情绪惯性)。对外表达取的是它;
  • 慢变 attitude — 对特定对象的长期态度,按情绪缓慢累积、多轮才成形,是快变情绪衰退回归的基线。持续被冒犯才会真的变冷,偶尔被呛一下会过去。只有态度被持久化,重启后情绪归于态度基线。
  • 稳态回弹 — 情绪与态度都带一份回到平静的拉力(向个体中性基线弱回归):再热烈或再低落,只要没有持续刺激就会慢慢回稳,不会"越聊越上头"或陷在某个极端里出不来(affective homeostasis;情绪基线本身也是态度与中性的混合,不随态度无限上漂)。
  • 唤醒双向 · 习惯化 · 分寸 — 唤醒(arousal)也是双极的:平淡对话会主动降到静息(不只是不涨)、重复互动会习惯化(新鲜感递减)、对刚认识的人有分寸感(不因聊久了就无端亲密)——从根上防「与内容无关地越聊越暧昧」(基于 seeking 吸引盆动力学;默认关、按需开旋钮,见配置全表)。

三时间尺度冲击-响应:单次冲击不记恨 / 反复刺激才沉淀(affect_math 真方程轨迹)

于是对话有了"脾气":被骂会不快、道歉能缓和、但一时的情绪不会永久定义这段关系,也不会因一路投入就单调滑向极端。

4. 双路语言:命题靠 LLM,情绪靠"漏"

借鉴语言的皮层/皮层下双通路:

  • Pull(皮层 · 随意) — LLM 负责命题内容,根据上下文与检索把"要说什么"组织成话;
  • Push(皮层下 · 不随意) — 情绪经用词倾向 / logit 偏置 / 隐状态 steering 自动漏进输出,而不是给模型一句"请表现得很生气"。

情感辅佐而非替换语言:它改变措辞的温度、节奏、边界感,让回应自然带情绪,而非戏剧化地演情绪。

5. 表达双通路:自发与随意 × 多通道

最终表现分自发(真情流露)与随意(社交掩饰)两条通路,落到多个表达通道——面部动作单元(FACS AU)、文本标签、生理信号、语音韵律。

6. 记忆 / 持久:短时注意力 ⊗ 长时记忆

多层记忆让数字人跨重启记得你,并在"当下注意得过来"与"长期记得住"之间架一座桥:

  • 对话运行态 — transcript 与对此人的长期态度落本地 SQLite,重启续上;态度还作为先验偏置当下的情绪评价(持续被冒犯,连初见的反应都会变冷)。
  • 短时注意力(工作记忆窗) — 喂给 LLM 的上下文不是简单截最近 N 轮,而是首因 + 近因的 U 形窗:既记得"第一次见面说的话"、也记得最近几轮(借鉴系列位置效应,避免单调截断丢掉开场)。
  • 情景记忆 + 三维召回 — 把对话经历按情绪显著性择要写成情景 episode(平淡的不记,借鉴海马"情绪/新颖性门控");召回时按 新近性 × 相关性 × 重要性 三维加权排序(幂律时序衰减 · 语义相似 · 写入显著度),高分的旧记忆升入注意力预算、与近期对话同台竞争(对应皮层记忆重激活),而非旁路堆砌——于是它记得你聊过什么、且只在相关时想起来。
  • 约定记得住、记不清就直说 — 含时间 / 地点 / 承诺的内容,即使当时情绪平淡,也经语义重要性通道单独入库(不被情绪显著性门挡掉),日后能答"我们约的几点";而真记不清时会坦诚说"不记得",不编造、也不拿脾气搪塞(事实优先于情绪)。
  • 遗忘是特性 — 长期事实带时序失效(新事实使旧失效)、情景库有容量上限,靠自然沉降而非物理删除来遗忘;确定性图谱 + 语义召回侧信道并存,语义侧信道失败绝不拖垮主对话。

记忆写什么/何时写/怎么召回/怎么排序,均以认知科学文献为依据定调,且全程确定性、不让 LLM 替数字人"编造"或"挑选"记忆。一键恢复出厂:python -m tools.reset_db --yes

记忆架构:注意力↔记忆桥(显著性写 · 三维召回 · 注入预算 · 时序遗忘)

7. 指定人格:不必从零认识一个人

性格该预置,关系才靠相处长——可以给数字人指定一份人格,免去每次从一张白纸开始:

  • 人设卡 — 名字 / 背景 / 口吻 / 与你的关系,作为身份注入对话("它是谁");
  • 气质底色 — 习惯性情绪基线、反应快慢与情绪恢复速度(偏暖还是偏冷、易激动还是沉稳),是性格的"生理底色",落到引擎的态度 / 情绪参数上;也可直接填大五人格(OCEAN 五维),自动映射成这份气质基线;
  • 预置关系 — 初见即已有的态度(一开始就熟络 / 在意某人)+ 预灌的共同记忆("我们一起去过海边"),跳过从零相处。

不指定时即中性无偏人格,默认即现有行为、不改变任何表现。"什么性格对应怎样的情绪基线"现已按 Mehrabian 大五→PAD 映射落地——在人格里填 OCEAN 五维即自动推导气质基线(或直接手调旋钮);更细的预设人格库 / 精确映射仍在持续打磨,引擎不替算法臆断。

人格注入:Persona 三层各接到哪(人设卡→语言 / 气质→引擎 / 预置关系→记忆)


项目运作流程:LLM ⊗ 情感引擎

把上面的情感引擎接进一次完整对话——LLM 只在「输入」「输出」两端与它结合(图中两个蓝框):输入端把你的话读成情绪,输出端被情绪调制着说话;夹在中间产生情绪的是那套确定性引擎(红框,无 LLM),LLM 既不进情绪计算热路径、也不替数字人"编造"记忆。

项目运作流程图

关键接口各自的作用(LLM ⊗ 情感接点已标注)

接口 / 节点 作用
ConversationModel.appraise_text(text) → (v,a) 评价桥 · LLM 输入接点:把你的话读成情绪坐标,作为刺激喂给引擎
ConversationModel.converse(history, affect, *, retrieved, push) 自然对话 · LLM 输出接点:按当前情绪 + 召回背景生成回应,情绪经用词倾向自然漏进措辞
LanguageModel.generate → LanguageDraft 图内 language 节点协议:研究模式的 affect↔language 双向收敛回路(python main.py --llm
ChannelDecoder(鸭子类型注入) 表达通道解码器:(v,a) → 韵律 / 生理 / 表情,可换成训练好的网络,编排层不依赖 torch
MemoryClientwrite_episode / recall · write / query 记忆读写 API:语义情景记忆(显著性写入 / 选择性召回)+ 确定性长期倾向(图谱·时序失效);上层不直连图谱、写入只在任务完成节点(节流)
图节点链 perception → appraisal → value → affect_core → mood → expression → supervisor(+ memory_recall 情感引擎各环:感知 → 评价先验(含长期态度/召回偏置) → 价值学习 → 显著度门控融合采样 e* → 慢心境 → 多通道表达 → 任务完成节流写记忆
入口 build_graph · runner.ConversationSession · main.py 装配并编译图 · 多轮会话基元(mood/价值/记忆跨轮持久)· CLI(python main.py 即进对话)

各接口均协议化、可注入(真 LLM / 占位模板 / steering 后端、真网络解码器、记忆后端都按协议替换),编排层不绑定具体 SDK——这是"先把对话做扎实、再逐步接多模态"而不动内核契约的底座。


预留给未来的通道

现阶段以文本输入、情绪化文本输出跑通整条回路,同时把若干扩展点的接口先留好,未来逐步接入而不动内核契约:

方向 现在 预留的未来通道
表达解码器 各通道用确定性占位函数 每个通道可换成可训练网络(韵律 RAVDESS / 生理 WESAD / 表情 AffectNet / 文本→VAD EmoBank),经鸭子类型协议注入,编排层不依赖 torch
输入感知 文本 → (v, a) 视觉图像 / 心电(ECG)/ 语气 / 面部表情 → 更丰富的多通道感知
输出形态 情绪化文本 + 通道值 Live2D 形象 / 情感 TTS 等多模态外化
记忆与经历 对话+态度落盘、情景择要落库 + 新近×相关×重要三维召回 + 首因/近因注意力窗 完整睡眠巩固/遗忘曲线、稳定人格/自我模型、跨会话人物画像
运行后端 默认本地(内存 / SQLite) env 一键切容器化 Postgres / Neo4j,接入真实图谱与运行态持久
社会认知与生理节律 情绪只建模自身、秒→分→天三时间尺度 已有实验性 v1(默认关):感知对方情绪并共情(ToM——对方难过则关怀 / 开心则替代喜悦)、应激后分钟-小时皮质醇余震(HPA 慢回路)、多层预测编码融合

项目结构

三层架构,依赖单向:编排 → 记忆 → 存储。

三层架构与依赖方向:只能自上而下调用,observability 横切

Zero/
├── main.py                  # CLI 入口:默认 python main.py 即进对话;--workspace / --llm / --trace
├── src/
│   ├── orchestration/       # 编排层:StateGraph 装配 + 运行入口
│   │   ├── graph.py         #   build_graph:节点装配 + 条件边路由
│   │   ├── state.py         #   AffectState / Stimulus(结构化 state,含 recalled_facts)
│   │   ├── supervisor.py    #   协调 + 任务完成节流写记忆 + first_contact 首因标记
│   │   ├── memory_recall.py #   长期倾向回灌先验 + 召回三维重排(新近×相关×重要,Hill 归一)
│   │   ├── chat_driver.py   #   交互对话核心:两时间尺度情绪 + U形注意力窗 + 高显著召回注入
│   │   └── runner.py        #   跑刺激序列 + 多轮对话会话(ConversationSession)
│   ├── agents/              # 各 Worker(节点契约 (state) -> dict 只回增量)
│   │   ├── affect_math.py   #   数学内核:OCC/TD/精度/高斯融合·工作空间·三时间尺度
│   │   ├── perception.py · appraisal.py · value.py
│   │   ├── affect_core.py   #   主动推断·后验采样 e*(并行流竞争 + ignition)
│   │   ├── mood.py          #   慢变心境双稳动力学
│   │   ├── regulation.py · expression.py   # 掩饰 + 双通路·多通道输出
│   │   ├── language.py · language_openai.py   # 语言生成+双向回路 / ConversationModel 协议 / 评价桥 / 自然对话
│   │   ├── persona.py       #   指定人格:人设卡(L1)+气质底色(L2)+预置关系(L3),默认中性、行为不变
│   │   ├── emotion_lexicon.py    #   细粒度情绪词 / 动机系统 / VAD 词典桥 / 时间包络
│   │   ├── language_steering.py  #   VA steering 适配器(开放权重)
│   │   ├── models/          #   可训练 torch 解码器(expression/prosody/physiology/facs/text + composite 复合)
│   │   └── datasets/        #   DataLoader:synthetic / ravdess / wesad / emobank(+st 句向量版) / facs
│   ├── memory/              # 记忆层:读写 API(显式 scope、任务完成节流、后端失败隔离 + Fact.sim)
│   ├── storage/             # 存储层(最底层):运行态 + 长期记忆,env 选后端
│   │   ├── checkpointer.py  #   memory / sqlite(异步 AsyncSqliteSaver) / postgres(待异步接线)
│   │   ├── graph_store.py   #   门面 + 工厂
│   │   ├── conversation_log.py  #   --chat 对话运行态:transcript + 跨重启 attitude 落本地 SQLite
│   │   └── backends/        #   deterministic(InMemory/Sqlite/Neo4j)+ semantic(Graphiti/SqliteVector)
│   └── observability/       # 横切:统一日志 setup_logging + 对话人读日志 setup_conversation_log(每启动落 logs/、级别可配)
├── tests/                   # 单测 + 行为/记忆回归
├── scripts/                 # 训练 train_*.py + demo(demo_modes 承接 main.py 三模式 / demo_pipeline 端到端 / demo_text_input 文本输入)+ 验证 verify_*.py
├── tools/                   # 运维/文档工具(reset_db.py 清库 · plot_timescales.py 生成动力学曲线图)
├── docs/                    # 对外架构图(框架 / 运作流程 / 记忆架构 / 人格注入,v1/v2 谱系,详见 docs/README.md)
├── notes/                   # 研究笔记 / 设计决策 / 工程实践(本地维护、不入库)
├── DATASETS.md              # 真网络化数据集获取指南(RAVDESS / WESAD / EmoBank / FACS)
├── .env.example                                     # 配置模板(cp 为 .env 启用)
├── personas/                                        # --chat 人格卡目录:*.example.json 模板随仓库共享 / 个人 *.json 走 gitignore;放多份 persona 改 ZERO_PERSONA_FILE 即切换
├── Dockerfile · docker-compose.yml                  # 容器化部署
└── pyproject.toml · environment.yml                 # 依赖与环境(core + ml/llm/nlp/steer/db 默认装;graphiti 按需)

快速开始

环境用 conda 管理(环境名 affective-expression,Python 3.12,依赖口径以 pyproject.toml 为准;也支持 uv sync)。

# 1. 建环境
conda env create -f environment.yml
conda activate affective-expression

# 2. 直接对话:情感引擎 ⊗ LLM(缺 LLM key 自动回退词典 + 模板,仍演示情绪演化)
python main.py

# 3. 看显著度门控工作空间:每个刺激点燃了哪些并行流
python main.py --workspace

# 4. 核心管线 (v,a) 轨迹 JSON
python main.py --trace

对话时每轮会打印一行 trace你这句≈(v,a)(你这句被读出的情绪坐标)|情绪=<词>(v,a)(数字人此刻的情绪)|对你的态度=(v,a)(它对你的长期态度)——一眼看清引擎在想什么。

真 LLM(OpenAI 兼容接口,本地 vLLM / 第三方网关皆可)需 llm extra 并在 .env 配置——配置只走 .env,代码不写死模型默认:

pip install -e ".[llm]"
# .env 内:
#   ZERO_OPENAI_API_KEY=sk-...                  # 必填
#   ZERO_OPENAI_MODEL=<你的 key 可访问的模型 id>  # 必填
#   ZERO_OPENAI_BASE_URL=https://.../v1          # 可选
python main.py            # 真模型对话
python main.py --llm      # 四情绪场景的文本输出情绪验证(批处理)

真网络化(把表达通道换成训练好的网络)需 ml extra,数据集获取见 DATASETS.md

pip install -e ".[ml]"
python -m scripts.train_prosody --root data/ravdess --epochs 300   # 权重存 artifacts/,再注入管线
python -m scripts.demo_pipeline                                    # 端到端:合成训练 → 注入 → 跑(无需外部数据)

不想自己训练?直接用现成权重:真实数据训练好的权重已随 Release 提供,拿来即用——从 weights-v0.1(稳定版 v0.1.0 附件是同一份)下载 5 个 .pt 放入仓库根目录 artifacts/(已 gitignore),各 load_* / scripts/*(如 demo_pipeline)自动加载;缺某通道回退内置默认 / 占位、不影响其它。

  • 五通道:text_affect_regressor.pt / text_affect_regressor_st.pt(文本→(v,a),词袋 / 句向量,EmoBank)· prosody_decoder.pt((v,a)→韵律,RAVDESS)· physiology_decoder.pt((v,a)→生理,WESAD)· expression_decoder.pt((v,a)→表情 FACS,demo)。

日志与排障:每次启动落一份 logs/zero-<时间戳>-<pid>.log;排障时 ZERO_LOG_LEVEL=DEBUG python main.py ... 可看每轮引擎 e*、记忆读写、LLM 请求/响应等详情,默认 INFO 保持安静、不打扰对话。对话另落一份人读日志 logs/conversation-<时间戳>-<pid>.log(每轮 user/Zero 原文 + 评价/情绪/态度 trace,默认开、ZERO_CONVERSATION_LOG=0 关且不落任何对话内容)。

开发/测试pytest(全套回归)· ruff check . && ruff format .(风格)· mypy src(类型)——保存时基础检查自动跑。


配置(.env

所有运行配置都走 .env(复制 .env.example 起步),代码不写死模型/后端默认。不设任何变量即全内存占位、零依赖可跑.env.example 里每个变量都有一行速记,下面按用途分组给出完整说明。

怎么读 .env(三类)

  • 【必填】 只有 ZERO_OPENAI_API_KEY + ZERO_OPENAI_MODEL(接真 LLM 用;缺了 --chat 自动回退词典+模板,仍能跑)。
  • 后端选择(顶部各组):.env.example 里的赋值多数就是内置默认,写不写效果一样,想切落盘/真库才改;少数是示例 / 推荐值——必填的 ZERO_OPENAI_MODEL、语义侧信道 ZERO_SEMANTIC_BACKEND=sqlite_vec--chat 的默认,其它入口内置默认为关)与 ZERO_GRAPHITI_MODEL / _EMBED_MODEL——以下面各表「默认」列为准。
  • 可选旋钮(底部,分两类):数字人对话 / 记忆组已直接给出推荐赋值——复制即数字人推荐配置,注释掉某行 = 回内置默认;研究级组(workspace 精度 / HPA / ToM / 层级融合等)保持注释 = 默认关 = 行为不变,取消注释才覆盖。最小推荐仍是两个:ZERO_PERSONA_FILE(治"上来就编造关系")+ ZERO_AFFECT_READOUT=map(治情绪标签逐轮翻号);ZERO_APPRAISE_CALIBRATE 视模型可选(强模型如 deepseek 本就把敌意读得够负、可不开)。

运行后端

运行态 Checkpointer 与 长期记忆图谱各自独立选后端,可任意组合;默认都在内存,落盘 / 真后端按需开。

--chat 例外:对话入口为让记忆开箱即跨会话生效,未显式设值时自动落盘——ZERO_CHECKPOINT_BACKEND=sqlite · ZERO_MEMORY_BACKEND=sqlite · ZERO_SEMANTIC_BACKEND=sqlite_vecmain.py 入口 setdefault,相应依赖缺失时优雅降级);在 .env 显式设值即可覆盖。

--chat 数据落点地图:一轮对话的数据各落哪个存储、归哪个变量管

变量 默认 说明
ZERO_CHECKPOINT_BACKEND memory 运行态后端:memory / sqlite / postgres(postgres 暂未接线、预留)
ZERO_CHECKPOINT_DB data/checkpoints.sqlite3 sqlite 后端的库文件路径
ZERO_PG_DSN postgres 后端 DSN(随 postgres 后端预留,暂未接线)
ZERO_MEMORY_BACKEND memory 长期记忆图谱(确定性 (scope,key) 失效):memory / sqlite(落盘)/ neo4j(需 db extra)
ZERO_GRAPH_DB data/graph.sqlite3 sqlite 图谱的库文件路径
ZERO_NEO4J_URI · _USER · _PASSWORD bolt://localhost:7687 · neo4j · password neo4j 连接(ZERO_MEMORY_BACKEND=neo4j 或 Graphiti 用 neo4j 图库时生效)

LLM 接入(OpenAI 兼容)

语言层(评价桥 + 自然对话)与语义记忆 embedding 共用一处 OpenAI 兼容接口,最小配置见上方「快速开始」。

变量 默认 说明
ZERO_OPENAI_API_KEY 必填
ZERO_OPENAI_MODEL —(无代码默认) 必填,须是 key 有权限的真实模型 id(limited 等权限标签不是模型名、会 400;可用 /v1/models 列出,如 qwen-flash / deepseek-v4-flash / gpt-5.5
ZERO_OPENAI_BASE_URL https://api.openai.com/v1 可指向 OpenAI / 本地 vLLM / Ollama / 第三方网关,留空用 SDK 默认

语义记忆侧信道(默认关)

确定性图谱之外,可叠一条语义召回侧信道(向量相似召回);默认关(--chat 对话入口例外、默认开 sqlite_vec,见上),侧信道失败绝不拖垮主对话

变量 默认 说明
ZERO_SEMANTIC_BACKEND 关(--chat 默认 sqlite_vec sqlite_vec(轻量、推荐)/ graphiti(深度集成,需 graphiti extra)
ZERO_GRAPHITI_DB neo4j Graphiti 图库,复用上面 NEO4J_*
ZERO_GRAPHITI_MODEL —(未设走 Graphiti 库默认) Graphiti 抽取实体 / 关系入图谱用的对话/推理 LLM(.env.example 给的是示例值)
ZERO_GRAPHITI_EMBED_MODEL text-embedding-3-small 向量嵌入模型(sqlite_vec / graphiti 都用它做相似召回,须是 key 有权限的 embedding 模型;.env.example 给的是示例值)

自查脚本python -m scripts.verify_graphiti_local——graphiti 后端闭环 smoke(写 episode → 语义召回 → recalled_context 非空即通),需 graphiti extra + LLM key + 图库服务(ZERO_GRAPHITI_DB 默认 neo4j)。

文本情感回归(输入侧,默认走词典 / LLM 评价桥):置 ZERO_TEXT_AFFECT_BACKEND=st 改用训练好的回归头,须同时给 ZERO_TEXT_AFFECT_MODEL_PATH(如 artifacts/text_affect_regressor_st.pt)。

指定人格(--chat

给数字人指定一份人格(能力详见上文「指定人格」一节):ZERO_PERSONA_FILE 指向一个人格 JSON(默认不设 = 中性无偏人格、即现有行为)。仓库自带一份「诚实陌生人」模板 personas/persona.example.json(与真正的 personas/persona.json 同处一目录),cp personas/persona.example.json personas/persona.json 改改即用(想要多重人格就在 personas/ 放多份、切换时改 ZERO_PERSONA_FILE 指向即可)。字段全可选(L1 人设卡 + L2 气质底色 + L3 预置关系)——只想要人设卡就只写 card 一个字段,不必写全、也不用往 .env 塞长文本:

{
  "name": "小津",
  "card": "你叫小津,是用户多年的老友……",   // L1 人设卡
  "setpoint": [0.1, -0.05],                  // L2 气质基线 (v,a):略偏暖、偏平静
  "reactivity": 0.6,                         // L2 对刺激的即时反应增益(↑≈神经质)
  "recovery": 0.4,                           // L2 情绪恢复残留比例(↑=情绪退得慢)
  "initial_attitude": [0.3, 0.1],            // L3 首次接触的初始态度(已经喜欢这个人)
  "seed_memories": ["我们去年夏天一起去过青岛看海", "你不吃香菜"]  // L3 预灌的共同记忆
}

L2 的「大五人格 → PAD 具体数值映射 / 预设人格库」属科学决策、须有文献依据支撑;本接口只提供旋钮 + 中性默认,不替算法拍板具体性格参数。

对话调优与排障(对症开旋钮)

对话不对劲时,多数能靠一两个旋钮解决——先按症状开,细节见下方全表:

症状 开什么
一上来就编造共同往事 / 假装认识你 ZERO_PERSONA_FILE(给它身份 +「初次见面不编造」,见上文「指定人格」)
情绪标签逐轮乱跳、与内容不符(敌意却标「兴奋」) ZERO_AFFECT_READOUT=map(取后验均值、消采样翻号)
敌意/负面被读得太轻 ZERO_APPRAISE_CALIBRATE=1视模型:强模型如 deepseek 本就够负、可不开)
越聊越「上头」、情绪停在高位 调低 ZERO_EMOTION_BASELINE_ATTITUDE_W(加大回中性的拉力)
越聊越「暧昧」/ 关系无端升温、与对话内容脱钩 ZERO_INTENSITY_FLOOR=0 + ZERO_AROUSAL_BASELINE=-0.08 + ZERO_ATTITUDE_REVERSION_A=0.4(去 arousal 直流偏置,见下「越聊越暧昧」全表)

两个自查脚本(无需改代码):python -m scripts.verify_affect_readout无需 LLM,实证 map 把翻号率从 ~20% 压到 0);python -m scripts.verify_appraise_calibration需 LLM key,按你的模型实测标定要不要开)。

微调旋钮·全表

默认开箱即用(仅 HISTORY_* / EMOTION_BASELINE_ATTITUDE_W 的默认改变 --chat,其余默认行为不变 / 关);设计依据见研究笔记(notes/,本地维护、不随仓库分发)。

① 数字人情绪 / 对话

变量 默认 作用
ZERO_AFFECT_READOUT sample 情绪读出:map 取后验均值(稳定,消逐轮翻号)/ sample 逐轮采样(默认,带随机波动)
ZERO_APPRAISE_CALIBRATE 分级标定锚抵消 LLM 把负面读太轻的正向偏置(敌意→更负);1 开启。视模型——强模型(deepseek 类)本就够负、可不开
ZERO_EMOTION_NOISE_STD 0.05 每轮情绪的随机噪声幅度(调小=更稳、0=关该噪声源)
ZERO_SAMPLE_SIGMA_MAX 0.5 后验采样的逐维抖动上限(仅 sample 读出下生效)
ZERO_CHAT_RNG_SEED 固定随机种子,贯穿引擎采样 + 情绪噪声,便于 eval 复现(留空=每次随机)
ZERO_EMOTION_BASELINE_ATTITUDE_W 0.6 情绪回落基线里「对此人态度」占比;<1 给回中性的拉力、防越聊越上头(1=不加回中性拉力)

② 治「越聊越暧昧 / 关系无端升温」(基于 seeking 吸引盆动力学;默认全部保持现有行为,.env.example 已按荐值直接赋值,⭐=数字人推荐开)

变量 默认 作用
ZERO_INTENSITY_FLOOR 0.2 ⭐arousal 强度下限;设 0 去掉中性输入的正 arousal 直流底噪(暧昧滑移的根之一)
ZERO_AROUSAL_BASELINE 0 ⭐arousal 基准平移;负值(荐 -0.08)让平淡对话给零/负唤醒(副交感 vagal brake / deactivation)
ZERO_ATTITUDE_REVERSION_A 同 valence(0.01) ⭐态度 arousal 维独立回归率(荐 0.3–0.5);令长期态度只累积效价、不累积唤醒偏置
ZERO_ATTITUDE_SETPOINT_A persona.setpoint[1] 态度 arousal 回归锚;未设=取气质底色的 a、0=中性
ZERO_HABITUATION_TAU 习惯化 τ(轮,荐 5–10):重复互动 arousal 响应按 exp(-n/τ) 递减(SCR 习惯化);空/0=关
ZERO_AROUSAL_GAIN_CAP 不 cap workspace arousal_gain 上限(荐 0.3–0.6);防高唤醒正反馈失稳;空=不设上限
ZERO_ATTITUDE_RATE_DECAY_K 0 越熟态度形成越慢;0=关,仅减缓漂移、非真多稳态
ZERO_FAMILIARITY_TAU 20 熟悉度累积 τ(轮),配合 RATE_DECAY_K;仅 K>0 时生效
ZERO_RELATIONSHIP_STAGE_HINT 给 LLM 关系距离软提示(曝光三档;确定性派生、不经 LLM 判跃迁);空/0=关

③ 记忆 / 注意力窗 + 召回排序(默认已按认知科学调好,一般不用动)

变量 默认 作用
ZERO_HISTORY_WINDOW 40 喂 LLM 的工作记忆窗总条数(越大记越久、越费 token)
ZERO_HISTORY_PRIMACY_K 5 窗内保留的「最初几条」(首因),其余留给最近几轮(近因)
ZERO_RECALL_SIM_MIN 0.65 召回余弦相似度下限(越高越只在强相关时才想起旧事)
ZERO_RECALL_INJECT_MIN 0.5 旧记忆升入注意力预算、与近期对话同台竞争的重要性门 ∈[0,1]
ZERO_RECALL_DECAY_D 0.5 三维重排:recency 幂律衰减指数 d
ZERO_RECALL_ALPHA · _BETA · _GAMMA 0.33 · 0.34 · 0.33 三维重排权重:recency · sim · importance
ZERO_RECALL_IMPORTANCE_SCALE 30 importance 归一 Hill 常数 C:p/(p+C)
ZERO_RECALL_AROUSAL_MOD 0 唤醒调制召回 importance(1 开启)
ZERO_EPISODE_MAX_PER_KEY 0(--chat 默认 300) 单人情景记忆条数上限,满了删最旧(0=不限)
ZERO_EPISODE_SALIENCE_MIN 0.15 情景写入的显著度门 salience=precision×|rpe|(含时间/约定内容旁路强写)
ZERO_EPISODE_SALIENCE_AFFECTIVE_ADD 0 低唤醒高语义补偿 salience+=0.3·|value|1 开启)
ZERO_EPISODE_DEDUP_MAX 0.92 情景写入去重余弦阈(高于此视为近义跳过)

④ 实验性 v1:社会认知 / 生理节律 / 层级融合(三项研究级方向,默认全关、行为不变;确定性热路径纯标量无 LLM/torch)

变量 默认 作用
ZERO_HPC_LAYERS · _COUPLING 1·0 层级预测编码:把单层融合升级为 2 层(感觉层→核心情感层)预测编码;1/0=平层、行为不变,coupling∈[0.3,0.8] 启用(>1/<0 报错)
ZERO_CORTISOL_ENABLED
(+8 子旋钮 _TAU/_IMPULSE
/_*_GATE/_*_ALPHA/_THETA_*
HPA 皮质醇慢回路:应激(目标受阻+高强度)后分钟-小时级余震——抬 arousal 基线 / 放大态度形成;触发解耦防 runaway;运行态跨会话持久(durable 后端)、绝不入记忆图谱
ZERO_CONTAGION_ALPHA
ZERO_CARE_BIAS_ALPHA
ZERO_VICARIOUS_ALPHA
(+ _VICARIOUS_THRESHOLD
0·0·0 ToM 社会情绪:感知对方情绪(图外确定性估计、不入热路径)并共情——情绪传染 / 对方难过则关怀(CARE)/ 对方开心则替代喜悦;上界 contagion≤0.3、三系数和≤0.6

⑤ 内核精度 / 评价机制·进阶旋钮(workspace 精度重构、评价补充;默认全关、行为不变,多为研究级、日常不必动;.env.example 有一行速记)

变量 默认 作用
ZERO_PRECISION_SPLIT value 流精度改用 precision_da(|δ|),消 β·V 与精度的混同;1 开启
ZERO_FUSE_INDEPENDENCE_CORRECT value 流 valence 维精度置极小,防共线导致过度自信;1 开启
ZERO_IGNITION_SURVIVAL_FALLBACK 全弱刺激时由 survival 流兜底广播;1 开启
ZERO_IGNITION_BETA ignite 软门控陡度 β(荐 20–50);空/注释=硬 step、行为不变,β 连续近似 GNW all-or-none
ZERO_VA_COUPLING_POS · _NEG 0.6 · 0.6 正 / 负效价侧 V-A 耦合系数(荐 pos 0.4–0.6、neg 0.6–0.8 体现 negativity bias,Kuppens 2013);也可在 persona JSON 配、persona 优先
ZERO_ATTITUDE_AROUSAL_WEIGHT 0 高唤醒 stimulus 放大态度累积率(McGaugh 2004);0=关
ZERO_HABITUATION_SENSITIZATION_GAIN
ZERO_SENSITIZATION_THRESHOLD
0·0.5 习惯化+敏化双过程:强刺激(|arousal|>阈)叠加敏化增益;gain 0=纯习惯化
ZERO_STANDARD_COMPLIANCE 关(恒 0) 确定性词典桥从用户话读社会规范违反/遵从 ∈[-1,1],通电 OCC 分支 B(pride/shame/reproach 等);词表初版、语义待细化;1 开启
ZERO_PANKSEPP_DISTINGUISH_FEAR (-v,+a) 象限按 arousal 阈值分 fear/rage;⚠ 缺乏神经生理依据(纯 arousal 阈值不足以区分 RAGE/FEAR),建议保持关闭
ZERO_MOOD_PRECISION 内置常量 mood 流精度加权(介于主评价流与 SURVIVAL_PRECISION=0.4 之间);调小=降低心境流投票权
ZERO_TEXT_AFFECT_PRECISION 内置常量 文本语义流精度(固定低值,Friston 2009 初始固定精度);调小=进一步压制文本流权重

⑥ 日志

变量 默认 作用
ZERO_LOG_DIR logs 日志目录(应用日志与人读对话日志共用)
ZERO_LOG_LEVEL INFO 文件与项目 logger 级别;排障设 DEBUG 看每轮 e*、记忆读写、LLM 请求详情
ZERO_CONVERSATION_LOG 每轮对话落人读日志 logs/conversation-<时间戳>-<pid>.log(user/Zero 原文 + 引擎 trace);设 0 关且不落任何对话内容

其它进阶变量.env.example 未列):ZERO_CHAT_THREAD 切对话线程 id,隔离不同会话的历史/态度/记忆 scope、防串味;ZERO_PUSH_LOGIT_BIAS 让 push 通路叠加 OpenAI logit_bias(需兼容 tokenizer,缺则优雅退回纯 prompt 用词倾向)。 想还原更早的行为逐项设回旧值即可(如窗口设回 20ZERO_EMOTION_BASELINE_ATTITUDE_W=1)。


文档

  • docs/ — 对外框架图 + 运作流程图(whiteboard-cli 渲染)
  • DATASETS.md — 真网络化所需数据集清单(获取方式 / 许可)
  • notes/ — 研究笔记:情感数学、文本输出情绪、并行脑路与工作空间、数字人路线图(本地维护、不随仓库分发)

About

情感引擎 × LLM 的数字人 — 贝叶斯主动推断确定性地生成情绪,LLM 只在输入/输出两端结合;三时间尺度+稳态、短时注意力与长时记忆的桥、可指定人格

Topics

Resources

Stars

4 stars

Watchers

0 watching

Forks

Packages

 
 
 

Contributors