背景

Kohaku-Lab 是一个虚拟开源 AI 研究实验室,由 KohakuBlueleaf(叶世颖,台湾)主导。其核心项目 KohakuTerrarium 是一个多 Agent 编排框架,定位类似于 LangGraph / CrewAI,但更注重插件化和运行时可组合性。

本文是为其贡献 OpenTelemetry 可观测性插件的前置调研,梳理生态架构、插件机制,并对比业界 Agent 框架的可观测性实践。

最后更新:2026 年 5 月(基于 KohakuTerrarium v1.4.0、kt-biome v1.2.0)

一、生态全景

Kohaku-Lab 组织下共有 6 个仓库,形成以 KohakuTerrarium 为核心的依赖链:

graph TB
    KT["KohakuTerrarium v1.4.0"]
    KR["KohakuRAG"]
    KB["kt-biome v1.2.0"]
    KTe["kt-template"]
    KV["KohakuVault"]

    KT -->|depends on| KV
    KB -->|kt install| KT
    KR -->|depends on| KT

    style KT fill:#e1f5fe
    style KB fill:#e8f5e9
项目定位语言与核心关系
KohakuTerrarium多 Agent 编排框架Python 3.10+核心本身
KohakuRAG分层 RAG 引擎Python依赖核心框架
kt-biome官方插件包Python 3.12+零依赖,运行时挂载
KohakuVaultSQLite KV 存储Python核心的 pip 依赖

关键约束:kt-biome 声明零运行时依赖(pyproject.toml 无任何 pip 依赖),通过 kt install 命令安装到框架中,运行时直接继承宿主框架的能力。

二、KohakuTerrarium 核心架构(v1.4.0)

2.1 整体分层

graph TB
    subgraph Surfaces["Runtime Surfaces"]
        CLI["CLI"]
        TUI["TUI"]
        WEB["Web Dashboard"]
        DESK["Desktop"]
    end

    subgraph Studio["studio/"]
        CAT["Catalog"]
        SESS["Sessions"]
        PERS["Persistence"]
    end

    subgraph Core["core/"]
        AGENT["Creature"]
        CTRL["Controller"]
        EXEC["Executor"]
        CH["Channel"]
        COMPACT["Compact"]
    end

    subgraph Mods["modules/ 7 protocols"]
        PLUG["Plugin"]
        TOOL["Tool"]
        SUB["SubAgent"]
        UCMD["UserCommand"]
    end

    subgraph Terr["terrarium/"]
        TR["Runtime"]
        OBS["Observer"]
        GROUP["Tool Groups"]
    end

    CLI --> Studio
    WEB --> Studio
    Studio --> TR
    TR --> AGENT
    TR --> GROUP
    AGENT --> PLUG
    CTRL --> TOOL
    CTRL --> SUB

    style PLUG fill:#e8f5e9
    style Studio fill:#fff3e0

v1.4.0 新增了多个重要模块:

模块定位说明
studio/程序化 API 层Catalog / Identity / Sessions / Persistence / Editors,封装 Terrarium 引擎
builtin_skills/内置技能系统10 个 subagent skills + 28 个 tool skills,Markdown 定义的 prompt engineering
parsing/结构化解析Events / Format / Patterns / State Machine
prompt/Prompt 工程Aggregator / FrameworkHints / SkillLoader / Template / ToolContributions
serving/服务化process_metrics + web serving
sandbox/沙箱执行Config / Parse / Presets / Profile / Violations
user_command/用户命令协议第 7 个 module protocol(Slash Commands)

2.2 编排代数(Compose Algebra)

框架提供 4 种组合原语,将 Creature 组装成复杂工作流:

graph LR
    A["Sequential"] --> B["Parallel"]
    B --> C["Fan-out"]
    C --> D["Repeat"]
运算符语义示例
>>顺序执行researcher >> writer
&并行执行analyst_a & analyst_b
|扇出到多个dispatcher | [a, b, c]
*重复 N 次reviewer * 3

2.3 并行执行模型

三层异步并行机制:

  • & 运算符asyncio.gather(*branches),并行运行所有分支,延迟取最慢的一个
  • SubAgentManagerspawn() 创建 asyncio.Taskwait_all() 等待全部完成(Promise.all 语义)
  • Terrarium Runtime:每个 Creature 获得独立 asyncio.Task,Output wiring 用 fire-and-forget 分发

执行模型:单线程 asyncio 事件循环(协作并发),无需 OS 线程/多进程。LLM 调用是真正的 I/O 并发。

2.4 插件 Hook 生命周期

这是 OTEL 插件的核心接入点。v1.4.0 中 PluginHook 从 11 个扩展至 15 个

sequenceDiagram
    participant T as Terrarium
    participant O as OTEL Plugin

    T->>O: on_load
    T->>O: on_agent_start
    T->>O: pre_llm_call
    T->>O: post_llm_call
    T->>O: pre_tool_dispatch
    T->>O: pre_tool_execute
    T->>O: post_tool_execute
    T->>O: pre_subagent_run
    T->>O: post_subagent_run
    T->>O: on_compact_start
    T->>O: on_compact_end
    T->>O: on_event
    T->>O: on_interrupt
    T->>O: on_task_promoted
    T->>O: on_agent_stop
    T->>O: on_unload

新增 Hook:

  • on_load / on_unload — 插件生命周期管理
  • pre_tool_dispatch — Tool 分发前拦截(可用于路由控制)
  • on_compact_start / on_compact_end — 非阻塞上下文压缩事件(v1.4.0 新增 Compact 系统)

现有参考实现:

  • event_logger.py — JSONL 结构化日志,挂载 8 个 Hook,记录 token 用量
  • cost_tracker.py — token 成本累计 + 预算阈值告警
  • otel_metrics.py — v1.2.0 新增,OpenTelemetry Metrics + Tracing(详见下文)

三、kt-biome 插件包结构(v1.2.0)

kt-biome 是框架的官方扩展包,也是 OTEL 插件的目标仓库(Issue #45 维护者确认)。

graph TB
    Y["kohaku.yaml"] --> C["creatures x10"]
    Y --> T["terrariums x5"]
    Y --> P["plugins x12"]
    Y --> TL["tools x4"]
    Y --> IO["io x4"]
    Y --> TG["triggers x3"]
    Y --> S["skills x3"]

    C --> G["general"]
    G --> SWE["swe"]
    G --> RES["researcher"]
    G --> BG["bounded_general"]

    style P fill:#e8f5e9

v1.2.0 更新

类别变化新增项
Creatures9 → 10bounded_general(max_iterations: 50)
Plugins11 → 12otel_metrics, multimodal_guard, seamless_memory, termination_goal, pev_verifier, context_files, family_guidance
Tools不变bash_docker(容器执行), bash_ssh(远程执行)
I/O5 → 4telegram(input + output)
Triggers不变cron(完整 cron 表达式支持)
Skills更新git-commit-flow, pdf-merge, todo-file

Creature 继承general 是基座(24 tools / 6 sub-agents),swe、researcher 等继承并扩展。bounded_general 新增迭代上限。

Terrarium 拓扑示例(swe_team):

graph LR
    ROOT["root"] -->|dispatch| TASKS["tasks"]
    TASKS -->|assign| SWE["swe"]
    SWE -->|output_wiring| REV["reviewer"]
    REV -->|collect| RESULTS["results"]

3.1 已有 OTEL 插件:otel_metrics.py

kt-biome v1.2.0 已经包含了一个 OpenTelemetry 插件实现(kt_biome/plugins/otel_metrics.py),核心设计:

  • Metrics:16 个 Counter + 7 个 Histogram,DELTA temporality
  • Tracing:可选,通过 OTLP HTTP 导出
  • 懒加载try: from opentelemetry... except ImportError,不强制依赖
  • 配置:kohaku.yaml options(service_name, endpoint, export_interval)
指标类型名称示例用途
Counterkt.llm.calls / kt.llm.tokens / kt.tool / kt.subagent / kt.compact调用计数
Histogramkt.llm.duration / kt.tool.duration / kt.agent.session.duration延迟分布

这意味着 Issue #45 的基础 OTEL 支持已被实现。后续贡献方向可以是:遵循 OTel GenAI gen_ai.* 语义约定、增强 tracing、对接可观测性平台。

四、Agent 可观测性:业界共识

OTEL 插件的设计不是凭空构建——业界已形成明确共识。以下是主流框架的可观测性实践对比。

4.1 框架架构对比

框架Agent 循环模型子 Agent可观测性方案语言
Claude CodeAsync Generator 状态机递归 query(),深度 ≤1原生 OTel(Traces + Metrics + Logs)TypeScript
OpenAI Agents SDKReAct LoopHandoff 机制内置 TraceProvider,自动采集Python
AutoGen (Microsoft)消息传递循环多 Agent 对话OTel 原生,直接用 gen_ai.*Python
CrewAISequential/Hierarchical任务委派EventBus Listener + OTel ExporterPython
OpenCode (sst)ReAct for 循环Tool-based,同步阻塞PubSub Broker + JSON 调试日志Go
KohakuTerrariumCreature Controller Loop垂直 + 水平 SubAgentPlugin Hooks + Observer + otel_metricsPython

4.2 代表性架构详解

Claude Code:状态机 + 原生 OTel

Claude Code 的核心是一个约 1700 行的 async generator 函数 query.ts。每次交互都经过同一条代码路径,每次循环迭代重建不可变状态。

graph TB
    INPUT["User Input"] --> LOOP["Agent Loop"]
    LOOP --> LLM["LLM Call"]
    LLM --> PARSE{"Response?"}
    PARSE -->|tool_use| TOOL["Tool Execute"]
    PARSE -->|end_turn| OUTPUT["Output"]
    TOOL --> LOOP

    subgraph otel["OTel Spans"]
        SP1["interaction"] --> SP2["llm_request"]
        SP1 --> SP3["tool"]
    end

其可观测性设计最值得关注的三点:

  • 三级信号:Metrics(token/cost)、Log Events(结构化日志 per prompt/tool/error)、Traces(Beta,span 层级:interaction → llm_request → tool → hook)
  • W3C Trace Context 传播:子进程继承 trace context,实现跨进程链路追踪
  • Hook 系统:9 种事件类型(PreToolUse / PostToolUse / SubagentStop 等),Hook 本身是外部进程(shell/HTTP/LLM)

已知缺陷:Hook 执行本身不在 OTel 追踪范围内(Issue #44983, #50287)。

OpenCode:ReAct + PubSub

OpenCode(已归档,迁移至 charmbracelet/crush)采用经典 ReAct 循环。子 Agent 以 Tool 形式存在,同步阻塞调用,只读权限。

graph TB
    INPUT["User Input"] --> FOR["Agent Loop"]
    FOR --> STREAM["Stream LLM"]
    STREAM --> CHECK{"tool_use?"}
    CHECK -->|Yes| EXEC["Execute Tool"]
    CHECK -->|No| EXIT["Return"]
    EXEC --> FOR

    subgraph obs["Observability"]
        BROKER["Broker PubSub"]
        SLOG["Structured Log"]
        JSON["JSON Traces"]
    end

四类 Agent(coder / summarizer / task / title)是扁平字符串常量,非层级结构。可观测性依赖 Go 泛型实现的 Broker[T] 事件总线 + 结构化日志,没有 OTel 接入。

4.3 OpenTelemetry GenAI 语义约定

OTel 已发布实验性的 GenAI 语义约定(gen_ai.* 命名空间),正在成为事实标准:

Span 类型名称用途
Agentinvoke_agent每次 Agent 调用一个 span
LLMchat每次模型调用一个 span
Toolexecute_tool每次工具执行一个 span

核心属性:

  • gen_ai.operation.name — 操作类型
  • gen_ai.request.model — 模型标识
  • gen_ai.agent.name / id — Agent 标识
  • gen_ai.usage.input/output_tokens — Token 用量

核心指标:

  • gen_ai.client.token.usage(Histogram)— Token 消耗
  • gen_ai.client.operation.duration(Histogram)— 操作耗时

4.4 Agent-as-Trace 模式(新兴共识)

各框架正在收敛到同一模式:

sequenceDiagram
    participant User
    participant Agent
    participant LLM
    participant Tool

    User->>Agent: invoke
    Note over Agent: span: invoke_agent

    Agent->>LLM: chat
    Note over LLM: span: gen_ai.chat
    LLM-->>Agent: response + tool_use

    Agent->>Tool: execute
    Note over Tool: span: execute_tool
    Tool-->>Agent: result

    Agent->>LLM: chat with result
    Note over LLM: span: gen_ai.chat
    LLM-->>Agent: final answer

    Agent-->>User: output

一次 Agent 调用 = 一条分布式 Trace,包含多个嵌套 Span(Agent → LLM → Tool → LLM → ...),Token 用量在 LLM Span 级别记录,Trace 级别汇总。

4.5 可观测性平台对比

平台协议数据模型与 OTel 关系
LangfuseOTLP 原生Trace → Observation(7 种类型)直接接入
Phoenix (Arize)OTLP + OpenInferenceSpan-based翻译层 GenAI → OpenInference
LangSmith自定义 + OTel 导出@traceable 装饰器单向导出,有上下文传播缺口
W&B Weave自定义 + OTel 导出@weave.op,自动 Patch 30+ Provider导出兼容

两套竞争的语义约定(OTel gen_ai.* vs OpenInference openinference.*)正在融合——Phoenix 构建翻译层,Langfuse 直接接受 OTLP。

五、关键结论

维度结论
基础 OTEL 支持已有实现(otel_metrics.py),Metrics + 可选 Tracing
接入方式实现 PluginBase + 注册 15 个 PluginHook
参考实现otel_metrics.py(OTEL)和 event_logger.py(JSONL 日志)
依赖约束懒加载模式,OTEL SDK 为可选依赖
数据源15 个 PluginHook → 足够构建完整 Trace + Metrics
语义标准应遵循 OTel GenAI gen_ai.* 语义约定(当前实现用 kt.* 前缀)
架构模式Agent-as-Trace(业界共识)

后续贡献方向

  1. 评估 otel_metrics.py 现有实现与 OTel GenAI 语义约定的差距
  2. 考虑从 kt.* 前缀迁移到 gen_ai.* 标准前缀
  3. 增强 Tracing 能力:完整的 Span 链路(Agent → LLM → Tool → SubAgent)
  4. 对接可观测性平台(Langfuse / Phoenix / Jaeger 等)
  5. 在 swe_team terrarium 上验证 end-to-end trace 链路完整性