---
title: 我是如何打造 OpenSecondBrain 的
description: open-second-brain 的故事：VPS 上的 Hermes、Obsidian、MCP、CLI 和几个 agent 运行时如何汇聚成一个为 AI 代理设计的小型文件型记忆系统。
canonical_url: https://techmeat.dev/posts/how-i-built-open-second-brain
date: 2026-05-09
tags: second-brain, dark-factory, hermes, openclaw, claude-code, codex
language: zh
---

我已经使用各种 AI 工具很长时间了，但在某个时刻我意识到：我不仅是在使用它们，而是几乎完全"被代理和 AI 相关的一切所包围"。

几个月来，代理们按照我的工作流来编写代码：规划、实现、审查、修复、再次检查。这种方式是有效的，但过程中总有一个奇怪的手工环节。即使代码是代理写的，我仍然需要在各个阶段之间移动任务、传递上下文、提醒规则、启动检查，并确保下一个执行者理解之前发生了什么。

重复性工作实在太多了。因此，下一个自然的步骤不是再做一个功能，而是自动化整个工作流本身。

于是 [OpenSecondBrain](https://github.com/itechmeat/open-second-brain) 项目诞生了——一次尝试，旨在为代理提供正常的记忆能力：我们在做什么、为什么做，以及已经做出了哪些决策。

## 从手工工作流到 Dark Factory

在[第一篇文章](/zh/posts/building-techmeat-dev-with-coding-agents/)中，我写过如何用编程代理启动这个博客。当时的工作流刻意保持简单：设定上下文、构建 Astro 项目、完成设计、添加文章、检查结果。

但我日常的流程要复杂得多。其中有角色划分、中间审查、针对不同任务类型的不同代理，以及每一步的质量控制。当这样的任务变多时，人就变成了调度员：把上下文搬到这儿、让这个去检查那个、把上一个代理的输出给下一个、别忘了记录决策。

我想要一种更刚性的模型，它越来越像 Dark Factory 这个概念：输入一个功能想法，输出一个已实现、已测试、已部署的功能。不是"代理写了一段代码"，而是一家工厂，能够自行将工作分解为阶段并推动整个过程。

距离真正的 Dark Factory 还很远。但第一个实际步骤已经存在了：部署在 VPS 上的 Hermes，配备针对不同任务的代理、技能、Telegram 界面，以及通过 OmniRoute 实现的廉价模型路由。

几乎立刻就暴露了这个工厂的第二个必要组成部分：代理需要记忆。

## 为什么代理需要 Second Brain

如果代理只工作一个会话，你只需把上下文放进提示词就够了。但如果代理在一个项目上工作数周，这就远远不够了。

它需要知道：

- 项目中已经确立了哪些规则；
- 讨论过哪些决策以及为什么选择了它们；
- 在调查过程中发现了哪些事实；
- 已经创建了哪些制品；
- 有哪些代理参与了工作；
- 人类知识库在哪里，代理服务区域又在哪里。

最重要的是——这不应仅仅依赖于"模型的记忆"。我需要的是一个简单的、可验证的、基于文件的知识系统，可以手动打开、在 Obsidian 中阅读、同步、部分提交或者完全不提交。

因此，open-second-brain 从一开始就不是"又一个带记忆的聊天机器人"，而是围绕 Markdown 知识库构建的一套小型基础设施。

## 为什么选择 Obsidian 和 Markdown

选择兼容 Obsidian 的知识库几乎是显而易见的。

首先，它们就是普通的 Markdown 文件。没有魔法，没有封闭的数据库，没有对特定服务的依赖。如果代理写了什么，我可以打开文件直接看到结果。

其次，Obsidian 已经很好地解决了 Second Brain 的人类端需求：笔记、wikilinks、Daily、手动导航、图谱、搜索。既然已经有趁手的工具，就没有必要自己做知识接口。

第三，代理并不需要 Obsidian 的全部功能。它们需要的是确定性操作：创建服务结构、向每日日志添加事件、构建页面索引、检查知识库健康状态、导出不含密钥的配置。所有这些都可以通过 CLI 和 MCP 来完成，不需要让模型在应该执行精确命令的地方去"思考"文件操作。

现在，open-second-brain 在知识库中创建代理区域 `AI Wiki/`，在 `Daily/*.md` 中维护每日日志，能够更新 Markdown 索引、检查配置，并且不会触碰 `## Raw events` 服务分区之上的人类笔记。

## 我给了一个空仓库——代理自己选择了架构

最有趣的是：我没有坐下来像设计经典库 API 那样设计这一切。我给了代理一些流行实现的链接、一个空仓库和一个任务：做一个通用插件，首先面向 Hermes，但要让其他代理也能接入。

第一次提交完全是文档性的：README 和项目引导，5 月 6 日。然后代理快速搭建了 CLI 基础、`o2b` 命令、init/doctor、知识库原语和索引。同一天就出现了 MCP 服务器——重要的一层，因为通过 MCP，不同的运行时可以获得相同的工具集，无需手动解析命令行。

最初的版本非常实用导向：让 Hermes 能够安装插件、初始化知识库、检查状态并写入事件。不是纸上的完美架构，而是为真实代理工作的最小可用记忆系统。

之后，项目在集成压力下开始演变。

## 从 Hermes 到通用插件

Hermes 仍然是主要的运行时。项目最初就是为它设计的：安装插件、指定知识库、给代理工具、让它把重要事件写入 Second Brain。

但很快我就意识到，只绑定 Hermes 是不对的。我已经有了不同的代理和不同的环境：Claude Code、Codex、OpenClaw。如果 Second Brain 要成为共享记忆，它就不能只存在于一个客户端中。

于是项目中出现了针对多个运行时的适配器和清单：

- Hermes 作为主要安装场景；
- Claude Code 通过 marketplace 清单和 MCP；
- Codex 通过自己的 marketplace 清单和 MCP；
- OpenClaw 先通过 JS 适配器，后来通过完整的原生插件入口；
- 通用的 MCP 契约，为将来出现的运行时做准备。

这是一个重要的架构决策：核心只能有一个，但入口可以有多个。代理们不需要争论真理在哪里。真理在知识库里，在共同的操作集合中。

## 一路上不得不修复的东西

open-second-brain 发展非常迅速：从 5 月 6 日到 5 月 9 日，项目从 README 走到了 `0.7.0` 版本。几乎每个版本都不是"化妆"，而是对真实集成问题的回应。

例如，OpenClaw 最初获得了原生插件兼容性，但运行时比预期的更严格。不得不在 tool 对象中添加 `name`，让 `register()` 变成同步的，然后把 OpenClaw 插件重写为纯 JavaScript，不使用 `child_process`，因为安全扫描器会阻止子进程。

下一个大主题是身份标识。如果日志里只写着 `@agent`，这样的日志几乎毫无用处。所以在 `0.6.0` 中出现了代理命名工作流：`o2b init --agent-name`，在 `AI Wiki/identity/agents.md` 中注册，并确保 Daily 中的记录获得正常的 `@agent-name` 而不是占位符。

之后又添加了时区支持、防止写入错误知识库的保护、Claude 和 Codex 的 marketplace 清单、MCP 的自动指令、空参数的规范化、安装流程检查、多代理注册表。这些听起来不像是什么英雄式的产品功能，但正是这样的细节区分了玩具和可以留在服务器上运行的工具。

## 0.7.0 版本：TypeScript 和 Bun 上的统一核心

最大的变化发生在 `0.7.0`：项目迁移到了基于 Bun 的统一 TypeScript 核心。

在此之前，仓库中存在并行的逻辑：用于 CLI/MCP 的 Python 实现、用于 OpenClaw 的 JavaScript 部分、Hermes shim。这种架构很快就开始漂移。在一个地方修了 bug——不等于在另一个地方也修了。在 Python 中添加了时区——别忘了在 JS 中也加上。

在 `0.7.0` 中，代理消除了重复：Hermes、Claude Code、Codex 和 OpenClaw 现在都从 `src/core/` 消费公共模块。CLI 位于 `src/cli/`，MCP 位于 `src/mcp/`，OpenClaw 入口通过 `bun build` 从 TypeScript 编译为 JS bundle。

同时还建立了正常的测试基础：`bun:test` 共 176 个用例、Python shim 测试、12 个进程的并发 append-event 测试、bundle 新鲜度检查和清单版本同步检查。

这正是代理工作流优势显现的时刻。让人手动在运行时之间搬运相同的代码并重写测试是很痛苦的。对代理来说——只要你给一个清晰的目标、约束和结果验证——这就很正常。

## 这一切如何在 VPS 上运行

整个故事运行在一台每月约 8 美元的普通 VPS 上。Hermes 也运行在那里，开发也可以在那里进行，AI 订阅的管理和通过 OmniRoute 的路由也在那里。

对我来说，这是实验的重要组成部分。我不希望 AI 辅助工作流需要单独的昂贵基础设施。只需要一台服务器、一个浏览器、Telegram 作为代理的接口、旁边的 Git 仓库和廉价的模型访问。

画面相当奇怪但可用：我可以在手机上通过 Telegram 给代理发消息，它在 VPS 上解析任务、进入仓库、使用所需技能、创建制品、运行检查并将重要事件记录到 Second Brain 中。

这还不是 Dark Factory。但也已经不仅仅是"和模型聊天"了。

## 成果如何

截至这篇草稿撰写时，open-second-brain 是一个小型但已经实用的代理开发记忆层。

它能做到：

- 初始化兼容 Obsidian 的知识库用于代理工作；
- 创建 `AI Wiki/` 和服务页面；
- 以 Markdown 格式写入每日事件；
- 保存代理的身份标识；
- 考虑用户的时区，而不仅仅是服务器时间；
- 检查知识库、配置和运行时清单的健康状态；
- 导出配置并对敏感值进行脱敏；
- 通过 CLI、MCP 和运行时适配器工作；
- 从单一仓库支持 Hermes、Claude Code、Codex 和 OpenClaw。

最有价值的甚至不是命令列表。有价值的是代理们获得了一个共享的记忆协议：当发生了什么持久的事情——代码、修复、配置、内容、调查结论、设计决策——需要把它记录下来，这样未来的我和未来的代理都能在之后找到它。

## 下一步

最近的目标是将 Hermes + open-second-brain 的组合推进到代理不仅写入事件，而且在规划和审查时真正使用积累的记忆的状态。

之后想要做的：

- 更好地将 Daily 日志与 wiki 页面关联；
- 添加更有用的搜索和项目历史摘要；
- 单独写一篇文章描述 Hermes 如何在 VPS 上工作以及通过 Telegram 的交互是怎样的；
- 将当前工作流转变为更自主的 Dark Factory；
- 验证不同的代理能否无痛苦地共享一个知识库而不破坏彼此的上下文。

目前的主要结论很简单：代理不仅需要模型和代码库的访问权限。它们需要一个环境，在这个环境中，决策、事实和事件成为过程中持久的一部分。

[open-second-brain](https://github.com/itechmeat/open-second-brain) 是我朝这个方向迈出的第一个实际步骤。

## 这篇文章是怎么写的

抱歉，这篇文章也是同一个代理 Hermes 写的。手工写的只有这一段和我的 [Facebook 帖子](https://www.facebook.com/reel/1355271143340726/)。我只是让代理把我的博客作为一个普通项目克隆下来，查看提交历史，并以 Facebook 帖子为基础进行写作。当然，我在发布前重读并修改了文本。别跟我说这没有灵魂，我把灵魂注入了代理中。