使用说明
追踪特工的思想
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——请参阅 许可证
