Rowboat:开源本地优先的 AI 同事,用长期记忆知识图谱驱动日常工作的实战指南
【免费下载链接】rowboatOpen-source AI coworker, with memory项目地址: https://gitcode.com/GitHub_Trending/rowb/rowboat
Rowboat 是一款开源的桌面端 AI 同事(AI coworker)应用,核心特性是把你的邮件、会议、Slack 与助手对话索引进一个 Obsidian 风格的活知识图谱,并基于这份长期记忆在你的机器上完成实际工作。本文以仓库根目录 README.md 为主体,结合 apps/x/packages/core/src/knowledge 下的知识图谱实现源码,系统讲解其功能矩阵、安装配置、模型接入与 MCP 工具扩展,以及"长期记忆 vs 即时检索"的技术设计思路。
项目定位与核心功能矩阵
Rowboat 的定位是一台桌面级的 AI 同事:它不只回答问题,而是把你的工作内容持续索引成一个活的、可检查、可编辑的知识图谱,再用这些知识在本地执行真实任务。它内置了多个与 AI 协作的工作台(work surfaces),覆盖日常工作中最常见的信息流:
| 工作台 | 功能 |
|---|---|
| Brain(大脑) | 将邮件、会议、Slack 和助手对话索引成 Obsidian 风格、带反向链接的活知识图谱 |
| Email(邮件) | 内置邮件客户端,把邮件分为"重要"与"其他",并利用全部工作上下文为重要邮件自动起草回复 |
| Background agents(后台代理) | 可配置在"新邮件到达"等事件触发或"每天早 8 点"等定时触发的代理,能连接工具、搜索网络、使用浏览器,并通过 Claude Code 或 Codex 编写代码 |
| Built-in Browser(内置浏览器) | 与主浏览器隔离,你可以只登录愿意让助手访问的账号,与助手协作完成网页任务 |
| Meeting Notes(会议记录) | 本地会议记录器,接入麦克风与扬声器,生成实时转写,将会议总结写入 Markdown 文件并更新知识图谱 |
| Code Mode(代码模式) | 通过 Claude Code 或 Codex 并行启动多个编码代理,由 Rowboat 注入工作上下文驱动它们 |
| Apps(应用) | 可在 Rowboat 内构建自己的工作台,获得全部工具与集成能力,并能分享给其他人 |
| Integrations(集成) | 一键连接大多数主流产品的集成 |
这些工作台共享同一套底层机制:知识图谱负责"记住",后台代理与编码代理负责"行动"。
安装与前置配置
系统支持:Mac / Windows / Linux 三平台桌面应用,官方下载入口在 Download。
Google 服务接入(Gmail / Calendar / Drive)
要连接 Google 服务,需要先在 Google Cloud Console 生成 OAuth 凭据(Client ID 与 Client Secret)。完整步骤记录在仓库根目录的 google-setup.md,要点如下:
- 在 Google Cloud Console 创建新项目;
- 依次启用 Gmail API、Google Calendar API、Google Drive API;
- 配置 OAuth 同意屏幕(App 信息、Audience 选 External、添加联系邮箱),无需发布应用,保持 Testing 模式即可;
- 在 Test Users 中添加你要连接 Rowboat 的邮箱;
- 创建 OAuth Client ID,应用类型选择Web application,授权重定向 URI 必须精确填写
http://localhost:8080/oauth/callback(无尾斜杠、端口 8080); - 复制 Client ID 与 Client Secret,在 Rowboat 提示时粘贴。
常见排错:浏览器显示 "Authorization Successful" 但应用报错时,优先核对重定向 URI 是否完全一致、应用类型是否为 Web application(Desktop/UWP 类型可能不提供 client secret 或处理重定向方式不同)。
语音输入(可选):Deepgram
在~/.rowboat/config/deepgram.json中添加 Deepgram API key 即可启用语音输入与语音备忘。源码侧的加载逻辑位于 apps/x/packages/core/src/voice/voice.ts,它通过readJsonConfig('deepgram.json')读取配置,并在调用 Deepgram 语音识别接口时以Authorization: Token <key>请求https://api.deepgram.com/v1/listen。
语音输出(可选):ElevenLabs
在~/.rowboat/config/elevenlabs.json中添加 ElevenLabs API key 以启用语音输出。从源码看,该配置还支持可选的voiceId字段(默认使用内置的DEFAULT_VOICE_ID),请求会携带xi-api-key头访问https://api.elevenlabs.io/v1/text-to-speech/<voiceId>,支持流式/stream输出。
网络搜索(可选):Exa
在~/.rowboat/config/exa-search.json中添加 Exa API key 以启用研究型搜索。
外部工具(可选):MCP 或 Composio
启用外部工具有两种方式:添加任意 MCP 服务器,或在~/.rowboat/config/composio.json中添加 Composio API key。源码 apps/x/packages/core/src/composio/client.ts 显示,Composio 客户端会读取WorkDir/config/composio.json,未登录账号时以x-api-key头访问https://backend.composio.dev/api/v3。
所有 API key 文件使用统一格式:
{ "apiKey": "<key>" }注意:README 给出的用户侧路径为~/.rowboat/config/*.json,而源码中的常量基于WorkDir(工作目录)计算,两者分别对应桌面应用的用户配置目录与程序工作目录,格式完全一致。
核心原理:长期记忆知识图谱(Brain)
与主流 AI 工具的本质差异
README 用一段话点明了设计差异:大多数 AI 工具在需要时通过搜索转写稿或文档来按需重建上下文;Rowboat 则维护长期存在的知识:
- 上下文随时间持续积累;
- 实体关系显式且可检查;
- 笔记由你亲自编辑,而不是藏在模型内部;
- 一切以纯 Markdown 形式保存在你的机器上。
结果是一种复利式记忆——记忆不断累积增值,而不是每次检索都从冷启动开始。
知识图谱构建系统的源码结构
知识图谱构建系统集中在 apps/x/packages/core/src/knowledge 目录,其内部文档 apps/x/packages/core/src/knowledge/README.md 给出了完整组件图:
- build_graph.ts:主编排器。批量处理源文件(邮件/转写稿),运行
note_creation代理抽取实体,只处理新增或变更的文件(通过状态跟踪)。 - note_curation.ts:整合("园丁")代理。
note_creation只追加不清理,笔记会随时间膨胀变质,每日一次整理将累积最多的笔记逐条重写。 - graph_state.ts:状态管理模块,采用 mtime + 哈希混合变更检测,状态存于
WorkDir/knowledge_graph_state.json。 - sync_gmail.ts 与 sync_fireflies.ts:同步脚本,从 Gmail 和 Fireflies 拉取数据,保存为 Markdown 文件,并在同步成功后触发知识图谱构建。
- classify_thread.ts:收件箱分类器,为每封邮件的 frontmatter 打上
knowledge: extract | skip判定。
变更检测策略(mtime + 哈希混合)
系统采用混合 mtime + 哈希方案避免重复处理:
- 快速检查:比较文件修改时间(mtime),未变化则确定跳过;
- 验证:mtime 变化时计算内容哈希——哈希未变说明是误报(mtime 变了但内容没变),跳过;哈希变了说明文件确实变更,进入处理流程。
这一策略既高效(只对可能变化的文件做哈希),又可靠(确认真实内容变更)。状态文件结构如下:
{ "processedFiles": { "/path/to/file.md": { "mtime": "2026-01-07T10:30:00.000Z", "hash": "a3f5e9d2c8b1...", "lastProcessed": "2026-01-07T10:35:00.000Z" } }, "lastBuildTime": "2026-01-07T10:35:00.000Z" }处理流程
- 同步运行(Gmail 或 Fireflies):拉取新数据 → 保存为 Markdown → 调用
buildGraph(SYNC_DIR); - buildGraph():加载状态 → 扫描源目录 → 只筛选新增/变更文件 →每个代理运行只处理 1 个源文件(BATCH_SIZE = 1),刻意防止跨文件实体污染 → 每批成功后增量保存进度;
- 代理处理批次:抽取实体(人物、组织、项目、主题)→ 在
WorkDir/knowledge/下创建/更新笔记 → 对出现在多个文件中的同一实体合并信息。
从 build_graph.ts 的源码注释可以看到,BATCH_SIZE = 1是刻意设计:"One source file per agent run — prevents cross-file entity contamination in the graph"。每次批量构建前还会重建一次知识索引(buildKnowledgeIndex()),确保提示词中包含前序批次产出的最新实体索引;每批成功后调用commitAll('Knowledge update', 'Rowboat')将变更提交进版本历史。
笔记创建的严格度配置
系统支持三档严格度,控制从邮件创建笔记的激进程度;会议在任何级别都会创建笔记。配置位于WorkDir/config/note_creation.json:
{ "strictness": "medium", "configured": true }首次运行系统会自动分析你的邮件并推荐设置(见 strictness_analyzer.ts)。各档位的取舍逻辑(来自 apps/x/packages/core/src/knowledge/README.md):
| 级别 | 哲学 | 过滤特点 |
|---|---|---|
| High | "会议创建笔记,邮件仅丰富之" | 邮件从不新建笔记,只更新已认识之人的现有笔记;熟人转介除外 |
| Medium | "两者都可建笔记,但邮件需有个人化内容" | 过滤消费服务、群发邮件、泛泛推销;任何人的友好转介都会建笔记 |
| Low | "广泛捕获,绝不漏掉潜在重要联系人" | 为任何可识别的人类发件人建笔记,只跳过明显的自动化邮件与新闻通讯 |
自动推荐逻辑:超过 100 个真人发件人 → 推荐 High;50–100 个 → Medium;消费服务邮件占比超 50% → Medium;少于 30 个发件人 → Low。
源码层面,配置读写由 note_creation_config.ts 负责,支持low | medium | high三值,缺省为medium;configured标记用于区分"系统自动分析配置"与"尚未配置"。值得注意的是,源码中严格的邮件准入判定是硬编码在构建管线里的:build_graph.ts的emailAdmission()只放行被分类器打上knowledge: extract的邮件,knowledge: skip的邮件被标记为已处理并永久跳过;旧的 labeling 代理 frontmatter 则通过hasNoiseLabels()检查噪音标签兜底。
所有权身份注入与 Email Reply Gate
每次note_creation/note_curation运行都会注入一个"记忆所有者"信息块(由 build_graph.ts 的buildOwnerBlock()从config/user.json+knowledge/Agent Notes/user.md构建)。提示词中的身份逻辑——自我排除、第一人称视角、Email Reply Gate、外发邮件处理、按域名识别同事——全部依赖它,绝不让代理从邮件头猜测用户身份。
其中最重要的选择性规则是Email Reply Gate("冷入站邮件绝不创建笔记")。该规则由代码机械计算而非交给模型判断——源码注释记录了一次实测:某测试语料中 14 条笔记里有 7 条来自未回复的冷推销邮件。代码通过解析邮件的### From:线程结构,判断"用户这方是否曾在该线程中发过消息":回复过才允许创建新的人物/组织笔记,且模型只负责判断回复的含义;纯入站线程则明确禁止创建任何新笔记(例外是真实的一对一/小团体会议邀请)。同时还会识别 Google Groups 的via重写格式,避免把外部发件人误判为同事。
每日整理(Curation)机制
note_creation只追加,若不定期整合,笔记会膨胀变质(重复活动、过期待办、frontmatter 漂移、模式从未沉淀为事实)。因此每日运行一次curateNotes()(源码常量:CURATION_INTERVAL_MS = 24h,每次最多处理CURATION_MAX_NOTES_PER_RUN = 8条):
- 将超过 60 天的活动折叠为月度摘要;
- 把反复出现的模式提升为带日期的 Key facts / Assistant 笔记(反思步骤);
- 将过期的未完成事项退役到 Dormant 列表;
- 校正 frontmatter/正文漂移与视角错误,并在 frontmatter 中盖上
curated_at时间戳。
候选资格:活动条目数 ≥ 8、自上次整理后有修改、有 7 天冷却期(防止每次小追加都触发重整理)。整理结果以 "Knowledge curation" 提交进版本历史。这就是源码注释所说的"图谱的复利循环"。
后台代理:事件驱动 + 定时驱动
README 提到后台代理可"在新邮件到达时"运行,也可"每天早 8 点"定时运行。调度器的实现位于 apps/x/packages/core/src/background-tasks/scheduler.ts:
- 每15 秒轮询一次任务清单(
POLL_INTERVAL_MS = 15_000,与 live-note 调度器一致); - 支持暂停/启用(
task.active)、进行中保护(lastAttemptAt晚于lastRunAt视为在途,且仅在退避窗口内视为 in-flight,崩溃恢复后可重试)、指数退避(backoffRemainingMs)、周期锚定(只有成功运行才推进周期,失败保留待下一次自然触发重试)。
触发源通过dueTimedTrigger(task.triggers, completedAt)判定,对应 README 中"事件触发"(如新邮件)与"定时触发"(如每天早 8 点)两类触发器。代理可连接工具、搜索网络、使用内置浏览器,并通过 Claude Code 或 Codex 写代码。
自带模型(Bring Your Own Model)
Rowboat 兼容你偏好的模型方案,且可随时切换:
- 本地模型:通过 Ollama 或 LM Studio;
- 托管模型:自带 API key / 提供商;
- 随时更换模型——你的数据始终留在本地 Markdown vault 中,不受模型供应商锁定。
从源码结构看,模型相关实现集中在 apps/x/packages/core/src/models(29 个文件),知识图谱与编码代理均有独立的模型默认值解析(如getKgModel()),说明不同工作流可以分别指定模型。
通过 MCP 扩展工具能力
Rowboat 通过Model Context Protocol(MCP)连接外部工具与服务,可接入搜索、数据库、CRM、支持工具、自动化,以及你自己的内部工具。README 给出的示例包括:Exa(网络搜索)、Twitter/X、ElevenLabs(语音)、Slack、Linear/Jira、GitHub 等。仓库源码 apps/x/packages/core/src/mcp(含mcp.ts、repo.ts)与运行时工具域 runtime/tools/domains/mcp.ts 提供了 MCP 服务器的连接与工具调用支持。
示例:并行网络搜索(Parallel Search MCP)
Parallel Search MCP 提供web_search与web_fetch两个工具,无需 Parallel 账号或 API key 即可进行公开网页搜索与页面提取(免费使用有速率限制)。
配置步骤:打开Settings → MCP Servers,在现有mcpServers对象中追加parallel条目并点击Save,保留其他服务器条目。若尚未配置任何服务器,使用:
{ "mcpServers": { "parallel": { "url": "https://search.parallel.ai/mcp" } } }该配置走 Rowboat 现有的 Streamable HTTP 客户端连接。配置完成后,让 Rowboat 列出parallel服务器上的工具,然后尝试:"Use Parallel to find the official MCP documentation."(用 Parallel 查找官方 MCP 文档)。
几点注意事项(README 明确说明):配置后 Rowboat 可以在工作中调用这些工具,受你的 MCP 工具权限约束;查询、请求的 URL 以及提供的目标或上下文会发送给 Parallel;此设置不会改动 Exa 及其他已配置的提供商;要移除时,删除Settings → MCP Servers中的parallel条目并保存即可。
Local-First 设计:一切尽在纯 Markdown
Rowboat 的本地优先设计是其记忆哲学的技术根基:
- 所有数据以纯 Markdown 本地存储;
- 无私有格式、无托管锁定;
- 你可以随时检查、编辑、备份或删除所有内容。
这意味着"记忆"是可读、可审计、可版本化的资产:WorkDir/knowledge/目录本身就是一本可被任何 Markdown 工具打开的知识库,knowledge_graph_state.json记录处理进度,version_history.ts的commitAll()把每次知识更新沉淀为可回溯的版本历史。
总结
Rowboat 的差异化路径可以概括为一句话:不是每次冷启动地检索,而是持续积累、显式可查、由你掌控的复利式记忆。本文覆盖了它的完整功能矩阵、Google 与语音/搜索/工具配置、知识图谱从同步到构建再到每日整理的技术管线(含严格度分层与 Email Reply Gate 的机械判定)、后台代理调度器、自带模型策略与 MCP 扩展方法。想深入实现细节的读者,可以从 apps/x/packages/core/src/knowledge/build_graph.ts 与 apps/x/packages/core/src/knowledge/README.md 开始,顺藤摸瓜阅读graph_state.ts、note_curation.ts与classify_thread.ts的完整实现。
【免费下载链接】rowboatOpen-source AI coworker, with memory项目地址: https://gitcode.com/GitHub_Trending/rowb/rowboat
创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考