【OpenLIT】Harness 6 件套之 Hook 总线:OTel 原生 55 Instrumentor 的零侵入观测原理
引子
2026 年的 AI Agent 工程化领域,有两个明显的「观测痛点」正在变得越来越尖锐:
- 多框架碎片化:同一个团队里,可能同时跑着 OpenAI SDK、Anthropic SDK、LangChain、LlamaIndex、CrewAI、MCP Client——每家各自打印日志、互不联通,调试时常常要打开 5 个窗口对时间戳。
- Span 嵌套混乱:Agent 主循环会调用 LLM,LLM 会触发 Tool,Tool 又会调向量库;没有一套统一的事件总线,Trace 出来就是一锅意大利面,分不清哪个 Span 是哪个 Agent 干的。
openlit/openlit(⭐2,739,Apache-2.0)是 2024 年由 ScaleOps 团队开源的「AI Engineering 平台」,覆盖观测(Observability)、评估(Evaluations)、规则引擎(Rule Engine)、Guardrails、Prompt 管理、密钥金库、Playground 7 大能力,但最核心的设计是用一行 openlit.init() 让 55 个 LLM/Agent/VectorDB/GPU 框架自动接入 OpenTelemetry——这恰好填补了 Harness 6 件套里「Hook 组件」的空缺。
本文将围绕 OpenLIT 的 Hook 总线设计展开:它如何用 OTel 三件套(Trace + Metric + Log)做「机制层」?如何用 Instrumentor Registry 做「策略层」?如何用 Guard Pipeline + Rule Engine 把「观测」升级为「治理」?以及最重要的——为什么 Hook 组件是 Harness 把 Agent 从「能跑」变成「能稳」的关键齿轮。
项目定位与核心价值
一句话定义
OpenLIT = OpenTelemetry-native LLM/Agent Observability SDK + Guardrail Pipeline + Rule Engine + UI。和 Langfuse、Helicone、Arize Phoenix 相比,OpenLIT 的最大差异是:
「我把 OTel 作为一等公民,而不是私有协议 —— 你的 Trace 可以无成本接入任何后端(Jaeger/Tempo/SigNoz/Datadog/NewRelic),不需要改一行业务代码。」
能力矩阵
| 能力 | 是否原生支持 | 备注 |
|---|---|---|
| 🔌 OpenTelemetry-native Trace / Metric / Log | ✅ | 三件套齐全,符合 OTel GenAI Semantic Conventions |
| 📊 50+ LLM Provider Instrumentor | ✅ | OpenAI、Anthropic、Cohere、Mistral、Bedrock、Gemini 等 |
| 🤖 18 个 Agent Framework Instrumentor | ✅ | LangChain、LangGraph、LlamaIndex、CrewAI、AutoGen、MCP、Smolagents、Pydantic AI 等 |
| 🗄️ VectorDB Instrumentor | ✅ | Chroma、Pinecone、Qdrant、Milvus、Mem0 |
| 🛡️ Guard Pipeline(7 类 Guard) | ✅ | PII、Prompt Injection、Sensitive Topic、Moderation、Schema、Topic Restriction、Custom |
| ⚙️ Rule Engine | ✅ | 条件 AND/OR 匹配 + 动态绑定 Prompt/Context/Eval Config |
| 📈 GPU 监控 | ✅ | NVIDIA + AMD 双支持 |
| 💲 自定义模型计费 | ✅ | 通过 pricing JSON 文件 |
| 💭 Prompt Hub | ✅ | 版本化 Prompt 管理 |
| 🔑 Vault | ✅ | API Key 集中管理 |
| 🧪 11 类 LLM-as-Judge Eval | ✅ | Hallucination、Bias、Toxicity、Safety 等 |
| 🌐 三语言 SDK | ✅ | Python、TypeScript、Go |
仓库统计
- 3 个 SDK:
sdk/python(最大)、sdk/typescript、sdk/go - 55 个 Instrumentor 模块:在
sdk/python/src/openlit/instrumentation/下,每个目录对应一个 Provider/Framework - 代码量:仅 Python SDK 就 5,000+ 文件,README 30,000+ 字符
- 社区:Apache-2.0 License,已被多家 LLM 厂商 / Agent 框架作为推荐观测方案
- 最近更新:2026-09-04(持续活跃)
整体架构
OpenLIT 的架构可以分成 6 层。每一层都围绕 Hook 组件展开:
graph TB
A["🎯 用户应用<br/>openlit.init() 一行接入"] --> B["⚙️ Instrumentor Registry<br/>55 个 Instrumentor 动态加载"]
B --> C["🪝 Hook 总线<br/>OTel Tracer + Meter + Event Logger"]
C --> D["📊 三件套<br/>Span / Metric / LogRecord"]
D --> E["📡 OTLP Exporter<br/>HTTP/gRPC 双协议"]
E --> F["🗄️ 后端存储<br/>Jaeger/Tempo/SigNoz/OpenLIT UI"]
A -.-> G["🛡️ Guard Pipeline<br/>PII/PromptInj/Topic..."]
G --> C
A -.-> H["⚙️ Rule Engine<br/>条件匹配 → Prompt/Eval"]
H --> C
style A fill:#C7CEEA,stroke:#7B8AB8,color:#333
style B fill:#E8D5F5,stroke:#A78BC9,color:#333
style C fill:#FFDAB9,stroke:#D89B6C,color:#333
style D fill:#FFF9C4,stroke:#D4C25A,color:#333
style E fill:#B5EAD7,stroke:#6BB89A,color:#333
style F fill:#F5F5F5,stroke:#999,color:#333
style G fill:#FFB3C6,stroke:#D87090,color:#333
style H fill:#E8D5F5,stroke:#A78BC9,color:#333关键设计哲学:
- 机制 vs 策略分离:OTel 三件套是「机制」(怎么记录),Instrumentor 是「策略」(记录谁)
- 零侵入:用户业务代码不需要 import openlit 的任何类型,只调用
openlit.init()即可 - 后端无关:OTLP 标准协议意味着可以对接任何 OTel 兼容后端
- 观测 + 治理双轨:Hook 总线不仅收集 Trace,还能被 Guard Pipeline / Rule Engine 当作触发点
核心机制一:Instrumentor Registry(Hook 装载器)
OpenLIT 的 Hook 总线设计,最精妙的部分是 「Instrumentor Registry」——一个 50+ Provider/Framework 的统一抽象层。
1. 注册表数据模型
1 | # sdk/python/src/openlit/_instrumentors.py |
这个 dict 是 Hook 总线的「调度表」:每个 key 是 Instrumentor 名称(用户友好),value 是实际要 import 的 Python 包名(pip 安装时的命名)。
2. 智能加载机制
1 | # sdk/python/src/openlit/_instrumentors.py(节选) |
核心技巧:
find_spec()自动探测:OpenLIT 不强迫用户写instrument(["openai", "langchain"]),而是扫描 sys.modules —— 用户 pip install 了什么包就启用什么 Instrumentor- 别名词典:用户写
'aiohttp'和写'aiohttp-client'等价 - 可选禁用:
instrumentor_list=['openai']可以只启用部分(其他即使装了也不挂 Hook)
3. OpenAI Instrumentor 实例
看一个具体 Instrumentor 怎么挂 Hook:
1 | # sdk/python/src/openlit/instrumentation/openai/openai.py(节选) |
Hook 装载的 4 个钩子时机:
| 钩子时机 | 触发位置 | 写入数据 |
|---|---|---|
| 请求前 | wrapper() 入口 | Span 属性(model、messages、temperature、tools) |
| 每个 Chunk | __next__() | TTFT、TBT、partial_response |
| 流结束 | process_streaming_chat_response() | 总 token 数、cost、latency、完整 response |
| 异常 | handle_exception() | error.type、status=ERROR、exception event |
这就是 Harness 的「机制和策略分离」典范:
- 机制(OTel SDK 负责):怎么开 Span、怎么记录 metric、怎么发 OTLP
- 策略(OpenLIT Instrumentor 负责):在 OpenAI 哪些字段要记录、TTFT 怎么算、cost 怎么估算
策略改了不影响机制,机制升级(OTel SDK 升级)不影响策略。
核心机制二:OTel 三件套(Hook 总线的物理层)
OpenLIT 严格遵循 OTel 三件套:Trace + Metric + LogRecord。每件都有独立的 setup 函数:
1. Trace 通道
1 | # sdk/python/src/openlit/otel/tracing.py(节选) |
关键设计:
- 「检测 + 复用」语义:如果用户已经配过 TracerProvider(比如在 FastAPI / Django 应用里自己装了 OTel),OpenLIT 不会覆盖而是添加 Instrumentor。这就是「机制层零侵入」
- 环境变量优先:OTLP endpoint 也可以用
OTEL_EXPORTER_OTLP_ENDPOINT标准环境变量,不用 OpenLIT 私有协议 - Batch/Simple 二选一:开发时禁用 Batch(错误立刻看到),生产时用 Batch(吞吐高)
2. Metric 通道(含 GenAI 专用桶)
1 | # sdk/python/src/openlit/otel/metrics.py(节选) |
为什么要专门定义桶? —— 因为 LLM 调用的延迟分布(亚秒到分钟级)、Token 数(小到 1、大到 67M)和其他服务完全不同。用默认 OTel 桶会全部丢失细节。
3. Event/Log 通道(精细事件)
1 | # sdk/python/src/openlit/otel/events.py(节选) |
Event vs Span 的区别(OTel 设计):
- Span:有 start/end 时间、parent-child 关系、duration
- Event:瞬时点(no duration),适合「用户发出 prompt」「检测到 PII」「guard deny」这种离散事件
1 | # __helpers.py 中的 otel_event 工厂 |
妙处:用户调用 otel_event('gen_ai.choice', attrs, body) 后,得到的 LogRecord 会自动继承全局 custom attributes 和当前 ContextVar 里 propagate 的属性。这就是 ContextVar 跨 Span/Event 标签传播 的关键。
核心机制三:ContextVar 跨调用传播(多 Agent 标签传递)
Agent 框架最大的观测难题:当 CrewAI 的 Agent A 调用 Agent B,B 又调 LLM C,OTel Span 默认没法把「agent=A 触发的」标签传给 C。OpenLIT 用 ContextVar 解决:
1 | # __helpers.py(节选) |
这就是 Hook 总线的「Context 穿透」:
graph LR
A["🤖 CrewAI Agent A<br/>(set_agent_name('researcher'))"] --> B["🔧 Tool: search"]
B --> C["🧠 OpenAI LLM<br/>(自动读取 ContextVar)"]
A -.标签传播.-> C
style A fill:#C7CEEA,stroke:#7B8AB8,color:#333
style B fill:#FFDAB9,stroke:#D89B6C,color:#333
style C fill:#E8D5F5,stroke:#A78BC9,color:#333CrewAI Instrumentor 在进入 Agent 作用域时 set_agent_name('researcher'),下游 LLM Instrumentor 读这个 ContextVar 把 gen_ai.agent.name=researcher 写进 Span —— 不需要改 LLM Instrumentor 一行代码。
ContextVar vs 全局变量:
| 维度 | ContextVar | 全局变量 |
|---|---|---|
| 协程安全 | ✅ 每个协程独立 | ❌ asyncio 下互相覆盖 |
| 嵌套作用域 | ✅ token reset 自动恢复 | ❌ 必须手动保存恢复 |
| 多线程 | ✅ 每个 thread 独立 | ⚠️ 要加锁 |
| 跨 await | ✅ 自动 propagate | ❌ 会丢失 |
OpenLIT 全用 ContextVar,所以支持 async / 多 Agent 并发。
核心机制四:Guard Pipeline(Hook 总线的「治理」升级)
光「观测」还不够,OpenLIT 在 Hook 总线上又加了一层「治理」——Guard Pipeline。这是一个有序的多 Guard 链,每个 Guard 可以在 LLM 调用前(preflight)/ 后(postflight)跑,决定 allow / warn / redact / deny。
1. 数据模型
1 | # sdk/python/src/openlit/guard/_base.py |
2. Pipeline 聚合算法
1 | # sdk/python/src/openlit/guard/_pipeline.py |
3. 7 类内置 Guard
1 | # sdk/python/src/openlit/guard/__init__.py |
4. Pipeline 的 4 条不变量
| # | 不变量 | 实现 |
|---|---|---|
| 1 | DENY 短路 | 一旦某个 Guard 返回 DENY,后面的 Guard 不跑(节省 LLM judge 成本) |
| 2 | REDACT 链式 | REDACT 改写后的文本传给下一个 Guard(不能跳过) |
| 3 | fail_open 默认 | 单个 Guard 崩溃 → 记 warning 后放行(不让坏 Guard 拖垮整个 LLM 调用) |
| 4 | OTel 双向 | 每个 Guard 都发 metric + event(观测性 vs 治理性闭环) |
这就是 Harness「Hook 既是观测点,也是治理点」的双重身份。
核心机制六:可运行的零侵入示例
下面是一段真实可运行的代码,演示 Hook 总线全部能力(Trace + Metric + Guard + ContextVar 传播):
1 | # pip install openlit openai |
预期 Hook 输出(伪 OTLP JSON):
1 | { |
零侵入的本质:用户业务代码 0 改动 OpenLIT —— 没有 import openlit 类型、没有传任何 OpenLIT 参数、没有用 OpenLIT 的 logger。Hook 在 import 期就完成了织入(基于 wrapt 库的 monkey-patch)。
核心机制七:Rule Engine(Hook 总线的「策略外置」)
除了运行时 Hook,OpenLIT 还有个「部署时 Hook」——Rule Engine。它允许在 UI 上定义条件规则,命中后自动注入Prompt、Context、Eval Config。
graph LR
A["⚙️ Rule 条件<br/>AND/OR 匹配<br/>(trace.attr.cost > 0.05)"] --> B{"🔍 匹配"}
B -->|命中| C["📚 关联 Prompt<br/>自动注入 system prompt"]
B -->|命中| D["🔢 关联 Context<br/>自动附加到 messages"]
B -->|命中| E["✅ 关联 Eval Config<br/>自动跑 LLM-as-Judge"]
style A fill:#E8D5F5,stroke:#A78BC9,color:#333
style B fill:#FFF9C4,stroke:#D4C25A,color:#333
style C fill:#C7CEEA,stroke:#7B8AB8,color:#333
style D fill:#B5EAD7,stroke:#6BB89A,color:#333
style E fill:#FFDAB9,stroke:#D89B6C,color:#333Rule YAML 示例:
1 | rules: |
Rule Engine 是 Hook 总线的「配置驱动」:
- 机制:Rule 匹配引擎(纯逻辑)
- 策略:Rule 本身(YAML/UI 配置)
- 可观测:每次 Rule 命中发 metric(
rule.evaluations{rule.name, rule.matched})
这和 Anthropic Claude Code 的 Rule(CLAUDE.md)、Agent Skills 的 SKILL.md 是同一思路 —— 「把策略从代码里搬出来,让非工程师也能改 Hook 行为」。
横向对比
对比一:OpenLIT vs Langfuse
| 维度 | OpenLIT | Langfuse |
|---|---|---|
| 协议基础 | OpenTelemetry 一等公民 | 私有协议 + 部分 OTel 兼容 |
| 后端兼容性 | ✅ 任何 OTel 后端(Jaeger/Tempo/SigNoz/Datadog) | ⚠️ 主要自家 UI,少量 OTel 输出 |
| Instrumentor 数量 | 55(Python)+ TS + Go | ~30(Python + JS) |
| Guardrail | ✅ 7 类内置 Guard + Pipeline | ⚠️ 仅基础 Eval,无运行时 Guard |
| Rule Engine | ✅ UI 拖拽条件 | ⚠️ 无 |
| 数据所有权 | 完全自托管(ClickHouse + OpenLIT UI) | 自托管但推荐用 Langfuse Cloud |
| Guard/Rule 配套 UI | ✅ 内置 | ❌ 无 |
| 生态成熟度 | Apache-2.0,1.5 年 | Other(部分 MIT),3 年+ |
关键差异:Langfuse 是「AI 优先的私有协议观测」,OpenLIT 是「OTel 原生的 AI 观测」。如果你已经在用 Jaeger/Tempo/Datadog,OpenLIT 无成本接入;如果你愿意吃一个私有协议,Langfuse 的 UI 更成熟。
对比二:OpenLIT vs Helicone
| 维度 | OpenLIT | Helicone |
|---|---|---|
| 核心定位 | AI Observability + Guardrail + Rule | AI Gateway + Observability + Routing |
| Hook 机制 | wrapt monkey-patch | Proxy 拦截(API 网关模式) |
| 数据来源 | SDK 内嵌 | API Gateway 转发(要换 endpoint) |
| 延迟开销 | 极低(in-process) | 中等(多一跳 HTTP) |
| 多模型切换 | ⚠️ 需手动改代码 | ✅ 自动 fallback |
| Guardrail | ✅ 运行时 + 配置双驱动 | ⚠️ 缓存 + rate limit,无 PII 检测 |
| OTel 兼容 | ✅ 一等 | ⚠️ 部分 |
关键差异:Helicone 是「网关式观测」(请求先到 Helicone 再到 OpenAI),适合多团队统一 LLM 入口;OpenLIT 是「SDK 式观测」(本地 hook 拦截),适合对延迟敏感的应用。
对比三:OpenLIT vs Arize Phoenix
| 维度 | OpenLIT | Arize Phoenix |
|---|---|---|
| 协议基础 | OpenTelemetry | OpenInference(OTel 子集) |
| 核心优势 | 多语言 SDK + Guard + Rule | Trace UI + Eval 体验最成熟 |
| 开源 vs SaaS | 全开源 + 自托管 | 开源 + 商业 SaaS |
| Instrumentor | 55+ | ~20 |
| Guard Pipeline | ✅ 7 类 Guard | ❌ 无 |
结论:Phoenix 在 Trace UI 上更成熟(Phoenix 6.x 的体验接近 Langfuse),但 OpenLIT 在「Hook 总线的治理能力」(Guard + Rule + 多语言 SDK)上领先。
优缺点对比
优势侧:架构简洁性 + 扩展性 + 易用性
graph LR
A["✅ 优势"] --> B["🎯 架构简洁性"]
A --> C["🔌 扩展性"]
A --> D["😊 易用性"]
B --> B1["一行 init 接入"]
B --> B2["OTel 标准协议"]
B --> B3["机制 vs 策略分离"]
C --> C1["55+ Instrumentor"]
C --> C2["3 语言 SDK"]
C --> C3["Guard/Rule/Metric 三扩展点"]
D --> D1["find_spec 自动探测"]
D --> D2["环境变量即配置"]
D --> D3["Fail-open 默认安全"]
style A fill:#B5EAD7,stroke:#6BB89A,color:#333
style B fill:#C7CEEA,stroke:#7B8AB8,color:#333
style C fill:#E8D5F5,stroke:#A78BC9,color:#333
style D fill:#FFDAB9,stroke:#D89B6C,color:#333
style B1 fill:#F5F5F5,stroke:#999,color:#333
style B2 fill:#F5F5F5,stroke:#999,color:#333
style B3 fill:#F5F5F5,stroke:#999,color:#333
style C1 fill:#F5F5F5,stroke:#999,color:#333
style C2 fill:#F5F5F5,stroke:#999,color:#333
style C3 fill:#F5F5F5,stroke:#999,color:#333
style D1 fill:#F5F5F5,stroke:#999,color:#333
style D2 fill:#F5F5F5,stroke:#999,color:#333
style D3 fill:#F5F5F5,stroke:#999,color:#333架构简洁性:Hook 总线只有「Instrumentor → Tracer/Meter/Logger → OTLP Exporter」3 层,新人能 5 分钟看懂。
扩展性:加一个新 Provider 只需新建 instrumentation/xxx/xxx.py + 在 MODULE_NAME_MAP 加一行 —— 业务代码零改动。加一种 Guard 只需继承 Guard 抽象类 + 实现 evaluate()。
易用性:openlit.init() 一行。Guard、Rule、计费都是声明式配置。
劣势侧:性能 + 复杂度 + 维护性
graph LR
A["⚠️ 劣势"] --> B["⚡ 性能"]
A --> C["🌀 复杂度"]
A --> D["🛠️ 维护性"]
B --> B1["monkey-patch 启动慢"]
B --> B2["每个调用多 5-20μs"]
B --> B3["OTel Batch 引入尾部延迟"]
C --> C1["55 Instrumentor 调试难"]
C --> C2["OTel API 抽象泄漏"]
C --> C3["ContextVar 链路难追踪"]
D --> D1["Provider 版本升级脆弱"]
D --> D2["OTel SemConv 演进快"]
D --> D3["三语言 SDK 维护成本高"]
style A fill:#FFB3C6,stroke:#D87090,color:#333
style B fill:#FFF9C4,stroke:#D4C25A,color:#333
style C fill:#E8D5F5,stroke:#A78BC9,color:#333
style D fill:#FFDAB9,stroke:#D89B6C,color:#333
style B1 fill:#F5F5F5,stroke:#999,color:#333
style B2 fill:#F5F5F5,stroke:#999,color:#333
style B3 fill:#F5F5F5,stroke:#999,color:#333
style C1 fill:#F5F5F5,stroke:#999,color:#333
style C2 fill:#F5F5F5,stroke:#999,color:#333
style C3 fill:#F5F5F5,stroke:#999,color:#333
style D1 fill:#F5F5F5,stroke:#999,color:#333
style D2 fill:#F5F5F5,stroke:#999,color:#333
style D3 fill:#F5F5F5,stroke:#999,color:#333性能:
- monkey-patch 启动慢:
openlit.init()阶段会 import + 检测 + 注入,冷启动多 200-800ms(取决于安装的包数)。Lambda/Cloud Function 场景要注意。 - 每调用开销:每个 LLM 调用多 5-20 微秒(Span 创建 + 属性写入 + metric record)。高频调用(>100 QPS)累计可观。
- OTel Batch 延迟:默认 Batch 5 秒 flush 一次,Trace 实时性下降(生产事故调试时可能错过现场)。
复杂度:
- 55 个 Instrumentor 调试地狱:如果 Hook 出问题,要先怀疑是 OpenLIT 的 Instrumentor、OTel SDK 还是 Provider SDK,三层叠加定位耗时。
- OTel API 抽象泄漏:用户偶尔需要直接用
trace.get_current_span(),增加学习成本。 - ContextVar 链路追踪:当 Agent A → B → C 串行调用,标签传播正确性难验证(需要手动加日志)。
维护性:
- Provider 版本升级脆弱:OpenAI/Anthropic SDK 一升级(breaking change),对应 Instrumentor 必须同步修。OpenLIT 仓库每天都有「deps bump」PR。
- OTel SemConv 演进快:GenAI Semantic Conventions 还在 alpha/beta 阶段,属性名经常变(
gen_ai.usage.input_tokens在 1.30 还是gen_ai.prompt_tokens)。 - 三语言 SDK 维护成本:Python/TypeScript/Go 三套代码要保持 feature parity,社区贡献者门槛高。
从零搭建启示(MVP)
如果我想复刻一个「极简版 OpenLIT」(500 行代码实现核心 Hook 总线),最小可行实现是什么?
阶段一:核心机制(必须,~150 行)
1 | # minimal_openlit.py |
这就是 Hook 总线的「最小可工作版本」 —— 1 个 Instrumentor + wrapt monkey-patch + OTel Tracer。
阶段二:上下文传播(推荐,~50 行)
加 ContextVar 支持,让上层框架自动给 Span 贴 agent 标签:
1 | from contextvars import ContextVar |
阶段三:Metric 通道(推荐,~30 行)
加 OTLP Metric Exporter,记录 token 计数:
1 | from opentelemetry import metrics |
阶段四:Guard Pipeline(可选,~150 行)
加 Pipeline + Guard 抽象,支持运行时拦截:
1 | class Guard: |
阶段五:完整方案(可选,~500 行)
加 Event Logger、Rule Engine、GPU Instrumentor、Self-host UI,就到 OpenLIT 的 1/10 规模。
踩坑预警
| # | 坑 | 怎么避 |
|---|---|---|
| 1 | openlit.init() 后 OpenAI() 创建 client,但 monkey-patch 已生效,导致 首次调用额外耗时 | 接受(生产环境冷启动多 200ms 不算大),或在 if __name__ == '__main__': 后再 import openai |
| 2 | 同时装了 openai 和 openai-agents 两个包,Instrumentor 冲突(都注册了 chat wrapper) | 用 instrumentor_list=['openai'] 显式启用需要的;社区反馈 Instrumentor 有「layer」概念,框架级(langchain)优先级高于 provider 级(openai) |
| 3 | fail_open 默认开启后,某个 Guard bug 直接放行恶意输入 | 生产环境改 fail_open=False;单元测试要覆盖 Guard 异常路径 |
| 4 | OTel SemConv 1.32 → 1.33 后,属性名变化导致 Grafana 看板失效 | 锁定 OTel SDK 版本,定期跑 e2e 测试 |
| 5 | ContextVar 在 asyncio.gather() 下泄漏 —— 多 Agent 并发时标签串台 | 用 copy_context() 显式传递,或用 OpenLIT 的 set_agent_name(token) 模式(token 显式 reset) |
趋势 + 总结
3 个趋势判断
OTel GenAI SemConv 即将稳定:2026 年 OTel GenAI Semantic Conventions 从 alpha 进入 stable,所有 LLM 观测厂商必须遵守。OpenLIT 抢先布局,未来兼容性最好。
「观测 + 治理」双轨合并:单纯的 trace 工具(Langfuse)→ 单纯 trace 不够,必须升级到 trace + guard + rule(OpenLIT 已做到)。未来 1-2 年所有观测工具都会加 Guardrail 能力。
ContextVar 标签传播成 Agent 框架标配:CrewAI、AutoGen、LangGraph 都在加 agent name 标签。Instrumentor 抢这个生态位价值巨大(OpenLIT 已经对接 18 个 Agent 框架)。
工程提炼
「Hook 组件不是花哨的可选配件,是 Harness 把 Agent 从 demo 变成产品的齿轮**。一行 init() 让 55 个 Provider 自动吐出标准 OTel Trace + Guard 决策 + Rule 注入 + Metric 计数——这种『基础设施红利』是任何团队自己造轮子造不出来的。」**
适用场景
| 场景 | 推荐 |
|---|---|
| 新 LLM 应用、需要可观测性 | ✅ OpenLIT(门槛最低,OTel 原生) |
| 已有 OTel 栈(Jaeger/Tempo),加 LLM 观测 | ✅ OpenLIT(无缝接入) |
| 需要统一 LLM 入口、自动 fallback、缓存 | ⚠️ Helicone(网关模式更合适) |
| 多团队共享 LLM 网关 | ⚠️ Helicone 或 LiteLLM Proxy + OpenLIT 后端 |
| 要最成熟的 Eval UI(Trace + Score 联动) | ⚠️ Langfuse / Arize Phoenix |
| 要运行时 PII/Prompt Injection 拦截 | ✅ OpenLIT Guard Pipeline |
| 不想要 OTel 依赖 | ⚠️ Langfuse 私有协议 |
附录:关键资源
- 仓库:https://github.com/openlit/openlit(⭐2,739,Apache-2.0)
- 官网:https://openlit.io/
- 文档:https://docs.openlit.io/
- Python SDK 入口:
sdk/python/src/openlit/__init__.py - Instrumentor 注册表:
sdk/python/src/openlit/_instrumentors.py - OTel 三件套:
sdk/python/src/openlit/otel/{tracing,metrics,events}.py - Guard Pipeline:
sdk/python/src/openlit/guard/_pipeline.py - Hook 时机参考(OpenAI 为例):
sdk/python/src/openlit/instrumentation/openai/openai.py - TypeScript SDK:
sdk/typescript/src/instrumentation/ - Go SDK:
sdk/go/
系列归属:本文属于 Harness Engineering 系列 · Hook/Event 组件专题。下一篇将分析 「OpenInference」(Arize 的 OTel 子集)vs OpenLIT 在 GenAI SemConv 上的协议分歧,敬请期待。