Skip to content

FirstBeat Ultimate

本地优先 · 残差注入 · 三条正交线 · 零后台线程

Python 3.12+ qwen2.5 7B llama.cpp AuraSDK Rust 3584-dim embedding 30 modules Rich CLI AGPL 3.0

这是什么 · 一句人话 · 架构全景 · 三条线 · 数据流 · 项目结构 · CLI 前端 · 生产者管线 · M@q v3 · Titans · Consolidation · 配置 · 安装 · 使用 · 消融 · 铁律 · 诊断 · 旧系统 · 路线图


🧠 这是什么

FirstBeat Ultimate 是一个本地优先的记忆场模式 AI 引擎。它不只是一个聊天机器人——它是一个有持久记忆情绪感知时间意识自我认知的 AI 对话系统。

与传统的 RAG(检索增强生成)不同,FirstBeat 的记忆不仅以文本形式注入 prompt(像所有 RAG 一样),更以残差向量的形式物理注入模型隐藏层——模型无法选择忽视它们。

传统 RAG:    prompt = "请回答" + "[相关文档: ...]"     → 模型可以跳过
FirstBeat:   h_layer_5 = h + α·R₀                    → 模型无法跳过
             h_layer_8 = h + α·R₁                    → 残差 h+=r
             h_layer_11 = h + α·R₂                   → 物理写入

🎯 核心创新

特性 传统 RAG RAG + 微调 FirstBeat
事实召回 ✅ prompt ✅ prompt ✅ prompt + 残差
记忆连续性 ❌ 无记忆 ❌ 静态快照 ✅ 实时更新
情绪感知 ✅ 22维调制
时间意识 ✅ 4粒度
注入方式 文本 (可跳过) 参数 (不可逆) 残差 (不可跳过, 可逆)
后台线程 通常有 N/A 0
外部依赖 Qdrant/Weaviate GPU 纯本地

💬 一句人话

让你的本地 AI 不只是"回答问题",而是"记得你、理解你、陪伴你"。

当你对 FirstBeat 说 "Rust 的 borrow checker 太难了,我想换 Python" 时,它不只是生成一段通用安慰——它会:

  1. 从记忆中召回你之前提到的 "项目交付压力" 和 "技术栈争论"
  2. 感知到你从焦虑转向沮丧的情绪变化
  3. 在模型深层注入 "现在是下午,你在工作,这个话题你已经纠结了 3 周" 的语境
  4. 调整自己的语气——更共情、更支持——因为这是 "倾诉" 而非 "提问"
  5. 生成回复后,把所有新信息写入记忆,供下次对话使用

🏗️ 架构全景

FirstBeat 由三条正交线组成——它们各自独立工作,可以任意组合开关,形成 2³ = 8 种运行模式。

                           用户输入: "Rust太难了,想换Python"
                                       │
                    ┌──────────────────┼──────────────────┐
                    ▼                  ▼                  ▼
              ┌──────────┐     ┌──────────────┐    ┌──────────┐
              │ 认知分析  │     │ qwen_embed   │    │ 实体抽取  │
              │ cognitive│     │   → q_vec    │    │ entity   │
              └──────────┘     └──────┬───────┘    └──────────┘
                    │                 │                  │
        意图: emotional_sharing   3584维向量        ["Rust","Python"]
        情绪: 沮丧 val=-0.6
                    │                 │                  │
        ┌───────────┴────────┬────────┴────────┬─────────┴──────────┐
        ▼                    ▼                 ▼                    ▼
  ┌───────────┐     ┌──────────────┐   ┌──────────────┐   ┌──────────────┐
  │  线 1     │     │    线 2      │   │    线 3      │   │ Consolidation│
  │ AuraSDK  │     │  M@q 记忆场   │   │ 6路场 logit  │   │  惰性维护    │
  │ 事实召回  │     │  残差 L5-12   │   │  逐token调制  │   │  轮次触发    │
  │ → prompt │     │  h += α·M@h  │   │  logits→采样  │   │              │
  └─────┬─────┘     └──────┬───────┘   └──────┬───────┘   └──────┬───────┘
        │                 │                  │                   │
        │  "上次你说       │  M_fact(L5-7)/   │  emotion(E)/     │  4h: shallow
        │   项目交付..."   │  M_session(L8-10)│  self_mirror(S)/ │  24h: deep
        │                 │  M_abstract(L11-12)│relationship(R)/  │  10min: impulse
        ▼                 ▼                  ▼  relationship/...  │
  ┌──────────────────────────────────────────────────────────────┴──┐
  │                     llama.cpp + qwen2.5 7B                       │
  │                                                                  │
  │   prompt  = [系统] + [AuraSDK 事实 1..N] + [画像/叙事/标签]     │
  │            + [关系状态] + [行为预测] + [自我镜像] + [用户消息]   │
  │                                                                  │
  │   ★ C++ 侧: h += α·M@h  (L5-L12, 每层残差注入)                  │
  │   ★ Python 侧: 每 token logits → 6路场调制 → 引擎采样            │
  │                                                                  │
  │   → 生成回复                                                      │
  └──────────────────────────────────────────────────────────────────┘
                                       │
                                       ▼
                              记忆写入 (store)
                          AuraSDK + M@q 三场更新

三条线一览

线 名称 机制 注入位置 延迟 开关
1 AuraSDK 事实召回 SDR + MinHash 检索 → prompt System prompt <1ms --no-aura
2 M@q 记忆场 三场 Gram 矩阵 → C++ hook h += α·M@h L5-12 隐藏层 <0.5ms/token --no-mfield
3 6路场 Python logit 调制 投影矩阵 → 逐 token 偏置 + 引擎采样 采样前 logits ~5ms --no-producers
Consolidation 惰性维护 轮次触发条件执行 后台 (无线程) <50ms 自动

🔬 三条线详解

线 1: AuraSDK 事实召回

用户: "上次说的那个 Rust 项目怎么样了?"
       │
       ▼
  AuraSDK.recall_structured("Rust 项目", top_k=10)
       │
       ├─ SDR (Sparse Distributed Representation)
       │   256k bits, 512 active → 语义哈希
       │
       ├─ MinHash trigram → 文本相似候选
       │
       ├─ 倒排索引交集 → 最终结果
       │
       ▼
  [
    {content: "我在用 Rust 写一个数据库引擎,感觉 borrow checker 太难了", score: 0.89},
    {content: "Rust 确实难,但是写出来的代码很有信心", score: 0.76},
    ...
  ]
       │
       ▼
  拼入 prompt system 消息:
  [相关记忆]
  1. 我在用 Rust 写一个数据库引擎...
  2. Rust 确实难,但是写出来的代码很有信心...

关键特性:

  • SDR 稀疏哈希 — 256,000 bits 中仅 512 active,高维抗噪
  • MinHash n-gram — trigram 级文本相似,抗拼写错误
  • 倒排索引 — O(log N) 检索,内存仅 ~3MB
  • 纠错反馈 — 用户纠正后自动调整权重
  • 纯 Rust 实现.pyd 编译,<1ms 延迟
# 底层 API
from aurasdk import Aura, Level
aura = Aura("./data/aura")
aura.store("我在用 Rust 写数据库", level=Level.Domain, tags=["编程", "Rust"])
results = aura.recall_structured("Rust 项目", top_k=10)
# → [{content, score, tags, metadata, ...}, ...]

线 2: M@q 记忆场 v3

M@q 是这个项目最核心的创新——三场异构结构(M_fact K-聚类 Gram + M_session EMA 池 + M_abstract 对比簇),通过 C++ hook h += α·M@h 物理注入 L5-L12 隐藏层。

完整架构见下方 M@q v3 三场拆解 章节。

查询流程 (产出 7 个残差向量)

M@q.query(q_vec, context={
    recalled_ids: [...],      # 本轮 AuraSDK 召回的 IDs
    matched_entities: [...],  # 用户消息中抽取的实体
    time_slot: "afternoon"    # 当前时段
})
    │
    ├─ 1. fact_user    ← Σ (time_slot_weight × M_fact_slot_user) @ q
    │                    用户历史记忆场响应 — "用户关心什么"
    │
    ├─ 2. fact_ai      ← Σ (time_slot_weight × M_fact_slot_ai) @ q
    │                    AI 历史回复场响应 — "AI 说过什么"
    │
    ├─ 3. fact_diff    ← fact_user - fact_ai
    │                    用户 vs AI 记忆盲区信号 — "用户说了但 AI 没记住的"
    │
    ├─ 4. session_user ← M_session_user @ q
    │                    最近 20 轮对话关联场 — "当前在聊什么"
    │
    ├─ 5. session_ai   ← M_session_ai @ q
    │                    AI 最近 20 轮回复关联场 — "AI 当前的语气基调"
    │
    ├─ 6. explicit     ← C @ q
    │                    共现扩展 — "通常一起被想起的记忆"
    │
    └─ 7. abstract     ← M_abstract @ q
                         抽象场 — "低频但重要的概括性记忆"

7 路向量注入策略:

向量 注入层 Alpha 作用
fact_user L5-7 0.06 用户记忆背景
fact_ai L5-7 0.04 AI 记忆背景
fact_diff L5-7 0.04 盲区信号
session_user L8-10 0.025 当前话题场
session_ai L8-10 0.015 AI 语气场
explicit L8-10 0.025 共现联想
abstract L11-12 0.0225 抽象概括

查询后:场偏置召回重排

# 不只是查询 M,还把抽象场用于重排 AuraSDK 召回结果
ref = q_vec + γ · R_abstract    # γ = 0.3, 场偏置强度
# 用 ref 而不是 q 做语义重排
# → 记忆场认为相关的记忆权重提升
reranked = cosine_similarity(ref, recall_results)

记忆写入:Titans 惊喜门控

见下文 Titans 惊喜门控 章节。

线 3: 6路场 Python logit 调制 (★ 逐 token 引擎掌舵)

架构反转: 引擎是驾驶员,llama.cpp 是发动机。

C++ 侧 M@q 做完逐层残差后输出 logits → Python 侧每 token 拦截 logits → 6 路场各自 modulate() → 引擎采样 (temperature + top_p + top_k) → 选出 next token。

           llama.cpp logits [152064]
                    │
     ┌──────────────┼──────────────┬──────────────┬────────────────┐
     ▼              ▼              ▼              ▼                ▼
 emotion(E)     self_mirror(S)  relationship(R)  predictor(P)   drift(d)
 E@embed→       S@embed→        R@embed→        P@embed→       d·embed→
 (v,a)→情绪     rank-64投影     Δstate预测       intent分布     投入度→
 方向偏置        经验方向偏置    信任/亲密词      意图一致词      temp/top_p
                    │                                       动态调节
              ┌─────┘
              ▼
          tags(T)
           T@embed→
           关联词偏置
结构 参数量 学习信号 调制方式
emotion E ∈ ℝ^{2×3584} 7.2K 词表 teacher (v,a) → SGD E@embed→(v,a)→情绪方向偏置
self_mirror S ∈ ℝ^{3584²} rank-64 459K 对话连续性 经验方向→一致性偏置
relationship R ∈ ℝ^{4×3584} 14K 自我暴露深度 trust→开放词, closeness→温暖词
predictor P ∈ ℝ^{5×3584} 18K intent one-hot intent→意图一致词
drift d ∈ ℝ^{3584} 3.6K disengage 信号 动态 temp/top_p
tags T ∈ ℝ^{12×3584} 43K 关键词 multi-hot tag_logits→关联词偏置

6 路场均通过投影矩阵将 embed(text) 映射到调制空间,全矩阵直驱,零 tokenizer 依赖,在线学习闭环:每轮交互后自动从本轮对话中更新矩阵。

详见 core/field_modulators.py

详见 惰性 Consolidation 章节。


📐 完整数据流

从用户输入到回复输出,共 11 个步骤。每步标注了内存/CPU 开销。

┌─ 用户: "Rust太难了,想换Python" ─────────────────────────────────────────────┐
│                                                                                │
│  Step 1 ─── 认知分析 [~50μs]                                                   │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  classify_intent() → "emotional_sharing"                                 │  │
│  │  analyze_emotion()  → ("沮丧", valence=-0.6, arousal=0.1, intensity=0.6) │  │
│  │  → CognitiveContext (供后续所有模块消费)                                   │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 2 ─── 实体抽取 [~500μs]                                                  │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  ★ Phase 4: BPE 涌现式实体 — qwen tokenizer subword 边界检测            │  │
│  │  → ["Rust", "Python"]                                                     │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 3 ─── 标签抽取 [~1ms]                                                    │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  关键词匹配 + embedding 最近邻                                            │  │
│  │  → ["编程", "情绪", "Rust", "Python"]                                    │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 4 ─── 时间特征 [<10μs]                                                   │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  → {hour: 14, month: 6, day_of_week: 1, season: "summer",               │  │
│  │     time_period: "afternoon"}                                            │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 5 ─── 嵌入编码 [~3ms]                                                     │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  qwen_embed("Rust太难了,想换Python") → q_vec [3584] f32                  │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 6 ─── 线1: AuraSDK 事实召回 [<1ms]                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  aura.recall_structured(q, top_k=20)                                     │  │
│  │  → 20 条候选,纠错反馈权重修正                                            │  │
│  │  记录共现: C.record_co_retrieval(recalled_ids)                           │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 7 ─── 线2: M@q 7路查询 [~4ms]                                            │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  mfield_output = memory_field.query(q_vec, context)                      │  │
│  │  → {fact_user, fact_ai, fact_diff, session_user, session_ai,            │  │
│  │     explicit, abstract}  全部是 [3584] f32 向量                          │  │
│  │  Persona 对称性盲区检测 → 修正 fact_diff                                 │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  ★ 在这里做语义重排 + prompt 拼装 ──────────────────────────────────────────   │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  场偏置重排: ref = q + γ·R_abstract → 对候选做 cosine 重排              │  │
│  │  动态选择: 根据 intent 选择注入数量 (casual→5条, emotional→8条)         │  │
│  │  prompt 通道拼装:                                                        │  │
│  │    [关系状态: 信任度0.72, 亲密度0.65, ...]                               │  │
│  │    [当前偏移: spend倾向+0.3, 话题稳定性0.8]                              │  │
│  │    [预测下一步: 倾诉→回忆→闲聊]                                           │  │
│  │    [AI自我镜像: 正在共情回应用户的情绪表达]                               │  │
│  │    [相关记忆] 1. 我之前写的Rust数据库项目...                              │  │
│  │               2. borrow checker确实很难适应...                            │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 8 ─── 状态更新 + 场上下文准备                                           │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  工作记忆更新: working_vec = 0.7×old + 0.3×q_vec                         │  │
│  │  话题转移检测: cos_sim(q, working) < 0.3 → shift                        │  │
│  │  情绪翻转检测: prev_valence > 0.2 → curr_valence < -0.2 → flip          │  │
│  │  时间节律查询: temporal_index.query(hour=14, season=summer, ...)         │  │
│  │  叙事弧检测: entity-overlap 聚类 → ["编程语言选择", "技术焦虑"]           │  │
│  │  → FieldState 容器 (供 6 路场 modulate() 消费)                          │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 9 ─── LLM 推理 ★ 逐 token 引擎掌舵 decode loop [~60s]                    │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  ChatML prompt 构建:                                                     │  │
│  │    <|im_start|>system + [prompt通道内容] + <|im_end|>                    │  │
│  │    <|im_start|>user + "Rust太难了..." + <|im_end|>                       │  │
│  │    <|im_start|>assistant                                                 │  │
│  │                                                                          │  │
│  │  prompt → llama_decode → logits                                          │  │
│  │    │                                                                     │  │
│  │    ├─ ★ C++ 侧: h += α·M@h  (L5-L12, .mfield mmap 零拷贝)              │  │
│  │    │                                                                     │  │
│  │    └─ ★ Python 侧: 每 token 拦截 logits                                  │  │
│  │         → 6 路场 modulate() → 引擎采样 (t+top_p+top_k) → next_token     │  │
│  │         → 停词检测: EOS / <|im_end|> / 文本级                           │  │
│  │                                                                          │  │
│  │  → "我完全理解你的感受。上次你提到在做数据库项目时被 borrow checker      │  │
│  │     折磨,那种反复编译报错又找不到原因的挫败感确实很消耗热情..."         │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 10 ── 轮次状态更新                                                       │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  prev_emotion = (-0.6, 0.1)                                             │  │
│  │  turn_history.append({text, valence, arousal, intent, tags})            │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  Step 11 ── Consolidation tick [条件触发]                                     │
│  ┌─────────────────────────────────────────────────────────────────────────┐  │
│  │  检查触发条件:                                                           │  │
│  │    4h → shallow: 画像轻更新 + 共现修剪 + 生命周期衰减                     │  │
│  │    24h → deep: 画像深更新(LLM) + 情绪锚点重算 + 话题树重建 + 矛盾检测    │  │
│  │    10min → impulse: 冲动源疲劳值更新                                     │  │
│  └─────────────────────────────────────────────────────────────────────────┘  │
│                                                                                │
│  memory.store(user_msg, tags, ai_reply, metadata)                              │
│  ├─ AuraSDK 写入 (user + AI 独立记录)                                         │
│  ├─ M@q 矩阵增量更新 (仅 user, AI 不进 M)                                     │
│  ├─ 时间模式索引更新                                                           │
│  ├─ 元数据持久化到 JSONL                                                       │
│  └─ 行为预测器 learn_from()                                                    │
│                                                                                │
└────────────────────────────────────────────────────────────────────────────────┘

📁 项目结构

d:\FirstBeat Ultimate\
│
├── README.md                    # ← 你正在读的文件,究极无敌飞天爆炸螺旋起飞详细
├── CLAUDE.md                    # AI Agent 启动时自动加载的唯一权威文档
├── config.py                    # 所有配置项,环境变量优先 (252行)
├── engine.py                    # ★ 主循环:11步数据流 + 交互/消融/单次模式 (~1500行)
├── cli.py                       # ★ Phase 7: Rich+prompt_toolkit 测试前端 (825行)
├── requirements.txt             # numpy + llama-cpp-python + rich + prompt-toolkit
│
├── core/                        # 核心模块 (8个文件, ★ Phase 5: trajectory.py 已拆除)
│   ├── embed.py                 #   qwen_embed 纯 Python 嵌入模型 (152K×3584)
│   │                            #   BPE tokenizer + mean pooling + mmap 零拷贝
│   ├── memory_field.py          #   ★ M@q v3 — 三场拆解: M_fact(K-聚类Gram) +
│   │                            #   M_session(EMA池) + M_abstract(对比簇) + .mfield C++导出 (~2150行)
│   ├── field_modulators.py      #   ★ Phase 5.1: 6路场 logit 调制器 (全矩阵直驱, ~950行)
│   ├── cognitive.py             #   ★ Phase 5: 纯路由层 — 意图委托 P, 情绪委托 E 矩阵
│   ├── narrative.py             #   叙事弧检测: entity-overlap 聚类 + 情绪轨迹标签
│   ├── temporal_index.py        #   4粒度时间模式索引: 月/星期/季节/时段
│   ├── consolidation.py         #   ★ 惰性 consolidation: shallow/deep/impulse 三级触发
│   └── injector.py              #   ★ 逐 token decode loop + 引擎采样 + C++ mfield 加载
│                                  #   (Phase 7: llama_model_n_layer 兼容旧版 llama-cpp-python)
│
├── producers/                   # 数据生产者 (13个文件)
│   ├── emotion.py               #   Russell 2D 情绪分析 (150+ 词汇 + E ∈ ℝ^{2×3584} 投影矩阵)
│   ├── entity.py                #   ★ Phase 4: BPE 涌现式实体 (qwen tokenizer subword)
│   ├── tags.py                  #   标签系统 (关键词 + embedding 最近邻)
│   ├── drift.py                 #   偏移率追踪 (spend/frugal/drift 三维)
│   ├── predictor.py             #   行为预测器 (n步马尔可夫链)
│   ├── relationship.py          #   关系状态追踪 (trust/closeness/familiarity/mode)
│   ├── impulse.py               #   冲动信号系统 (疲劳值模型)
│   ├── self_mirror.py           #   AI 自我镜像生成
│   ├── portrait_manager.py      #   PORTRAIT.md 生命周期管理
│   ├── portrait_writer.py       #   画像实时写入 (仅实时层)
│   ├── portrait_renderer.py     #   画像渲染为 LLM prompt
│   ├── portrait_extractors.py   #   画像特征提取 (纯函数)
│   └── portrait_state.py        #   画像条目状态机
│
├── aurasdk/                     # AuraSDK Rust 核心 (★ Phase 7: 多版本兼容)
│   ├── __init__.py              #   Python 绑定 (auto-detect cp312/cp314)
│   ├── LICENSE                  #   AuraSDK 上游 MIT 许可证
│   └── _core.cp312-win_amd64.pyd#   编译的 Rust 核心 (~5MB, Python 3.12+)
│
├── data/                        # 运行时数据 (~2.2GB)
│   ├── qwen_embed_f32.npy       #   嵌入表 152K×3584 (~2GB)
│   ├── qwen_tokenizer.json      #   BPE 词典
│   ├── active.mfield            #   ★ C++ hook 消费的 M 矩阵文件 (8层×3584² f16, 196MB, 自动生成)
│   ├── baseline_vectors.npy     #   冷启动基线向量
│   ├── tag_embeddings.npy       #   标签嵌入索引
│   ├── memory_metadata.jsonl    #   记忆元数据 (每轮持久化)
│   ├── correction_log.jsonl     #   纠错反馈日志
│   ├── conflicts.jsonl          #   矛盾检测结果
│   ├── topic_notes.jsonl        #   话题笔记
│   ├── emotion_reversals.jsonl  #   情绪翻转事件
│   ├── cooccurrence_matrix.npz  #   共现矩阵持久化
│   ├── hyperedge_index.json     #   超边索引
│   ├── temporal_pattern.json    #   时间模式
│   ├── tag_affinity.json        #   标签亲和度
│   ├── drift_state.jsonl        #   偏移率状态
│   ├── relationship_state.json  #   关系状态持久化
│   ├── impulse_state.json       #   冲动源状态
│   ├── PORTRAIT.md              #   AI 自我画像
│   ├── benchmark_phase6.log     #   ★ 消融 benchmark 日志
│   ├── .cli_history             #   ★ CLI 命令历史 (跨会话持久化)
│   └── aura/                    #   AuraSDK 索引文件
│
├── docs/                        # 文档
│   └── archive/                 #   历史设计文档 (SPEC.md, spec_memory_emergence.md 等)
│
└── .claude/                     # Claude Code 配置
    ├── settings.json
    └── memory/                  #   项目记忆 (13 个文件)

代码量统计

目录 文件数 代码行数 说明
core/ 8 ~5,400 核心引擎 (★ Phase 5.1: trajectory.py/GateTone 拆除, field_modulators 简化)
producers/ 13 ~4,350 数据生产者
engine.py 1 ~1,500 主循环 + CLI (★ Phase 7: aura_results 诊断字段)
config.py 1 ~252 配置
cli.py 1 ~825 ★ Phase 7: Rich+prompt_toolkit 测试前端
scripts/ 9 ~2,600 辅助脚本 (含 benchmark runner)
aurasdk/ 1 ~68 AuraSDK Python 绑定
总计 34 ~15,150 不含空行和注释

🖥️ CLI 测试前端 (★ Phase 7)

基于 Rich + prompt_toolkit 的彩色终端前端,专为记忆系统测试设计。

特性

  • 🎨 彩色终端 — Rich 渲染的诊断面板,可折叠/展开
  • 📝 命令历史 — 跨会话持久化到 data/.cli_history
  • 🔧 通道开关运行时切换/aura /mfield /mfact /msession /mabstract /fields /producers /rerank
  • 🔍 记忆浏览器/recall <query> 测试 AuraSDK 召回,/mem [N] 查看最近记忆,/search <kw> 关键词搜索
  • 📊 诊断面板 — 每轮自动显示 intent/emotion/valence/arousal/tags/entities + AuraSDK 召回摘要 + M@q 记忆场范数 + 耗时

快速启动

# 交互模式 (默认显示诊断面板)
python cli.py

# 关闭诊断面板
python cli.py --no-diag

# 交互命令:
> /help           # 命令列表
> /toggles        # 查看所有通道开关状态
> /stats          # 系统统计 (AuraSDK记录数/记忆数/轮次/consolidation)
> /recall Rust    # 测试 AuraSDK 召回
> /mem 5          # 查看最近5条记忆
> /diag off       # 关闭诊断面板
> /mfield off     # 关 M@q 记忆场
> /save           # 保存对话日志
> /quit           # 退出

与 engine.py 的关系

cli.pyengine.py 并行可用,共享同一个 FirstBeatEngine 核心:

python engine.py python cli.py
用途 精简交互 / 消融 / 单次生成 测试驱动交互
界面 纯文本 Rich 彩色面板
诊断 stderr verbose 输出 每轮内联面板
命令历史 无持久化 跨会话 FileHistory
运行时开关 命令行参数 交互命令随时切换
记忆浏览 无内置 /recall /mem /search

📊 生产者管线 (★ Phase 5: 22模块 CVEC trajectory 已拆除)

Phase 5 通道重标定后,原 22 个 trajectory 模块各归各位:

  • 标量/离散信号 (情绪值, 意图分类, 关系参数) → prompt 文本注入
  • 向量信号 (6 路投影矩阵) → 逐 token logit 调制
  • 统计追踪 (drift, impulse) → 引擎参数动态调节

详见 三条线详解 中的线 3 和 core/field_modulators.py


🧬 M@q v3 三场拆解

为什么需要 v3 — 三种异构结构

v3 的核心洞察:不同类型记忆的语义结构根本不同,但不同类型记忆的语义结构根本不同:

  • 事实记忆 "Rust 项目上周五交付" → 离散锚点,K-聚类自然,时间敏感
  • 会话记忆 近 20 轮对话流 → 连续漂移,EMA 更适合,不应离散化
  • 抽象记忆 "用户频繁换技术栈" → 跨时间槽缓慢收敛,需要对比更新防止坍缩

v3 三场拆解:M_fact (K-聚类 Gram) + M_session (EMA 池) + M_abstract (对比簇)。

v3 架构

┌─ M_fact (K-聚类锚点 Gram) ──────────────────────────┐
│ 8 槽 = 4 时间槽 × 2 源 (user/ai)                     │
│ 每槽 K 个簇 (K=3-5 自适应):                           │
│   center_k ∈ ℝ³⁵⁸⁴  (EMA)                            │
│   M_k ∈ ℝ³⁵⁸⁴ˣ³⁵⁸⁴  (float16 Gram)                  │
│ 写入: cos_sim ≥ threshold → 最近簇 Titan gate 更新    │
│       cos_sim < threshold → 新建簇 (≤ K_max)         │
│ 查询: softmax(q·center_k / τ) 加权各簇               │
│ C++ 映射: L5-L7                                       │
└──────────────────────────────────────────────────────┘

┌─ M_session (EMA 向量池) ────────────────────────────┐
│ 2 池 (user/ai):                                      │
│   pool: FIFO [(vec, ts)] (窗口 20)                    │
│   ema: EMA(β=0.8)                                    │
│ 查询: recency-weighted 平均                           │
│       trend = ema - prev_ema (话题漂移)               │
│ C++ 映射: L8-L10 (rank-1 outer(ema, ema) 近似)       │
└──────────────────────────────────────────────────────┘

┌─ M_abstract (持久聚类 + 对比更新) ───────────────────┐
│ K 个簇 (K=8-16, 跨时间槽):                            │
│ 写入: novelty > threshold → contrastive update        │
│   M += η·outer(dc,dc) − μ·outer(dc⊥,dc⊥)  (吸引+斥力)│
│ 回收: 7天未活跃 + N<3 → 自动退场                     │
│ C++ 映射: L11-L12                                     │
└──────────────────────────────────────────────────────┘

MFieldExporter → .mfield 文件 (Python→C++ mmap):
  [alphas: f32×8] + [M_L5: f16×3584²] + ... + [M_L12: f16×3584²]
  196 MB/文件, C++ 侧 ggml_mul_mat 零拷贝读取

查询产出 (向后兼容 7 路向量)

output = mf.query(q_vec, context={...})
# → {
#     "fact_user":    [3584] f32,  # M_fact user 加权
#     "fact_ai":      [3584] f32,  # M_fact ai 加权
#     "fact_diff":    [3584] f32,  # user - ai 盲区信号
#     "session_user": [3584] f32,  # M_session user EMA
#     "session_ai":   [3584] f32,  # M_session ai EMA
#     "explicit":     [3584] f32,  # AuraSDK 共现扩展 (非 M@q 子场)
#     "abstract":     [3584] f32,  # M_abstract 加权
#   }

时间分片权重 (M_fact 层加权融合)

时间槽 L5 (today-heavy) L6 (week-heavy) L7 (older-heavy)
today 0.60 0.25 0.10
this_week 0.25 0.50 0.20
this_month 0.10 0.15 0.40
older 0.05 0.10 0.30

显式共现矩阵 C

如果记忆 A 和记忆 B 在同一轮对话中被 AuraSDK 同时召回 → C[A][B] += 1。 查询: explicit_vec = C @ q → "和 q 相似的记忆,通常和哪些其他记忆一起被想起"

实体超边索引 H

H["Rust"] = [mem_001, mem_042, mem_103] → 精确锁定同时涉及多个实体的记忆。


⚡ Titans 惊喜门控

借鉴 Google Titans 架构的记忆更新机制。核心思想:越出乎意料的信息,记得越牢

数学原理

给定新记忆向量 d:

1. 惊喜度计算:
   surprise = 1 - cos_sim(d, M@d)
   # 如果 d 和已有记忆很相似 → surprise 低 (意料之中)
   # 如果 d 和已有记忆完全不同 → surprise 高 (意外 → 记得牢)

2. 门控值:
   gate = η · surprise + β · momentum_prev
   # η = 惊喜缩放因子 (默认 1.0)
   # β = 动量初始强度 (默认 0.5)
   # momentum = β + momentum_prev × (1-γ)
   # γ = 动量衰减率 (默认 0.5)

3. 生命周期权重:
   gate_final = gate × lifecycle_weight
   # hot: 1.5  |  warm: 1.0  |  cool: 0.5  |  stale: 0.2  |  archived: 0.05

4. 矩阵更新:
   M_new = (1 - λ) · M_old + gate_final · v ⊗ v
   # λ = 遗忘率 (默认 1e-5, 每轮忘记十万分之一)

为什么这样设计

冷启动 (M ≈ 0):
  → surprise 极高 → gate 极大 → 疯狂写入
  → 快速建立记忆基础

记忆饱和 (|M| 大):
  → surprise 低 → gate 小 → 谨慎写入
  → 只记真正新的东西

遗忘 (λ > 0):
  → 旧记忆逐渐淡出
  → 避免矩阵越来越稠密

可调参数

参数 环境变量 默认值 调参建议
惊喜缩放 M_SURPRISE_ETA 1.0 >1: 更激进写入;<1: 保守
动量初始 M_MOMENTUM_BETA 0.5 连续相似内容时增益
动量衰减 M_MOMENTUM_DECAY 0.5 越大衰减越快
每轮遗忘 M_FORGET_LAMBDA 1e-5 0 = 永不遗忘

🕐 惰性 Consolidation

老系统用 10+ 后台线程做定时维护。新系统的哲学是:不做任何不需要现在做的事

所有维护工作被推迟到对话间隙,条件触发——不启动任何线程。

三级触发机制

每轮对话结束后 → consolidation.tick()

┌────────────────────────────────────────────────────────────┐
│                                                            │
│  [Shallow — 每 4 小时]                                     │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Portfolio 画像轻更新:                                │  │
│  │    - 提取最新记忆特征                                │  │
│  │    - 更新实时层画像条目                              │  │
│  │                                                      │  │
│  │  共现边修剪:                                         │  │
│  │    - 移除 C 中共现 < 2 的弱边                       │  │
│  │                                                      │  │
│  │  生命周期衰减:                                        │  │
│  │    - hot → warm (7天无活动)                          │  │
│  │    - warm → cool (30天)                              │  │
│  │    - cool → stale (90天)                             │  │
│  │    - stale → archived (180天)                        │  │
│  │                                                      │  │
│  │  AI 情绪脱敏:                                         │  │
│  │    - AI 回复的 valence 绝对值衰减                    │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                            │
│  [Deep — 每 24 小时]                                       │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  Portfolio 画像深更新 (需要 LLM):                     │  │
│  │    - 重新分析用户兴趣变化                            │  │
│  │    - 更新稳定层画像条目                              │  │
│  │                                                      │  │
│  │  情绪锚点重算:                                        │  │
│  │    - 统计每日/周的平均情绪                           │  │
│  │    - 更新情绪基线                                    │  │
│  │                                                      │  │
│  │  话题树重建:                                         │  │
│  │    - 从所有记忆抽取话题标签                          │  │
│  │    - 构建层级话题树                                  │  │
│  │                                                      │  │
│  │  叙事弧演进:                                          │  │
│  │    - 延长/合并/关闭活跃故事线                        │  │
│  │                                                      │  │
│  │  矛盾检测:                                            │  │
│  │    - 检测记忆间的逻辑矛盾                            │  │
│  │    - 记录到 conflicts.jsonl                          │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                            │
│  [Impulse Fatigue — 每 10 分钟]                             │
│  ┌──────────────────────────────────────────────────────┐  │
│  │  冲动源疲劳值更新:                                    │  │
│  │    - fatigue(t) = fatigue(t-1) × decay - time_passed │  │
│  │    - 每次触发: fatigue += 0.3                        │  │
│  │    - 每分钟恢复: fatigue -= 0.02                     │  │
│  └──────────────────────────────────────────────────────┘  │
│                                                            │
└────────────────────────────────────────────────────────────┘

⚙️ 配置参考

环境变量全集 (63 项)

AuraSDK 事实召回 (线1)

变量 默认值 说明
AURA_ENABLED true 开关 AuraSDK
AURA_DATA_DIR ./data/aura 索引目录
AURA_RECALL_TOP_K 10 召回数量

Qwen Embed 模型

变量 默认值 说明
QWEN_EMBED_PATH ./data/qwen_embed_f32.npy 嵌入表 (2GB)
QWEN_TOKENIZER_PATH ./data/qwen_tokenizer.json BPE 词典

M@q 记忆场 (线2)

变量 默认值 说明
M_FIELD_ENABLED true 开关 M@q
M_MATRIX_PATH ./data/m_matrix_f32.npy M₀ 事实场
M_MATRIX_COOC_PATH ./data/m_matrix_cooc_f32.npy 显式共现
M_MATRIX_ABSTRACT_PATH ./data/m_matrix_abstract_f32.npy 抽象场
M_CASCADE_ALPHA 0.5 级联查询层间传递强度
FIELD_RERANK_GAMMA 0.3 场偏置召回强度
M_SESSION_SIZE 20 M₁ session 窗口
M_NOVELTY_THRESHOLD 0.1 M₂ novelty 最低阈值
M_SURPRISE_ETA 1.0 惊喜缩放因子
M_MOMENTUM_BETA 0.5 动量初始强度
M_MOMENTUM_DECAY 0.5 动量衰减率
M_FORGET_LAMBDA 1e-5 每轮遗忘率

时间分片权重

变量 默认值 说明
TIME_SLOT_TODAY_WEIGHT 0.5 今天
TIME_SLOT_WEEK_WEIGHT 0.3 本周
TIME_SLOT_MONTH_WEIGHT 0.15 本月
TIME_SLOT_OLDER_WEIGHT 0.05 更早

生命周期权重

变量 默认值 说明
LIFECYCLE_HOT_WEIGHT 1.5 热点记忆
LIFECYCLE_WARM_WEIGHT 1.0 温记忆
LIFECYCLE_COOL_WEIGHT 0.5 凉记忆
LIFECYCLE_STALE_WEIGHT 0.2 旧记忆
LIFECYCLE_ARCHIVED_WEIGHT 0.05 归档

6路场 Python logit 调制 (线3)

变量 默认值 说明
PRODUCERS_ENABLED true ★ 开关 Python logit 调制 (替代旧 --no-traj)
STEERING_STRENGTH 1.0 全局强度倍率
GATE_TONE_WARMTH 0.5 温暖度
GATE_TONE_DIRECTNESS 0.5 直接度
GATE_TONE_FORMALITY 0.5 正式度

废弃配置: TRAJECTORY_ENABLED, TRAJ_ORTHO_EPSILON, TRAJ_MAX_NORM (Phase 5 拆除)

工作记忆

变量 默认值 说明
WORKING_MEM_DECAY 0.7 旧向量保留比例
WORKING_MEM_UPDATE_RATE 0.3 新轮次混合比例
TOPIC_SHIFT_THRESHOLD 0.3 话题转移 cos_sim 阈值

Consolidation

变量 默认值 说明
SHALLOW_CONSOL_INTERVAL 14400 Shallow 间隔 (秒, 4h)
DEEP_CONSOL_INTERVAL 86400 Deep 间隔 (秒, 24h)
IMPULSE_FATIGUE_INTERVAL 600 Impulse 间隔 (秒, 10min)

Llama.cpp 推理

变量 默认值 说明
QWEN_GGUF_PATH (必须设置) GGUF 模型路径 — 指向 qwen2.5 GGUF 文件
MINGW_BIN_DIR (自动检测) MinGW DLL 目录 (Windows, 可选)
LLAMA_N_CTX 4096 上下文长度
LLAMA_N_THREADS 8 CPU 线程数
LLAMA_N_GPU_LAYERS 0 ★ GPU 层数 (>0 启用 CUDA GPU 推理)
VERBOSE false 打印诊断信息
CLI_DIAG_ENABLED true ★ CLI 诊断面板开关
CLI_HISTORY_PATH ./data/.cli_history ★ CLI 命令历史文件

纠错与情绪

变量 默认值 说明
CORRECTION_DELTA_WRONG -0.1 纠错惩罚
CORRECTION_DELTA_RIGHT 0.05 纠错奖励
EMOTION_FLIP_POS_THRESHOLD 0.2 正面翻转阈值
EMOTION_FLIP_NEG_THRESHOLD -0.2 负面翻转阈值
BLIND_ZONE_SIM_GAP 0.3 Persona 盲区差异阈值
BLIND_ZONE_MIX_WEIGHT 0.3 盲区向量混合权重
MAX_TURN_HISTORY 100 保留最近 N 轮状态

📦 安装指南

前置条件

组件 最低版本 说明
Python 3.12+ ★ Phase 7: 支持 3.12/3.14 (aurasdk 多版本 .pyd 自动检测)
MinGW (Windows) 64-bit llama-cpp-python 依赖
内存 16GB+ 嵌入表 2GB + 模型 14GB = 峰值 ~16GB
磁盘 5GB+ 数据文件 + 模型文件

从零搭建

# 1. 克隆仓库
git clone <repo-url> "FirstBeat Ultimate"
cd "FirstBeat Ultimate"

# 2. 创建虚拟环境
python -m venv venv
# Windows:
venv\Scripts\activate
# Linux/Mac:
source venv/bin/activate

# 3. 安装 Python 依赖
pip install -r requirements.txt
# numpy>=1.24 + llama-cpp-python>=0.3.0 + rich>=13 + prompt-toolkit>=3

# 4. 准备数据文件
# 以下是必须的数据文件,放在 data/ 目录下:

# 4a. qwen_embed_f32.npy (嵌入表,~2GB)
#     从 qwen2.5 GGUF 中提取 (或从 Release 下载):
python scripts/extract_embedding_table.py path/to/qwen2.5-7b-instruct.gguf

# 4b. qwen_tokenizer.json (BPE 词典)
#     与嵌入表配套的 tokenizer 配置,随 Release 提供

# 4c. Qwen2.5 GGUF 模型
#     设置环境变量指向模型文件:
#     Windows: $env:QWEN_GGUF_PATH = 'X:/path/to/qwen2.5-7b-instruct.gguf'
#     Linux:   export QWEN_GGUF_PATH=/path/to/qwen2.5-7b-instruct.gguf

# 4d. AuraSDK 核心 (.pyd / .so)
#     ★ 从 GitHub Releases 下载预编译二进制,或自行编译
#     详见 docs/aurasdk-setup.md
#     放入 aurasdk/ 目录,引擎会自动检测

# 4e. (可选) llama.cpp fork 编译
#     如果使用 M@q 记忆场,需要编译 llama.cpp fork
#     详见 docs/llama-cpp-fork.md

环境变量快速设置 (Windows)

$env:AURA_ENABLED = "true"
$env:M_FIELD_ENABLED = "true"
$env:PRODUCERS_ENABLED = "true"
$env:QWEN_GGUF_PATH = "X:/path/to/qwen2.5-7b-instruct.gguf"
$env:MINGW_BIN_DIR = "X:/mingw64/bin"
$env:LLAMA_N_THREADS = "8"
$env:VERBOSE = "false"

环境变量快速设置 (Linux/Mac)

export AURA_ENABLED=true
export M_FIELD_ENABLED=true
export PRODUCERS_ENABLED=true
export QWEN_GGUF_PATH="/path/to/qwen2.5-7b-instruct.gguf"
export LLAMA_N_THREADS=8
export VERBOSE=false

🚀 使用指南

交互式对话

# 方式 1: 精简交互 (原始终端)
python engine.py

# 方式 2: Rich 彩色前端 (推荐用于测试)
python cli.py

engine.py 交互模式

# 输出:
# FirstBeat Ultimate — 记忆场模式
# 输入消息开始对话,/quit 退出,/stats 统计
# AuraSDK: on  M@q: on  PythonFields: on
#
# > Rust太难了,想换Python
# [AI 回复...]
#
# > /stats
#   AuraSDK records: 42
#   M@q memories: 42
#   Turn history: 15
#   Consolidation: shallow=2, deep=0
#   Tags: 128 categories
#
# > /quit

cli.py 测试前端 (★ Phase 7)

# 彩色终端 + 诊断面板 + 命令历史 + 记忆浏览器
python cli.py

# 交互命令一览:
#   对话:     /clear      清屏重置
#   通道开关: /aura on|off  /mfield on|off  /fields on|off  /producers on|off
#   子场粒度: /mfact on|off  /msession on|off  /mabstract on|off
#   记忆浏览: /recall <q>  /mem [N]  /search <kw>
#   诊断:     /diag on|off  /stats  /toggles  /save
#   其他:     /help  /quit

单次生成

python engine.py -m "Rust的borrow checker怎么理解?"

# 带调试输出:
VERBOSE=true python engine.py -m "今天心情不太好"

# 输出:
# [回复文本]
#
# --- diagnostics ---
#   intent: emotional_sharing
#   entities: ['Rust', 'borrow checker']
#   tags: ['编程', 'Rust', '学习']
#   aura_recalled: 10
#   aura_injected: 6
#   mfield_mode: v3_7way
#   mfield_norms: {'fact_user': 0.85, 'fact_ai': 0.42, ...}
#   R_q_ratio: 0.73
#   topic_shift: False
#   fields_active: 6
#   elapsed_ms: 1842.3

消融对比

python engine.py --benchmark

# 自动跑 7 组 × 3 场景 = 21 次生成
# 也可通过独立脚本运行:
# python scripts/run_benchmark_phase6.py
#
# 输出:
# ======================================================================
# FirstBeat Ultimate — 消融对比
# ======================================================================
#
# ──────────────────────────────────────────────────────────────────────
# 场景: 编程 — "Rust的borrow checker太难了,我想换Python了"
# ──────────────────────────────────────────────────────────────────────
#
#   [full         ] (82341ms)
#   我完全理解你的感受。Borrow checker 确实是 Rust 最大的心理门槛...
#
#   [-Aura        ] (45821ms)
#   换语言是个很大的决定呢,让我帮你分析一下 Rust 和 Python 的差异...
#
#   [-M_fact      ] (51923ms)
#   [回复缺事实锚点,变通用]
#
#   [-M_session   ] (50012ms)
#   [回复缺近期话题连续性]
#
#   [-M_abstract  ] (49230ms)
#   [回复缺长期模式感知]
#
#   [-PythonFields] (48210ms)
#   [语气/情绪一致性减弱]
#
#   [none         ] (42810ms)
#   [纯 qwen2.5 回复,最快但最空洞]

线开关

# 只关 AuraSDK
python engine.py --no-aura -m "测试消息"

# 只关 M@q
python engine.py --no-mfield -m "测试消息"

# 只关 Python logit 调制
python engine.py --no-producers -m "测试消息"

# 全关 = 纯 qwen2.5
python engine.py --no-aura --no-mfield --no-producers -m "测试消息"

# 级联回退 (单层 M₀@q, Phase 2 legacy)
python engine.py --no-cascaded -m "测试消息"

# 关场偏置重排
python engine.py --no-field-rerank -m "测试消息"

🧪 消融测试

消融 (Ablation) 是理解每条线价值的核心工具。通过逐一关掉组件,观察回复质量的变化。

7 组配置 (Phase 6: 子场粒度消融)

配置名 AuraSDK M_fact M_session M_abstract Python Fields 说明
full 完整引擎
-Aura 无事实召回
-M_fact 无事实记忆场
-M_session 无会话记忆场
-M_abstract 无抽象记忆场
-PythonFields 无 logit 调制
none 纯 qwen2.5

验证结果 (2026-06-23 · Phase 6 · 21/21 全过)

情绪场景: "最近工作压力好大,感觉快撑不住了"
──────────────────────────────────────────────────────────
full           ✅ "像上次项目交付前那样,你展现出了强大的能力..."
               → 唯一有记忆引用的配置,个性化最强

-Aura          ⚠️  快 42%,但丢失个性化事实引用

-M_fact        ⚠️  缺事实锚点,回复变通用

-M_session     ⚠️  缺近期话题连续性

-M_abstract    ⚠️  缺长期模式感知

-PythonFields  ⚠️  语气/情绪一致性减弱

none           ❌  最快 (43s),但最空洞
──────────────────────────────────────────────────────────

→ C++ M@q hook 已激活,每条线独立可测。

### 三条线估值

| 线 | 核心价值 | 可替代性 |
|----|----------|----------|
| **AuraSDK 召回** | 事实锚定 — "记得上次说了什么" | **不可替代** — full vs -Aura 差异最显著 |
| **M@q 记忆场** | 语境连续性 — "知道我们在持续聊什么" | **有加价** — 个性化程度的质变 |
| **6路场 logit 调制** | 语气/情绪/关系一致性 — "逐 token 引擎掌舵" | **个性化定调** — full vs -PythonFields 差异显著 |

---

## 🏛️ 架构铁律

### 1. 依赖方向 (只能向下)

engine.py → core/cognitive.py + core/field_modulators.py + core/memory_field.py + core/injector.py + core/consolidation.py │ │ │ └─ core/embed.py ←──┴───────────────────────┘ │ aurasdk/_core.pyd (Rust)


- `core/embed.py` 是唯一底层依赖,被 field_modulators 和 memory_field 共用
- `core/field_modulators.py` 独立 (Phase 5.1: 6路场投影矩阵 + 逐 token 调制)
- `core/injector.py` 独立 (逐 token decode loop + 引擎采样 + C++ mfield 加载)
- `core/consolidation.py` 惰性维护,被 engine 每轮 tick
- AuraSDK 只被 engine 和 memory_field 调用
- **禁止循环依赖** — 这是项目级别的硬约束

### 2. 核心设计决策

| 决策 | 理由 |
|------|------|
| **零 Qdrant** | M@q 从 AuraSDK 内容 + qwen_embed 构建 V 矩阵,不做外部向量库 |
| **C++ 残差 + Python 调制 双通道** | M@q 在 llama.cpp 内部 `h += α·M@h`;6路场在 Python 侧逐 token 拦截 logits → 调制 → 采样 |
| **残差不可跳过** | C++ 侧 M@q 物理注入隐藏层 + Python 侧偏置 logits,模型无法忽视 (vs prompt 文本可跳过) |
| **线间正交** | 三条线互不依赖,可独立开关,支持消融实验 |
| **冷启动优雅退化** | 零记忆 → M=0, R=0 → 等价于纯 prompt 模式,不会崩溃 |
| **零后台线程** | 所有维护工作在对话间隙惰性执行,不启动任何后台线程 |
| **轮次驱动** | 所有状态机(画像、关系、冲动)以对话轮次为时钟,跨会话持久化 |

### 3. 数据纯净

| 规则 | 原因 |
|------|------|
| AI 回复不进 M@q 矩阵 | 防止 AI 的泛泛回复污染用户独特的记忆表示 |
| AI 回复作为独立 AuraSDK 记录 | 标记 source=ai, tag=AI,不与用户记忆混淆 |
| 冷启动基线向量 | 所有基线文本硬编码在 config.py,零记忆时也能产出有效引导 |

### 4. 通道哲学 (Phase 6 确立)

标量 / 离散值 (trust, closeness, drift, predictor 概率分布) → prompt 通道 (文本注入) → 写成中文比映射为 3584D 向量更有效

高维语义内容 (情绪、记忆场、叙事弧、话题) → 残差通道 (h += r) → 需要直接修改模型隐藏状态才能生效


---

## 📈 诊断监控

### 四路核心诊断指标

每轮对话的 `result["diagnostics"]` 包含:

| 指标 | 含义 | 正常范围 | 警戒 |
|------|------|----------|------|
| `R_q_ratio` | `∥R∥ / ∥q∥` — 记忆场响应强度 | 0.3-0.9 | >1.5: 记忆场主导 |
| `elapsed_ms` | 总耗时 | 1500-8000ms | >10000ms: 资源紧张 |
| `fields_active` | 活跃 Python 场数 | 5-7 | <4: 场调制故障 |
| `mfield_norms` | 7 路向量范数 | 0.1-1.0 | 全 0: 冷启动; 全 >2: 过饱和 |
| `mfield_cpp_loaded` | C++ M@q hook 状态 | `True` | `False`: C++ 残差注入未生效 |

### Verbose 模式输出

```bash
VERBOSE=true python engine.py -m "测试消息"

# stderr 输出:
# FieldRerank drift=0.9412 gain=+0.0321 avg_q=0.5234 avg_ref=0.5555
# mfield_norms: fact_user=0.85 fact_ai=0.42 fact_diff=0.63 ...
# R_q_ratio: 0.73
# topic_shift: False
# fields_active: 6
# cons_shallow: False
# cons_deep: False
# elapsed_ms: 1842.3

交互式命令

> /stats    # 输出引擎状态
  AuraSDK records: 42
  M@q memories: 42
  Turn history: 15
  Consolidation: shallow=2, deep=0
  Tags: 128 categories

> /quit     # 退出 (记忆自动保存)

🔄 与旧系统的关系

维度 旧 (CH Memory System) 新 (FirstBeat Ultimate)
代码量 ~40,000 行 ~15,150 行 — 减少 62%
服务框架 FastAPI (HTTP 服务器) 无框架 — 单进程
向量存储 Qdrant (外部服务) .npy 文件 — 零外部依赖
事实检索 9 路 Qdrant 并行查询 AuraSDK SDR+MinHash
LLM DeepSeek API (远程) qwen2.5 7B (本地)
认知注入 prompt 拼装 (可跳过) 残差注入 (不可跳过)
后台线程 5 个 0
记忆维护 定时线程自动触发 惰性 consolidation — 对话间隙触发
前端界面 Rich CLI (测试前端) + engine 交互模式
外部依赖 Qdrant + FastAPI + uvicorn + httpx numpy + llama-cpp-python + rich + prompt-toolkit
Python 版本 3.10+ 3.12+ (多版本 .pyd 兼容)

旧项目 d:\First Beat CH Memory System\ 原封不动,两个系统完全独立。


🗺️ 路线图

Phase 1 ✅ 基础设施

  • BPE 涌现式实体抽取
  • 标签系统 (关键词 + embedding NN)
  • 4 粒度时间模式索引
  • 29 项配置 + 10 个数据文件

Phase 2 ✅ M@q v2 重构

  • 双源分离 (user/ai)
  • 4 时间分片 (today/week/month/older)
  • C 显式共现矩阵
  • H 实体超边索引
  • 生命周期权重
  • 惰性矩阵分配 (零内存冷启动)

Phase 3 ✅ M@q 三场拆解

  • M_fact (K-聚类锚点 Gram) + M_session (EMA 池) + M_abstract (对比簇)
  • MFieldExporter → .mfield C++ mmap 导出
  • 50/50 结构测试全过

Phase 4 ✅ 投影矩阵 + 死模块活化

  • 6 路投影矩阵全激活: E/R/d/P/T/S — 全矩阵直驱, 零 tokenizer 依赖
  • entity BPE 涌现式替换 jieba
  • cognitive 退缩为纯路由
  • 在线学习闭环: 每轮交互后自动更新矩阵

Phase 5 ✅ 管线集成

  • trajectory.py 1125行拆除 (CVEC 全清)
  • calibrate_alpha.py 109行拆除
  • cognitive.py 移除 to_extractor_ctx()
  • 三通道就位: C++ M@q L5-12 + Python 6路 logit 调制 + Prompt 文本

Phase 6 ✅ 标定 + 消融验证 (2026-06-23)

  • 子场粒度开关: mfact/msession/mabstract/python_fields 独立控制
  • 7 组消融矩阵 × 3 场景 = 21/21 全过
  • C++ M@q hook 激活确认 (libllama 符号对接成功)
  • 消融结论: full 最有个性化, none 最快但最空洞

Phase 7 ✅ CLI 测试前端 + 多版本兼容 (2026-06-24)

  • cli.py Rich+prompt_toolkit 测试前端 (825行)
  • AuraSDK 多 Python 版本兼容 (cp312 + cp314 .pyd 自动检测)
  • CUDA GPU 推理支持 (LLAMA_N_GPU_LAYERS 可配)

Phase 5.1 ✅ 场架构统一 (2026-06-25)

  • GateTone 拆除: dead no-op 类 + _compute_gate_tuning() + gate_tuning 字段全清
  • ΔV→E 矩阵升级: EmotionDeltaV per-word 标量表 → EmotionProjection E ∈ ℝ^{2×3584}
  • EmotionModulator 简化: ~85行 → ~25行, 删 tokenize_fn/_word_tid/_ensure_built
  • 6 场全部统一为矩阵模型, 零 tokenizer 依赖
  • verify_phase6: 83/83 全过, 净删 ~320行

🚧 进行中

  • 记忆积累 — 通过大量对话积累 M_fact/M_session/M_abstract 区分度增长 (>50轮)

📋 计划中

  • 跨平台支持 — Linux/Mac 兼容性测试
  • GPU 卸载优化 — LLAMA_N_GPU_LAYERS 最优分层策略测试
  • web UI — 轻量前端界面

🛠️ 开发者须知

修改代码前的检查清单

  1. 这个改动影响哪条线?(AuraSDK / M@q / 6路场 logit 调制 / Consolidation)
  2. 是否破坏了线间正交?(可以通过开关独立测试吗?)
  3. 冷启动场景下会怎样?(M=0, 零记忆)
  4. 是否有内存泄漏?(numpy 数组大,容易忘 .copy())
  5. 消融对比能看出来差异吗?(--benchmark)

数据文件惯用扩展名

扩展名 用途
.npy numpy 数组,大矩阵
.npz numpy 压缩数组,稀疏矩阵
.jsonl JSON Lines,每行一条记录,可追加
.json 配置/索引/状态文件,覆盖写入
.pyd Windows Python 扩展 (Rust 编译)

Python 3.12+ 语法提示

# 项目兼容 Python 3.12+ (aurasdk 多版本 .pyd 自动检测)

# Optional 类型简写
def foo(x: int | None = None) -> str | None:

# 海象运算符
if (n := len(data)) > 10:

# f-string 表达式
logger.info(f"score: {score:.4f}")

# match/case (Python 3.10+)
match intent:
    case "emotional_sharing":
        ...
    case "casual":
        ...

👥 社区与贡献

FirstBeat Ultimate 是一个开源项目,欢迎贡献!

资源

文档 说明
CONTRIBUTING.md 贡献指南 — 开发环境、代码风格、PR 流程
CODE_OF_CONDUCT.md 行为准则 (Contributor Covenant 2.1)
SECURITY.md 安全策略与漏洞报告
CHANGELOG.md 版本变更记录
docs/llama-cpp-fork.md llama.cpp fork 说明 — M@q hook 修改详解与构建指南
docs/aurasdk-setup.md AuraSDK 编译与安装 — 从源码构建 Rust 核心
scripts/extract_embedding_table.py GGUF 嵌入表提取脚本

快速参与

# 1. 安装开发依赖
pip install -r requirements.txt ruff pre-commit
pre-commit install

# 2. 运行语法检查
ruff check .

# 3. 运行验证脚本
python scripts/verify_phase6.py

🙏 致谢

  • teolex2020/AuraSDK — MIT licensed Rust 核心,提供了 <1ms 的 SDR+MinHash 检索能力
  • qwen2.5 — 7B 中英双语模型,embedding 表和 GGUF 推理
  • llama.cpp — CPU-first LLM 推理框架 + 自维护 fork (M@q hook L5-12)
  • Google Titans — 惊喜门控 + 动量记忆更新机制的论文灵感
  • CH Memory System — 40,000 行旧项目,提供了 17 个记忆维度的原始设计

📄 许可证

Copyright (c) 2026 初痕 (Chuchen)
SPDX-License-Identifier: AGPL-3.0

AuraSDK Rust 核心 (aurasdk/_core.cp*-win_amd64.pyd, 多版本兼容,不在仓库中 — 详见 docs/aurasdk-setup.md) 受其自身 MIT 许可证约束。



— 本地优先 · 残差注入 · 零后台线程 · 冷启动优雅退化 —

最后修订: 2026-06-25 · Phase 5.1 场架构统一 (GateTone 拆除 + ΔV→E 矩阵, 6 场全矩阵直驱)

About

memory system

Resources

Code of conduct

Contributing

Security policy

Stars

2 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages