SoyaOS

Scope 事件与可观测性

每次 SoyaOS 运行都会发出的事件流,以及怎么消费它们。

SoyaOS 里每次 Agent 运行都会发出一串 Scope 事件——按顺序追加的 JSON 行,详细到足以排障、审计、回放。Scope 也是实时进度 UI、审计日志、外接 webhook 背后的底座。

envelope

每条 Scope 事件都共享这个 envelope:

{
  "kind":     "stage_started",
  "run_id":   "run_018f3a4b1c2d3e4f",
  "ts":       "2026-05-14T08:11:43.512Z",
  "pack":     "soya:[email protected]",
  "tenant":   "acme",
  "comet":    "cmt-a3",
  "sig":      "ed25519:…"
}
  • kind ——判别器。决定额外字段有哪些。
  • run_id ——ULID。一次运行内贯穿整条事件流。
  • ts ——RFC 3339,毫秒精度,永远 UTC。
  • pack ——按实际解析的版本写的完整包引用。
  • tenant ——Moon 租户 ID;多租户日志聚合时有用。
  • comet ——发出该事件的 Comet 实例。
  • sig ——对该事件规范 JSON(去掉 sig 本身)的 Ed25519 签名,由 Comet 的运行 Key 签出。下游可验证事件没被篡改。

事件类型

健康的运行里大致按这个顺序出现:

Kind何时发出关键额外字段
run_startedComet 接受一次运行。inputs_hash, cache_mode
stage_started一个 prompt / tool 阶段开始。stage
tool_called调用了一个声明过的工具。tool, args, tool_id
tool_completed工具返回。tool_id, ok, duration_ms
llm_request向上游 LLM 发出请求。upstream, model, prompt_tokens
llm_response上游响应完整接收。upstream, completion_tokens
artifact_writtenAgent 在 /workdir/out 写了一个产物。name, schema, size_bytes
stage_completed阶段正常退出。stage, artifacts
capability_violation沙箱或能力检查失败。surface, requested, matched
error未捕获异常,或工具非零退出。stage, message, code
run_completed终结事件。永远恰好发一次。ok, total_ms, artifacts, cost

run_completed 即使在失败时(ok: false)也会发。把它当「流结束」的订阅者永远不会挂死。

消费方式

CLI 里

soyaos --json run hello --input @hello.json | jq -c .

管道接 jqvector、任意行式工具。输出是换行分隔的 JSON(“NDJSON”)。

OpenAI 兼容客户端

/v1/chat/completions 端点在 stream: true 时按 SSE 流式返回。data: 帧是 OpenAI 形状(choices[0].delta.content);Scope 事件在并行的 x-soya-scope: SSE 通道里同步发,需要的客户端可以一起订。

Webhook

Moon 可以配置成把一批 Scope 事件 POST 到 webhook URL:

# moon.config.yaml(片段)
webhooks:
  - url: https://your-app.example.com/soya-events
    secret: ${WEBHOOK_SECRET}
    kinds: [run_completed, capability_violation]   # 过滤;默认全发
    delivery: at_least_once

at_least_once 意味着会出现重复——按 (run_id, kind, ts) 去重。

长订阅

soyaos scope tail --tenant acme --filter 'kind == "run_completed"' --since 5m

排障级 tail。「刚才跑了什么、为什么」时用。先打 Moon 的环形缓冲(每租户最近约 1 万条事件),再流式收新事件。

SoyaScope——UI

SoyaScope 是本地 web UI,把 Scope 事件流可视化。在 solo 里就是 http://127.0.0.1:7474/ 落地页。按 run_id 分组、展示阶段时间线、能力越界标红、可以从任意事件之后回放运行。

签名与完整性

每条 Scope 事件里的 Ed25519 签名用的是单次运行 Key,不是 Comet 的长期 Key。链路:

  1. Moon 接受运行时签发一对新签名密钥。
  2. Comet 通过它的认证 WebSocket 收到私钥。
  3. Comet 发每条 Scope 事件前签名。
  4. Moon 把公钥跟运行记录存在一起;下游订阅者用它验签。

把 Scope 事件接进外部 SIEM 时,可以用 Moon 的单次运行公钥验每条事件的 sig——从「Comet 发出」到「落进审计日志」全链路可追溯。

保留期

Moon 默认保留:

  • 热环形缓冲——每租户最近 1 万条。内存,亚毫秒级读。
  • 温冷存储——30 天,跟 SoyaPack 仓库共用同一 S3 兼容桶。按 run_id 可查。
  • 冷归档——超过 30 天,只有租户设了 archive: true 才存。按月 gzip。

ent-private 部署自己配保留策略;上面是 cloud / ent-cloud 的默认。

每条事件在一次请求中扮演的角色见架构;SSE 线协议见 HTTP API

在 GitHub 上编辑本页