我的 agent 配置方案

返回

起因是我昨天在推特发了一张图 简单记录了自己diy的agent云端方案 能实现一些简单的coding任务

觉得蛮有研究价值的 决定在这里展开描述一下

[思考]

如下👇

我的 Agent 配置总览:Lody 与 Cherry Studio 作为入口,Nowledge Mem 连接记忆,多个运行时接入右侧模型来源。

先回忆一些概念

概念放到这套配置里理解
ADE · Agent Development Environment围绕 Agent 任务的开发环境。开任务、看进度、审改动,我主要和这一层打交道
Agent Runtime真正执行任务的程序,比如 Dimcode、Pi、Claude Code、Codex。负责调用模型、操作工具、继续下一步
Memory 系统把值得留下的背景和结论存起来,让不同 Runtime 按需检索;还要约定什么时候读、什么时候写
BYOK · Bring Your Own Key带自己的 API Key 接模型,工具和模型来源可以分开选
P2P 组网让自己的几台设备通过私有网络互通,尽量直连,必要时走中继
内网穿透给内部服务接一个外部入口,比如通过域名访问云端的记忆服务
ACP · Agent Client Protocol客户端和 Runtime 之间的协议,用来传任务、会话消息和执行事件

组网和穿透容易混在一起。拿常见方案举例:Tailscale适合把自己的节点连起来,Cloudflare Tunnel可以把指定服务接到外部入口。它们是这里的原理示例,具体选哪个要看服务放在哪里。

为什么这样搭

我想要的是能自己 DIY,界面、模型和 Runtime 都能自由搭配。代码放在自己管理的环境里,执行权限自己定,用起来也更放心。

Lody:手机上也能接着看任务

Lody 的理念里,我比较认同 local-first:工具可以换,积累下来的项目上下文应该能留住、能带走。它用本地副本和跨设备同步组织协作,CLI 和桌面客户端也已开源。不过跨设备协作目前仍依赖托管同步服务,官方说明尚未支持端到端加密。见项目理念。

落到使用上,最吸引我的是远程体验:云端跑任务,我在手机上看进度、收通知、处理审批。配合 Diff 审阅、worktree 和 ACP 接入,能同时放几个任务,也能看清 Agent 改了什么。移动端能力见官方说明。

[出现]

Memoh:把工作环境留在云端

Memoh 的思路是给每个 Agent 一个能长期工作的独立环境:有自己的工作空间、浏览器、工具和记忆,再接上消息渠道、定时任务。对我来说,这比每次开任务都重新准备环境省事。官方介绍里有更完整的说明。

我这里还考虑了海外部署和出口 IP。把执行环境放在海外主机上,可以集中处理模型调用、浏览器和外部资源访问的网络问题。

另一个看中的点就是容器工作空间隔离。不同 Bot 可以在各自的环境里装依赖、跑命令,配合目录挂载和权限设置,能缩小误操作波及其他项目的范围。拿来试新工具、新流程时,心里也更有底。

Nowledge Mem:换工具,不想再介绍一遍项目

重要的上下文不该绑在一个账号上,封号或换平台,也不想从头磨合。Nowledge Mem 中立、privacy-first,也支持 local-first,正好用来留下项目约定和踩坑经验,让 Agent 换到更合适的模型或工具时,还能带着这些背景接着干。

所以,Memoh 的记忆服务于 Bot,跨工具的积累交给 Nowledge Mem 集中管理。一台主实例连接多个客户端,nmem 是访问它的 CLI,连接方式参考官方的远程访问方案。

[智慧]

我想让下一个 Agent 知道项目为什么这么做,少让我从头讲一遍。

保存结论时带上理由和适用条件,比只留一句“已经解决”更方便下次接着干。

Dimcode:把不同模型安排进同一个任务

Dimcode 现在的项目名是 DimAgent,强调同一个 Runtime,接不同入口、用不同模型,状态留在运行它的机器上。桌面、终端和 ACP 共用执行核心,这点很适合自己组合工具。

比起单纯“支持很多模型”,我更关注它在官网介绍的这几项:

  • 子 Agent 可以分别选模型:例如把写代码和审查拆开,交给不同模型,再汇总结果。
  • 长任务的恢复机制:独立压缩上下文、分层处理错误,适合探索放到云端持续跑的任务。
  • 执行过程能回看:结构化 trace 记录模型调用、工具执行和权限决定,出问题时更容易找到卡在哪一步。

Pi、Claude Code、Codex 也留着,按任务和使用习惯选择。没有必要为了统一,强行只留一个 Runtime。

模型来源则放在最右边。需要自己集中管理接口时,可以用自建 New API;其他来源按各自支持的方式接。BYOK 和订阅登录分开配置,手里有哪个渠道,就确认它能配合哪些 Runtime 使用。

把云端这条线串起来

回看折腾路线,以前主要围绕本地,现在主要探索云端方案。以前更多是在电脑前用工具,现在想试试把工作环境留在服务器上,让手机、浏览器都能接着参与。

所以图里保留了上下两部分:下面是本地那一套,上面是这次想展开的云端方案。这里的“云端”是我自己部署和管理的执行环境,前面提到的数据可控、工具可替换,仍然是选型时在意的事。

沿着原图从左往右看,就是Client → Memory → Agent Runtime → Gateway → Model Access:从使用的消费端,一层层走到提供模型能力的供给端。

  • Client · 操作台:Lody 接收需求,让我查看和控制任务。
  • Memory · 资料库:Nowledge Mem 提供项目背景,让任务带着已有经验往下走。
  • Agent Runtime · 引擎:Dimcode 等运行时组织上下文、调用模型和工具,真正推动任务执行。
  • Gateway · 供油管路:按需统一接入和转发模型请求,自建 New API 可以承担这一层;直接接模型来源时可以省略。
  • Model Access · 燃油供应端:通过选定的 API 或 Coding Plan 获取模型能力,支撑引擎持续工作。
Architecture flowAn architecture diagram grouped by dependency.Client操作台:LodyMemory资料库:NowledgeMemAgent Runtime引擎:Dimcode 等Gateway供油管路:按需接入Model Access燃油供应端Architecture flowAn architecture diagram grouped by dependency.Client操作台:LodyMemory资料库:NowledgeMemAgent Runtime引擎:Dimcode 等Gateway供油管路:按需接入Model Access燃油供应端

Memoh 则是承载这套云端执行环境的车间,提供容器工作空间,具体工具由其中的 Runtime 按自身配置调用。Token 可以类比成燃油用量:模型读入上下文、生成内容都会产生用量,反复推理和修改也会持续“耗油”。它实际是模型处理内容的计量单位,耗得多不代表做得好。

这里的箭头表示分层阅读顺序。实际调用时,Lody 接到云端 Runtime,Runtime 按需读写记忆,再通过网关或直接访问模型来源;Memory 不承担请求转发。

我这里只把 Memoh 当作云端服务器来运行独立 Runtime,并没有让 Lody 通过 ACP 协议调用 Memoh 自身的 Agent、工具等能力。Memoh 官方的 Agents / ACP 功能则是由 Memoh 启动和连接外部编码 Agent,接入方向不同。

配置也可以直接交给 AI

配置时也可以直接找 AI 帮忙。复制下面这段 Prompt,让 AI 按你的实际环境调整;这里记录的是我这次容器环境的配置思路:

# 云端 Agent 环境复现提示词

## 第 0 步:先读官方文档,再检查现有安装与配置(不要盲目重装)
- 平台(Lody):https://lody.ai/docs/
- Memoh 工作区与钩子:https://docs.memoh.ai/zh/guides/hooks.html
- coding agent(dimcode):https://dimcode.dev/docs/
- 记忆服务远程接入(nmem):https://mem.nowledge.co/docs/remote-access

## 当前环境约束与配置约定
- 无 systemd:用平台钩子(WorkspaceStart)触发恢复脚本,
  脚本必须幂等(已装已跑就跳过)。
- 本方案用一条 WorkspaceStart hook 统一恢复服务,
  一个 type=command 的 action 指向总调度脚本;
  各服务在脚本内部串行启动。
  hooks.json 的字段与结构以官方文档为准,不要凭记忆手写。
- work_dir 必须显式写。文档的解析顺序是 action.work_dir
  → 请求里的 workspace CWD → /data;前两项都缺省才回退到 /data。
  本方案显式写 "/",仅用于固定工作目录。
- timeout 限制单个 action 的执行时间,按服务数量调整,
  总调度必须在预算内跑完。
- on_error 默认 fail;本方案用 ignore 记录 action 错误并继续。
  脚本内部仍需逐项处理服务启动失败,不能靠 ignore 保证后续服务启动。
- 脚本放 /data/.memoh/restore-services.sh,并同步一份到 overlay root
  (如 /usr/local/bin/);挂载时序以当前环境实测为准。
  启动服务前在超时预算内确认 /data 已正确挂载、数据与 secrets 可用;
  启动日志可写 /var/log 等有写权限的位置,避免只依赖 /data。
- action 的执行身份文档没有规定,先在 action 中执行 id 并记录结果。
  若确实以 root 运行,所有服务 launcher 必须显式降权。
- 当前托管环境仅保证 /data 持久;/etc 和 ~ 下的文件可跨普通重启存活,
  但平台会在每次启动时主动重写少数受管文件
  (如 /etc/hostname、/etc/hosts)。对这些被覆写的文件,
  在恢复脚本里每次重放,改前先备份;其余不必 symlink。
- secrets 放 /data 下 0600 文件,经环境变量传给进程,不进 argv;
  不要直接写进 hooks.json(其 env 字段是明文)。

## 步骤
1. 写 /data/.memoh/restore-services.sh(幂等、串行、带日志),
   同步到 overlay root(如 /usr/local/bin/restore-services.sh),
   并注册一条 WorkspaceStart hook。
2. 安装 mise;用 mise use -g 声明所需运行时。
   注意:bashrc / .profile 里的 activate 只对交互或登录 shell 生效,
   钩子通常不读这两个文件。恢复脚本和各个 launcher 内部要自己
   export HOME 和 PATH(含 mise shims),不能依赖 shell rc。
3. Nowledge Mem 服务端:按实际部署方式以普通用户身份运行,
   监听 127.0.0.1:14242;数据目录指向 /data;
   dimcode 通过 MCP 端点 http://127.0.0.1:14242/mcp/ 接入,
   按服务端要求配置认证;nmem CLI 配置不会自动传给 MCP 客户端。
4. dimcode web:只绑 127.0.0.1;进程可能改名,
   幂等检测用端口监听(ss/curl)而非进程名。
5. (可选)固定 hostname:在恢复脚本里重写 /etc/hostname
   和 /etc/hosts 的 127.0.1.1 行,两个都先备份。
6. 按 Lody 文档配置远程接入与独立 Runtime 的 ACP 启动命令。

## 验收
重启环境后自动满足:各端口可 curl 通、记忆库数据仍在(未重置)。
从 Lody 发起一次任务,确认 Runtime 能调用工具并返回结果。

## 附注
以上是最小核心。仅当你确实有外部访问需求时再考虑:
- 本地设备要连进容器内网(如远程连 nmem)→ 参考
  https://mem.nowledge.co/docs/remote-access 配置 Tailscale 内网互联;
- 要公网域名访问容器内服务 → 参考
  https://developers.cloudflare.com/cloudflare-one/connections/connect-networks/
  配置 cloudflared 隧道。
不需要则两者都不装。

这只是我目前的一种尝试,远没到标准答案。 同样的思路也可以放到 NAS、家里的常开主机或其他 Linux Server 上。提示词里的 /data 和恢复钩子针对的是当前容器环境,换个平台就需要让 AI 按实际情况调整。

这样搭也方便把手里零散的模型额度用起来。比如 OpenCode Go 接 Pi,Dimcode 按兼容接口接入已有渠道,Runtime 放远程或本地都可以;Memoh 平台内的 Token 额度也可以结合自己的套餐安排任务。这里整合的是使用入口和任务分配,各家的额度仍然分别计算。OpenCode Go 已把 Pi 列入验证过的客户端,其他组合还要实际试一下。

长期记忆的部署位置,我还想再调整。 考虑到所用 Memoh 托管环境的资源回收问题,把 Nowledge Mem 服务端一起放进去,可能会让记忆服务跟着工作空间中断。重启能保留 /data,也不能直接当作资源回收后仍有保障;具体保留规则需要单独确认。

后面可以考虑把记忆独立出来:用 Nowledge Cloud,或者部署在自己的 Linux Server / NAS 上,再让各个 Runtime 远程连接。工作环境可以继续折腾,长期积累的记忆尽量放在稳定、有备份的地方。上面的 Prompt 保留了这次尝试的同环境部署方式,长期使用时可以按这个方向改。

最后

这套方案目前能做一些简单的 coding 任务,需要用实际项目去进行磨合,DIY 的乐趣也在这里:按自己的习惯一点点搭,让它慢慢变成一套愿意每天用的工具。

[期待]