架构
Planet、Moon、Comet——组成每一种 SoyaOS 部署的三种节点角色。
SoyaOS 是一份能扮演三种角色的二进制。部署,无非是这三种角色组成的某一种形态。无论你是在笔记本上跑 solo 还是在封闭机房里跑 enterprise-private,角色边界和角色间协议永远不变——变的只有拓扑。
三种节点角色
Comet
Comet 是短生命周期的工作节点。它跑一次 Agent 调用、把输出流式吐出来,然后退出。Comet 是无状态的——从 Moon 拉取 SoyaPack 包、挂载沙箱化的 /workdir,过程中持续发出 Scope 事件。
心智模型:Comet 就是为一次 Agent 运行准备的、被严格塑形的
kubectl exec。
Comet 具体做的事:
- 通过出网 HTTPS WebSocket 订阅一个 Moon,等任务。
- 把 SoyaPack 物化到临时目录,校验签名,能力白名单在本机不可满足时直接拒绝运行。
- 通过同一个 WebSocket 把 stdout 和 Scope 事件回流。
- 超过
idle_timeout(默认 300s)或max_runs(默认无限)后自动退出。
Moon
Moon 是单租户的控制面。它承载开发者和用户对话的 API 表面、托管 SoyaPack 仓库、签发 API Key、转发 Scope 事件。Moon 不自己跑 Agent——它把任务派发给 Comet。
心智模型:Moon 是「团队工作区」。一家公司 / 一个工作室 / 一户人家配一个。
Moon 内部组件:
- OpenAI 兼容端点(
/v1/chat/completions)——接收model: "soya:*"请求,解析到具体 SoyaPack 版本,挑一个 Comet,返回流式响应。 - SoyaPack 仓库——版本化、内容寻址的包,后端是 S3 兼容对象存储。
- 鉴权表面——签发 API Key 和能力 token;push 时校验包签名。
- Scope broker——把每次运行的事件多路复用给订阅者(Studio、开发者门户、webhook)。
Planet
Planet 是联邦根。它持有身份(你是谁)、计费(如有)、跨 Moon 路由。在 solo 部署里没有独立 Planet——Planet、Moon、Comet 折叠到一个进程。
心智模型:Planet 是「星座运营方」。单租户部署可选不用。
Planet 的职责:
- 身份——用户和 Moon 的 OIDC 颁发方;签 SSO 断言。
- 路由——把租户 URL(
tenant.moon.example.com)映射到具体的 Moon。 - 跨 Moon 合约——唯一有权授权某个 SoyaPack 在源租户之外的 Moon 上运行的实体。
一次请求是怎么流动的
- 客户端调用 Moon 上的 OpenAI 兼容端点:
POST /v1/chat/completions,model: "soya:compo"。 - Moon 把
soya:compo解析到具体 SoyaPack 版本(如soya:[email protected]),挑一个热 Comet(或冷启)。 - Comet 在沙箱里执行 Agent,按能力白名单调上游 LLM,把 Scope 事件经 Moon 回流。
- Moon 把事件多路复用给订阅者(Studio、开发者门户、webhook)。
- Agent 完成后,Comet 发出最终产物 JSON,自动退出(或按
idle_timeout回到热池)。
一次实际的事件轨迹
一次 soya:compo 调用的 Scope 事件流大致是:
00.000 run_started run_id=run_018f… pack=soya:[email protected] comet=cmt-a3
00.012 stage_started stage=outline
00.087 tool_called tool=fetch_reference args={url:…} # 能力检查:egress.host
00.412 tool_completed tool=fetch_reference ok=true
00.514 llm_request upstream=claude-sonnet-4-6 prompt_tokens=1842
01.823 llm_response completion_tokens=612
01.834 stage_completed stage=outline artifacts=[outline.v1]
01.835 stage_started stage=writer
…
04.219 run_completed ok=true artifacts=[outline.v1, guide.v1]
每条事件都是 JSON,envelope 一致(run_id、ts、kind),且都由 Comet 的运行 Key 签名——详见 Scope 事件与可观测性。
为什么这样切?
- 扩缩形态:Comet 是牛群,Moon 是宠物,Planet 是接近宠物的存在。一个 Moon 后面可以挂百万 Comet。Moon 单实例垂直扩展到约 1 万并发;再往上就按租户分片到多个 Moon。
- 安全:每个 Agent 都跑在 Comet 的能力白名单里;Moon 永远不执行用户代码。被攻破的 Comet 拿不到 Moon 的秘密——Comet 只见到自己那条短期运行 Key。
- 联邦:多个 Moon 可以挂在同一个 Planet 下,也可以在
enterprise-cloud部署里向多个 Planet 汇聚。Planet 故障不会把 Moon 拖下水——Moon 缓存身份证书,直到证书过期前一直能继续服务。
角色到版本的映射
| 版本 | Comet 跑在哪里 | Moon 跑在哪里 | Planet 跑在哪里 |
|---|---|---|---|
solo | 进程内 | 进程内 | 无(折叠掉) |
cluster | 你的 LAN / VPC | 你的 VPS | 无 或 你的 VPS |
cloud | soyaos.ai | soyaos.ai | soyaos.ai |
hybrid | 你的 VPC | soyaos.ai | soyaos.ai |
ent-cloud | soyaos.ai(独占) | soyaos.ai(独占) | soyaos.ai(region 绑定) |
ent-private | 客户自运维 | 客户自运维 | 客户自运维 |