# AI 笔记软件技术栈说明
> 文档性质:团队技术基线
> 基线版本:v2.3
> 适用范围:桌面客户端、本地知识库、RAG、Agent、Skill、多模型接入、多模态处理与可选云同步
> 目标读者:前端、Rust 桌面端、Python AI Core、算法、测试与后续接手项目的开发成员
> 实施状态更新:2026-09-02。本文同时包含目标架构、当前实现和第二阶段接口基线。第一阶段已完成 Vue Web 联调前端、FastAPI、Knowledge/Retrieval、Agent/Tool/Permission、Skill/Plugin 声明式运行时、Mock/OpenAI-Compatible/Ollama Provider、DeepSeek/OpenAI 预设、模型发现及开发阶段 Fernet 凭据存储。Web Workspace 已通过 FastAPI 接入后端配置的真实单 Vault;第二阶段 Agent Trace 持久化、分页快照、可恢复 SSE、stdio MCP Bridge、隔离 Plugin Host、Plugin Command 与 Plugin Settings/Secret Contract 已完成。后续继续接入真实音频处理、Provider 协议增强、Benchmark、文档导出、主题包、Trace 可视化、Mermaid 和函数图像。Tauri/Rust Host、Stronghold、原生多 Vault 文件系统和 Sync Server 仍未实现。
---
## 1. 文档目的
本文档用于统一项目的技术栈、运行结构、模块边界和开发约定。团队成员可以据此确定一个功能应落在哪个模块、需要调用哪些接口、数据由谁持有,以及功能完成后应进行哪些测试。
项目以桌面笔记工作区为主要运行形态。用户的 Markdown 笔记和附件保存在本地 Vault 中,桌面客户端负责编辑、文件管理和交互;Python AI Core 提供知识索引、RAG、Agent、Skill 和多模态处理能力;模型访问通过统一 Provider Adapter 接入;云同步作为独立能力按需部署。
开发过程中遵守以下基础约定:
1. Markdown 文件保存用户正文,是笔记内容的持久化载体。
2. SQLite 保存可重建的结构化索引、元数据、运行记录和应用状态。
3. Vue 前端不直接持有模型厂商协议,也不直接访问本地数据库。
4. Python AI Core 不直接处理桌面窗口、系统密钥和操作系统 UI。
5. Rust Host 统一处理桌面系统能力、Sidecar 生命周期和敏感资源访问。
6. RAG、Agent、Skill、Plugin、Provider 通过项目内部接口连接,业务代码不直接依赖某一家模型厂商或插件协议的数据结构。
7. Skill 使用已注册能力组织 AI 工作流;Plugin 可以向系统注册新的程序能力,两者分别维护 Manifest 和权限。
8. 客户端包含完整的本地业务与 AI 能力,用户无需部署服务器即可使用笔记、检索、RAG、Agent、Skill 和 Plugin。
9. Sync Server 作为独立基础设施提供多设备同步,可由用户自行部署,也可在后续提供托管实例。
10. 本地可重建索引不作为默认云同步对象,各设备根据自己的 Embedding 和检索配置重新构建索引。
---
## 2. 技术栈总览
| 层 | 技术选型 | 在项目中的用途 |
| --- | --- | --- |
| 桌面容器 | Tauri 2 + Rust | 桌面窗口、系统 API、本地文件访问、Sidecar 管理、安全边界 |
| 前端 | Vue 3 + TypeScript + Vite | 工作区、编辑器、AI 对话、搜索、设置、扩展管理等用户界面 |
| 状态管理 | Pinia | 管理工作区、编辑器、搜索、会话、Agent、Skill、主题与模型状态 |
| UI 基础 | 当前公共 Vue 组件 + Element Plus 图标 + Design Token;目标按需引入 Reka UI | 通用交互组件、无障碍交互和主题化能力 |
| Markdown 编辑器 | Milkdown + CodeMirror 6 | 可视化 Markdown 编辑与源码编辑 |
| 图表渲染 | Mermaid + 受控 SVG 输出 | Markdown 流程图、时序图等图表的预览与静态导出 |
| 函数图像 | `FunctionPlot` 结构化模型 + Renderer Adapter | 二维函数解析、交互预览与导出静态图 |
| 本地核心服务 | Python + FastAPI + Pydantic v2 | RAG、Agent、Skill、模型访问、多模态、索引和本地 API |
| Python 打包 | PyInstaller / Nuitka | 将 Python AI Core 打包为 Tauri Sidecar |
| 笔记存储 | Markdown + Assets | 保存用户正文和附件 |
| 元数据 | SQLite | 笔记元数据、Block、标签、会话、Trace、任务、索引状态 |
| 全文检索 | SQLite FTS5 | 关键词、标题、术语、标签等文本检索 |
| 向量检索 | sqlite-vec + VectorStore | 本地语义检索 |
| Embedding | 可插拔 EmbeddingProvider,默认本地 BGE-M3 类模型 | 为 Note Block 生成向量 |
| Reranker | BGE reranker 类 Cross-Encoder | 对候选检索结果进行精排 |
| Agent | 自研 Agent Runtime | 模型推理、工具选择、工具调用、结果回灌、运行控制 |
| Skill | 自研声明式 Skill Runtime | 复用提示词、工具集合、权限和检索配置 |
| Plugin | 自研 Plugin Runtime + Plugin Manifest + MCP Bridge | 扩展程序能力、Tool、外部服务集成和受控 UI Contribution |
| Theme | Theme Manifest + Design Token + 受限 CSS | 本地主题包导入、预览、启停与社区格式兼容 |
| LLM | 自研 Provider Adapter | 统一不同模型服务商的输入、输出、Streaming 与 Tool Calling |
| 模型协议 | OpenAI Responses / Chat Completions compatible / Anthropic Messages / Ollama | 用户自定义模型接入 |
| ASR | faster-whisper | 音频转写 |
| 说话人分离 | pyannote.audio | 课堂、会议等多人音频中的说话人区分 |
| 情感识别 | emotion2vec | 可选音频分析能力 |
| 文档导出 | Document AST + Exporter Adapter | Markdown 到 HTML、PDF、DOCX,并保留图表、公式和代码块 |
| 密钥存储 | 当前 Fernet 开发存储;目标 Tauri Stronghold | Web 联调期避免明文落盘,桌面集成后保存模型 API Key 和同步凭证 |
| 云同步 | 独立 Sync Server:FastAPI + PostgreSQL + S3/MinIO | 可选自托管,多设备 Vault 同步、版本管理和设备管理 |
| 测试 | pytest + Vitest + 版本化 RAG / Agent Dataset | 后端、前端组件、接口、检索质量、Agent 行为和模型适配器测试 |
表中的技术选型构成当前开发基线。新增依赖时需要明确其所属层、调用方、运行位置和替换成本,避免同一功能出现多套并行实现。
---
## 3. 系统运行架构
```mermaid
flowchart TB
subgraph Desktop["Tauri Desktop App"]
direction TB
subgraph Frontend["Vue 3 / TypeScript"]
direction LR
Workspace["Workspace"]
Editor["Markdown Editor"]
Chat["AI Chat"]
SearchUI["Search"]
TraceUI["Agent Trace"]
Settings["Settings"]
SkillUI["Skill UI"]
ThemeUI["Theme Manager"]
TaskUI["Task UI"]
end
IPC["Tauri IPC"]
subgraph Rust["Rust Host"]
direction LR
File["File Access"]
Secret["Secret Vault"]
Sidecar["Sidecar Manager"]
OS["OS API"]
Permission["Permission"]
Protocol["Window / Protocol"]
end
Frontend --> IPC
IPC --> Rust
end
Rust -->|"localhost / IPC"| API
subgraph AI["Python AI Core"]
direction TB
API["FastAPI / Local API"]
subgraph Core["Application Core"]
direction LR
Note["Note Core"]
RAG["RAG Engine"]
Agent["Agent Runtime"]
end
subgraph RetrievalLayer["Retrieval Pipeline"]
direction LR
Retrieval["Hybrid Retrieval"]
Reranker["Reranker"]
end
subgraph AgentLayer["Agent & Extension Layer"]
direction LR
Tools["Tool Registry"]
Skills["Skill Runtime"]
Plugins["Plugin Runtime"]
end
Provider["Provider Abstraction
OpenAI · Anthropic · Ollama · …"]
Multimodal["Multimodal Processing
Whisper · Pyannote · OCR · Emotion2Vec"]
API --> Note
API --> RAG
API --> Agent
API --> Skills
API --> Plugins
RAG --> Retrieval
Retrieval --> Reranker
Skills -->|"build configuration"| Agent
Agent --> RAG
Agent --> Tools
Plugins -->|"register tools"| Tools
Agent --> Provider
Multimodal --> Note
end
subgraph Storage["Local Knowledge & Storage"]
direction LR
Vault[("Markdown Vault")]
subgraph DB["SQLite"]
direction TB
Metadata["Metadata"]
FTS["FTS5"]
Vector["Vector Index"]
Trace["Agent Trace"]
end
end
Note <--> Vault
Note <--> Metadata
Retrieval --> FTS
Retrieval --> Vector
Agent --> Trace
```
系统运行时包含三个主要进程边界。
第一部分是 Tauri Desktop App。Vue 前端运行在 Tauri WebView 中,Rust Host 与前端通过 Tauri IPC 通信。文件系统、系统密钥、窗口管理、系统通知等能力由 Rust 暴露受控命令。
第二部分是 Python AI Core。桌面程序启动后由 Rust Host 拉起 AI Core Sidecar,Sidecar 在 `127.0.0.1` 的随机端口监听。Rust Host 为本次进程生成临时访问令牌,并将地址和令牌提供给前端 API Client。模型流式生成、Agent Trace 等长连接数据通过 SSE 或 WebSocket 传输。
第三部分是本地 Vault 和 SQLite。Vault 中的 Markdown 与 Assets 属于用户数据;SQLite 保存索引和应用状态。Note Core 负责维护两者之间的一致性。文件发生变化时,由文件监听机制通知 Note Core 执行增量解析和索引更新。
第四部分是可选 Sync Server。Sync Server 运行在用户自行部署或项目后续提供的服务器环境中,通过 HTTPS / WebSocket 与多个客户端通信。它负责身份、设备、Vault、文件版本、同步游标和对象存储,不承载桌面端的 RAG、Agent、Embedding、Reranker 或本地模型运行。未配置 Sync Server 时,客户端保持完整的本地工作能力。
---
## 4. 代码边界与依赖方向
项目中的功能按照以下五个核心域组织:
```text
Knowledge Core
Retrieval Core
Agent Core
Extension Core
Model Core
```
### 4.1 Knowledge Core
Knowledge Core 管理笔记本身,主要实体包括 `Note`、`NoteBlock`、`Tag`、`Link`、`Attachment` 和 `Task`。Markdown 解析、文件路径映射、Block 生成、标题路径、附件引用、标签和双向链接都属于该模块。
Knowledge Core 可以调用文件访问层和 SQLite Repository。它不负责调用大模型,不包含 Provider SDK,也不实现 Agent Loop。
### 4.2 Retrieval Core
Retrieval Core 负责从 Knowledge Core 已建立的索引中检索内容,包含 FTS5、Embedding、VectorStore、RRF、Reranker、Metadata Filter 和 Citation 组装。
Retrieval Core 接收结构化查询参数并返回 `SearchResult` 或 `RetrievedBlock`。调用方可以是搜索页面、RAG Engine 或 Agent Tool。该模块不直接向前端输出聊天文本。
### 4.3 Agent Core
Agent Core 管理一次 Agent Run 的状态和执行过程。它通过 Model Core 请求模型,通过 Tool Registry 调用系统能力,并将 Tool Result 回灌到下一轮模型请求。
Agent Core 负责步骤数、超时、Token Budget、取消、Trace 和权限检查。具体笔记查询通过 Tool Registry 调用 Knowledge Core 或 Retrieval Core。
### 4.4 Extension Core
Extension Core 管理 Skill、Plugin 和 Theme 三类扩展。
Skill Runtime 读取 Skill Manifest,将提示词、工具集合、权限声明、模型能力要求和检索配置转换为 Agent Configuration。Skill 复用项目已经存在的能力,本身不提供新的可执行程序能力。
Plugin Runtime 负责安装、启用、停用和卸载功能插件。Plugin 可以向 Tool Registry 注册新工具,也可以声明 Command、Importer、Exporter、Sidebar Panel 等 Contribution。需要运行后端逻辑的第三方 Plugin 通过独立 Plugin Host 或 MCP Bridge 与主程序通信,插件进程不直接加载进 Python AI Core。
Theme Runtime 由桌面前端处理,读取 Theme Manifest 和 CSS Design Token。Theme 只参与界面外观和允许开放的样式覆盖。
三类扩展之间允许组合使用。Plugin 提供的新 Tool 注册到 Tool Registry 后,Skill 可以在 Manifest 中声明使用这些 Tool,Agent Runtime 按正常权限流程完成调用。
### 4.5 Model Core
Model Core 负责模型服务访问。内部接口覆盖文本生成、流式事件、Tool Calling、模型能力、Embedding 和错误转换。
OpenAI、Anthropic、Ollama 等实现都位于 Provider Adapter 内部。Agent、Chat 和 Skill 只使用项目自己的 `ModelRequest`、`ModelEvent`、`ToolDefinition` 等类型。
### 4.6 依赖约定
依赖方向固定为:
```text
UI
↓
Application API
↓
Domain Service
↓
Repository / Adapter
↓
External Runtime
```
典型调用示例:
```text
AI Chat
→ /api/chat
→ RAG Engine
→ Retrieval Core
→ VectorStore / FTS5
→ Provider Adapter
```
```text
Agent
→ Tool Registry
→ notes.search
→ Retrieval Core
→ SQLite / VectorStore
```
```text
Skill
→ Skill Runtime
→ Agent Configuration
→ Agent Runtime
```
```text
Plugin
→ Plugin Runtime
→ Plugin Host / MCP Bridge
→ Register Tool / Command / Contribution
→ Tool Registry / Frontend Extension Slot
```
```text
Skill
→ Tool Binding
→ Plugin-provided Tool
→ Plugin Host
```
Provider Adapter、VectorStore、EmbeddingProvider、Plugin Host 等基础适配器由接口暴露能力,上层模块不引用具体实现类。
---
## 5. 桌面端技术说明
### 5.1 Tauri 2 与 Rust Host
Tauri 2 提供应用的桌面运行环境。Rust Host 主要处理需要操作系统权限或进程控制的能力,包括:
- Vault 目录选择和文件系统访问;
- 文件创建、移动、重命名、删除和监听;
- Stronghold 密钥读写;
- Python AI Core Sidecar 生命周期;
- 应用窗口和自定义协议;
- 系统通知、剪贴板和系统路径;
- 敏感能力授权。
前端需要读取文件时优先通过项目封装后的 Rust Command 或 Python API 获取,不在 Vue 组件中直接散布 Tauri 文件系统调用。文件编辑功能可以由一个统一的 `WorkspaceService` 封装,便于后续处理路径规范、文件锁、自动保存和错误提示。
Sidecar Manager 在应用启动时完成以下工作:
```text
确定 ai-core 可执行文件
→ 生成随机端口
→ 生成本地 Session Token
→ 启动 Sidecar
→ 轮询 /health
→ 建立 API Client
```
应用关闭时发送正常关闭信号,超时后再终止子进程。AI Core 异常退出时,Rust Host记录退出原因并允许用户重新启动 AI 服务,Markdown 编辑功能继续可用。
### 5.2 Vue 3 + TypeScript + Vite
Vue 3 负责全部用户交互界面。项目采用 Composition API 和 TypeScript,页面组件主要负责交互组织,业务请求通过 Service 层完成。
建议前端目录按照功能域组织:
```text
src/
├── features/
│ ├── workspace/
│ ├── editor/
│ ├── search/
│ ├── chat/
│ ├── agent/
│ ├── skills/
│ ├── themes/
│ ├── tasks/
│ └── settings/
├── components/
├── services/
├── stores/
├── contracts/
└── router/
```
`features` 保存面向功能的页面和组件;`services` 封装 Tauri IPC 与 Python API;`stores` 管理跨组件状态;`contracts` 保存前端使用的统一 DTO 类型。
### 5.3 Pinia
Pinia 只保存需要跨组件共享或跨页面持续存在的状态。编辑器内部临时状态尽量保留在组件或编辑器实例中,减少全局 Store 的更新频率。
建议保持以下 Store:
| Store | 主要状态 |
| --- | --- |
| `workspaceStore` | 当前 Vault、目录树、打开文件、文件监听状态 |
| `noteStore` | 笔记元数据、当前 Note、最近访问记录 |
| `editorStore` | 编辑模式、活动编辑器、保存状态 |
| `searchStore` | 查询条件、搜索结果、检索模式 |
| `chatStore` | 会话、消息、Streaming 状态 |
| `agentStore` | Agent Run、步骤、Tool Call、Trace |
| `skillStore` | 已安装 Skill、启用状态、运行参数 |
| `themeStore` | 当前主题、主题元数据 |
| `taskStore` | 笔记任务和 Agent 创建的任务 |
| `providerStore` | Provider 配置、模型列表、模型能力 |
| `settingsStore` | 应用级设置 |
Store 不直接访问数据库,也不直接拼接 OpenAI 或 Anthropic 请求体。
### 5.4 Reka UI 与 Design Token
Reka UI / Headless Components 提供 Dialog、Popover、Menu、Tabs、Select、Tooltip、Command Palette 等基础交互。视觉层使用项目自己的 Design Token。
所有需要被主题修改的视觉属性都通过 CSS Variables 暴露,例如:
```css
:root {
--background-primary: #ffffff;
--background-secondary: #f6f6f6;
--text-primary: #202020;
--text-secondary: #666666;
--accent-primary: #5b67f1;
--editor-font-family: system-ui;
--editor-font-size: 16px;
--radius-small: 4px;
--radius-medium: 8px;
--radius-large: 12px;
}
```
业务组件中优先引用 Design Token。主题包负责覆盖 Token 和允许开放的组件样式。主题加载器需要限制资源路径,避免主题 CSS 引用 Vault 外的任意本地文件。
### 5.5 Theme Package 与社区格式
第二阶段统一 Theme Package 的本地分发格式:
```text
my-theme/
├── theme.yaml
├── theme.css
├── preview.png
└── README.md
```
`theme.yaml` 至少声明 `id`、`name`、`version`、`author` 和 `min_app_version`。导入流程固定为 Manifest 校验、CSS 安全检查、隔离预览、安装、启用;停用或卸载后必须恢复内置 Design Token,不残留全局样式。
主题 CSS 只能使用开放的 Token 和宿主允许的稳定选择器,不允许脚本、远程资源、任意本地路径、`@import` 或覆盖安全相关界面。第二阶段只定义本地导入和社区包兼容格式,不把联网 Theme Marketplace 作为客户端依赖。
---
## 6. Markdown 编辑与知识结构
### 6.1 Milkdown 与 CodeMirror 6
Milkdown 负责日常所见即所得编辑,CodeMirror 6 提供 Markdown 源码模式和代码块增强能力。
两个编辑器共享同一份 Markdown 文本。模式切换时通过编辑器适配层读取当前内容、同步保存并初始化目标编辑器。自动保存经过统一 `EditorDocumentService`,避免两个编辑器分别实现文件写入。
### 6.2 Markdown 文件
一个 Vault 可以采用以下结构:
```text
Vault/
├── Notes/
│ ├── 数据结构/
│ │ └── 红黑树.md
│ └── 操作系统/
│ └── 死锁.md
├── Assets/
│ ├── Images/
│ ├── Audio/
│ └── Documents/
└── .ainote/
├── app.db
├── cache/
├── models/
├── skills/
├── themes/
└── logs/
```
`Notes` 和 `Assets` 属于用户可见数据。`.ainote` 保存应用生成的数据,可以通过重新索引恢复的内容不写入 Markdown 正文。
### 6.3 Note Block
RAG 和引用定位使用 Note Block 作为基础单位。Block 由 Markdown AST 生成,切分时保留标题层级。
一个 Block 至少包含:
```text
block_id
note_id
heading_path
start_offset
end_offset
content
content_hash
token_count
```
例如:
```text
heading_path = 数据结构 / 红黑树 / 删除操作 / Case 2
```
`block_id` 在同一内容未发生结构性变化时保持稳定。编辑后通过 `content_hash` 判断哪些 Block 需要重新建立全文和向量索引。
### 6.4 文件监听与增量索引
Rust Host 监听 Vault 中的创建、修改、移动、重命名和删除事件。变更事件经过 debounce 后提交给 Note Core。
笔记修改的数据流为:
```text
Save Markdown
→ File Change Event
→ Parse Markdown AST
→ Diff Note Blocks
→ Update Metadata
→ Update FTS5
→ Re-embed Changed Blocks
→ Update VectorStore
```
外部编辑器修改文件时也走相同流程。索引任务写入 `index_jobs`,前端可以展示待处理、处理中和失败状态。
### 6.5 Mermaid Code Block
Mermaid 使用标准 fenced code block 持久化,Markdown 文件仍是唯一正文来源:
````markdown
```mermaid
flowchart LR
A[Markdown] --> B[Renderer]
```
````
前端识别代码块后调用 Mermaid Renderer 生成 SVG。渲染必须支持亮暗主题、编辑后重新计算、错误占位、缩放查看和销毁旧实例。生成的 SVG 经过净化后才能插入 DOM;导出链路使用同一份 Mermaid 源码生成稳定的 SVG 或图片,不能抓取编辑器界面截图。
### 6.6 函数图像 Block
函数图像采用独立 fenced block,并在实现稳定后冻结语法:
````markdown
```function-plot
y = x^2
y = sin(x)
```
````
解析层将文本转换为与渲染库无关的 `FunctionPlot`,至少包含表达式、定义域、显示范围、坐标轴和渲染配置。表达式解析不得使用 `eval` 或执行任意 JavaScript。交互预览和导出共享同一数据模型;HTML 可以保留交互渲染,PDF/DOCX 使用 SVG 或栅格化静态图。
---
## 7. SQLite 与数据归属
SQLite 位于 `.ainote/app.db`,承担本地结构化数据和索引管理。
推荐至少维护以下表:
```text
notes
blocks
tags
note_tags
links
attachments
tasks
conversations
messages
agent_runs
tool_calls
skills
providers
index_jobs
sync_state
```
其中 `notes` 和 `blocks` 保存 Markdown 的结构化投影;FTS5 建立全文索引;sqlite-vec 保存 Block 向量;当前实现以 `agent_runs` 和 `agent_events` 保存 Agent Trace;Provider 表保存非敏感模型配置。
API Key、同步 Token 等机密数据不进入 SQLite,通过 `credential_id` 与 Stronghold 中的实际密钥关联。
数据库 Schema 使用迁移机制维护。Python 侧可以使用 SQLAlchemy + Alembic 管理表结构变更。每次修改 Schema 时提交对应 migration,禁止依赖运行时自动删表重建。
---
## 8. 本地 AI Core
### 8.1 FastAPI 服务
Python AI Core 负责所有 AI 和检索功能,以独立 Sidecar 运行。FastAPI 提供本地接口,Pydantic v2 定义请求、响应和内部 DTO。
建议 API 按业务域组织:
```text
/api/notes
/api/search
/api/chat
/api/agent
/api/skills
/api/providers
/api/tasks
/api/media
/api/index
```
普通 CRUD 使用 HTTP JSON。LLM Streaming 和 Agent 实时执行事件使用 SSE;需要双向控制的长任务可以采用 WebSocket。
每个请求包含本次桌面会话的本地 Token。AI Core 只监听 `127.0.0.1`。
### 8.2 Pydantic Contracts
API 和内部核心数据结构使用明确 Schema。重要 Contract 包括:
```text
Note
NoteBlock
SearchRequest
SearchResult
Citation
ModelRequest
ModelEvent
ModelCapability
ToolDefinition
ToolCall
ToolResult
SkillManifest
PluginManifest
PluginContribution
PluginStatus
AgentState
AgentRun
AgentEvent
ProviderConfig
```
接口字段变更需要同步更新前端 TypeScript Contract。Monorepo 中可以维护 OpenAPI 生成流程,自动生成部分 TypeScript API 类型,减少手工重复定义。
---
## 9. 检索与 RAG
### 9.1 检索目标
搜索功能需要同时覆盖精确术语和语义表达。课程名、函数名、代码标识符、专有名词适合 FTS5;自然语言问题和同义表达适合向量检索。
RAG Engine 使用以下处理链路:
```mermaid
flowchart LR
Q["User Query"] --> QA["Query Analyzer"]
QA --> F["FTS5 / BM25"]
QA --> V["Vector Search"]
F --> RRF["RRF Fusion"]
V --> RRF
RRF --> RR["Reranker"]
RR --> MF["Metadata Filter"]
MF --> CB["Context Builder"]
CB --> LLM["Provider Adapter"]
LLM --> AC["Answer + Citation"]
```
### 9.2 FTS5
FTS5 索引标题、Heading Path、Block 正文、标签和可检索附件文本。返回结果统一映射为 `RetrievedBlock`。
全文检索接口需要支持:
- query;
- folder / note / tag 范围;
- 时间范围;
- limit;
- offset;
- 返回命中片段。
### 9.3 VectorStore
向量实现通过 `VectorStore` 抽象:
```python
class VectorStore(Protocol):
async def upsert(self, records: list[VectorRecord]) -> None: ...
async def delete(self, ids: list[str]) -> None: ...
async def search(
self,
vector: list[float],
*,
top_k: int,
filters: VectorFilter | None = None,
) -> list[VectorHit]: ...
```
默认实现为 `SqliteVecStore`。RAG Engine 不读取 sqlite-vec 的内部表,不直接拼接 sqlite-vec 特有 SQL。
### 9.4 EmbeddingProvider
Embedding 通过统一接口调用:
```python
class EmbeddingProvider(Protocol):
async def embed_documents(self, texts: list[str]) -> list[list[float]]: ...
async def embed_query(self, query: str) -> list[float]: ...
```
目标默认配置使用本地 BGE-M3 类模型。当前第一阶段实现是 128 维 `HashEmbeddingProvider`,只用于离线跑通向量存储、索引更新和 Hybrid 链路,不代表真实语义召回质量。第二阶段接入真实 Embedding 时继续实现相同接口,上层 Retrieval Core 不依赖具体模型运行时。
索引记录需要保存 embedding model id、模型版本、向量维度和归一化方式。用户更换模型或任一索引兼容字段变化后,索引服务必须将旧向量标记为不可用并要求重建,禁止把不同模型生成的向量写入同一索引空间。
### 9.5 RRF 与 Reranker
FTS5 和 Vector Search 分别产生候选集合,经 RRF 进行排名融合。融合后的候选交给 BGE reranker 类 Cross-Encoder 进行精排。
初始参数可以采用:
```text
FTS5 Top 20
Vector Top 20
RRF Top 20
Reranker Top 8
Context Top 5~8
```
参数保留在 Retrieval Config 中,Benchmark 完成后再依据测试结果调整。
### 9.6 Citation
进入 Context Builder 的每个 Block都携带:
```text
note_id
block_id
file_path
heading_path
content
source_metadata
```
LLM 返回的引用映射回 `Citation`。前端点击引用后打开对应文件并定位 Block。
音频生成的笔记可以额外保存:
```text
source_audio
start_time
end_time
speaker
```
引用可以继续跳转至原始音频时间。
---
## 10. Agent Runtime
### 10.1 Agent 执行模型
Agent Runtime 维护一次任务的完整执行状态:
```mermaid
flowchart TB
U["User Request"] --> C["Build Agent Context"]
C --> M["Model Provider"]
M -->|Text| O["Final / Intermediate Output"]
M -->|Tool Call| P["Permission Check"]
P --> T["Tool Registry"]
T --> E["Execute Tool"]
E --> R["Tool Result"]
R --> M
```
AgentState 包含:
```text
run_id
messages
available_tools
current_skill
current_model
step
max_steps
token_budget
tool_results
citations
status
cancelled
```
每轮模型调用都可以产生文本、Thinking、Tool Call、Usage 和错误事件。Agent Runtime 将这些事件转换为统一 AgentEvent 推送给前端。
### 10.2 运行控制
Agent Run 至少提供以下限制:
- `max_steps`;
- 单 Tool 超时;
- 整体任务超时;
- 最大 Token Budget;
- 用户取消;
- 高风险 Tool 二次确认;
- 网络访问权限;
- 并发 Tool 数量。
Agent 运行过程中产生的每一步写入 `agent_runs` 和 `agent_events`,用户可以在 Agent Trace 中查看工具名称、参数摘要、耗时、执行结果和权限状态。SSE 与 Benchmark 均从同一事件事实读取,不维护旁路数据。
### 10.3 Tool Registry
Agent 可调用能力统一注册到 Tool Registry。
第一阶段工具集:
```text
notes.search
notes.read
notes.create
notes.update
notes.list
notes.move
rag.search
tasks.create
tasks.update
tasks.list
attachments.read
audio.transcribe
```
内部 Tool 定义采用统一结构:
```json
{
"name": "notes.search",
"description": "Search notes in current vault",
"parameters": {
"type": "object",
"properties": {
"query": {
"type": "string"
}
},
"required": ["query"]
}
}
```
Tool Executor 对参数再次进行 Pydantic 校验。文件修改类 Tool 调用 Knowledge Core,不允许 Tool 自行读取或修改 SQLite 表。
### 10.4 Agent Trace Contract
第二阶段的 Trace 不从前端临时状态反推,而由 Agent Runtime 产生可回放事件。一个 Trace 至少覆盖:
```text
Run Started / Completed / Failed / Cancelled
Model Call Started / Completed
Thinking / Text Delta
Tool Call / Tool Result
Permission Required / Resolved
Citation
Usage
Error
```
每个事件携带 `run_id`、单调递增的 `sequence`、时间戳和结构化 `data`。Tool 事件额外记录调用 ID、参数摘要、耗时、权限结果、输出摘要和错误;Provider 事件记录 Provider、模型、Usage 和耗时,但不得记录 API Key、完整敏感正文或未经净化的第三方响应。
前端先按 `run_id + sequence` 回放和去重,再构建 Trace Tree。Benchmark 复用同一事件流统计工具选择、步骤、延迟和 Token Usage,不另建一套只供测试使用的 Agent 执行协议。持久化层接入后,SSE 使用 `Last-Event-ID` 或等价游标恢复中断连接。
---
## 11. Skill Runtime
Skill 用于将一组稳定的 AI 使用方式保存为可复用配置。一个 Skill 可以携带提示词、允许使用的工具、权限声明、检索参数和输出要求。
建议目录结构:
```text
skills/
└── exam-review/
├── skill.yaml
├── prompt.md
├── README.md
└── icon.svg
```
`skill.yaml` 示例:
```yaml
id: exam-review
name: 期末复习助手
version: 1.0.0
description: 根据课程笔记生成复习内容和任务
permissions:
- notes.search
- notes.read
- tasks.create
tools:
- notes.search
- notes.read
- tasks.create
retrieval:
top_k: 10
rerank: true
citation: true
model:
required_capabilities:
- chat
- tool_calling
```
加载流程为:
```text
Read Manifest
→ Validate Schema
→ Resolve Permissions
→ Load Prompt
→ Resolve Tool Definitions
→ Apply Retrieval Config
→ Check Model Capabilities
→ Build Agent Configuration
```
Skill Runtime 返回 Agent Configuration,由 Agent Runtime 执行。Skill 自身不持有独立 Agent Loop。
安装 Skill 时展示权限。Skill 更新后新增权限需要重新确认。比赛版本中 Skill 不包含可执行 Python 或 JavaScript 文件。
Skill Manifest 中引用的 Tool 由 Tool Registry 解析。Tool 可以来自应用内置模块,也可以由已启用 Plugin 注册。Skill 安装时如果缺少所需 Plugin 或 Tool,Skill 状态标记为 `dependency_missing`,界面显示缺失依赖,不进入 Agent Run。
---
## 12. Plugin Runtime
Plugin 用于扩展应用原有代码没有提供的程序能力。典型用途包括接入第三方服务、增加 Agent Tool、增加导入导出格式、增加命令和提供受控的侧边栏面板。
### 12.1 Skill、Plugin 与 Theme 的职责
三类扩展在代码和权限上分别管理:
| 类型 | 主要作用 | 是否提供可执行能力 | 与 Agent 的关系 |
| --- | --- | --- | --- |
| Skill | 保存 AI 工作方法、Prompt、Tool 绑定、检索和模型配置 | 不直接提供 | 生成 Agent Configuration |
| Plugin | 提供新功能、Tool、外部服务适配和 UI Contribution | 可以提供 | 向 Tool Registry 注册能力 |
| Theme | 修改界面视觉和编辑器样式 | 不提供业务执行能力 | 无直接依赖 |
一个典型组合可以表示为:
```text
GitHub Plugin
→ 注册 github.search_issues Tool
→ Tool Registry
Issue Review Skill
→ 声明使用 github.search_issues
→ Skill Runtime
→ Agent Runtime
→ github.search_issues
→ GitHub Plugin
```
Plugin 为 Skill 和 Agent 提供能力来源,Skill 负责描述这些能力如何组合使用。
### 12.2 Plugin Package
Plugin 使用 Manifest 描述基本信息、入口、权限、依赖和 Contribution。
建议目录:
```text
plugins/
└── example-plugin/
├── plugin.yaml
├── README.md
├── icon.svg
├── backend/
│ └── ...
└── ui/
└── ...
```
`plugin.yaml` 示例:
```yaml
id: example-plugin
name: Example Plugin
version: 1.0.0
description: 提供示例外部服务能力
permissions:
- notes.read
- network.request
contributes:
tools:
- example.search
commands:
- example.open-panel
panels:
- example-panel
backend:
type: mcp
transport: stdio
```
Manifest 进入安装流程前使用 Pydantic Schema 校验。Plugin ID、版本和 Contribution ID 在本地 Plugin Registry 中保持唯一。
### 12.3 Plugin Contribution
Plugin Manifest 可以声明以下 Contribution:
```text
Tool
Command
Importer
Exporter
Sidebar Panel
Settings Section
```
其中 Tool 面向 Agent;Command 面向命令面板和快捷操作;Importer / Exporter 用于文件格式扩展;Sidebar Panel 和 Settings Section 为前端提供受控扩展位置。
第一阶段只落地声明式 Tool Contribution。第二阶段新增 Command 和 Settings Contribution:Command 由后端注册为稳定 ID、标题、参数和执行目标,前端只消费 Contribution Contract;Settings Schema 首批只允许 `string`、`number`、`boolean`、`select` 和 `secret reference`,由宿主动态生成表单。
Secret Setting 只保存 Credential ID,明文通过 Secret API 写入凭据存储,不进入 Manifest、Plugin Storage、Pinia 或 Agent Trace。Importer、Exporter 和 Sidebar Panel 保留现有 Manifest 扩展位,未完成宿主实现前不得标记为可用。
Contribution 由宿主应用决定挂载位置。Plugin 不直接修改应用路由、Pinia Store 或核心数据库 Schema。
### 12.4 Plugin Host
带后端执行逻辑的第三方 Plugin 运行在独立 Plugin Host 中。项目不将第三方 Python 模块直接 `import` 到 AI Core,也不将第三方动态库直接加载到 Rust Host。
运行关系:
```text
Plugin Runtime
↓
Read & Validate Manifest
↓
Resolve Permission
↓
Start Plugin Host
↓
Establish MCP / Internal RPC Channel
↓
Discover Contributions
↓
Register Tools / Commands
↓
Ready
```
Plugin Host 负责:
- 启动和关闭插件后端;
- 管理插件进程;
- 建立 MCP 或内部 RPC 通道;
- 转换 Tool Definition;
- 执行超时控制;
- 收集健康状态;
- 在插件崩溃时注销对应 Tool;
- 隔离插件日志。
内置 Plugin 可以使用相同的 Plugin Interface 注册能力,减少内置功能和社区扩展之间的接口差异。
Python 包形式的 MCP Server 推荐使用固定版本的 `uvx --isolated --from == ` 启动,以隔离依赖并避免污染 AI Core 环境;包内脚本和非 Python Server 仍可使用受控 `command + args`。`uvx` 的虚拟环境不是安全沙箱,不能限制文件、网络、子进程或系统调用。
面向社区或不可信 Plugin 开放前,Tauri/Rust Host 必须增加平台级沙箱、完整进程树回收、包来源/签名校验,并在首次安装或命令变化时向用户完整展示 executable 和参数、要求明确同意。当前 Python Host 的独立进程、环境裁剪和 Permission 只用于可信开发联调,不能替代这些生产安全门槛。
在该门槛完成前,后端仅允许 `APP_ENVIRONMENT=development` 启动未沙箱化 MCP Host;生产环境统一返回 `MCP_TRUST_APPROVAL_REQUIRED`。Python `uvx` Server 在开发模式首次运行可能联网解析依赖,生产版本必须在安装/更新阶段预取并验证固定版本,正常运行阶段只使用已经准备好的环境。
### 12.5 MCP Bridge
MCP Bridge 用于接入具有 MCP Server 接口的插件或外部工具服务。
当前已实现本地 stdio 首版:Plugin Runtime 在授权后的启用阶段启动独立 Server 进程,完成 `initialize`、capability negotiation、分页 `tools/list`、`tools/call`、取消、超时、异常退出和 Host Restart。实现接受 `2025-11-25`、`2025-06-18`、`2025-03-26` 与 `2024-11-05` 协议版本;Streamable HTTP、Resource、Prompt、Sampling 与操作系统级沙箱仍属于后续范围。
MCP Tool 进入系统后的调用路径为:
```text
MCP Server
↓
MCP Bridge
↓
Plugin Runtime
↓
Tool Registry
↓
Agent Runtime
```
Tool Registry 仍使用项目自己的 `ToolDefinition` 和 `ToolResult`。MCP Bridge 负责协议转换,Agent Runtime 不直接依赖 MCP 数据结构。
MCP 能力首先用于 Tool 和 Resource 类扩展。需要复杂 UI 的插件通过 Frontend Extension Slot 单独处理。
当前 stdio MCP Bridge 已覆盖以下协议边界:
```text
Server Process / Connection Lifecycle
initialize 与 capability negotiation
tools/list 与 ToolDefinition 映射
tools/call 与 ToolResult 映射
超时、取消和进程退出
协议错误与业务错误转换
健康检查与 Tool 注销
```
首个宿主实现支持本地 `stdio` 传输;其他传输在兼容性测试后增加。外部 Server 的 Tool 名称进入项目注册表前添加 Plugin 命名空间,并校验 JSON Schema、权限、重复 ID 及其与 Manifest Contribution 的一致性。MCP 调用复用项目自己的 Permission、超时、Agent Trace、日志净化和结果大小限制;子进程环境按白名单裁剪,不传入 Provider Key、Vault 或数据库路径。
### 12.6 Frontend Extension Slot
前端预留受控扩展点:
```text
Command Palette
Toolbar Action
Sidebar Panel
Settings Section
Context Menu
```
Plugin UI 不能直接访问 Rust Command、Stronghold、Pinia 内部状态和任意本地文件。宿主通过 Plugin Bridge 提供允许的 API,例如:
```text
workspace.getCurrentNote
notes.read
commands.execute
events.subscribe
pluginStorage.get
pluginStorage.set
```
需要使用敏感能力时仍进入统一 Permission 流程。
比赛版本可以优先实现 Command、Tool、Settings Section 和简单 Sidebar Panel,复杂前端插件 API 在接口稳定后继续扩展。
### 12.7 Plugin 生命周期
Plugin 状态至少包括:
```text
installed
disabled
starting
ready
error
dependency_missing
permission_required
```
完整生命周期:
```text
Install
→ Validate Manifest
→ Resolve Dependencies
→ Request Permissions
→ Register Metadata
→ Enable
→ Start Host
→ Register Contributions
→ Ready
```
停用 Plugin 时先从 Tool Registry 和前端 Extension Registry 注销 Contribution,再关闭 Plugin Host。
卸载前检查是否存在启用中的 Skill 依赖该 Plugin。存在依赖时向用户显示受影响 Skill。
### 12.8 Plugin Storage
每个 Plugin 获得独立的配置和数据命名空间:
```text
.ainote/
└── plugins/
└── /
├── config.json
├── data/
└── logs/
```
Plugin Storage API 负责访问该目录。插件不能通过自身目录拼接相对路径访问其他插件数据或 Stronghold。
需要保存密钥的 Plugin 通过 Secret API 请求独立 Credential ID,由 Stronghold 保存实际值。
第二阶段 Plugin 安装记录、启停状态、授权、配置 Schema 版本和 Contribution 元数据需要持久化。应用启动时先恢复元数据,再启动已启用的 Host;恢复失败的 Plugin 保持隔离并标记为 `error`,不能留下已注册但没有可用执行后端的 Tool 或 Command。
---
## 13. Provider Adapter 与模型接入
### 13.1 统一模型协议
项目内部统一使用 `ModelRequest` 和 `ModelEvent`。Provider Adapter 负责和实际模型协议转换。
```text
Chat / Agent / Skill
↓
ModelRequest
↓
Provider Adapter
↓
OpenAI / Anthropic / Ollama / Compatible API
↓
Provider Response
↓
ModelEvent
```
首批 Adapter:
```text
OpenAIResponsesProvider
OpenAIChatCompletionsProvider
OpenAICompatibleProvider
AnthropicMessagesProvider
OllamaProvider
```
### 13.2 ModelRequest
建议统一字段:
```text
provider_id
model
system
messages
tools
temperature
max_tokens
response_format
attachments
metadata
```
Provider 只转换自己支持的字段。模型能力通过 Capability 描述:
```text
chat
vision
tool_calling
reasoning
streaming
structured_output
embedding
```
Skill 或 Agent 启动前可以根据 Capability 检查当前模型是否满足任务要求。
### 13.3 Streaming
所有 Provider 的流式响应映射为:
```text
TextDelta
ThinkingDelta
ToolCallStart
ToolCallDelta
ToolCallEnd
Usage
Error
Done
```
前端 Streaming UI 只认识这些事件类型。
第二阶段 Provider 兼容性不以 Adapter 数量为目标,而以同一组行为测试为准:普通对话、Streaming、Tool Calling、Reasoning Event、取消、Usage 和错误映射。优先验证 OpenAI Responses、OpenAI Chat Completions、OpenAI-Compatible、Anthropic Messages 与 Ollama;不支持的 Capability 必须在请求前拒绝,不能静默丢弃 Tool 或附件。
### 13.4 Provider 配置与 API Key
目标桌面架构将普通 Provider 配置保存在 SQLite。当前 Web 联调版由内存 `ProviderRegistry` 持有,AI Core 重启后清空:
```text
provider_id
provider_type
base_url
default_model
credential_id
enabled
```
当前开发版使用 Fernet 加密文件保存 `credential_id` 对应的实际 API Key,并允许环境变量回退;Tauri 集成后由 Stronghold 替换该存储实现。
设置页面执行“测试连接”时:
```text
读取 Provider Config
→ Credential Resolver 按 ID 读取开发密文或环境变量
→ AI Core 调用 Provider
→ 返回连接测试结果
```
当前设置页已经提供 OpenAI、DeepSeek 与 Ollama 预设,保存后通过 `/api/providers/{provider_id}/models` 自动发现模型。Credential API 只返回配置状态,不提供任何明文读取接口。
日志中不记录完整 API Key。请求异常信息在进入前端前过滤 Authorization Header 和密钥片段。
---
## 14. 多模态处理
### 14.1 音频处理
课堂或会议音频进入 Media Pipeline:
```mermaid
flowchart LR
A["Audio"] --> D["pyannote.audio"]
D --> S["Speaker Segments"]
S --> W["faster-whisper"]
W --> T["Timestamped Transcript"]
T --> C["Content Structuring"]
C --> M["Markdown Note"]
M --> I["Index Pipeline"]
```
pyannote.audio 生成说话人区间;faster-whisper 对各区间进行转写。最终 Transcript 至少包含:
```text
speaker
start_time
end_time
text
```
内容结构化模块将 Transcript 整理为 Markdown,同时保留音频时间信息,后续 RAG 引用可以跳回音频片段。
音频管线使用后台 Job,不在 HTTP 请求中长时间同步阻塞。转写结果统一为:
```text
job_id
attachment_id
language
segments[]
speaker
start_time
end_time
text
status
error
```
`pyannote.audio` 和 `faster-whisper` 通过独立 Adapter 加载,模型下载、设备选择、精度、批量大小和缓存目录由配置管理。缺少说话人模型时可以只返回时间戳转写,但必须明确标记 diarization 不可用;模型失败不能生成伪造的 completed 结果。
### 14.2 OCR
OCR 作为 Media Pipeline 的输入适配能力,用于图片笔记、白板照片、PPT 截图和扫描资料。OCR 输出进入附件文本索引,也可以由用户选择生成 Markdown。
OCR 引擎在当前技术栈中尚未固定,调用接口先定义为 `OCRProvider`,具体实现完成 PoC 后确定。
### 14.3 emotion2vec
emotion2vec 作为音频扩展分析模块。输出可以附加到音频段元数据,不参与核心 RAG 索引和 Agent 启动流程。
### 14.4 Document AST 与多格式导出
第二阶段建立统一导出链路:
```text
Markdown
→ Markdown AST
→ Document AST
→ DocumentExporter
├── HtmlExporter
├── PdfExporter
└── DocxExporter
```
`Document AST` 是导出器共享的中间表示,覆盖标题、段落、列表、表格、图片、引用、代码块、数学公式、Mermaid 和函数图像。Exporter 不直接解析编辑器 DOM,避免不同界面状态产生不同输出。
统一接口返回文件、MIME、警告和失败节点:
```python
class DocumentExporter(Protocol):
async def export(
self,
document: Document,
options: ExportOptions,
) -> ExportResult: ...
```
HTML 导出保留结构化语义和受控样式;PDF 与 DOCX 在不支持交互内容时使用静态 SVG 或图片。具体底层库在 PoC 后冻结,但必须封装在 Exporter Adapter 内,不允许导出库的数据结构渗透到 Knowledge Core。
### 14.5 可视化内容的统一静态输出
Mermaid Renderer 和 Function Plot Renderer 除前端预览外,都必须提供可重复的静态输出接口。导出器只消费 SVG、PNG 或带尺寸信息的资源引用,不调用 Vue 组件。渲染结果按源码 Hash、主题和渲染器版本缓存;源码、主题或版本变化时缓存失效。
---
## 15. 安全与权限
### 15.1 敏感信息
模型 API Key、同步 Token 和其他凭证统一存放在 Stronghold。以下位置不保存明文密钥:
```text
Markdown
SQLite
普通 JSON / YAML
前端 Pinia 持久化
应用日志
Agent Trace
```
### 15.2 Tool 权限
Tool Permission 使用命名空间形式:
```text
notes.read
notes.search
notes.write
notes.delete
tasks.read
tasks.write
attachments.read
network.request
```
读操作可以按 Skill 授权持续生效。删除文件、外部网络请求等高影响能力可以配置为每次确认。
### 15.3 Plugin 权限与隔离
Plugin Manifest 必须声明所需权限。插件安装、启用和权限升级时,由宿主应用展示权限范围并记录用户授权结果。
Plugin 与 Tool 复用统一权限命名空间,第一阶段包含:
```text
notes.read
notes.search
notes.write
notes.delete
tasks.read
tasks.write
attachments.read
network.request
secrets.use
ui.command
ui.settings
ui.sidebar
```
Plugin 后端运行在独立 Plugin Host 中,通过 MCP Bridge 或内部 RPC 使用宿主提供的能力。第三方 Plugin 不直接获得 SQLite 文件路径、Stronghold 主密钥、Rust Host 内部对象或其他 Plugin 的数据目录。
Plugin 向 Tool Registry 注册工具后,Agent 调用该工具仍经过 Tool Permission。Skill 引用 Plugin Tool 时,需要同时满足 Skill 声明的权限、Plugin 自身获得的权限以及当前用户对高影响操作的确认策略。
第三方 Plugin 崩溃时,Plugin Runtime 将状态更新为 `error`,注销对应 Tool、Command 和 UI Contribution,并向正在执行的 Agent 返回 `PLUGIN_UNAVAILABLE`。其他 Plugin、AI Core 和 Markdown 编辑功能继续运行。
Plugin 需要使用 API Key 等敏感数据时,通过 Secret API 创建独立 `credential_id`。Plugin 只能请求使用属于自身命名空间的凭证,实际明文继续由 Stronghold 保存。
### 15.4 RAG 上下文
Agent Context 明确区分:
```text
System Instruction
Skill Instruction
User Instruction
Retrieved Context
Tool Result
```
Retrieved Context 保存笔记内容和检索来源。Tool Registry 的权限来源于 Agent Configuration 和用户授权,不从检索文本中解析权限要求。
---
## 16. 云同步与多设备互联
### 16.1 架构定位
项目采用本地优先的厚客户端结构。Tauri Desktop App、Rust Host 和 Python AI Core 共同组成完整客户端,笔记编辑、Markdown 文件管理、SQLite 元数据、FTS5、向量索引、RAG、Agent、Skill、Plugin、模型接入和多模态处理都可以在用户设备上运行。
Sync Server 是一项独立部署的基础设施,用于在多个客户端之间同步 Vault 数据。用户没有服务器时可以直接使用本地模式;用户拥有 NAS、VPS、实验室服务器或其他可运行 Docker 的环境时,可以部署自己的 Sync Server 并连接多个客户端。
```mermaid
flowchart TB
subgraph Server["Optional Self-hosted Sync Server"]
direction TB
SyncAPI["Sync API / WebSocket"]
Auth["Auth & Device"]
VaultSvc["Vault & Revision"]
Push["Change Notification"]
PG[("PostgreSQL")]
OBJ[("S3 / MinIO")]
SyncAPI --> Auth
SyncAPI --> VaultSvc
SyncAPI --> Push
VaultSvc --> PG
VaultSvc --> OBJ
end
subgraph A["Desktop Client A"]
direction TB
AUI["Vue + Tauri"]
ACore["Python AI Core"]
AVault[("Markdown Vault")]
ADB[("SQLite / FTS5 / Vector")]
AUI --> ACore
ACore --> AVault
ACore --> ADB
end
subgraph B["Desktop Client B"]
direction TB
BUI["Vue + Tauri"]
BCore["Python AI Core"]
BVault[("Markdown Vault")]
BDB[("SQLite / FTS5 / Vector")]
BUI --> BCore
BCore --> BVault
BCore --> BDB
end
A <-->|"HTTPS / WebSocket"| Server
B <-->|"HTTPS / WebSocket"| Server
```
每台设备维护自己的 Markdown Vault、SQLite、FTS5 和 Vector Index。服务器保存同步需要的远程版本和文件对象。设备拉取远程变化后,本地 Note Core 触发增量索引。
该架构支持三种运行方式:
| 模式 | 是否需要账号 | 是否需要用户服务器 | 主要能力 |
| --- | --- | --- | --- |
| 本地模式 | 否 | 否 | 单设备完整笔记与 AI 功能 |
| 自托管同步 | 是,由自建 Server 管理 | 是 | 多设备同步、版本记录、设备管理 |
| 托管同步 | 是 | 否 | 后续可提供的官方托管实例,使用相同 Sync Protocol |
客户端和 Sync Server 使用同一套同步协议。自托管与托管模式只改变服务器部署位置,不改变本地 Vault 和客户端核心业务结构。
### 16.2 Sync Server 的职责
Sync Server 处理跨设备数据协调。服务端主要模块包括:
```text
Authentication
Device Management
Vault Management
Sync Coordinator
Revision History
Conflict Detection
Change Notification
Object Storage
```
`Authentication` 管理用户登录和访问令牌。`Device Management` 记录已授权设备和设备状态。`Vault Management` 管理远程 Vault 和成员关系。`Sync Coordinator` 接收客户端变更并计算需要拉取的 Revision。`Revision History` 保存文件版本。`Change Notification` 通过 WebSocket 或长连接通知在线设备存在新的远程变更。大文件和附件由 S3 / MinIO 保存。
服务器不运行以下客户端计算模块:
```text
RAG Engine
Embedding
Reranker
FTS5
Vector Index
Agent Runtime
Skill Runtime
本地 LLM
ASR 模型
```
这些模块依赖本地设备的模型选择和计算环境。各设备可以采用不同的 Embedding Provider、模型和计算配置。
### 16.3 服务端存储
PostgreSQL 保存同步控制数据,例如:
```text
users
devices
vaults
vault_members
files
file_revisions
sync_cursors
sessions
```
文件记录可以包含:
```text
file_id
vault_id
path
revision
content_hash
size
updated_at
updated_by_device
object_key
```
Markdown、图片、音频、PDF 和其他附件对象保存在 S3 / MinIO。
服务端数据关系可以简化为:
```text
User
├── Device
└── Vault
├── Member
├── File
│ └── Revision
└── Asset
```
客户端使用稳定 `file_id` 识别同步对象。文件路径发生移动或重命名时继续沿用原 `file_id`。
### 16.4 同步范围
默认同步:
```text
Markdown
Assets
Task 数据
用户创建的 Skill
Skill 配置
Theme 配置
基础 Workspace 配置
```
可选同步:
```text
AI Conversation
Agent History
Plugin 安装清单
Theme 安装清单
Workspace Layout
部分应用设置
```
默认不同步:
```text
FTS5 Index
Vector Index
Embedding
RAG Cache
模型 Cache
临时文件
Agent 中间运行状态
本地日志
设备级性能配置
```
例如 Client A 使用本地 BGE-M3,Client B 使用另一种 Embedding Provider。服务器只同步 Markdown。Client B 收到文件后按照自己的 Embedding 配置生成向量,并写入本机 VectorStore。
### 16.5 多设备同步流程
客户端文件保存后先完成本地写入,再异步提交同步任务:
```text
Local Markdown Save
→ Local Revision Record
→ Sync Queue
→ Upload Metadata
→ Upload Changed Object
→ Commit Remote Revision
→ Notify Other Devices
```
另一设备收到远程变化后:
```text
Remote Change Notification
→ Pull Revision Metadata
→ Download Changed Object
→ Validate Hash
→ Update Local Vault
→ File Change Event
→ Note Core
→ Incremental Reindex
```
同步失败不会回滚已经成功保存的本地 Markdown。失败任务留在 Sync Queue 中等待网络恢复或用户手动重试。
### 16.6 Revision 与冲突检测
文件同步携带客户端修改基于的版本号,避免使用修改时间直接覆盖远程内容。
上传请求至少包含:
```json
{
"file_id": "file_xxx",
"base_revision": 10,
"content_hash": "sha256:...",
"device_id": "device_xxx"
}
```
当服务器当前 Revision 与 `base_revision` 一致时,可以接受客户端提交并生成下一 Revision。
```text
Client base_revision = 10
Server revision = 10
→ Commit revision 11
```
当服务器已经存在其他设备提交的新 Revision 时,服务端返回冲突:
```text
Client base_revision = 10
Server revision = 11
→ Conflict
```
客户端保留本地版本和远程版本,并提供:
```text
保留本地版本
保留远程版本
比较差异
手动合并
```
无法自动处理的冲突可以生成单独的冲突文件,例如:
```text
死锁 (conflict-Laptop-20260826).md
```
第一阶段同步采用文件级 Revision 和冲突检测。实时多人协同编辑涉及操作级合并,可在后续版本评估 Yjs、Automerge 或其他 CRDT 方案。
### 16.7 Skill、Plugin 与 Theme 的跨设备处理
Skill 主要由 Manifest、Prompt 和配置组成,可以作为 Vault 配置的一部分同步。另一设备拉取后由 Skill Runtime 重新校验 Manifest、权限和 Tool 依赖。
Plugin 包含可执行能力,跨设备同步只同步安装清单和版本信息,例如:
```json
{
"plugin_id": "github-integration",
"version": "1.3.2"
}
```
另一设备缺少该 Plugin 时显示依赖提示,由用户确认安装。Plugin 二进制或可执行代码不通过普通 Vault 同步直接复制到其他设备。
Theme 可以同步启用配置和主题清单。自定义主题文件是否同步由用户配置。
### 16.8 Provider 与密钥的跨设备处理
普通 Provider 配置可以选择同步,例如:
```text
provider_type
base_url
default_model
model_preferences
```
API Key、同步 Token 和 Plugin Credential 不进入普通 Vault 同步。每台设备通过 Tauri Stronghold 保存自己的密钥。
后续如需跨设备同步凭证,应设计独立的端到端加密 Credential Vault,并包含新设备授权、密钥恢复和密钥轮换机制。
### 16.9 自托管部署
Sync Server 提供 Docker Compose 作为标准部署方式。基础部署包含:
```text
Sync API
PostgreSQL
MinIO
```
示意结构:
```yaml
services:
sync-server:
image: project/sync-server
depends_on:
- postgres
- minio
postgres:
image: postgres
minio:
image: minio/minio
```
用户部署完成后在客户端填写:
```text
Server URL
Username
Password / Token
```
客户端完成登录、设备注册和 Vault 绑定后启动同步。
生产部署需要配置 HTTPS。对象存储、数据库备份、域名、反向代理和邮件服务等属于部署层配置。
### 16.10 与 Typora、Obsidian 的同步能力区分
项目在 Markdown 本地存储理念上与 Typora、Obsidian 存在相似基础,主要差异集中在同步服务和 AI 运行架构。
#### Typora
Typora 官方文档说明其工作内容保存为本地 Markdown 纯文本文件,跨设备同步可以使用 iCloud Drive、Google Drive、OneDrive、Dropbox 等第三方同步工具。当前 Typora 官方同步文档没有提供由 Typora 自身运行的多设备 Sync Server。
本项目同样直接保存 Markdown 文件,并将多设备同步协议和 Sync Server 纳入项目自身架构。用户无需把 Vault 放入第三方云盘目录即可使用应用内版本同步、设备管理和冲突检测。
#### Obsidian
Obsidian 以本地 Vault 为基础,离线时仍可访问笔记。其官方文档列出了 Obsidian Sync、iCloud、OneDrive、Google Drive、Syncthing 和 Git 等多种同步方式。
Obsidian Sync 是官方提供的附加订阅服务。按照 2026 年 8 月的官方页面,Sync Standard 按年付费折算为每用户每月 4 美元,Sync Plus 按年付费折算为每用户每月 8 美元。官方 Sync 提供远程 Vault、端到端加密、版本历史、共享 Vault 和跨设备同步。Obsidian Headless 同样连接 Obsidian Sync 服务,并要求有效的 Sync 订阅。
本项目把可自托管的 Sync Server 纳入正式技术架构。用户可以在自己的 VPS、NAS、实验室服务器或私有云中部署同一套 Sync Server。客户端使用统一 Sync Protocol 连接自托管实例;后续如提供项目托管实例,也继续使用相同协议。
#### 技术差异汇总
| 项目 | 本地 Markdown | 离线使用 | 官方应用内同步方案 | 官方同步付费要求 | 项目自身提供自托管 Sync Server | AI / RAG 本地运行 |
| --- | --- | --- | --- | --- | --- | --- |
| Typora | 支持 | 支持 | 当前官方文档主要引导第三方文件同步 | 取决于第三方服务 | 当前官方文档未提供 | 不属于其核心同步架构 |
| Obsidian | 支持 | 支持 | Obsidian Sync,同时支持多种第三方同步方式 | Obsidian Sync 需要订阅 | 当前官方文档未提供 Obsidian Sync 服务端自托管方案 | 可通过插件或其他方案扩展 |
| 本项目 | 支持 | 支持 | 内置 Sync Client + Sync Protocol | 自托管不需要项目方 Sync 订阅 | 支持,作为正式架构组成部分 | RAG、Agent、Skill、Plugin 和索引位于客户端 |
这组差异体现部署控制权和本地 AI 架构。项目不将 `Local-first` 作为独有特性;Typora 和 Obsidian 都采用本地文件工作方式。项目的同步定位为:
```text
完整本地客户端
+
官方定义的 Sync Protocol
+
可选自托管 Sync Server
+
多设备增量同步
```
### 16.11 后续安全扩展
同步协议后续可以加入端到端加密模式。客户端在上传前完成内容加密,服务器保存密文对象和必要的同步元数据。
```text
Markdown / Asset
→ Client Encryption
→ Encrypted Object
→ Sync Server
→ S3 / MinIO
```
端到端加密设计需要覆盖 Vault Key、密钥派生、新设备授权、恢复机制和密钥轮换。该功能在基础 Revision、冲突处理和多设备同步稳定后单独设计。
### 16.12 官方资料依据
本文对 Typora 和 Obsidian 的比较基于 2026 年 8 月可访问的官方资料:
- Typora Support — Work with Mobile and other Devices: https://support.typora.io/Sync/
- Obsidian Help — Sync your notes across devices: https://obsidian.md/help/sync-notes
- Obsidian Help — Introduction to Obsidian Sync: https://obsidian.md/help/sync
- Obsidian Help — Plans and storage limits: https://obsidian.md/help/sync/plans
- Obsidian Help — Headless Sync: https://obsidian.md/help/sync/headless
---
## 17. 本地接口约定
### 17.1 API 结构
FastAPI 接口按业务资源组织。示例:
```text
GET /api/notes/{note_id}
POST /api/search
POST /api/chat
POST /api/agent/runs
POST /api/agent/runs/{run_id}/cancel
GET /api/agent/runs/{run_id}/events
GET /api/skills
GET /api/plugins
POST /api/plugins/install
POST /api/plugins/{plugin_id}/enable
POST /api/plugins/{plugin_id}/disable
POST /api/providers/test
POST /api/index/rebuild
GET /health
```
第一阶段已实现路径和第二阶段冻结草案分别见 `../contracts/后端接口契约-开发版.md` 与 `../contracts/第二阶段接口契约-开发版.md`。规划接口完成前不得在前端假定其可用;完成后以 OpenAPI、Pydantic Contract 和 TypeScript Wire DTO 的一致结果为准。
HTTP 返回统一错误结构:
```json
{
"error": {
"code": "PROVIDER_TIMEOUT",
"message": "Model provider request timed out",
"details": {}
}
}
```
错误代码由项目定义,前端根据 `code` 决定提示和恢复操作,不解析第三方 SDK 的异常文本来判断业务逻辑。
### 17.2 ID
数据库主实体使用应用生成的稳定 ID。文件路径可以修改,不能作为 Note、Block、Agent Run 等对象的唯一业务 ID。
推荐实体:
```text
note_id
block_id
attachment_id
conversation_id
message_id
run_id
tool_call_id
skill_id
plugin_id
provider_id
```
### 17.3 时间
内部 API 使用 UTC ISO 8601 时间。前端根据用户系统时区显示。
### 17.4 日志
日志按模块记录:
```text
desktop.log
ai-core.log
index.log
agent.log
sync.log
```
日志包含 request_id / run_id 等关联字段。日志不得写入完整正文、API Key 和未经用户允许的文件内容。
---
## 18. 工程组织
项目采用 Monorepo:
```text
ainote/
├── apps/
│ └── desktop/
│ ├── src/
│ └── src-tauri/
│
├── services/
│ └── ai-core/
│ ├── app/
│ │ ├── api/
│ │ ├── notes/
│ │ ├── rag/
│ │ ├── agent/
│ │ ├── skills/
│ │ ├── providers/
│ │ ├── media/
│ │ ├── extensions/
│ │ ├── export/
│ │ └── database/
│ └── tests/
│
├── packages/
│ ├── contracts/
│ ├── ui/
│ ├── plugin-sdk/
│ └── theme-sdk/
│
├── skills/
│ └── builtin/
│
├── plugins/
│ └── builtin/
│
├── themes/
│ └── builtin/
│
├── benchmarks/
│ ├── rag/
│ │ ├── datasets/
│ │ └── reports/
│ └── agent/
│ ├── datasets/
│ └── reports/
│
├── infra/
│ └── cloud/
│
└── docs/
```
目录和功能归属按以下规则执行:
- 桌面页面和交互位于 `apps/desktop/src/features`。
- Rust Command、Sidecar、Stronghold、文件监听位于 `apps/desktop/src-tauri`。
- Python API Endpoint 位于 `services/ai-core/app/api`。
- 核心业务逻辑位于对应 domain 目录,不直接写在 Router 中。
- 数据库访问集中在 database/repository 层。
- Provider SDK 只出现在 `providers`。
- VectorStore 具体实现只出现在 Retrieval 基础设施层。
- 内置 Skill 放在 `skills/builtin`,不硬编码在 Agent Runtime。
- Plugin Runtime、Plugin Host 和 MCP Bridge 位于 Extension Core,对第三方插件暴露的稳定接口放在 `packages/plugin-sdk`。
- Mermaid 与函数图像的 Markdown 源码解析归编辑/文档模型,交互渲染归前端 Renderer,静态渲染契约由 Export Service 复用。
- Document AST 和 Exporter Adapter 位于 Export Service,导出器不得读取 Vue 组件 DOM 或 Provider 内部状态。
- 内置 Plugin 放在 `plugins/builtin`,通过与第三方 Plugin 相同的 Contribution 接口注册。
- Benchmark 数据和运行脚本放在 `benchmarks`。
---
## 19. 开发环境与启动方式
### 19.1 基础环境
当前 Web 联调开发机需要准备:
```text
Node.js 22+
pnpm 10+
Python 3.11+
uv
SQLite
Git
```
Rust Toolchain 与 Tauri CLI 只在桌面容器阶段安装。当前轻量 Embedding/Reranker 不要求 CUDA;接入 faster-whisper、pyannote.audio 或真实本地模型时再按所选运行时增加 CPU/GPU 依赖。
### 19.2 本地开发
当前开发模式下分别启动 FastAPI 和 Vite:
```text
Terminal A
cd backend
uv run uvicorn app.main:app --reload --host 127.0.0.1 --port 8000
Terminal B
cd frontend
pnpm dev
```
Vite 将 `/api` 与 `/health` 代理到固定开发端口。正式桌面构建时改为 Tauri Sidecar 随机端口和临时访问令牌模式。
### 19.3 配置
环境配置分为:
```text
development
test
production
```
模型 API Key 不放入仓库 `.env` 示例。`.env.example` 只包含无敏感值的配置字段说明。
---
## 20. 测试基线
### 20.1 单元与接口测试
Python 使用 pytest。重点覆盖:
- Markdown Parser;
- Note Block diff;
- FTS Query;
- VectorStore;
- RRF;
- Citation;
- Tool 参数校验;
- Agent step limit;
- Skill Manifest;
- Plugin Manifest;
- Plugin Lifecycle;
- Plugin Tool Registration;
- MCP 生命周期、Tool 映射、取消与异常退出;
- Provider Adapter;
- 权限判断;
- API 错误转换。
前端测试重点覆盖 Store、Service 和关键交互流程。Rust 侧覆盖路径处理、Sidecar 启停和 Secret 访问封装。
第二阶段还需要增加 Theme Manifest/CSS 安全校验、Mermaid 错误与主题切换、Function Plot 表达式拒绝策略、Document AST 快照和 HTML/PDF/DOCX 导出回归测试。多模态测试使用小型固定音频 Fixture,模型级测试与不下载模型的快速单元测试分组执行。
### 20.2 RAG Benchmark
RAG Dataset 结构:
```text
query
expected_note_id
expected_block_id
expected_citation
tags
```
至少比较:
```text
FTS5
Vector
Hybrid
Hybrid + Reranker
```
核心指标:
```text
Hit@1
Hit@5
Recall@K
MRR
Citation Hit Rate
P50 Latency
P95 Latency
```
Benchmark 参数、Embedding 模型、Reranker、数据集版本和运行环境需要一起记录,保证不同实验结果可以复现。
### 20.3 Agent Benchmark
Agent Dataset 保存任务目标、允许工具、期望工具序列和结果条件。
核心指标:
```text
Task Success Rate
Tool Selection Accuracy
Tool Argument Accuracy
Invalid Tool Call Rate
Average Steps
Average Latency
Token Usage
```
Agent Benchmark 同时记录模型 Provider、模型版本、Skill、可用工具集合、运行配置和 Dataset 版本。指标直接从 Agent Trace Contract 计算,测试框架不得绕过权限或使用另一套 Tool 执行器。
---
## 21. 主要功能的数据流
### 21.1 编辑笔记
```text
User
→ Milkdown / CodeMirror
→ EditorDocumentService
→ Rust File Access
→ Markdown File
→ File Watch Event
→ Note Core
→ Block Diff
→ SQLite / FTS5 / Vector Index
```
### 21.2 搜索笔记
```text
Search UI
→ /api/search
→ Retrieval Core
→ FTS5 / VectorStore
→ Result Fusion
→ SearchResult
→ Frontend
→ Open & Highlight Note Block
```
### 21.3 AI 知识库问答
```text
AI Chat
→ RAG Engine
→ Hybrid Retrieval
→ Reranker
→ Context Builder
→ Provider Adapter
→ LLM
→ Answer + Citation
→ Frontend
```
### 21.4 Agent 操作笔记
```text
User Task
→ Agent Runtime
→ Provider Adapter
→ Tool Call
→ Permission Check
→ Tool Registry
→ Knowledge / Retrieval / Task Service
→ Tool Result
→ Agent Runtime
→ Provider Adapter
→ Final Result
```
### 21.5 Skill 执行
```text
Select Skill
→ Skill Runtime
→ Validate Manifest
→ Resolve Permission
→ Resolve Tool Dependencies
→ Bind Built-in / Plugin Tools
→ Apply Retrieval Config
→ Check Model Capability
→ Build Agent Configuration
→ Agent Runtime
```
### 21.6 Plugin 加载与 Tool 调用
```text
Install / Enable Plugin
→ Plugin Runtime
→ Validate Plugin Manifest
→ Resolve Permission
→ Start Plugin Host
→ Discover Contributions
→ Register Tool
→ Tool Registry
→ Agent Runtime Available Tools
```
Agent 调用插件 Tool 时:
```text
Agent Runtime
→ Tool Registry
→ Permission Check
→ Plugin Tool Adapter
→ Plugin Host / MCP Bridge
→ Plugin Backend
→ Tool Result
→ Agent Runtime
```
### 21.7 课堂录音转笔记
```text
Audio
→ pyannote.audio
→ Speaker Segments
→ faster-whisper
→ Timestamped Transcript
→ Content Structuring
→ Markdown
→ Note Core
→ RAG Index
```
### 21.8 MCP Tool 接入
```text
Enable Plugin
→ Start MCP Server
→ MCP initialize / tools/list
→ Validate Schema and Permission
→ Namespace Tool ID
→ Register Tool Registry
→ Agent Tool Call
→ MCP tools/call
→ Normalize ToolResult / Error
→ Agent Trace
```
### 21.9 Mermaid 与函数图像
```text
Markdown Fenced Block
→ Parse Source
→ Mermaid / FunctionPlot Model
→ Renderer Adapter
├── Interactive Preview
└── Sanitized SVG / Image
→ Export Service
```
### 21.10 多格式文档导出
```text
Markdown
→ Markdown AST
→ Document AST
→ Resolve Assets / Formula / Diagram / Plot
→ Select Exporter
├── HTML
├── PDF
└── DOCX
→ ExportResult + Warnings
```
---
## 22. 异常处理与恢复
桌面应用需要区分编辑能力和 AI 能力的可用状态。
Python AI Core 启动失败时,前端显示 AI 服务不可用状态,并允许用户查看日志或重新启动 Sidecar。Markdown 编辑、文件浏览和基础本地操作保持可用。
Embedding 或 Reranker 模型下载失败时,对应索引任务进入失败状态。FTS5 搜索仍可运行。用户可以重新下载模型或切换 Embedding Provider 后重新建立向量索引。
模型 Provider 请求失败时由 Provider Adapter 转换为统一错误代码,例如:
```text
PROVIDER_AUTH_FAILED
PROVIDER_RATE_LIMITED
PROVIDER_TIMEOUT
PROVIDER_UNAVAILABLE
MODEL_NOT_FOUND
MODEL_CAPABILITY_MISMATCH
```
Agent Tool 执行失败后,Tool Result 中携带可处理的错误类型。Agent Runtime 根据 Tool 是否允许重试和剩余步骤决定后续行为。
SQLite 索引损坏或版本不一致时,应用允许重建 `.ainote/app.db` 中的可重建索引。执行重建前保留用户任务、会话和必要应用状态的迁移策略。
---
## 23. 当前版本实施边界
第一阶段围绕可联调的本地知识工作流建立基础接口:
```text
Markdown Workspace
→ 编辑与文件管理
→ SQLite / FTS5 索引
→ Embedding / Vector Search
→ Hybrid RAG
→ Citation
→ Provider Adapter
→ AI Chat
→ Agent Runtime
→ Tool Registry
→ Skill Runtime
→ Plugin Runtime
→ Plugin Manifest / Tool Contribution
```
第一阶段 Plugin Runtime 已完成安装、启用、停用、权限和声明式 Tool 注册,建立 Skill 调用 Plugin Tool 的基础链路。Command、Settings 和 MCP 执行不计入第一阶段完成项。
截至 2026-09-02,上述第一阶段后端链路和 Web 联调前端均已完成;第二阶段前置的 Workspace 去 Mock 联调、Agent Trace 持久化/恢复接口、stdio MCP Bridge / Plugin Host 以及 Plugin Command/Settings 后端 Contract 也已完成。当前验证基线为后端 107 项测试、前端 29 项测试、TypeScript 类型检查及生产构建通过。向量链路当前使用 `HashEmbeddingProvider` 验证工程正确性,真实 Embedding 召回质量不属于该测试结论。
第二阶段在既有 Contract 上接入:
```text
Multimodal
├── faster-whisper
└── pyannote.audio
Extension / Model
├── MCP Bridge(stdio 首版已实现)
├── Plugin Command Contribution
├── Plugin Settings Contribution
└── Provider Streaming / Tool Calling / Error Mapping 增强
Quality
├── RAG Benchmark
├── Agent Benchmark
└── Retrieval 参数调优
Content Output
├── Markdown → HTML / PDF / DOCX
├── Mermaid 编辑、预览与静态导出
└── Function Plot 解析、预览与静态导出
Frontend Extension
├── Theme Package 导入与社区包格式
├── Agent Trace 可视化
├── Plugin Command UI
└── Plugin Settings UI
```
上述列表描述第二阶段技术范围,其中 stdio MCP Bridge 已实现,其余能力以各自开发说明的状态为准。每项功能必须继续经过现有 Service、Contract、Permission 和 Adapter 边界,不因 Demo 需要在 Vue 组件、Router 或 Agent Runtime 中直接绑定第三方协议。
第三阶段处理:
```text
Sync Protocol
自托管 Sync Server
设备注册与 Vault 绑定
文件级 Revision
冲突检测与版本历史
Skill / Theme 配置同步
Plugin 安装清单同步
Skill 分发
Plugin 分发与社区仓库
Plugin Sidebar Panel 等前端扩展点
联网 Theme Marketplace
OCR 深度集成
更多多模态能力
扩展协议
```
Sync Server 按独立服务开发和部署,不进入桌面客户端核心启动依赖。第一版同步完成文件级 Revision、多设备增量同步和冲突保留后,再评估端到端加密与实时协同编辑。
阶段划分用于限定交付范围。人员分工、任务顺序和协作安排以阶段分工表为准,不在技术栈说明中重复维护;本文只维护技术选型、模块边界和跨模块 Contract。
---
## 24. 团队开发约定
一个新功能进入开发前,需要先回答以下问题:
1. 功能属于哪个核心域。
2. 用户数据保存在哪里。
3. 是否需要新增数据库字段或 migration。
4. 是否需要新增 Tauri 系统权限。
5. 是否需要新增 Tool Permission 或 Plugin Permission。
6. 是否应该作为内置功能、Skill 或 Plugin 实现。
7. 是否新增 Plugin Contribution 或 Plugin SDK 接口。
8. 是否涉及 Provider 能力差异。
9. 是否产生新的流式事件。
10. 是否影响 Block、FTS5 或 Vector Index。
11. 是否需要加入 Benchmark。
12. 失败后用户如何恢复。
涉及跨模块接口的 PR 同时更新对应 Contract 和本文档。Provider、Skill、Tool、VectorStore 等公共接口发生破坏性修改时,需要在 PR 中说明迁移方式。
技术栈选型优先服务当前功能。新增框架或基础设施需要能解决明确的项目问题,并说明它与现有模块的集成位置。团队统一维护一条主要实现路径,便于比赛版本测试、打包和现场演示。
---
## 25. 当前技术基线摘要
目标桌面端采用 Tauri 2、Rust、Vue 3 和 TypeScript;当前可运行形态是 Vue/Vite Web 前端加 FastAPI。用户笔记以 Markdown 和 Assets 保存在本地 Vault,SQLite 已管理笔记元数据、全文索引、向量索引、任务及 Agent Trace;Provider/Extension Registry 当前仍为内存实现。
Python AI Core 未来作为 Tauri Sidecar 运行,当前由开发命令独立启动,FastAPI 提供本地接口。Knowledge Core 管理笔记结构;Retrieval Core 当前通过 FTS5、`HashEmbeddingProvider`、sqlite-vec、RRF 和轻量 Reranker 跑通混合检索,真实 Embedding 与正式 Benchmark 在第二阶段接入;Agent Runtime 使用 Tool Registry 操作知识库和任务,并将扩展 Agent Trace Contract 供可视化和 Benchmark 共用;Skill Runtime 将提示词、工具、权限和检索参数组装为可复用 Agent 配置。
当前 Plugin Runtime 支持 Manifest、生命周期和声明式白名单 Tool Contribution,并已通过 stdio MCP Bridge 接入独立进程 Tool、Host 状态与重启接口;Command 与 Settings Contribution 尚待后续阶段实现。Provider Adapter 当前实现 Mock、OpenAI Chat/OpenAI-Compatible 与 Ollama,第二阶段按统一行为测试完善 OpenAI Responses、Anthropic Messages 等协议。多模态目标方案使用 faster-whisper、pyannote.audio 和可选 emotion2vec;当前只读取 Host 预生成 transcript。
第二阶段内容输出以 Document AST、Exporter Adapter、Mermaid Renderer 和 Function Plot Renderer 为共同边界,支持 HTML、PDF、DOCX 与静态图导出。Theme Package 使用 Manifest、Design Token 和受限 CSS 实现本地导入;联网主题市场不属于本阶段核心依赖。API Key 在 Web 联调期由 Fernet 开发存储加密保存,桌面版迁移到 Tauri Stronghold。多设备同步的目标方案为独立、可自托管的 Sync Server,目前尚未实现;本地核心功能不依赖 Sync Server。
该技术基线用于指导当前比赛版本的代码组织、接口设计、模块协作、测试和交付。