跳转到内容

什么是 OpAgent

OpAgent是一个真正意义上的AgentOS

传统操作系统回答的是:应用怎么启动?文件放在哪里?进程怎么隔离?网络怎么连接?出错了怎么处理?

Agent 操作系统回答的是另一组问题:

  • Agent怎么启动?
  • Agent在哪里运行?
  • Agent有哪些能力?
  • Agent之间如何协作?
  • 单个Agent崩溃会不会影响主程序?
  • 运行在本机,还是运行在远程?
  • 不同机器、不同Agent的Token消耗、进程和端口占用等。

把这些问题放到一起,就不再是一个简单的聊天框了。它更像是 Agent 的运行层。

在 OpAgent 里,一个任务大概是这样发生的:

  1. 你打开一个目录,比如 docs/
  2. OpAgent 把这个目录作为一个工作空间。
  3. 你给这个目录绑定一个写作 Agent。
  4. Agent 读取目录里的资料,和你在 Markdown 里讨论。
  5. 对话过程保存成文件,Agent 的输出也写回目录。
  6. 如果需要,它可以调用另一个校对 Agent,或者调用一个工具。
  7. 如果这个目录在远程机器上,OpAgent 会通过 SSH 启动远端 runtime,让 Agent 在远程目录里工作。

如果只做一个 Agent,很多事情都可以写死在程序里。但当一个用户有多个目录、多个 Agent、多个模型、多个远程环境时,就需要一层系统来管这些关系。AgentOS做的就是这一层。

为什么不是 LangChain、LangGraph、Claude SDK?

Section titled “为什么不是 LangChain、LangGraph、Claude SDK?”

从 2025 年 4 月份开始,我研究 MCP 协议。当时我正在做一个 Golang 插件系统,于是想到:既然 MCP 可以调用 Tools,为什么不能调用 Agent?于是有了一个想法:把 Agent 像插件一样装进运行时里。

LangChain、LangGraph 更适合在代码里编排一次 Agent 流程。开发者把模型、工具、状态图写进同一个程序,再由这个程序对外提供能力。

但 OpAgent 想做的不是“写 Agent 应用的框架”,而是“运行 Agent 的环境”。在这个环境里:

  • 一个 Agent 可以由不同团队独立开发。
  • 一个 Agent 可以是独立进程,崩溃后不拖垮主程序。
  • 一个 Agent 可以用 Go、Python、Node 或其他语言实现。
  • 一个 Agent 可以安装、升级、替换。
  • 一个 Agent 可以是本地,也可以是远程。
  • 一个目录可以有自己的 Agent,子目录也可以有自己的 Agent。

所以 OpAgent 更关心运行时、通信协议、进程边界、目录绑定和文件保存方式,而不是把所有 Agent 逻辑都写到一个应用进程里。

在 OpAgent 里,Agent、Tool、Skill 都叫 Node。

这样做是为了让它们使用同一套接入方式。Agent 负责理解任务和规划;Tool 负责执行具体动作;Skill 负责封装某类能力。它们职责不同,但在 runtime 看来,都是可以被发现、被调用的能力单元。

一个复杂 Agent 可以作为独立进程运行,也可以部署成远程服务。一个简单的提示词 Agent 不需要启动独立进程,runtime 直接读取它的定义并加载到内存里。

type OpNode struct {
ID string `json:"id"` // persistent node id, e.g. agent-cm1...
HostID string `json:"hostID,omitempty" mapstructure:"hostID"` // host id
UID string `json:"uid"` // owner/tenant identifier
OpCodes []OpCode `json:"opCodes,omitempty"`
Kind string `json:"kind"` // agent | skill | tools
URI string `json:"uri"` // resource locator (file://, cloudos://, ...)
Cwd string `json:"cwd"` // current working directory
Tags []string `json:"tags,omitempty"`
Run Run `json:"run,omitempty"`
Meta any `json:"meta,omitempty"` // AgentMeta | SkillMeta | ToolsMeta
}

Node 之间通过 OpCode 表达自己能做什么。比如:

agent/call
agent/continue
agent/loop/create
prompt/get
agent/scan
node/list
notify/message
thread/submit
thread/compact
......

runtime 看到这些声明后,就知道应该把请求发给谁。一个 Agent 要调用另一个 Agent,不需要知道对方是本地进程、远程服务,还是内存里的轻量定义;只要按协议发送对应的操作即可。

这个设计受 MCP 启发。MCP 把上层消息和底层连接拆开:上层用 JSON-RPC 表达请求、响应和通知,底层可以用 stdio、HTTP stream 等方式传输。OpAgent 也采用类似思路,让不同语言、不同部署方式的 Agent 能接到同一个系统里。

很多工具把“项目”当作边界:一个项目,一个 AI 助手,一份上下文。

OpAgent 更愿意用目录作为边界。目录本来就是你组织工作的方式:docs/ 放文档,src/ 放代码,deploy/ 放部署脚本,research/ 放资料。不同目录需要的 Agent 往往也不同。

比如:

  • docs/ 绑定写作 Agent。
  • src/ 绑定代码 Agent。
  • deploy/ 绑定运维 Agent。
  • research/ 绑定研究 Agent。

这些 Agent 不需要挤在同一个大上下文里。它们各自读自己目录里的文件,修改自己负责的内容。需要协作时,通过文件和对话记录把结果交给下一个 Agent。

在很多 AI 产品里,对话存在应用自己的数据库里。你可以在界面里回看,但很难直接编辑、复制、用 Git 管理,也很难让另一个工具继续处理。

OpAgent 把对话保存成 Markdown 文件。

这意味着你让 Agent 写的一份方案,不会只停留在聊天记录里。它本身就是一个 .md 文件。你可以直接打开它,改标题,删掉废话,补充资料,提交到 Git,或者把它移动到另一个目录继续用。

一次需求讨论、一轮代码审查、一段排障过程,都可以作为文件留下来。之后再打开,不需要先回忆当时聊了什么,文件就在目录里。

OpAgent 这里延续的是 UNIX 的思路:能落到文件里的,就不要藏进应用自己的黑盒数据库。

在 UNIX 里,文件不只是“文档”。配置是文件,日志是文件,输入输出也是文件。这样做的好处很朴素:用户可以用已有工具打开、搜索、复制、备份、diff、提交到 Git,也可以把一个程序的输出交给另一个程序继续处理。

OpAgent 把这个思路放到 Agent 工作流里:

  • 对话是 Markdown 文件。
  • Thread 是 jsonl 文件。
  • Agent、Skill、模型和工作区配置尽量是本地文件。
  • Agent 生成的草稿、计划、审阅结果,也回到当前目录里的文件。

文件系统在这里不是一个“保存结果”的地方,而是 Agent 协作的接口。人可以直接编辑这些文件,Agent 也可以继续读取这些文件;一个 Agent 写下来的内容,可以被另一个 Agent 接着处理。

传统 IDE 往往是一个窗口对应一个项目。打开另一个项目,就要再开一个窗口。

OpAgent 把窗口和工作空间拆开。窗口只是界面容器,工作空间才是具体目录。

所以一个窗口里可以同时放多个目录。你可以在同一个窗口里打开写作目录、代码目录、资料目录和远程服务器目录。每个目录有自己的 Agent、对话和配置。移除一个目录,也不会影响其他目录。

很多 AI 工具把对话放在侧边栏里。这样一来,AI 更像一个临时助手:它说完一段内容,用户再把有用部分复制到正文里。时间一长,对话和文档就分成了两个世界。

OpAgent 不这样做。它把对话和文件放在同一个编辑区里:上面是文件 tab,放正在写的文档、代码、配置;下面是对话 tab,放和 Agent 讨论这些内容的过程。

上下分开,是为了区分“结果”和“过程”。共用同一个编辑区,是为了让结果和过程可以随时互相转化。

比如写一份方案,上面的文件 tab 是正式文档,下面的对话 tab 是和 Agent 讨论思路、补充背景、修改段落的过程。Agent 生成的内容不需要先从聊天框复制出来。你可以直接在对话里删改、整理,把成熟的部分放进正式文档;也可以让 Agent 继续读取你改过的内容,接着往下做。

这个设计的重点不是复用界面组件,而是改变 AI 参与工作的方式:对话不再是旁边的一串聊天记录,而是文档生成过程的一部分。

OpAgent 不把“本地”和“远程”做成两套产品。本地目录、远程服务器目录,在界面里都是工作空间。区别只在于:Agent 实际在哪台机器上读文件、写文件、执行命令。

本地工作空间很直接:目录在你的电脑上,Agent 就在这台机器上工作。写作资料、私人笔记、小项目代码、临时研究文档,都可以放在本地。这样做的好处是简单、可控,数据不用离开自己的机器。

远程工作空间解决的是另一类问题:很多真实工作现场并不在本机。代码可能在开发机上,数据可能在内网服务器上,任务可能依赖 Linux 环境、GPU、数据库或公司内网。传统做法要么把文件同步到本地,要么开终端登录服务器。OpAgent 的做法是:本地客户端只负责界面,Agent 真正运行在远程机器上。

连接远程时,OpAgent 会通过 SSH 准备远端环境,在远端启动 opagent-runtimeopagent-server,再通过本地端口转发连回来。用户看到的是一个普通工作空间 tab,但文件读写、命令执行、上下文保存都发生在远程目录里。

这样,本地和远程可以放在同一个窗口里。一个 tab 是本机文档目录,另一个 tab 是远程开发机上的代码目录。你不用在编辑器、终端、远程桌面之间来回切换,也不用为了让 Agent 工作而把服务器上的内容搬到本地。

这个设计的重点不是“支持 SSH”本身,而是让 Agent 跟着工作现场走:文件在哪里,环境在哪里,Agent 就在哪里运行;人仍然用同一个 OpAgent 窗口管理它们。

OpAgent 把 Markdown 当作人和 Agent 共同使用的界面。

原因很简单:人能直接读,Agent 也容易改。标题、列表、代码块、表格、引用和链接,已经足够表达大部分协作过程。

在 OpAgent 里,对话、计划、任务拆解、审阅结果和 Agent 输出,都可以用 Markdown 保存。用户可以直接改,Agent 下一轮也能继续读。

当下很多编辑器是在已有编辑器上加一个 AI 侧边栏。OpAgent 的思路不同:从一开始就把 AI 工作过程放进 Markdown 文件里。

场景OpAgentCursorClaude CodeObsidianTypora
Markdown 编辑✅所见即所得⚠️源码编辑❌终端输出✅所见即所得✅所见即所得
Markdown 修改审阅✅AI 修改可审查⚠️源码审查⚠️源码审查❌无❌无
工作空间✅一个窗口多个工作空间⚠️一个窗口一个工作空间⚠️终端 tab⚠️一个窗口一个工作空间⚠️一个窗口一个工作空间
对话文件✅本地 .md 文件❌隐藏在应用数据里⚠️隐藏在项目数据里❌无原生能力❌无
多模型✅任意模型✅任意模型❌主要绑定 Anthropic❌无原生能力❌无
一个项目多个 Agent✅Agent 和目录绑定❌项目级单一 AI❌会话级❌无原生能力❌无
管理 Agents、Skills✅可视化管理❌隐藏在文件里❌无❌无❌无

OpAgent 不需要重新实现所有 Agent 能力。

Claude Code、Codex,或者团队内部已有的命令行 Agent、服务型 Agent,都应该能接进来。

OpAgent 提供 opagent-protocol SDK。外部 Agent 实现协议后,就可以作为一个标准 Node 被调用:绑定到目录,接收上下文,流式返回结果,也可以执行 agent/callthread/submitnotify/message 等操作。

这样外部 Agent 不只是一个孤立终端工具。它可以进入 OpAgent 的目录、文件、对话和工作空间体系中。用户仍然在同一个界面里使用它,结果也仍然回到当前工作目录。

Marketplace 用来分发 Agent、Skill、Tool 和 Workspace 模板。

这里的“安装”不是把一个黑盒功能塞进应用里。安装后,你会在本地得到一组文件:Agent 定义、提示词、配置、示例目录,或者一套完整的 Workspace 模板。

比如团队做了一个“产品需求评审”工作流,可以把它打包成模板。其他人安装后,会得到目录结构、Agent 配置、模型配置、提示词和示例文件。用户可以直接用,也可以改成自己的版本。

Marketplace 解决的是复用问题:一个人或一个团队跑通的 Agent 工作方式,不必每次从零配置。

LLM 已经不只是回答问题。它可以读文件、改代码、查资料、调用工具、执行命令。

但很多产品的工作方式还停留在聊天框里:对话存在应用内部,生成结果需要复制出来,Agent 只能跟着一个项目或一个会话走。时间久了,用户很难整理这些过程,也很难把它们交给另一个工具继续处理。

OpAgent 的做法很直接:把 Agent 放到目录里,把对话保存成文件,把外部 Agent 接到同一个协议里,把本地和远程目录放到同一个窗口里。