内容
# Adversaria
**一款完全在您本地运行的会议记录工具。**
无需任何机器人加入您的通话。无需上传任何内容。录音完成后立即删除。
拔掉网线,它的工作方式完全相同。
[**⬇ 下载 macOS 版本**](https://github.com/LaghariLabs/adversaria-releases/releases/latest)
· macOS 14.4+ on Apple Silicon · Windows in progress · MIT licensed
---
它记录您的系统音频 **和麦克风** 为两个独立的流(无需机器人加入通话),并在本地进行转录
([faster-whisper](https://github.com/SYSTRAN/faster-whisper) 在 Windows/CUDA 上,MLX
在 Apple Silicon 上),并使用托管的本地 LLM
(Rapid-MLX 在 macOS 上,Ollama 在 Windows 上)生成结构化笔记。在默认的本地模式下,会议
音频、转录文本和提示都保留在本地。 可选的云/BYOK 模式是明确的,并在使用前披露;请参阅
[网络边界指南](docs/PRIVACY_NETWORK_BOUNDARIES.md)。
## 功能
捕捉是容易的部分。 Adversaria 的设计围绕着捕捉之后的事情 —
将录音转化为可搜索、可操作和可携带的内容。
**录音**
- **没有机器人加入通话。** 它捕捉您的机器已经播放的音频和
麦克风已经听到的音频,作为 **两个独立的流** ,因此它总是知道谁
在说话。 音频文件在转录成功后立即删除。
- **说话者标注的转录文本** — `我:` / `他们:` ,以及设备上的 **说话者识别**
远程端的说话者,标记为 Speaker 1/2/…,并带有 `[MM:SS]` 时间戳。 支持多语言,包括 **阿拉伯语/RTL** 摘要。
- **录音伴侣 + 凹槽小药丸** — 在录音过程中,应用程序会折叠成一个
薄面板,停靠在通话旁边;切换到其他应用程序时,一个小药丸会缩进
凹槽,显示实时计时器、每个通道的波形和正在运行的字幕。
可以从任何地方使用 **⌘⇧M** 切换; **⌘⇧N** 可以快速记笔记。
**组织 — 整个事情的重点**
- **匹配会议的笔记。** 它可以检测 1:1、 工作面试、头脑风暴、
站会或您刚刚观看的视频,并以不同的方式编写每个会议。 您的手动选择始终优先。
- **自动编译待办事项。** 会议中的行动项会提取到一个 **分类面板**
(逾期 / 本周 / 稍后,拖放以更改截止日期)或一个关注队列 — 带有所有者、可编辑的截止日期、
会议范围的筛选器和每日两次的通知摘要。 您永远不需要重新输入后续行动。
- **周报** — 由本地模型编写的您的周报:做出的决定、未完成的事项和统计数据。
- **知识图谱** — 每个会议、人员、标签和行动所有者的交互式地图,完全基于本地数据构建,无需任何 LLM 调用。 点击人员即可查看档案:您与他们一起参加的每个会议,以及可编辑的个人资料。
- **自动填充的联系人** — 人员的 **角色和公司是从实际发言内容中提取的** ;您可以添加电子邮件、电话号码和 LinkedIn。 任何您输入的内容始终优先于模型推断的内容。
- **跨会议提问** — 混合检索(SQLite FTS5 + 设备嵌入 + 图形锚定,RRF 融合)由本地模型回答,附带它引用的会议。
- **会议洞察,无需 AI 调用** — 讲话时间占比、讲话速度(对比 130-175 wpm 目标)、填充词率、中断次数、最长独白。
- **保持侧边栏简洁** — 紧凑的行在日期分区中,存档、每个会议的 **标签** 、日期热图、固定 / 删除 / **隐私锁定** (每个会议的 PIN),以及搜索中的 `@` 以按与会者筛选。
**您可以自由使用**
- **导出** 会议为暗色 **幻灯片** (HTML → 单页 PDF)、 **Markdown** 或便携式 **`.adversaria.json` 包** ;使用 `[[wikilinks]]` 将所有内容镜像到 Obsidian 保险库;从设置 → 数据备份和恢复。
- **导入** 语音备忘录或音频文件,它会像其他内容一样在本地转录。
- **[MCP 服务器](https://github.com/LaghariLabs/adversaria-mcp)** — 一个单独的、开源的、**只读** 服务器,通过模型上下文协议公开您的会议和待办事项,以便 **Claude Desktop、Claude Code 或任何 MCP 客户端** 可以回答问题。 它在本地运行,不进行任何网络调用。 工具:`list_recent_meetings` 、 `search_meetings` 、 `get_meeting` 、 `get_action_items` 。
- **与单个会议聊天** ,按需重新总结、编辑摘要,并为转录机经常遗漏的名称添加自定义词汇。
## 安装(macOS,Apple Silicon)
**直接使用?** 从
[发布页面](https://github.com/LaghariLabs/adversaria-releases/releases/latest) 下载签名、 notarized 的 DMG,拖到 Applications 文件夹,然后启动。 需要 macOS 14.4+ on Apple Silicon。
要自己构建 — 打包的应用程序捆绑了 Python 机器学习服务,因此 **运行时不需要终端** :
1. 构建安装程序(一条命令;需要 [Prerequisites](#prerequisites) 中开发工具链):
```bash
./scripts/build-dmg.sh
```
→ 生成 `src-tauri/target/release/bundle/dmg/Adversaria_aarch64.dmg`。
2. 打开 `.dmg` ,将 **Adversaria** 拖到 **Applications** ,然后启动它。
3. 完成应用内设置。 Adversaria 检查硬件,推荐根据您的 Mac(建议,但不是强制的 — 您可以稍后在 **设置 → AI 引擎** 中切换)选择本地模型,下载并验证它,启动其捆绑的 Rapid-MLX 运行时,并运行示例摘要。 无需 Homebrew、Python 或单独启动的服务器。
模型下载有几个 gigabytes,第一次本地启动可能需要几分钟。 本地构建的临时 DMG 仅用于开发 — 官方构建已签名并 notarized,并在
[发布页面](https://github.com/LaghariLabs/adversaria-releases/releases/latest) 上发布。
## 工作原理
```
React UI ──invoke──▶ Tauri (Rust) ──HTTP──▶ Python 机器学习服务 (FastAPI :9876)
│ ├─ faster-whisper (转录)
│ └─ 托管的 Rapid-MLX / Ollama
├─ 本地捕获 → 加密块存储
└─ SQLCipher 会议历史 + OS 密钥链密钥
```
1. 按 **⌘⇧M** (macOS) / **Ctrl+Shift+M** (Windows) — 或使用托盘菜单 — 开始录音; Rust
后端通过 WASAPI 环回捕捉系统音频到 WAV 文件中。
2. 再次按下停止。 WAV 路径被发送到 Python 服务,它转录并使用您选择的提示模板总结转录文本。
3. 会议(标题、转录文本、摘要)被保存到 SQLite 并在 UI 中显示。 **音频文件在会议保存后立即删除。**
## 先决条件
| 工具 | 原因 | 安装 |
|------|-----|---------|
| Rust(稳定版) | Tauri 后端 | https://rustup.rs |
| Node.js 18+ | React 前端 | https://nodejs.org |
| Python 3.11+ & [uv](https://docs.astral.sh/uv/) | 机器学习服务 | `pip install uv` 或 uv 安装程序 |
| Ollama | 本地 LLM 总结 | https://ollama.com/download |
| NVIDIA GPU + CUDA/cuDNN | *可选* — 更快的转录 | 自动回落到 CPU |
拉取总结模型(Windows 默认配置为
`qwen3.6:35b-a3b` ;任何 Ollama 模型都有效 — 在设置中设置):
```powershell
ollama pull qwen3.6:35b-a3b
```
还拉取用于语义跨会议 Ask 搜索的嵌入模型(v0.3.30+;可选 — 如果没有,则 Ask 静默回落到仅关键字搜索):
```powershell
ollama pull bge-m3
```
## 运行(开发)
您需要两个进程:Python 机器学习服务和 Tauri 应用程序。 以下命令适用于 Windows。
> **macOS(Apple Silicon):** 设置有所不同 — MLX 转录 + Rapid-MLX 用于 LLM,`uv sync --extra mlx` ,以及 `HF_HUB_DISABLE_XET=1` (否则模型下载会卡在 0 字节)。
**终端 1 — Python 机器学习服务:**
```powershell
cd python-service
uv sync
uv run uvicorn src.server:app --host 127.0.0.1 --port 9876 --log-level info
```
> 首次启动时,会下载 whisper `large-v3` 模型(~3 GB)。 在没有 NVIDIA GPU 的机器上,服务会自动回落到 CPU — 考虑
> `WHISPER_MODEL=medium` (见下文),因为 `large-v3` 在 CPU 上很慢。
**终端 2 — 桌面应用程序:**
```powershell
npm install
npm run tauri dev
```
验证所有内容是否已连接:打开应用程序中的 **设置** — 服务状态指示器应为绿色 — 或手动检查:
```powershell
curl http://127.0.0.1:9876/health
# {"status":"ok","whisper_model":"large-v3","ollama_available":true}
```
### 试用
1. 使用 **⌘⇧M** (macOS) / **Ctrl+Shift+M** (Windows)、托盘菜单或应用内按钮开始录音。
2. 播放任何带有语音的音频(会议、YouTube 视频、语音备忘录)。
3. 停止录音。 转录和总结完成后,会议会出现在列表中,带有转录文本和结构化摘要。
## 配置
### 应用程序配置
存储在 `%APPDATA%\meeting-note-taker\config.json` ,可在设置 UI 中编辑:
| 键 | 默认值 | 备注 |
|-----|---------|-------|
| `python_service_url` | `http://127.0.0.1:9876` | 机器学习服务基准 URL |
| `default_prompt_template` | `general` | `python-service/prompts/` 中的任何模板: `general` 、 `one-on-one` 、 `client-meeting` 、 `brainstorm` 、 `youtube` 、 `interview` |
| `archive_after_days` | `30` | 未固定会议折叠到侧边栏存档的天数; `0` = 永远不会(搜索始终跨存档) |
| `sidebar_view` | `compact` | 侧边栏会议列表样式: `compact` (单行, hover 显示详情)或 `full` (经典卡片,带片段和标签) |
| `recording_view` | `balanced` | 录音时的布局: `balanced` (实时转录 + 笔记, 50/50)或 `transcript` (转录优先,底部为笔记);在下一次录音开始时应用 |
| `ollama_model` | `qwen3.6:35b-a3b` (Win)/ 硬件选择的固定配置文件(macOS) | 发送到服务的 LLM 模型名称 |
| `summary_language` | `en` | `en` 、 `ar` (阿拉伯语)或 `auto` (匹配口语) |
| `user_name` | (空白) | 您的显示名称;在新转录文本中替换 `Me:` 说话者标签 |
| `custom_vocabulary` | (空白) | 偏置转录拼写的名称/公司/行话(逗号或换行分隔) |
| `auto_detect_meetings` | `false` | 当呼叫应用程序使用您的麦克风时提示录音(基于麦克风, **非** 日历) |
| `claude_api_key` | `null` | 保留用于云回落(尚未连接) |
### 个性化转录和笔记
- **您的姓名** — 在设置中设置,以便在转录文本中用您的姓名标记您的发言,而不是 `Me:` ,这样笔记会用您的姓名归因于您。
- **自定义词汇** — 添加名称、公司和行话(逗号或换行分隔),以便转录正确拼写。 它被馈送到 Whisper
作为 Windows/CUDA 和 Apple-Silicon 后端的 `initial_prompt` 。
### 启用自动检测
自动检测 **默认关闭** 。 要启用它: **设置 → 勾选“自动检测会议” → 点击保存设置** (仅勾选不生效 — 您必须保存)。 无需重启。 当识别的呼叫应用程序(Zoom、Teams、Webex、Slack 或 Google Meet 等)使用您的麦克风约 4-6 秒时,会出现一个浮动卡片,提示“会议检测到 — 录音 / 忽略”。 它是 **基于麦克风的,而不是基于日历的** ,并且永远不会自行录音 — 您点击 **录音** 。 仅限 macOS 14.4+;WhatsApp/FaceTime 尚未识别。
### 机器学习服务环境变量
| 变量 | 默认值 | 备注 |
|----------|---------|-------|
| `WHISPER_MODEL` | `large-v3` | 例如 `medium` 、 `small` — 较小在 CPU 上更快 |
| `WHISPER_DEVICE` | `auto` | `auto` 尝试 CUDA,回落到 CPU;或强制 `cuda`/`cpu` |
| `WHISPER_COMPUTE_TYPE` | `float16` | `int8` 在 CPU 上自动使用 |
| `HF_HUB_DISABLE_XET` | (未设置) | 在 macOS 上设置为 `1` ,如果 MLX 模型下载卡在 0 字节(损坏的 `hf_xet` ) |
示例(CPU友好):
```powershell
$env:WHISPER_MODEL = "medium"
uv run uvicorn src.server:app --host 127.0.0.1 --port 9876 --log-level info
```
### 提示模板
模板位于 `python-service/prompts/*.md` 。 每个都是一个带有 `{{transcript}}` 占位符的系统提示。 通过在该目录中添加新的 `.md` 文件,可以添加自己的模板 — 它会自动出现在 API 和模板列表中。
## 测试
```powershell
# Python 服务(42+ 个单元/集成测试,ML 依赖被模拟 — 在 <1 秒内运行)
cd python-service
uv run pytest
# Rust 后端
cd src-tauri
cargo check
# 前端类型检查
npx tsc --noEmit
```
## 项目结构
```
src/ React 前端(组件、钩子、类型化的 IPC 包装器)
src-tauri/src/ Rust 后端
audio/mod.rs 有界限的本地捕获 → 加密存储
commands.rs Tauri IPC 命令(录音、转录、历史、配置)
http_client.rs Python 服务的类型化客户端
storage.rs SQLite 会议存储
tray.rs 系统托盘 + 全局热键(⌘⇧M / Ctrl+Shift+M 录音,⌘⇧N 快速笔记)
python-service/
src/server.py FastAPI 应用程序: /health /transcribe /summarize /templates
src/transcriber.py faster-whisper 包装器(CUDA 带 CPU 回落)
src/summarizer.py Ollama 包装器 + 提示模板加载
prompts/ 可编辑的总结模板
docs/superpowers/ 设计规格和阶段计划
```
## 隐私
- 在默认本地模式下,会议音频、转录文本和提示保留在设备上。 显式云转录或云总结仅发送已在设置和注册流程中披露的数据。
- 捕获在录制/待处理时加密,处理成功后删除;处理失败时,加密数据保持加密状态,可见且可重试。
- 转录文本和摘要存储在本地 SQLite 中(`%APPDATA%\meeting-note-taker\meetings.db` )。
- 无分析或自动崩溃报告上传。 注册、模型下载、更新、日历集成和可选云提供商已在
[隐私和网络边界](docs/PRIVACY_NETWORK_BOUNDARIES.md) 中记录。
## 已知限制
- 录音过程中的实时字幕是一个尽力而为的滚动预览;权威转录文本在您停止后生成。
- 说话者标签基于通道( `我:` = 您的麦克风, `他们:` = 系统音频);
群组通话中个别远程说话者尚未按名称分离( **说话者识别** 已在 `docs/SPEC_DIARIZATION.md` 中规范,但未构建)。
- 打包的应用程序使用系统 **ffmpeg** (Homebrew)通过 `PATH` ;将静态 ffmpeg 捆绑到其他 Mac 上以实现可移植性是待定的。
- 云回落(Claude API)已计划但未连接。 跨会议搜索今日为关键词/FTS5; **语义嵌入** 是后续工作。
- **日历集成** (Google/Microsoft, 只读)已规范( `docs/SPEC_CALENDAR.md` )但未构建 — 它需要您自己的 OAuth 客户端 ID。