用 OpenCode 和共享记忆自托管 AI 智能体环境
Self-hosting an AI agent environment with OpenCode and shared memory
作者用 OpenCode 在 Ubuntu VPS 上自托管 AI 智能体环境,模型经 OpenRouter 和 OpenAI 订阅接入,共享记忆通过 Dropbox 同步到 VPS,并用 Tailscale 实现私有访问。
这篇文章是我在去米兰的火车上用手机构思的。回到家后,我敲了一个词,它就上线了。下面是它背后的设置,先从一点背景说起。
如今的前沿模型可以通过 API 广泛获取,而使用它们的一种常见方式是在自己的电脑上通过一个 harness 来运行,比如 Claude Code 或 OpenCode。harness 让 AI agent 能够与本地文件交互、进行修改并产生输出。
单次模型调用是无状态的:要在之前的讨论基础上继续,就需要把相关上下文提供给它。harness 或提供方的 API 会管理这些上下文,其中可以包括对话历史、摘要和选定的信息。许多 agent 系统还使用持久记忆:通常是关于重要事实和决策的笔记,可以跨对话和项目延续。
先做共享记忆
这个想法让我很感兴趣。我自己的设置很分散:订阅了多家提供方,网页上有聊天,不同机器上有本地会话,项目工作也散落在各处。
第一个问题是跨机器和 harness 整合记忆。我在一个共享文件夹(我这里是 Dropbox,但 Google Drive 也一样可行)中为记忆布局定义了几条基本规则。每个 harness 都被指示通过全局 AGENTS.md 中的自定义指令来读取和更新相关笔记,Claude Code 则用 CLAUDE.md 中的等效配置。
布局本身很简单:
~/dropbox/memory/
├── MEMORY.md # rules, conventions, links to notes
├── <note>.md # detailed note on a concept
└── projects/
└── <project>/
├── MEMORY.md # same as above with short summaries for smaller models
└── <note>.md # detailed note on a concept
其中一条规则是,任何写入记忆的内容都需要手动确认。这可以减少同步冲突,并让记忆保持精简:即使有今天这么大的上下文窗口,花在记忆上的每个 token 都意味着留给实际工作的少一个。这对安全也很重要,因为写入记忆的任何内容都会同步到每一台读取它的机器和 harness。
对于跨机器的本地工作来说,仅这一点就让我完成了大约 80%,这个数字的严谨程度正如你所预料的那样。
一个始终在线的环境
下一个问题是在网页聊天和本地工作之间切换。如果我在火车上从某家提供方的网页聊天开始讨论,那么当我切换到本地 harness 时,就必须重新建立上下文,因为这些聊天存在于我的共享记忆之外。于是我开始研究自托管一个 agent 环境,它能给我:
- 共享记忆,跨会话和项目。
- 始终在线的访问,方便讨论工作。
- 跨机器的连续性,这样无论我在哪里,都能继续讨论并完成工作。
- 模型自由,不被锁定在某家专有提供方上。
- Harness 自由,不受制于专有 UI。共享记忆已经让这一点不那么令人担忧了。
为什么不直接用现有平台?
这些需求排除了专有 agent 平台,但有几个可行的开源选项。OpenClaw、Agent Zero 和 Hermes Agent 都支持通用 agent、持久记忆和后台工作。其中一个可能就符合要求,但我还有两点额外考虑。
第一,我已经有了一个在多个 harness 之间共享的可用记忆布局。我想要的是能建立在这个基础之上的东西,而不是让基础去适应一个新平台。
其次,我希望能够自由地按照自己选择的方向扩展这套设置。我想要掌控安全模型:代理可以访问什么、在哪里执行命令、它们如何被隔离,以及哪些操作需要我的批准。
预构建的解决方案当然可以定制,但我希望从第一天起就划定这些边界。选择和连接这些构建模块,似乎比围绕自己的安全模型重塑一个打包好的系统更直接。
这套设置
对我来说,代理环境将现有的运行框架、共享记忆、远程访问以及代理可以工作的边界整合在一起。我的方案最终很简单:
- 在 VPS 上运行 OpenCode,模型通过 OpenRouter 和 OpenAI 订阅提供。
- 我现有的共享记忆,由无头 Dropbox 客户端按固定计划同步到 VPS。
- OpenCode 内置的 Web UI,它取代了我使用的各提供商网页聊天。
- 通过 Tailscale 进行私有访问。
边界正是我的安全模型所在之处:
- 一台 Ubuntu VPS,使用非 sudo 账户运行 OpenCode。
- 不向 Tailscale 网络上的其他机器出站。
- 写入仅限于工作目录;其他位置只读访问。
- 除模型提供商(OpenRouter 密钥设有用量限制)和 Dropbox 外,没有其他凭据;Dropbox 在单独账户下运行,且只同步记忆文件夹。
- 共享记忆由 Dropbox 文件版本控制和定期备份提供支持。
vicbot 的开端。
九十分钟与一次信仰之跃
这个想法我已经探索了几天,但实现总共只花了 90 分钟。Opus 5.5 设计并实现了这套解决方案,而我把大部分时间花在坚持让它给我手动运行的指令上。大约进行到 80% 时(又是这个数字),在 Tailscale 和 OpenCode 都正常工作后,我放手了,让它通过 SSH 登录到机器上完成剩下的工作。是的,我意识到在说了那么多关于安全模型的话之后这有点讽刺,但反正那台机器上没有任何凭据。
试用代理
我构思了这篇文章的想法,并通过 Web UI 开始了讨论。这个博客运行在自定义的 Node.js 设置上,而我的共享记忆中已经有涵盖其内容和风格的笔记,所以代理可以立即接上现有的上下文。
我提供了初始文本,与代理讨论了研究和结构,并制定了一个实现和发布它的计划,这些都被记入了博客的笔记中。所有这些都发生在我的手机上,在开往米兰的火车上。
回到家后,我在博客项目中打开了一个新的 Claude Code 会话,输入了 please continue。
基于我的共享记忆,它给出了一个实现和部署计划。我输入的下一个词是
go。五分钟后,文章上线了。作为对比,准备和润色文本花了两个多小时,这更多说明的是我,而不是这套设置。
这正是我想要的那种连续性:无论我身在何处,都可以讨论和规划工作,然后在另一台机器上继续。这也是我的运行框架自由需求在实践中得到验证:规划发生在 OpenCode 中,实现发生在 Claude Code 中,而共享记忆是两者的共同基础。
到目前为止它运行良好,我建议你也尝试类似的做法。以本文中的构建模块为起点,探索你自己的需求,并组装出一套适合你的设置。任何前沿模型都可以帮助你完成研究并把它搭建起来。
既然我已经有了一个远程代理,我打算看看再添加一些用于后台工作和其他有趣的任务。 目标是构建我自己的vicbot ;)
来源:Hacker News · smalldata.tech