架构概览
DeskMate 是怎么搭起来的:进程、事件协议、两个循环、记忆,以及每一块在仓库里的位置。
这是写给第一次读代码的人的简版。完整设计(中文)是 docs/architecture.md,背后的决策是 ADR,术语表是 CONTEXT.md。这三份一直是中文。提 PR 时,请使用它们定义的术语。
一个核心,多个前端
DeskMate 是一个核心加若干前端。核心拥有全部状态和全部智能,其余都很薄。
| 进程 | 它是什么 | 做什么 |
|---|---|---|
| Main | Electron 主进程 | 窗口、托盘、全局快捷键、系统权限,启动并看护核心。不放业务逻辑。 |
| Core | Electron 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)里,分三层:
- 片段:角色经历过的一段时间里发生了什么,结束时做摘要。
- 事实:关于用户的持久陈述,每条都可以被替换或过期。
- 关系:对两人关系现状的持续感受。
检索用嵌入模型,由你在设置里选(默认 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 延伸阅读
最后更新于