本地优先 · 残差注入 · 三条正交线 · 零后台线程
这是什么 · 一句人话 · 架构全景 · 三条线 · 数据流 · 项目结构 · 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" 时,它不只是生成一段通用安慰——它会:
- 从记忆中召回你之前提到的 "项目交付压力" 和 "技术栈争论"
- 感知到你从焦虑转向沮丧的情绪变化
- 在模型深层注入 "现在是下午,你在工作,这个话题你已经纠结了 3 周" 的语境
- 调整自己的语气——更共情、更支持——因为这是 "倾诉" 而非 "提问"
- 生成回复后,把所有新信息写入记忆,供下次对话使用
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 | 自动 |
用户: "上次说的那个 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, ...}, ...]M@q 是这个项目最核心的创新——三场异构结构(M_fact K-聚类 Gram + M_session EMA 池 + M_abstract 对比簇),通过 C++ hook h += α·M@h 物理注入 L5-L12 隐藏层。
完整架构见下方 M@q v3 三场拆解 章节。
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 惊喜门控 章节。
架构反转: 引擎是驾驶员,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 依赖,在线学习闭环:每轮交互后自动从本轮对话中更新矩阵。
详见 惰性 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 | 不含空行和注释 |
基于 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 # 退出cli.py 和 engine.py 并行可用,共享同一个 FirstBeatEngine 核心:
python engine.py |
python cli.py |
|
|---|---|---|
| 用途 | 精简交互 / 消融 / 单次生成 | 测试驱动交互 |
| 界面 | 纯文本 | Rich 彩色面板 |
| 诊断 | stderr verbose 输出 | 每轮内联面板 |
| 命令历史 | 无持久化 | 跨会话 FileHistory |
| 运行时开关 | 命令行参数 | 交互命令随时切换 |
| 记忆浏览 | 无内置 | /recall /mem /search |
Phase 5 通道重标定后,原 22 个 trajectory 模块各归各位:
- 标量/离散信号 (情绪值, 意图分类, 关系参数) → prompt 文本注入
- 向量信号 (6 路投影矩阵) → 逐 token logit 调制
- 统计追踪 (drift, impulse) → 引擎参数动态调节
详见 三条线详解 中的线 3 和 core/field_modulators.py。
v3 的核心洞察:不同类型记忆的语义结构根本不同,但不同类型记忆的语义结构根本不同:
- 事实记忆 "Rust 项目上周五交付" → 离散锚点,K-聚类自然,时间敏感
- 会话记忆 近 20 轮对话流 → 连续漂移,EMA 更适合,不应离散化
- 抽象记忆 "用户频繁换技术栈" → 跨时间槽缓慢收敛,需要对比更新防止坍缩
v3 三场拆解:M_fact (K-聚类 Gram) + M_session (EMA 池) + M_abstract (对比簇)。
┌─ 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 零拷贝读取
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 加权
# }| 时间槽 | 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 |
如果记忆 A 和记忆 B 在同一轮对话中被 AuraSDK 同时召回 → C[A][B] += 1。
查询: explicit_vec = C @ q → "和 q 相似的记忆,通常和哪些其他记忆一起被想起"
H["Rust"] = [mem_001, mem_042, mem_103] → 精确锁定同时涉及多个实体的记忆。
借鉴 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 = 永不遗忘 |
老系统用 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 │ │
│ └──────────────────────────────────────────────────────┘ │
│ │
└────────────────────────────────────────────────────────────┘
| 变量 | 默认值 | 说明 |
|---|---|---|
AURA_ENABLED |
true |
开关 AuraSDK |
AURA_DATA_DIR |
./data/aura |
索引目录 |
AURA_RECALL_TOP_K |
10 |
召回数量 |
| 变量 | 默认值 | 说明 |
|---|---|---|
QWEN_EMBED_PATH |
./data/qwen_embed_f32.npy |
嵌入表 (2GB) |
QWEN_TOKENIZER_PATH |
./data/qwen_tokenizer.json |
BPE 词典 |
| 变量 | 默认值 | 说明 |
|---|---|---|
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 |
归档 |
| 变量 | 默认值 | 说明 |
|---|---|---|
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 阈值 |
| 变量 | 默认值 | 说明 |
|---|---|---|
SHALLOW_CONSOL_INTERVAL |
14400 |
Shallow 间隔 (秒, 4h) |
DEEP_CONSOL_INTERVAL |
86400 |
Deep 间隔 (秒, 24h) |
IMPULSE_FATIGUE_INTERVAL |
600 |
Impulse 间隔 (秒, 10min) |
| 变量 | 默认值 | 说明 |
|---|---|---|
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$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"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# 输出:
# 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# 彩色终端 + 诊断面板 + 命令历史 + 记忆浏览器
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 /quitpython 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.3python 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) 是理解每条线价值的核心工具。通过逐一关掉组件,观察回复质量的变化。
| 配置名 | AuraSDK | M_fact | M_session | M_abstract | Python Fields | 说明 |
|---|---|---|---|---|---|---|
full |
✅ | ✅ | ✅ | ✅ | ✅ | 完整引擎 |
-Aura |
❌ | ✅ | ✅ | ✅ | ✅ | 无事实召回 |
-M_fact |
✅ | ❌ | ✅ | ✅ | ✅ | 无事实记忆场 |
-M_session |
✅ | ✅ | ❌ | ✅ | ✅ | 无会话记忆场 |
-M_abstract |
✅ | ✅ | ✅ | ❌ | ✅ | 无抽象记忆场 |
-PythonFields |
✅ | ✅ | ✅ | ✅ | ❌ | 无 logit 调制 |
none |
❌ | ❌ | ❌ | ❌ | ❌ | 纯 qwen2.5 |
情绪场景: "最近工作压力好大,感觉快撑不住了"
──────────────────────────────────────────────────────────
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\ 原封不动,两个系统完全独立。
- BPE 涌现式实体抽取
- 标签系统 (关键词 + embedding NN)
- 4 粒度时间模式索引
- 29 项配置 + 10 个数据文件
- 双源分离 (user/ai)
- 4 时间分片 (today/week/month/older)
- C 显式共现矩阵
- H 实体超边索引
- 生命周期权重
- 惰性矩阵分配 (零内存冷启动)
- M_fact (K-聚类锚点 Gram) + M_session (EMA 池) + M_abstract (对比簇)
- MFieldExporter → .mfield C++ mmap 导出
- 50/50 结构测试全过
- 6 路投影矩阵全激活: E/R/d/P/T/S — 全矩阵直驱, 零 tokenizer 依赖
- entity BPE 涌现式替换 jieba
- cognitive 退缩为纯路由
- 在线学习闭环: 每轮交互后自动更新矩阵
- trajectory.py 1125行拆除 (CVEC 全清)
- calibrate_alpha.py 109行拆除
- cognitive.py 移除 to_extractor_ctx()
- 三通道就位: C++ M@q L5-12 + Python 6路 logit 调制 + Prompt 文本
- 子场粒度开关: mfact/msession/mabstract/python_fields 独立控制
- 7 组消融矩阵 × 3 场景 = 21/21 全过
- C++ M@q hook 激活确认 (libllama 符号对接成功)
- 消融结论: full 最有个性化, none 最快但最空洞
cli.pyRich+prompt_toolkit 测试前端 (825行)- AuraSDK 多 Python 版本兼容 (cp312 + cp314 .pyd 自动检测)
- CUDA GPU 推理支持 (LLAMA_N_GPU_LAYERS 可配)
- GateTone 拆除: dead no-op 类 +
_compute_gate_tuning()+ gate_tuning 字段全清 - ΔV→E 矩阵升级:
EmotionDeltaVper-word 标量表 →EmotionProjectionE ∈ ℝ^{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 — 轻量前端界面
- 这个改动影响哪条线?(AuraSDK / M@q / 6路场 logit 调制 / Consolidation)
- 是否破坏了线间正交?(可以通过开关独立测试吗?)
- 冷启动场景下会怎样?(M=0, 零记忆)
- 是否有内存泄漏?(numpy 数组大,容易忘
.copy()) - 消融对比能看出来差异吗?(
--benchmark)
| 扩展名 | 用途 |
|---|---|
.npy |
numpy 数组,大矩阵 |
.npz |
numpy 压缩数组,稀疏矩阵 |
.jsonl |
JSON Lines,每行一条记录,可追加 |
.json |
配置/索引/状态文件,覆盖写入 |
.pyd |
Windows Python 扩展 (Rust 编译) |
# 项目兼容 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 场全矩阵直驱)
