# AI 笔记软件技术栈说明 > 文档性质:团队技术基线 > 基线版本:v2.3 > 适用范围:桌面客户端、本地知识库、RAG、Agent、Skill、多模型接入、多模态处理与可选云同步 > 目标读者:前端、Rust 桌面端、Python AI Core、算法、测试与后续接手项目的开发成员 > 实施状态更新:2026-09-01。本文同时包含目标架构、当前实现和第二阶段接口基线。第一阶段已完成 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/Settings、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 注册能力,减少内置功能和社区扩展之间的接口差异。 ### 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-01,上述第一阶段后端链路和 Web 联调前端均已完成;第二阶段前置的 Workspace 去 Mock 联调、Agent Trace 持久化/恢复接口以及 stdio MCP Bridge / Plugin Host 也已完成。当前验证基线为后端 87 项测试、前端 27 项测试及生产构建通过。向量链路当前使用 `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。 该技术基线用于指导当前比赛版本的代码组织、接口设计、模块协作、测试和交付。