DeskMate

架构概览

DeskMate 是怎么搭起来的:进程、事件协议、两个循环、记忆,以及每一块在仓库里的位置。

这是写给第一次读代码的人的简版。完整设计(中文)是 docs/architecture.md,背后的决策是 ADR,术语表是 CONTEXT.md。这三份一直是中文。提 PR 时,请使用它们定义的术语。

一个核心,多个前端

DeskMate 是一个核心加若干前端。核心拥有全部状态和全部智能,其余都很薄。

进程它是什么做什么
MainElectron 主进程窗口、托盘、全局快捷键、系统权限,启动并看护核心。不放业务逻辑。
CoreElectron utilityProcess(TypeScript)事件总线、对话循环、思考循环、行动及其闸门、感知、记忆、情绪、模型路由、MCP 客户端、本地模型。
Audio隐藏的 BrowserWindow带回声消除的麦克风采集、TTS 播放,以及嘴型跟随的播放时钟。
Stage透明的 BrowserWindow渲染形象和字幕气泡;按像素做命中测试,点击会穿过透明区域。
Console普通 BrowserWindow(React、shadcn)角色、记忆、工具、任务、模型、设置。它从不直接碰数据,一切都经过核心。

Audio 单独成一个进程,是因为回声消除需要麦克风和扬声器输出在同一个音频上下文里。它和 Stage 分开,是为了关掉形象时对话不会结束。

核心崩溃时,主进程按指数退避重启它(1 秒起,最长 30 秒),核心从持久化的状态恢复。一分钟内崩溃五次就停止自动重启,托盘里会提供手动重启。

事件协议

核心和前端只通过有类型的事件通信,类型定义在 src/shared/protocol,所有进程共用。

type Envelope<T extends EventType> = {
  v: 1;
  id: string; // ULID
  ts: number; // core monotonic clock, ms
  characterId?: string;
  type: T;
  payload: PayloadOf<T>;
};
  • 事件说的是发生了什么,或前端请求什么。核心的内部状态从不直接暴露。
  • 前端要数据时发一个查询(queries.ts):问和答在同一个端口上。查询不广播,也不记日志。
  • 每个事件都会追加到 logs/events.jsonl,用于调试和回放。
  • 高频数据(音频块、嘴型帧、播放位置)不走总线,走和 Audio 进程之间的两条直连通道。

两个循环

  • 对话循环(src/core/conversation/)是你在和它说话的那一个。它很快:拿到一轮完整的用户发言(或一次“要不要主动开口”的决定),调用角色的 converse 模型,把回复流式切成句子,每句交给 TTS。它随时可以被打断;记住的是你真正听到的那一部分。模型输出里可以带 [affect joy]、[delegate] 这样的标记。
  • 思考循环(src/core/deliberation/)是干活的那一个。对话循环里的 [delegate] 会变成一个任务:在 deliberate 模型上跑的工具调用循环,一次只跑一个。结果回到对话循环,用角色自己的声音说出来。思考循环从不说话。

语音链路是级联的,VAD、轮次检测、ASR、模型、TTS,而不是端到端语音。理由在 ADR-0001。

行动

角色能做的一切,都是某个行动提供方提供的行动:MCP 服务、内置的 computer 提供方,以及 recall、look 这样的内置行动。它们以统一的形状注册进同一个注册表,由同一道闸门决定一次调用能不能执行。见工具与行动提供方。

记忆

记忆属于单个角色,存在一个 SQLite 文件(memory.sqlite)里,分三层:

  1. 片段:角色经历过的一段时间里发生了什么,结束时做摘要。
  2. 事实:关于用户的持久陈述,每条都可以被替换或过期。
  3. 关系:对两人关系现状的持续感受。

检索用嵌入模型,由你在设置里选(默认 bge-m3);换模型会在后台把所有记忆重新嵌入,期间旧向量继续可用。角色空闲时会“做梦”:把片段整合成事实。

情绪与自主

每个角色都有一个两轴的情绪,效价和唤醒度,它按半衰期回落到基线。形象表现它,声音带着它。角色会不会、什么时候主动开口,由另一套驱力系统驱动(无聊和想要陪伴,用 character.json 里的 urge 调节),并受主动性等级(安静、陪伴、提议、自主)约束;主动性等级是用户设置,对所有角色生效。

各部分在哪里

src/main/       Electron main process
src/core/       the core
  conversation/   conversation loop
  deliberation/   tasks
  actions/        MCP, computer use, gating
  characters/     characters, avatar import, character packs
  memory/         memory store, retrieval, dreaming
  models/         model services and routing
  voice/          TTS vendors
  local-models/   model manifest and downloader
src/renderer/   stage, audio and console renderers
src/shared/     protocol types, i18n dictionaries
native/         the two Swift helpers
assets/         built-in avatar, default character, known avatars
scripts/        model download, icons, built-in avatar
website/        this site

延伸阅读

最后更新于