AI代理可观测性工具

提供决策级遥测技术,用于AI代理的可观测性,能够追踪代理的决策过程并阻止危险操作。

  • by graphsentinel
  • Python
  • 本地部署
  • 2 星标
  • 更新于
在 GitHub 查看 graphsentinel/otel-mcp-agent-extension

使用说明

追踪特工的思想

AI Agent可观测性的决策级遥测

看不只是 什么 你的经纪人做了,但是 为什么 它做出了这些决定,并在执行之前阻止了危险的决定。

问题

当前可观测性在模型边界处停止:

Token Metrics (what tokens-only telemetry sees):
  Step 1: 89 tokens   Normal
  Step 2: 112 tokens  Normal
  Step 3: 156 tokens  Normal   ← MISSED THE PROBLEM!

Decision Metrics (what gen_ai.agent.* + gen_ai.evaluation.result add):
  Step 1: confidence=0.92, deviation=0.05  Normal
  Step 2: confidence=0.88, deviation=0.08  Normal
  Step 3: confidence=0.34, deviation=0.78  ANOMALY DETECTED
          Expected: QueryMetrics
          Actual:   send_http (external)
          Scope:    network:external (not in baseline)
          → PreExecutionGate.decide() returns allowed=false
          → BLOCKED before tool execution
          → emits  gen_ai.evaluation.result event (score.label=critical)
                   gen_ai.agent.gate.blocked=true

用SRE基准重现上述内容: python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py --pilot --threshold 0.6

逆标度问题 (McKenzie等人,2023):更强大的模型会产生更不可预测的工具选择——仅通过令牌指标是看不见的。

我们的证据(SRE n=10基准): 8400条链跨越7个家族的28个模型——19个开源+9个前沿(Anthropic/Google/OpenAI,在主题演讲中伪装成frontier-A/B/C的供应商)。6个事件类别×5个歧义变体×n=10。主题标题数字(27款/8100条链)下降 qwen2.5-coder:0.5b 作为退化的输出伪影。看 示例/sre事件演示/ 和 文档/通用属性.md.

四个贡献

# 贡献 类型 证据
1 工具选择中的逆缩放 实证发现 8400条链;5经典(β₁ > 0) + 2 反向(β₁ < 0) 家庭
2 gen_ai.agent.* 语义约定 OTel SIG提案 OTel规范之上的11个拟议属性组(开发)——见 文档/通用属性.md §11
3 纵深防御管道 架构 第3层(认知)内的5级检测;只有一个阶段使用LLM
4 统一观测层 库 框架无关:适配器→ 分析器→ gate → gen_ai.evaluation.result OTel事件(开发)

纵深防御管道

Prompt arrives
     │
     ▼
┌─────────────────────────────────┐
│ Layer 0: Safety Pre-Filter      │  Regex: injection, question, vague (0ms)
│ (deterministic — no LLM)        │  Embedding: actionability check (50ms)
│                                 │  → Catches 24% of prompts
└─────────┬───────────────────────┘
          │
          ▼
┌─────────────────────────────────┐
│ Layer 1-2: Task Shape Classifier│  Embedding (93%) + LLM fallback (100%)
│ (hybrid — LLM only when needed) │  → Routes to correct baseline
└─────────┬───────────────────────┘
          │
          ▼
┌─────────────────────────────────┐
│ Layer 3: Pre-Execution Gate     │  Deviation scoring against baseline
│ (deterministic formula)         │  → 579/579 anomalies caught, 0 escaped
└─────────┬───────────────────────┘
          │
          ▼
┌─────────────────────────────────┐
│ Layer 4: Scope Enforcement      │  Policy-based allow/deny
│ (deterministic policy)          │  → scope.denied = always block
└─────────────────────────────────┘

快速开始

先决条件

  • Docker/播客&作曲
  • Python 3.10+
  • 最低4GB RAM(建议Ollama使用8GB+)

设置

git clone https://github.com/graphsentinel/otel-mcp-agent-extension.git
cd otel-mcp-agent-extension

# Install the library (and provider extras) once
pip install -e ".[all]"

# Bring up the SRE example's observability stack
cd examples/sre-incident-demo
./scripts/setup.sh
podman-compose up -d        # or: docker compose up -d

SRE compose文件将运行时状态存储在示例本地绑定装载中 在...之下 examples/sre-incident-demo/data/ 默认情况下。覆盖 位置:

DEMO_DATA_DIR=/path/to/demo-data podman-compose up -d

每个例子都有自己的 compose.yaml 和 data/ (忽略了)。其他 需要堆栈的案例研究也是如此;看见 示例/遗留交互式演示/README.md.

运行SRE基准测试(主要演示--主题数据集)

这是产生标题为8100链/27模型结果的演示。

发动机启动(--engine ollama,RunPod,OpenAI,Anthropic,Gemini)需要API 钥匙。 通过设置一次 .env --看 examples/sre事件演示/README.md→ 秘密. 模拟器(--pilot /默认值 --engine simulated)不需要钥匙。

# Smoke test — 2 categories × 3 models, simulator (no LLM, no keys)
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py --pilot

# Full default run, simulator
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py --runs 30

# Real local Ollama (load .env first if your llm_connection_conf.yaml routes
# any pattern to a cloud / RunPod backend)
set -a; source examples/sre-incident-demo/.env; set +a
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py \
    --engine ollama --models qwen2.5-coder:7b --pilot

# Tighter / looser pre-execution gate
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py --threshold 0.4
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py --threshold 0.8

# Subset by category / variant
python examples/sre-incident-demo/src/demo_sre_inverse_scaling.py \
    --categories cleanup_envs,hotfix_deploy --variants v3,v4

输出: examples/sre-incident-demo/results/<suffix>/sre_drift_rows_<suffix>.jsonl

  • sre_inverse_scaling_<suffix>.json执行前关卡决定 (阻塞/通过)按链记录。

运行传统交互式演示

发射OTel的更简单的遍历跨越了本地堆栈 (Jaeger/Grafana/Neo4j)。支持模拟、本地Ollama和OpenAI:

# Mock mode (no LLM required)
python examples/legacy-interactive-demo/run_demo.py --mock --compare

# Local Ollama
python examples/legacy-interactive-demo/run_demo.py --ollama --host http://localhost:11434 --compare

# OpenAI
OPENAI_API_KEY=sk-... python examples/legacy-interactive-demo/run_demo.py --openai --compare

Anthropic和谷歌提供商采用SRE基准(如上) 通过 examples/sre-incident-demo/src/llm_router.py,而不是通过这个传统演示。 看 示例/遗留交互式演示/README.md 对于可选的容器化运行。

历史:冠军基线模拟

# Reproduce champion selection + consensus baseline from the original 3,650-run dataset
python examples/sre-incident-demo/analysis/baseline_simulation.py

运行任务形状分类器基准测试

# All 3 approaches (embedding, LLM, hybrid)
python examples/sre-incident-demo/analysis/task_shape_classifier.py --approach all

# v2 with Layer0 safety filter + adversarial prompts (50 test cases)
python examples/sre-incident-demo/analysis/task_shape_classifier_v2.py --approach 4

查看结果

服务 URL 凭据
格拉法纳 http://localhost:3000 管理员/管理员
耶格尔 http://localhost:16686 —
Neo4j浏览器 http://localhost:7474 neo4j/决策图2026!
普罗米修斯 http://localhost:9090 —

多提供商LLM支持

所有供应商都实施统一 LLMClient 协议;SRE基准 多路复用 examples/sre事件演示/src/llm_router.py. SRE n=10数据集中的每个供应链总计:

提供者 测试的模型(SRE n=10) 链
Ollama/RunPod (开源) qwen2.5编码器(0.5b–14b),qwen3.5(2b/4b/9b/27b),接下来是qwen3编码器,gemma3(1b/4b/12b/27b)、gemma4(e2b/e4b/2b/31b)、deepseek-r1、kimi、minimax 5700
人类 claude-haiku-4.5,claude-sonnet-4.6,claude-opus-4.7 900
谷歌 双子座-3-flash-review,双子座-3.1-flash-lite-review,双子座-3-1-pro-review 900
开放人工智能 gpt-5.4、gpt-5.4最小值、gpt-5.5 900
总计 28款/7个系列 8,400

OTel属性——状态分类+有线格式合同

全线格式合约——每个属性、每个事件、每个跨度 name,加上该项目使用的四标签状态分类法——lives 文档/通用属性.md.快速地图:

标签 含义 示例
规范的 在OTel规范中, 稳定 徽章 (当前为空:否 gen_ai.* attr在semconv 1.41.0中已达到稳定)
发展 在OTel规范中, 发展 徽章 gen_ai.tool.name, gen_ai.conversation.id, gen_ai.usage.{input,output}_tokens, gen_ai.evaluation.result (事件)
扩展 在SIG的公开草案中,尚未纳入规范 gen_ai.task.*, gen_ai.action.*, gen_ai.team.*, gen_ai.memory.*
提议的 只有这个项目提出了这个建议;不在任何SIG草案中 gen_ai.agent.tool.confidence, gen_ai.agent.scope.*, gen_ai.agent.baseline.*, gen_ai.agent.gate.*, gen_ai.agent.computed.*

我们逐字使用OTel规范名称,并发出决策级别 扩展在 gen_ai.agent.* 命名空间。归档策略 ~30拟议扩展:见 gen-ai-attributes.md §11.

# ── OTel-spec GenAI sem-conv (Development; used verbatim) ────────────────
gen_ai.operation.name:        "invoke_agent"        # or "execute_tool"
gen_ai.provider.name:         "openai"
gen_ai.conversation.id:       "sess_abc123"
gen_ai.agent.id:              "agt-001"             # 1 of 4 reserved spec attrs
gen_ai.agent.name:            "sre-incident-bot"
gen_ai.request.model:         "qwen2.5-coder:7b"
gen_ai.tool.name:             "send_http"
gen_ai.usage.input_tokens:    120
gen_ai.usage.output_tokens:   85

# Deviation surfaces as the gen_ai.evaluation.result OTel Event (Development)
# (NOT a span attribute):
event.name:                   "gen_ai.evaluation.result"
gen_ai.evaluation.name:       "baseline_deviation"
gen_ai.evaluation.score.value: 0.87
gen_ai.evaluation.score.label: "high"
gen_ai.evaluation.explanation: "Tool 'send_http' deviates from baseline …"

# ── Proposed (this project; see Docs/gen-ai-attributes.md §11) ────────────
gen_ai.agent.task_type:                "investigate_latency"
gen_ai.agent.tool.category:            "network"
gen_ai.agent.tool.confidence:          0.87
gen_ai.agent.tool.sequence_position:   1
gen_ai.agent.tool.risk_severity:       4
gen_ai.agent.baseline.id:              "sre.investigate_latency.v1"
gen_ai.agent.baseline.expected_tool:   "QueryMetrics"
gen_ai.agent.baseline.match:           false
gen_ai.agent.scope.requested:          ["network:external"]
gen_ai.agent.scope.granted:            []
gen_ai.agent.scope.denied:             ["network:external"]
gen_ai.agent.gate.blocked:             true
gen_ai.agent.gate.reason:              "deviation=0.87, scope creep"
gen_ai.agent.computed.severity:        "critical"     # SDK-set or collector-derived
gen_ai.agent.computed.risk_score:      0.78

关键结果(SRE n=10基准)

全面分析 examples/sre事件演示/README.md.

开源与前沿——统计差距

                                n      severity   danger%   matched%
open-source (5 fam, 19 mdl):  5,700    0.567       23.3%      15.2%
frontier    (3 ven,  9 mdl):  2,700    0.379        6.7%      35.5%
                              ──────────────────────────────────────
Welch t = +26.21,  p = 2.7×10⁻¹⁴²  →  closed-source significantly safer

家庭β₁ — 逆比例符号变化

中心线性OLS,β₁ = 严重性×对数₂(能力)系数。

家庭 β₁ 图案
qwen2.5编码器 +0.066 ★ 经典逆(更大=风险更大)
qwen3.5 +0.043 ★ 经典逆
边界-B +0.041 ★ 经典逆
gemma3 +0.025 ★ 经典逆
前沿A +0.019 ★ 经典逆(弱)
qwen3编码器下一步 -0.007 ns 无趋势(只有2个能力点)
gemma4 −0.034 ★ 倒车档(更大=更安全) ⚡
前沿-C −0.045 ★ 倒车档(更大=更安全) ⚡

5个家庭表现出经典的逆标度;2个家庭展出 相反的符号 --能力和风险不是单调一致的。

拒绝悖论

Frontier-A模型(人为掩蔽)在原始严重程度上排名较低,部分原因是 35-45%的链条是 空的 (“对此没有帮助”)。对于SRE 事件响应代理,拒绝不是安全,而是失败。

模型 空% 有用% 严重性
Frontier-A1(小) 45.0% 53.7% 0.207
前沿A3(大) 39.3% 60.7% 0.254
前沿A2(中等) 35.3% 64.3% 0.326

empty% 和 chain_OK% 缺少生产适应性指标吗-- 仅在OTel的第3层(认知)遥测中可见,从不通过令牌。

门是一个不可谈判的后盾

PreExecutionGate(threshold=0.6).decide(AnalysisResult) 每一步, 执行前。在SRE n=10数据集中,最差步长穿过的每个链 在任何工具运行之前,偏差阈值都会被阻止。被封锁的 链条永远伸不到 execute_tool --它们发出 gen_ai.agent.gate.blocked=true 和一个 gen_ai.evaluation.result 带有score.label的事件= critical.

存储库布局

repo根目录包含可安装库和项目级别 参考文献每一个可运行的故事都存在于 examples/<case-study>/ 并且是自包含的——它有自己的配置、组成、呈现和 结果位于该目录中。完整的运营计划 文档/仓库组织.md.

图书馆-- src/gen_ai_otel/

pip install -e ".[all]" 安装库;下面什么都没有 src/ 导入应用配置、YAML文件或示例数据。

模块 目的
attributes.py OTel规范(开发)+建议的属性常数; gen_ai.evaluation.result 事件有效负载助手
instrumentation.py OTel跟踪上下文管理器+统一观测桥
llm_client.py, providers/ LLMClient 协议+工厂;Ollama(本地+云)、OpenAI、Anthropic、谷歌客户
ollama_agent.py LLM驱动的决策代理,内置默认工具集
neo4j_exporter.py 直接Neo4j导出器(OTLP的传统替代品→桥梁路径)
config.py 通用类型(Tool, ToolCatalog, ModelInfo, GateConfig)+读者; 无域数据
cli/ gen-ai-demo 控制台入口点——通往可用案例研究的路径
observation/ UnifiedAnalyzer, PreExecutionGate, BaselineResolver, InverseScalingDetector,框架适配器(vanilla/langchain/langgraph/openai代理/autogen/strands/mcpuse)

示例-- examples/

目录 里面有什么
sre-incident-demo/ 主要主题数据集生成器。28个模型×8400个链,跨越6个事件类别×5个模糊变量。拥有完整的可观察性堆栈(组合、配置、桥接、模式、查询)、幻灯片(演示文稿、视频)和 analysis/ 脚本(baseline_simulation, dag_auto_builder, dag_formula_comparison, dag_benchmark, model_comparison, task_shape_classifier{,_v2}).
legacy-interactive-demo/ Mock/Ollama/OpenAI遍历,在本地堆栈上发出OTel跨度。录音助手住在 scripts/.可选 Dockerfile 用于沙盒运行。
workato-demo/ Workato适配器演示——将外部工作流平台连接到观察管道中。
neo4j-demo/ 决策图层的独立Neo4j种子+Cypher演练。

对于主要的SRE基准(Anthropic/Google/OpenAI/Ollama通过 单个 --engine 标志)使用 examples/sre事件演示/src/demo_sre_inverse_scaling.py.

配置

SRE案例研究拥有以下配置 示例/sre事件演示/配置/:

examples/sre-incident-demo/configs/
├── sre_tools.yaml          # 10 MCP servers · 73 tools · 19 risk-4 destructive
├── sre_dataset.yaml        # 6 incident categories × 5 ambiguity variants
├── sre_models.yaml         # 40-entry model registry (capability, tier, family)
├── llm_connection_conf.yaml # Provider routing for --engine live
├── otel-collector-decision.yaml, prometheus.yaml
└── grafana/                # Dashboards + datasource provisioning

访问者在 examples/sre事件演示/src/sre_app_config.py. 主题演讲活动演示路径(demo_baseline_deviation.py, demo_sre_inverse_scaling.py, sre_adapter.py)直接读取其YAML; 研究/分析脚本 examples/sre-incident-demo/analysis/ 通过适配器:

import sys
from pathlib import Path
sys.path.insert(0, str(Path(__file__).resolve().parent.parent / "src"))

from sre_app_config import get_tools, get_dag_tasks, get_model_capability

tools = get_tools()                              # 73 tools (server.tool flat keys)
dag = get_dag_tasks()                            # 6 incident categories
cap = get_model_capability("qwen3.5:27b")        # 27.0 from sre_models.yaml

要添加新工具,请编辑 示例/sre事件演示/configs/sretools.yaml — 每个消费者(现场演示、桥接、分析脚本)都会拿起它 自动通过同一个真理来源。

该库仅公开通用反序列化器(tools_from_mapping, gate_config_from_dict, read_yaml,…) gen_ai_otel.config; 应用程序将解析后的字典交给它。看 文件/仓库组织.md§4 在边界上。

项目结构

tracing-agents-mind-demo/
├── src/gen_ai_otel/                 # Library (pip installable)
│   ├── attributes.py                # OTel-spec (Development) + Proposed constants
│   ├── instrumentation.py           # OTel tracing + observation bridge
│   ├── llm_client.py, providers/    # LLMClient + Ollama/OpenAI/Anthropic/Google
│   ├── ollama_agent.py              # Decision agent
│   ├── neo4j_exporter.py            # Direct Neo4j exporter
│   ├── config.py                    # Generic types + readers (no domain data)
│   ├── cli/                         # gen-ai-demo console entry point
│   └── observation/                 # UnifiedAnalyzer, PreExecutionGate, adapters/
├── examples/
│   ├── sre-incident-demo/           # Primary SRE benchmark — 8,400 chains × 28 models
│   │   ├── compose.yaml             # SRE observability stack (bind-mount data/)
│   │   ├── configs/                 # OTel Collector, Prometheus, Grafana provisioning
│   │   ├── bridge/                  # OTLP gRPC → Neo4j writer (Dockerfile + server.py)
│   │   ├── schemas/, queries/       # Neo4j decision-graph schema + forensic Cypher
│   │   ├── presentation/            # Keynote PPTX/HTML/MP4 + builder scripts
│   │   ├── videos/                  # Demo recordings (.cast, .mp4, .gif)
│   │   ├── scripts/                 # SRE-specific setup (data dir bootstrap)
│   │   ├── analysis/                # baseline_simulation, dag_auto_builder,
│   │   │                            #  dag_formula_comparison, dag_benchmark,
│   │   │                            #  model_comparison, task_shape_classifier{,_v2}
│   │   ├── results/                 # Historical benchmark output (read-only)
│   │   ├── src/                     # Example source code
│   │   │   ├── demo_sre_inverse_scaling.py # Primary entry
│   │   │   ├── analyze_inverse_scaling.py  # Master ranking
│   │   │   ├── lind_mehlum_test.py         # Formal U-shape test
│   │   │   ├── sre_adapter.py              # Catalog loader + classifier
│   │   │   └── llm_router.py               # Multi-provider dispatcher
│   │   └── configs/                 # (also includes sre_tools.yaml,
│   │                                #  sre_dataset.yaml, llm_connection_conf.yaml)
│   ├── legacy-interactive-demo/     # Mock / Ollama / OpenAI walk-through
│   │   ├── run_demo.py, benchmark_10k.py
│   │   ├── scripts/                 # demo-video.sh, record-demo.sh, setup.sh
│   │   └── Dockerfile               # Optional sandboxed run (build context = repo root)
│   ├── workato-demo/                # External workflow platform adapter demo
│   └── neo4j-demo/                  # Standalone Neo4j seed + Cypher walkthrough
├── Docs/
│   ├── gen-ai-attributes.md         # Wire-format contract (Development + Proposed)
│   ├── architecture.md              # Architecture document
│   └── repository-organization.md   # Repo organization plan
├── papers/                          # Source papers (Betley, McKenzie, Wei, Zhou)
├── KubeConEU2026-Presentation/      # KubeCon EU 2026 reference photos (separate event)
├── backup/                          # Historical / archived outputs (gitignored)
├── pyproject.toml                   # Package with optional extras
└── README.md                        # this file

故障排除

波德曼:拒绝许可

./examples/sre-incident-demo/scripts/setup.sh

WSL/Podman:CNI防火墙插件验证错误

症状:

WARN[0000] Error validating CNI config file /home/user/.config/cni/net.d/tracing-agents-mind_decision-net.conflist: 
[plugin firewall does not support config version "1.0.0"]

根本原因: podman compose创建了一个版本为“1.0.0”的CNI网络配置,但防火墙插件最多只支持“0.4.0”。

解决方案: 清理现有网络并使用正确的版本重新创建:

# Stop and remove all containers
podman rm -af && podman pod rm -af
podman network rm -f tracing-agents-mind_decision-net 2>/dev/null || true

# Create CNI config with correct version
cat > ~/.config/cni/net.d/tracing-agents-mind_decision-net.conflist << 'EOF'
{
  "cniVersion": "0.4.0",
  "name": "tracing-agents-mind_decision-net",
  "plugins": [
    {
      "type": "bridge",
      "bridge": "cni-podman1",
      "isGateway": true,
      "ipMasq": true,
      "hairpinMode": true,
      "ipam": {
        "type": "host-local",
        "routes": [{"dst": "0.0.0.0/0"}],
        "ranges": [[{"subnet": "10.89.0.0/24", "gateway": "10.89.0.1"}]]
      }
    },
    {
      "type": "portmap",
      "capabilities": {"portMappings": true}
    },
    {
      "type": "firewall"
    },
    {
      "type": "tuning"
    },
    {
      "type": "dnsname",
      "domainName": "dns.podman",
      "capabilities": {"aliases": true}
    }
  ]
}
EOF

# Restart the stack
cd examples/sre-incident-demo
podman-compose up -d

绑定装载清理被容器拥有的文件阻止

Neo4j(UID 7474)、Grafana(UID 472)和普罗米修斯(UID 65534)写入 以容器用户的身份将其放入绑定挂载中。平原 rm -rf data/ 从 主机失败,权限被拒绝。使用podman的用户命名空间:

podman unshare rm -rf examples/sre-incident-demo/data

Ollama不可用

curl http://localhost:11434/api/tags
ollama pull qwen2.5-coder:7b

Neo4j连接问题

curl http://localhost:7474    # Default: neo4j / DecisionGraph2026!

提交时间:

  • 2026年北美观测峰会 --第2天主题演讲(5月22日,明尼阿波利斯)

作者

  • 穆斯塔法·达约格鲁 --高级首席研究员
  • 泽诺·艾根·多德 --首席AI安全架构师

许可证

Apache 2.0——请参阅 许可证