1. 项目缘起从“订阅疲劳”到“本地优先”的觉醒不知道从什么时候开始生产力软件从你“购买”的东西变成了你“租用”的东西。你需要一个AI会议记录员每月18美元。你还希望它能生成行动项升级到专业版。需要它在多个设备上同步那是另一个付费层级。哦对了——如果你哪天取消了订阅你的笔记理论上还“在我们的云端”但想再访问它们祝你好运。这种模式让我感到厌倦。不是轻微的不快而是真正意义上的、彻底的厌倦。我的工作充斥着背靠背的会议一个AI会议助手对我来说确实有用。但我无法接受为一项我的笔记本电脑自身就能完成的功能持续支付一笔订阅费。于是我决定自己动手构建了Oats AI——一个免费、本地运行、开源的AI会议助手。没有订阅没有云端依赖没有付费墙。这背后的核心驱动力是一种对“所有权”的回归渴望。我们使用的工具正在越来越多地控制我们的数据和工作流。当服务中断、价格调整或者你决定离开时你创造的内容和形成的习惯就可能面临风险。Oats AI的诞生正是对这种趋势的一次具体回应将控制权交还给用户让强大的AI能力在本地、私密、一次性的环境中为你服务。2. 核心设计哲学极简、本地与实用主义Oats AI的设计遵循一套清晰的原则我称之为“禅意极简主义”工作流。这不是一个功能臃肿的瑞士军刀而是一把精心打磨的专用刻刀。2.1 “禅意极简主义”界面设计整个应用只有两个核心面板布局清晰毫无干扰。左侧是手动笔记区保留了最传统的记录方式让你在听会时能快速记下灵感或关键词。右侧是实时转录区文字随着会议发言逐行滚动呈现。两个面板并置的设计源于一个简单的洞察人在处理信息时需要“输入”和“输出”的并置参照。手动笔记是你的主动思考AI转录是客观记录两者对照能最大程度避免信息遗漏。在界面角落有一个微小的、规律脉动的视觉指示器我们称之为“麦浪脉冲”。它的唯一作用就是告诉你“我正在聆听。”没有闪烁的广告没有烦人的通知没有复杂的仪表盘。当会议结束你点击“总结”按钮AI开始工作生成关键要点和行动项。整个体验的目标是让你捕获所需然后继续你的一天。就像它的名字“燕麦”所寓意的一样——不华丽但提供你真正需要的营养。2.2 坚定不移的“本地优先”架构这是Oats AI与市面上绝大多数同类工具的根本区别。大多数AI会议工具的工作流程是录制你的会议音频 - 上传到他们的服务器 - 在云端进行语音识别和自然语言处理 - 将结果返回给你。这套流程能提供更“顺滑”的体验也构成了他们收取月费的理由——云服务器和算力不是免费的。Oats AI彻底颠覆了这个模式。所有处理都在你的设备上完成音频捕获直接调用操作系统底层的音频API。在Windows上使用WASAPI环回接口在macOS上使用ScreenCaptureKit。这意味着应用可以直接捕获系统播放的音频流无需安装虚拟音频驱动也无需管理员权限。你的会议声音从未离开过你的声卡。语音转录使用whisper.cpp这是一个高度优化的C移植版它让OpenAI强大的Whisper语音识别模型能够高效地在你的CPU或GPU上运行完全不需要网络连接。无论是英特尔芯片还是苹果硅它都能利用本地算力完成繁重的识别任务。数据存储所有的转录文本、笔记和生成的摘要都存储在一个本地SQLite数据库中这个数据库文件就放在应用目录旁。没有账户体系没有云同步开关也没有任何服务商能在理论上接触到你的会议录音。对于日常涉及敏感商业对话的企业环境来说这种隐私保障的价值远超过大多数工具愿意承认的程度。注意选择whisper.cpp而非原版PyTorch实现的Whisper是出于性能和部署便利性的权衡。原版模型对Python环境和GPU内存有较高要求而whisper.cpp将模型转换为GGML格式大幅降低了内存占用并提供了纯C的推理实现使得将其打包进一个独立的Rust桌面应用变得可行。虽然识别精度在极端口音或嘈杂环境下可能略有损失但对于清晰的会议语音其准确性已完全满足商用要求。2.3 关于“免费”的重新定义在今天SaaS软件即服务的世界里“免费”这个词已经变得面目全非。Oats AI试图回归这个词的本意没有14天试用期下载即用功能完整。没有“免费版”功能限制实时转录、总结、本地存储所有核心功能一视同仁。没有“个人免费团队收费”的套路无论你是独自使用还是团队共享通过分享应用本身它都是免费的。永远不需要信用卡从下载到使用的全生命周期你不会被要求绑定任何支付方式。应用的代码完全开源托管在GitHub上。任何人都可以审查代码、参与贡献或者基于此构建自己的版本。这种开放性是信任的基石。3. 技术栈深度解析为什么是Rust和Tauri构建一个本地优先、高性能的桌面应用技术选型至关重要。Oats AI选择了Rust Tauri的组合这是一次深思熟虑的“现代原生应用”实践。3.1 选择Rust性能、安全与可控性Rust语言是项目的基石它带来了几个决定性的优势零成本抽象与极致性能会议音频的实时处理是计算密集型任务。Rust允许我们编写高性能的音频处理和数据推理代码而无需像C/C那样手动管理内存也避免了Python等解释型语言在循环和数值计算上的性能开销。whisper.cpp本身是C库通过Rust的FFI外部函数接口可以高效、安全地调用形成强大的本地算力引擎。内存安全与线程安全音频流处理、AI模型推理、用户界面响应需要多线程协作。Rust的所有权系统和生命周期检查器在编译期就杜绝了数据竞争和内存泄漏这类在C中常见的棘手问题这对于需要长时间稳定运行的后台服务型应用至关重要。强大的生态系统与打包Rust的cargo构建工具和包管理器使得管理复杂依赖如音频库、数据库驱动、模型推理库变得异常清晰。最终我们可以将所有依赖和模型文件编译链接成一个独立的、静态的可执行文件实现真正的“单一二进制文件”分发。3.2 选择Tauri轻量级窗口与系统集成Tauri是一个构建小型、快速桌面应用的框架。与Electron等基于Chromium的方案相比它的优势非常明显极小的体积与内存占用Tauri使用操作系统自带的WebView在Windows上是WebView2在macOS上是WKWebView在Linux上是WebKitGTK来渲染界面。这意味着应用本体可以非常小Oats AI的安装包在20MB左右并且运行时内存占用极低不会像Electron应用那样动辄占用数百MB内存。强大的系统原生API调用能力Tauri提供了一套优雅的机制让前端JavaScript可以安全地调用后端Rust编写的系统级功能。这正是Oats AI所需要的前端界面监听按钮点击后端Rust代码处理音频捕获、调用Whisper模型、读写SQLite数据库。这种前后端分离但紧密结合的模型既保证了界面的灵活性使用HTML/CSS/JS任意前端框架又确保了核心业务的性能和安全性。无缝的打包与分发Tauri能轻松地为Windows、macOS和Linux生成安装包并处理应用图标、菜单、系统托盘等原生功能大大降低了跨平台桌面开发的复杂度。实操心得Rust与Tauri的集成要点在实际开发中将whisper.cpp这样的本地C库集成进RustTauri项目需要一些技巧。通常的步骤是将whisper.cpp的源码作为子模块引入并编写一个build.rs脚本指导Cargo如何编译这些C代码。创建Rust的unsafe外部函数声明extern C来映射whisper.cpp暴露的核心C API。在这些unsafe包装器之上构建一层安全的、符合Rust习惯的API供Tauri的后端命令调用。在Tauri的tauri.conf.json中正确声明这些需要调用的后端命令并配置前端绑定的权限。这个过程虽然初期有学习成本但一旦打通你就获得了一个兼具原生性能、安全性和现代开发体验的坚实基础。4. 核心功能实现细节与实操指南4.1 实时音频捕获绕过虚拟驱动的系统级方案大多数录音软件需要你安装一个虚拟音频电缆驱动将系统声音重定向到虚拟输入设备然后才能录制。Oats AI避开了这个繁琐且需要权限的步骤。在Windows上的实现WASAPI Loopback Windows Audio Session API (WASAPI) 的环回模式允许应用程序捕获正在由音频端点设备如扬声器或耳机渲染的音频流。关键步骤如下// 伪代码展示核心逻辑 use windows::Media::Audio; // 1. 获取默认的音频渲染设备扬声器 let render_device AudioDevice::GetDefaultRenderDevice(); // 2. 激活该设备上的音频客户端并指定为环回模式 let audio_client render_device.Activate::IAudioClient(LOOPBACK, CLIENT_EVENTS); // 3. 初始化音频客户端设置格式通常为44.1kHz/48kHz, 16-bit stereo audio_client.Initialize(SHARED, STREAMFLAGS_LOOPBACK, buffer_duration); // 4. 获取捕获客户端开始捕获数据 let capture_client audio_client.GetService::IAudioCaptureClient(); let packet capture_client.GetBuffer(); // 这里得到的就是系统播放的原始PCM数据获取到的PCM数据会被送入一个缓冲区等待whisper.cpp进行处理。这种方法的优势是零配置对用户完全透明。在macOS上的实现ScreenCaptureKit 从macOS 12.3开始ScreenCaptureKit API提供了强大的屏幕、窗口和音频捕获能力。用于捕获系统音频时// 伪代码Swift示意 import ScreenCaptureKit // 1. 创建一个音频内容过滤器指定捕获系统音频 let audioFilter SCContentFilter(audio: .system) // 2. 创建流配置 let streamConfig SCStreamConfiguration() streamConfig.capturesAudio true // 3. 创建流并开始捕获 let stream SCStream(filter: audioFilter, configuration: streamConfig, delegate: self) try stream.addStreamOutput(self, type: .audio, sampleHandlerQueue: audioQueue) try stream.startCapture()在委托的回调中你会收到包含音频样本缓冲区的CMSampleBuffer可以将其提取并转换为whisper.cpp所需的格式。重要提示在macOS上使用ScreenCaptureKit需要用户在系统设置-隐私与安全性-屏幕录制中授权该应用。这是操作系统级别的安全限制应用首次尝试捕获时会自动触发系统弹窗引导用户授权。这是保障用户隐私的必要步骤。4.2 本地语音识别Whisper.cpp的集成与优化whisper.cpp是项目的核心引擎。集成它不仅仅是调用一个函数那么简单需要考虑实时性、资源占用和准确性之间的平衡。模型选择与加载whisper.cpp支持多种规模的Whisper模型tiny, base, small, medium, large。对于实时会议转录我们通常选择small或base模型。tiny和base模型速度极快内存占用小小于150MB适合配置较低的机器但复杂句子或专业术语的识别准确率会下降。small模型在速度和准确率之间取得了很好的平衡是大多数场景的推荐选择。内存占用约500MB。medium和large模型准确率最高但推理速度慢内存占用大1GB不适合实时场景更适合事后处理录音文件。Oats AI在首次启动时会从开源镜像下载选定的模型文件.bin格式到本地用户目录。之后每次启动直接加载无需网络。实时流式处理策略 纯粹的Whisper模型是为整段音频设计的。为了实现“实时”感我们需要采用流式处理音频缓冲与分块将持续捕获的音频数据如每500毫秒填充到一个环形缓冲区。语音活动检测VAD辅助简单的能量检测或使用专门的VAD库如webrtc-vad来判断当前缓冲区是否包含有效语音。只在有语音时才送入模型可以节省大量算力。上下文窗口将当前语音块与前几秒的音频上下文一起送入模型进行识别可以提高识别连贯性尤其是处理句子中间被切分的情况。结果聚合与去重模型会输出带时间戳的文本片段。需要将连续片段的文本拼接起来并处理可能出现的重复识别当一句话跨越两个音频块时模型可能会在边界处重复输出部分词语。GPU加速如果可用whisper.cpp支持通过CUDANVIDIA或MetalApple Silicon进行GPU加速。在应用设置中可以提供一个选项让用户选择推理后端CPU、CUDA、Metal。启用GPU后转录速度会有显著提升同时降低CPU占用让电脑在开会时仍能流畅运行其他程序。4.3 AI总结与行动项提取本地与云端双引擎保障会议结束后的总结功能是Oats AI超越单纯转录器的关键。这里设计了一个优雅的降级策略优先使用免费的云端大模型API如果不可用则自动降级到本地轻量模型。首选方案OpenRouter免费APIOpenRouter是一个聚合了多家AI模型提供商如Anthropic、Google、Mistral AI的平台它提供一个统一的API并且有非常慷慨的免费额度。实现流程如下用户自主获取API密钥用户需要访问OpenRouter网站用GitHub或Google账号注册在控制台生成一个免费的API密钥。这个密钥完全属于用户Oats AI仅在前端本地存储如使用localStorage以供调用不会发送到我们的服务器。构建提示词Prompt将完整的会议转录文本连同精心设计的指令发送给OpenRouter API。指令示例你是一个专业的会议纪要助手。请仔细阅读以下会议转录文本并生成一份简洁的总结需包含 1. 会议核心讨论要点3-5条。 2. 明确的行动项Action Items每条需包含“负责人”如可推断、“具体任务”和“截止时间”如提及。 请用清晰的中文或英文根据会议语言输出格式工整。 转录文本[此处插入完整的会议转录]调用与解析应用使用用户的密钥直接调用OpenRouter API例如选择mistralai/mistral-7b-instruct或google/gemma-3-4b-it这类免费的较小模型接收返回的JSON格式结果解析并格式化后展示给用户。降级方案内置本地总结器考虑到网络问题、API服务不稳定或用户极度注重隐私的情况Oats AI内置了一个轻量级的本地总结引擎。这个引擎通常基于一个在本地运行的、参数较少的开源语言模型例如通过llama.cpp运行的TinyLlama或Phi-2模型。工作原理本地模型同样接收转录文本和提示词但在本地CPU/GPU上进行推理。速度会比云端API慢且总结质量可能稍逊于更大的云端模型但保证了绝对的可离线工作和数据隐私。触发条件当应用检测到网络不通或调用OpenRouter API超时/失败时会自动切换至本地模式并在界面上给出提示。这种双引擎设计确保了核心功能的鲁棒性你永远可以拿到一份会议总结无论是否联网。4.4 数据持久化简单可靠的本地存储所有数据都存储在一个SQLite数据库文件中例如oats_ai.db位于应用配置目录下如macOS的~/Library/Application Support/Oats AI/ Windows的%APPDATA%\Oats AI。数据库表结构设计简单高效meetings表存储每次会议的基本信息开始时间、结束时间、自定义标题等。transcripts表存储完整的转录文本与meetings表关联。actions表存储AI提取或用户手动添加的行动项包含任务描述、负责人、截止时间、状态等字段。notes表存储用户在手写笔记区输入的内容。使用SQLite的FTS5全文搜索扩展可以为转录文本和笔记建立全文搜索索引方便用户日后快速查找某次会议上讨论过的特定话题。所有数据备份就是复制这个数据库文件。迁移到新电脑也只需移动这个文件。5. 构建、分发与社区运营实践5.1 从源码到可分发二进制文件为了让用户获得“下载即用”的体验自动化构建和打包流程至关重要。我们使用GitHub Actions来实现跨平台的持续集成。GitHub Actions工作流核心步骤环境准备在ubuntu-latest,windows-latest,macos-latest三个runner上分别触发构建。安装Rust和Node.js因为Tauri前端可能使用Node.js生态工具如npm, yarn。缓存依赖缓存Cargo的registry和target目录以及前端的node_modules大幅加速后续构建。前端构建运行npm install和npm run build生成前端静态资源。后端构建与打包运行cargo tauri build。Tauri CLI会处理所有繁重的工作编译Rust代码捆绑前端资源下载并打包Whisper模型文件为每个平台生成相应的安装包Windows的.msi/.exe macOS的.dmg/.app Linux的.AppImage/.deb。上传制品将生成的安装包作为构建产物上传供用户下载。处理模型文件 Whisper模型文件几百MB不能直接放在代码仓库里。我们的解决方案是在构建脚本中检查目标平台然后从稳定的开源镜像如Hugging Face下载指定版本的模型文件到临时目录。在Tauri的配置中将这些模型文件指定为“资源文件”Tauri在打包时会自动将其包含进应用包内。应用首次运行时再将这些资源文件解压或复制到用户的可写数据目录中。这样既控制了Git仓库大小又保证了用户开箱即用。5.2 开源协作与社区反馈将项目完全开源在GitHub上带来了意想不到的积极影响。问题发现与修复更快开发者同行会提交Issue报告bug甚至直接提交Pull Request修复问题。一个关于macOS特定版本上音频捕获的棘手问题就是由社区贡献者发现的解决方案。功能建议的众包GitHub的Discussion板块成了功能需求的集散地。有人提议增加“说话人分离”功能有人想要导出为Markdown格式还有人建议集成日历。这些讨论帮助我们规划路线图并区分需求的普遍性。安全性与信任代码公开可审阅彻底消除了用户对“后门”或数据滥用的担忧。这对于一个处理音频数据的工具来说是至关重要的信任凭证。维护一个开源项目的实操心得清晰的READMEREADME是项目的门面。必须包含简洁有力的项目介绍、功能特性列表、清晰的下载安装指南、简明扼要的构建说明、贡献指南以及常见问题解答。管理Issue模板设置Bug报告和功能请求的模板引导用户提供必要信息如操作系统版本、应用版本、复现步骤能极大提高沟通效率。版本发布与更新使用语义化版本控制。每次发布新版本时在GitHub Releases页面撰写详细的更新日志说明新特性、改进和修复的问题。考虑内置一个简单的更新检查机制例如启动时请求一个包含最新版本号的JSON文件提升用户体验。保持焦点作为个人或小团队项目很容易被纷至沓来的功能建议淹没。必须坚持项目的核心哲学极简、本地、免费对不符合主线的需求勇敢说“不”或者将其标记为“未来可能考虑”。6. 常见问题、故障排查与性能调优在实际使用和用户反馈中我们积累了一系列典型问题和解决方案。6.1 音频捕获相关问题问题现象可能原因解决方案应用显示“正在聆听”但转录区无文字1. 系统音量过低或静音。2. 会议软件如Zoom、Teams输出音频到非默认设备。3. (macOS) 未授予“屏幕录制”权限。1. 调高系统音量确保会议软件有声音输出。2. 在系统声音设置中将会议软件的输出设备改为系统的“默认”设备。3. 前往系统设置-隐私与安全性-屏幕录制确保Oats AI已被勾选。重启应用。转录文字延迟很高或断断续续1. 电脑CPU负载过高。2. 选择的Whisper模型太大如用了large模型。3. 后台有其他程序大量占用CPU/GPU。1. 关闭不必要的程序释放系统资源。2. 在应用设置中切换到更小的模型如base或small。3. 如果支持尝试开启GPU加速Metal/CUDA。识别准确率低错别字多1. 会议音频质量差多人同时说话、背景噪音大。2. 发言人语速过快或有浓重口音。3. 讨论内容专业术语过多。1. 鼓励参会者使用耳机并开启发言人的降噪功能。2. 会后可对生成的转录文本进行快速校对和编辑。Oats AI的转录是可编辑的。3. 目前Whisper对中文的识别准确率已很高但对某些小众方言或专业领域仍需人工辅助。6.2 总结功能相关问题问题现象可能原因解决方案点击“总结”后长时间无响应1. 网络连接问题云端API请求超时。2. 转录文本过长超出模型上下文窗口。3. 本地总结器模型首次加载慢。1. 检查网络稍后重试。应用应会在超时后自动切换本地模式。2. 对于超长会议如2小时以上总结可能需要更长时间。请耐心等待。3. 首次使用本地总结功能时需要下载模型文件请保持网络通畅。生成的行动项不准确或遗漏1. AI模型理解偏差。2. 会议讨论本身模糊未明确责任人和时间。1. AI总结仅供参考。重要行动项务必在会议结束时与参会者口头确认并手动在笔记区补充或修正。2. 可以尝试在会议中更清晰地表述行动项例如“小明请在下周三前将方案初稿发给大家评审。”OpenRouter API密钥无效1. 密钥输入错误。2. 密钥的免费额度已用尽或过期。1. 前往OpenRouter网站重新复制API密钥在应用设置中更新。2. OpenRouter的免费额度通常足够个人使用。如果耗尽可注册新账号获取新密钥或等待额度重置。6.3 性能与资源调优建议Oats AI设计为轻量但在低配电脑或处理超长会议时仍可进行优化实时转录模型选择在设置中优先选择tiny或base模型。对于大多数语音清晰的会议base模型在速度和精度上已有很好平衡。关闭实时预览如果不需要边开会边看逐字稿可以在设置中关闭“实时转录显示”让应用只后台录音和缓存音频会后一次性转录。这能显著降低实时渲染文本带来的界面开销。管理历史数据定期在应用内清理早期的、不再需要的会议记录。可以直接在界面删除或手动删除数据库文件位于应用配置目录以释放磁盘空间。GPU加速如果你的电脑有NVIDIA独立显卡或苹果M系列芯片务必在设置中启用CUDA或Metal加速。这通常是提升性能最有效的手段。7. 从WicaraAI到Oats AI产品思维的演进有些用户可能知道我们之前的产品WicaraAI一个本地的音视频文件转录工具。WicaraAI是一个优秀的“单点工具”它把一件事做到了极致给你一个文件还你一份精准的转录稿。但Oats AI代表了一种产品思维的演进。我们意识到在真实的会议场景中一份完整的逐字稿往往不是终点而是起点。用户真正的痛点是信息过载和行动失焦。他们需要的不是“所有说了什么”而是“我们决定了什么”以及“接下来要做什么”。因此Oats AI没有选择在转录的准确率上无止境地内卷当然它依然优秀而是向前迈了一步聚焦于“理解”和“提取”。它将转录作为基础设施在此基础上构建了实时性和总结性这两个更贴近会议核心价值的功能。它继承了WicaraAI的所有优点——本地、免费、开源、隐私并将这些优点应用到了一个更完整、更闭环的用户场景中。这种演进也反映了我们对工具的看法最好的工具应该融入工作流而不是制造新的工作流。Oats AI不要求你改变开会的方式不要求你安装复杂的插件不要求你的同事也使用它。它只是一个安静的、高效的倾听者和整理者在你需要的时候给你支持在你结束后帮你收尾。构建Oats AI的过程是一次对抗软件“租借化”和复杂性膨胀的个人实践。它证明利用现代开源技术和本地算力我们完全有能力创造出既强大又尊重用户隐私和所有权的工具。它可能没有SaaS产品那些花哨的“团队协作看板”或“会议效率分析”但它切实地解决了一个高频、刚需的问题并且以一种让你感到安心和掌控的方式。如果你也厌倦了为那些本质上在你自己电脑上运行的功能支付没完没了的订阅费如果你看重数据的隐私和安全那么Oats AI或许就是你一直在找的那个“燕麦式”的工具——朴实、营养、管饱。项目的所有代码都在GitHub上欢迎你来使用、审视甚至一起让它变得更好。这不仅仅是一个工具也是关于我们如何与科技共处的一种选择。