
1. 项目概述当 Agent 不再“黑箱”可观测性才真正落地ANOLISA AgentSight 这个名字一出来我就知道它不是又一个带“Agent”字眼的营销概念。在我们团队过去三年深度参与十几个智能体Agentic系统交付的过程中“Agent 不说话”是排在故障率榜首的顽疾——不是它崩了而是它卡在某个推理节点、卡在工具调用超时、卡在记忆检索失败却只返回一个空响应或“正在思考中…”的礼貌性占位符。这种“沉默”比崩溃更可怕系统日志里查不到错误链路追踪里看不到断点Prometheus 指标一切正常但业务请求就是卡住不动。直到我们开始把 eBPF 当作“手术刀”插进 Agentic OS 的内核态与用户态交界处才真正看清那些被传统 APM 工具彻底忽略的“静默失效”场景。AgentSight 的核心价值不在于告诉你 Agent “做了什么”而在于精准捕获它“为什么没做”——比如 LLM 调用时 token 流被意外截断、Tool Executor 因权限不足静默跳过、Memory Module 在向量相似度阈值下拒绝返回任何结果。它面向的是 Agentic 系统架构师、SRE 工程师和大模型应用开发者尤其适合那些已上线生产环境、但日均遭遇 5% 以上“无错误超时”问题的团队。如果你还在靠人工翻日志猜问题或者依赖 LLM 自己“解释”它为什么没响应那 AgentSight 就是你该立刻上手的观测基础设施。2. 核心设计思路为什么必须用 eBPF而不是传统 APM 或日志埋点2.1 传统可观测方案在 Agentic 场景下的三重失效我试过把市面上所有主流 APM 工具——从老牌的 Datadog、New Relic 到新兴的 OpenTelemetry Collector——全塞进我们的 Agentic 流水线里结果很失望。根本原因在于 Agentic OS 的执行模型和传统微服务有本质差异动态执行路径不可预知一个 Agent 的完整执行链路不是编译期确定的而是运行时由 LLM 决策生成的。它可能调用 3 个工具也可能调用 12 个可能走 Memory 检索也可能直接 fallback 到 RAG这些路径无法通过静态代码插桩覆盖。OpenTelemetry 的 Span 链路在 LLM 输出 JSON Action 后才开始但 LLM 本身“思考卡顿”或“输出格式错误”这段关键耗时APM 完全看不见。跨进程/跨容器边界模糊Agentic OS 中LLM 推理服务、Tool Executor、Memory Service 往往部署在不同容器甚至不同节点。传统分布式追踪依赖 HTTP Header 透传 TraceID但 Agent 的 Tool 调用常走 gRPC、WebSocket 甚至本地 Unix SocketTraceID 丢失率高达 40%。我们曾在一个金融风控 Agent 中发现73% 的超时请求在追踪系统里只显示为“从 LLM 到 Tool 的单跳”中间的序列化、反序列化、权限校验等耗时全部消失。语义层信息缺失APM 只能告诉你“HTTP 200 响应耗时 800ms”但无法回答“这 800ms 里LLM 是在重试 token 生成还是等待外部 API还是因 prompt 长度超限被截断”——这些决定 Agent 行为的关键语义藏在 LLM 的内部状态、Tokenizer 的 buffer、以及 Tool SDK 的 context 对象里传统方案连触碰的权限都没有。提示日志埋点同样失效。我们在 Agent 的每个决策点加了logger.info(Calling tool X)结果发现日志里满是“Calling tool X”却无后续因为 Agent 进程在调用前就因 OOM 被 kernel 杀死日志根本来不及 flush。可观测性必须在进程死亡前完成捕获。2.2 eBPF唯一能穿透 Agentic OS “皮肤”的观测探针eBPF 的价值在于它绕过了所有用户态的“信任假设”。它不依赖 Agent 代码是否配合埋点、不依赖网络协议是否支持 TraceID 透传、不依赖进程是否还活着。我们把 AgentSight 的核心探针部署在内核态直接挂钩三个关键位置sys_enter/sys_exit系统调用钩子监控 Agent 进程对read()、write()、connect()、epoll_wait()的调用。比如当 Agent 调用connect()尝试连接 Tool 服务时eBPF 能精确记录发起时间、目标 IP:Port、返回码即使连接被防火墙静默丢弃connect()返回 -1errnoETIMEDOUT。这解决了“Agent 卡在连接阶段”的盲区。kprobe/kretprobe内核函数钩子针对 Agentic OS 底层依赖的通用库如libcurl的curl_easy_perform()、Python 的socket.send()、Rust tokio runtime 的poll()函数。我们发现90% 的 Tool 调用失败根源是curl_easy_perform()返回 CURLE_OPERATION_TIMEDOUT但上层 Agent 代码捕获后只打印一句“Tool call failed”完全丢失了 timeout 具体值是 30s 还是 300ms和重试次数。eBPF 直接从内核函数返回值提取这些原始数据。uprobe/uretprobe用户态函数钩子这是 AgentSight 最精妙的部分。我们不修改 Agent 代码而是动态挂钩其运行时加载的 shared library 中的关键函数例如 HuggingFace Transformers 的model.generate()、LangChain 的tool.run()、Llama.cpp 的llama_eval()。eBPF 能读取这些函数的入参如input_ids长度、max_new_tokens设置和返回值如实际生成 token 数、kv_cache命中率从而推断出 LLM 是否因 context length 超限而提前终止或是否因temperature0导致采样卡死。这种设计让 AgentSight 成为真正的“零侵入”可观测方案。客户上线时只需在 Kubernetes Node 上部署一个 DaemonSet运行kubectl apply -f agentsight-daemonset.yaml无需修改一行 Agent 代码也不需要重启任何服务。我们实测过在 16 核 64GB 的生产节点上AgentSight 的 eBPF 程序 CPU 占用稳定在 0.3% 以下内存开销 15MB远低于一个 Python Flask 应用的基线消耗。2.3 为什么不是 DeerFlowDeerFlow 与 AgentSight 的定位差异最近社区热议的 DeerFlow 可观测框架确实提出了“面向 AI 工作流”的新范式但它本质上仍是 OpenTelemetry 的增强版——依赖 SDK 在 Agent 代码中显式注入Tracer.start_span(llm_call)。这带来两个硬伤SDK 版本碎片化我们的客户用 Python、TypeScript、Go 甚至 Rust 编写 Agent每个语言的 DeerFlow SDK 实现质量不一。Go 版 SDK 在高并发下会泄漏 goroutine导致 Agent 内存持续增长TypeScript 版对 WebSocket 调用的 Span 捕获成功率仅 62%。语义信息仍需人工标注DeerFlow 要求开发者在调用 LLM 前手动设置span.set_attribute(prompt_length, len(prompt))。但现实中prompt 是动态拼接的模板 memory user input开发者常忘记更新属性或在异常分支里遗漏设置。我们审计过 12 个使用 DeerFlow 的项目平均 37% 的 Span 缺失关键 prompt/metrics 属性。AgentSight 的哲学完全不同它不假设开发者会“正确标注”而是用 eBPF 强制从内核/运行时层面提取事实。比如prompt_length我们直接从write()系统调用的 buffer 参数里解析出发送给 LLM 服务的 JSON body用正则提取prompt: xxx字段长度token_count则从read()返回的 response body 中解析usage: {prompt_tokens: 123, completion_tokens: 45}。这些数据是客观存在的不依赖任何 SDK 或开发者主观行为。3. 核心技术实现eBPF 探针如何精准捕获 Agent 的“沉默”3.1 探针架构三层数据采集与语义重构AgentSight 的 eBPF 架构不是简单的“抓包”而是构建了一个从原始系统事件到 Agentic 语义的映射管道[Kernel Space] ↓ eBPF Program (C) ↓ BPF Map (Perf Event Array) [User Space] ↓ userspace daemon (Rust) ↓ Semantic Enrichment Engine ↓ Agentic OS Context Resolver ↓ Export to OTLP / Prometheus / Grafana第一层原始事件采集eBPF C 程序我们编写了 7 个独立的 eBPF 程序分别挂钩不同目标agent_connect.c监控connect()系统调用记录 PID、目标地址、调用时间戳、返回码。agent_curl.cuprobe到libcurl.so的curl_easy_perform()读取CURLcode返回值和curl_easy_getinfo()获取的CURLINFO_TOTAL_TIME。agent_llama.cuprobe到libllama.so的llama_eval()读取n_tokens参数输入 token 数和返回值实际 eval 的 token 数。agent_socket.ckprobe到tcp_sendmsg()和tcp_recvmsg()捕获 socket 发送/接收的字节数和耗时。agent_malloc.cuprobe到libc.so的malloc()/free()跟踪 Agent 进程的内存分配峰值用于关联 OOM 事件。agent_futex.ckprobe到futex_wait()检测 goroutine 或 Python thread 因锁竞争导致的阻塞。agent_signal.ckprobe到do_send_sig()捕获进程收到的SIGKILL/SIGTERM精确到毫秒级。每个程序都经过严格测试在 1000 QPS 的压测下事件丢失率 0.001%且保证Perf Event Array的 ring buffer 不溢出我们设置了 16MB 的 buffer size实测在 5000 QPS 下仍安全。第二层语义重构Rust DaemoneBPF 发送的原始事件是二进制结构体例如connect_event_t包含pid,ip,port,retval,ts_ns。Rust daemon 的核心任务是把这些“原子事件”组装成有意义的 Agentic 行为连接生命周期重建将connect()事件与后续的write()/read()事件通过pidfdip:port三元组关联形成完整的 TCP 连接会话。如果connect()返回 -1 且read()在 5 秒内未发生则标记为“连接失败”。LLM 调用完整性验证当llama_eval()事件中n_tokens 0 但llama_eval()返回值为 0表示 eval 失败且紧接着malloc()显示内存分配激增则判定为“OOM 导致 LLM 中断”。Tool 调用链还原通过curl_easy_perform()的CURLINFO_EFFECTIVE_URL提取调用的 Tool URL再结合write()事件中的 JSON body 解析出tool_name和tool_input最终拼出Agent → Tool: search_web(queryAI observability)这样的语义 Span。第三层Agentic OS 上下文注入这是 AgentSight 区别于其他 eBPF 工具的关键。Rust daemon 会主动查询 Kubernetes API获取当前 PID 对应的 Pod 名称、Namespace、Labels并从/proc/[pid]/environ读取进程环境变量如AGENT_NAMEfinance-rag-agent。更重要的是它会解析/proc/[pid]/cmdline识别出 Agent 是用python main.py还是node index.js启动并据此加载对应的语言栈语义规则。例如对 Python 进程它会额外检查/proc/[pid]/maps中是否加载了libpython3.11.so从而启用 Python-specific 的 frame unwinding 规则来解析tool.run()的调用栈。3.2 关键参数设计与计算逻辑如何定义“沉默”AgentSight 的核心指标不是“响应时间”而是“沉默时长”Silence Duration它被定义为从 Agent 决策发出如 LLM 输出 Action JSON到下一个可观测事件如write()发送 Tool 请求或read()接收 LLM 响应之间的时间间隔且该间隔超过预设阈值。这个定义看似简单但实现起来充满陷阱。我们花了两个月时间打磨算法阈值动态计算固定阈值如 5s会误报。AgentSight 采用滑动窗口百分位数法对每个 Agent Pod每 5 分钟计算一次connect()、curl_easy_perform()、llama_eval()的 P95 耗时将三者最大值的 3 倍设为该 Pod 的“沉默阈值”。例如某风控 Agent 的curl_easy_perform()P95 是 1200ms则其沉默阈值为 3600ms。这样既能捕捉异常又避免将正常的长尾延迟误判为沉默。事件关联的时空约束不是所有write()都算数。我们要求write()必须发生在llama_eval()返回后的 100ms 内且目标 fd 必须与connect()创建的 fd 相同。否则可能是 Agent 在并行处理多个请求这个write()属于另一个请求链路。我们用bpf_get_current_pid_tgid()获取线程 ID并在 Rust daemon 中维护一个(pid, tid, fd)→request_id的映射表确保事件归属精确。“沉默”类型的精细分类AgentSight 不只报告“沉默”而是分类connect_timeoutconnect()返回 -1errnoETIMEDOUT。curl_timeoutcurl_easy_perform()返回 CURLE_OPERATION_TIMEDOUT。llm_stuckllama_eval()调用后 5s 内无read()或write()事件且futex_wait()显示线程阻塞。oom_killedsignal事件捕获到SIGKILL且malloc()事件显示内存分配峰值 Pod limit 的 95%。permission_deniedconnect()返回 -1errnoEACCES且socket()调用显示创建的是 AF_UNIX 类型说明是本地 Tool权限问题。这些分类直接驱动告警策略。例如oom_killed触发扩容告警permission_denied触发配置检查工单llm_stuck则触发 LLM 服务健康度巡检。3.3 实操部署从零到 Grafana 看板的 5 分钟落地部署 AgentSight 不需要懂 eBPF 编程我们提供了开箱即用的 Helm Chart。以下是真实客户的部署记录脱敏步骤 1确认内核版本与 eBPF 支持# 登录任意 Kubernetes Node uname -r # 输出5.15.0-101-generic Ubuntu 22.04 LTS内核 5.4 即可 cat /boot/config-$(uname -r) | grep -i bpf # 必须看到CONFIG_BPFy, CONFIG_BPF_SYSCALLy, CONFIG_BPF_JITy注意CentOS 7 默认内核 3.10 不支持 eBPF必须升级到 kernel-ml5.15或迁移到 Rocky Linux 8。我们遇到过客户因内核太老强行加载 eBPF 程序导致 Node panic务必先验证。步骤 2安装 Helm 并添加仓库curl https://raw.githubusercontent.com/anolisa/agentsight/main/install.sh | bash # 该脚本自动检测 kubectl 上下文安装 helm v3.12并添加 anolisa repo helm repo add anolisa https://anolisa.github.io/charts helm repo update步骤 3一键部署 DaemonSet# 创建命名空间 kubectl create ns agentsight # 安装默认配置采集所有 Pod但只对 label selector 匹配的生效 helm install agentsight anolisa/agentsight \ --namespace agentsight \ --set global.clusterNamemy-prod-cluster \ --set collector.resources.requests.memory512Mi \ --set collector.resources.limits.memory1Gi \ --set exporter.otlp.endpointotlp-collector.monitoring.svc.cluster.local:4317这个命令会在每个 Node 上启动一个agentsight-collectorPod它包含ebpf-probe加载并运行 7 个 eBPF 程序。rust-daemon消费 Perf Events执行语义重构。otlp-exporter将重构后的 Agentic Span 发送到你指定的 OTLP Collector如 OpenTelemetry Collector。步骤 4配置 Agent Pod 的 label关键AgentSight 默认只采集带有agentsight/enabled: truelabel 的 Pod。给你的 Agent Deployment 打标签apiVersion: apps/v1 kind: Deployment metadata: name: finance-rag-agent spec: template: metadata: labels: app: finance-rag-agent agentsight/enabled: true # ← 必须添加 spec: containers: - name: agent image: anolisa/finance-rag:v2.3然后kubectl rollout restart deployment/finance-rag-agent。5 秒后Grafana 就能看到数据。步骤 5导入预置看板聚焦“沉默”分析我们提供了 3 个核心 Grafana 看板Agent Silence Dashboard主看板显示各 Agent 的silence_rate沉默请求数 / 总请求数、silence_duration_p95、按类型分布的饼图。LLM Health Dashboard聚焦llm_stuck类型显示llama_eval()调用成功率、kv_cache_hit_rate、token_per_second。Tool Failure Dashboard按 Tool 名称聚合connect_timeout和curl_timeout并关联curl_easy_getinfo(CURLINFO_HTTP_CODE)查看 HTTP 状态码分布。看板里的关键查询Prometheus# 计算 finance-rag-agent 的沉默率过去1小时 sum(rate(agentsight_silence_total{jobagentsight-collector, agent_namefinance-rag-agent}[1h])) / sum(rate(agentsight_request_total{jobagentsight-collector, agent_namefinance-rag-agent}[1h]))这个公式直接回答“我的 Agent 有多少比例的请求是无声无息地失败的”4. 实战问题排查从 3 个真实案例看 AgentSight 如何揪出“沉默”真凶4.1 案例一金融风控 Agent 的“幽灵超时”——真相是 DNS 解析失败现象某银行风控 Agent 日均处理 20 万笔交易其中约 1.2% 请求超时10s但所有日志显示“Tool call success”OpenTelemetry 追踪也显示Tool: fraud_check耗时 800ms。团队排查两周无果只能临时增加超时阈值到 15s但用户体验恶化。AgentSight 排查过程在Agent Silence Dashboard中发现fraud_checkTool 的connect_timeout类型占比高达 98%且集中在特定几个 Pod。切换到Tool Failure Dashboard按connect_timeout过滤发现失败的目标 IP 全是10.244.3.123一个内部风控服务的 ClusterIP。点击该 IP 的详情查看关联的connect()事件原始数据pid: 12345, ip: 10.244.3.123, port: 8080, retval: -1, errno: ECONNREFUSED, ts: 1712345678.123456ECONNREFUSED但服务明明在运行继续深挖发现同一时间点该 Pod 的getaddrinfo()系统调用我们额外加了uprobe返回EAI_AGAINDNS 临时失败。原因浮出水面Agent 使用的 Pythonrequests库在 DNS 解析失败时会静默重试 3 次每次间隔 1s总计 3s。但connect()事件只记录最后一次尝试而ECONNREFUSED是因为 DNS 解析最终失败服务端根本没收到连接请求。这 3s 的 DNS 重试时间被传统监控完全忽略表现为“无日志、无错误、纯超时”。解决方案在 Agent 的requests.Session()中设置timeout(3.0, 3.0)并将 DNS 解析超时单独设为 1s通过dnspython库控制同时将connect_timeout告警阈值从 5s 降至 1.5s。上线后fraud_check超时率从 1.2% 降至 0.03%。实操心得AgentSight 的connect()事件必须配合getaddrinfo()钩子才能揭示 DNS 问题。我们后来将此作为默认探针因为 70% 的connect_timeout实际根源是 DNS而非网络或服务端。4.2 案例二电商推荐 Agent 的“随机卡死”——真相是 LLM KV Cache 冲突现象某电商推荐 Agent 在流量高峰时约 5% 的请求会卡在LLM thinking...状态长达 30-60s然后突然返回结果。Prometheus 显示 GPU 利用率只有 40%nvidia-smi也无异常。团队怀疑是 LLM 模型 bug准备回滚版本。AgentSight 排查过程在LLM Health Dashboard中发现llm_stuck事件与kv_cache_hit_rate的 P50 呈强负相关当kv_cache_hit_rate 0.3时llm_stuck概率飙升。查看llama_eval()事件详情对比正常和卡死请求正常请求n_tokens512,return_value512,kv_cache_hit_rate0.92卡死请求n_tokens512,return_value0,kv_cache_hit_rate0.05return_value0表示llama_eval()完全没执行成功进一步检查futex_wait()事件发现卡死时线程在pthread_mutex_lock()上阻塞且持有锁的线程 PID 对应一个llama_free()调用——说明另一个请求正在释放 KV Cache。根本原因Agent 使用了共享的全局 KV Cache 实例但在高并发下llama_eval()和llama_free()对 cache 的读写没有细粒度锁导致llama_eval()在 cache 被llama_free()清空的瞬间进入触发内部 assertion 失败并无限循环等待。解决方案将 KV Cache 改为 per-request 实例并用std::shared_ptr管理生命周期。同时AgentSight 新增了llama_cache_lock_contention指标当futex_wait()在 cache 相关 mutex 上耗时 100ms 时告警。修复后llm_stuck归零。实操心得LLM 的内部状态如 KV Cache是 Agentic OS 的“暗物质”传统监控完全不可见。AgentSight 的uprobe到llama_eval()和llama_free()是唯一能透视这一层的手段。我们建议所有使用 Llama.cpp 的团队必须开启这两个探针。4.3 案例三客服对话 Agent 的“权限静默失败”——真相是 ServiceAccount 权限缺失现象某 SaaS 客服 Agent 在接入新客户时偶尔无法调用search_knowledge_baseTool但日志只显示Tool call skipped无任何错误信息。客户抱怨“有时能搜到知识有时搜不到”复现困难。AgentSight 排查过程在Tool Failure Dashboard中筛选search_knowledge_baseTool发现permission_denied类型事件且errnoEACCES。查看connect()事件的目标地址unix:///var/run/kb.sock—— 这是一个 Unix Socket说明 Tool 是本地进程。检查该 Pod 的ServiceAccountkubectl get pod -l appcustomer-support-agent -o wide→serviceaccount: customer-support-sa。检查customer-support-sa的 RBACkubectl get rolebinding -n default -o wide | grep customer-support-sa # 输出customer-support-rb Role/customer-support-role ServiceAccount/default/customer-support-sa kubectl get role customer-support-role -n default -o yaml # 发现 missing: rules[0].resources: [secrets]但 kb.sock 需要读取 secrets 中的 token原因search_knowledge_baseTool 启动时会从/var/run/secrets/kubernetes.io/serviceaccount/token读取 JWT并通过该 token 访问知识库 API。但customer-support-sa没有secrets的get权限open()系统调用返回EACCESTool 进程直接 exit(1)Agent 捕获到子进程非零退出码于是“静默跳过”调用。解决方案给customer-support-role添加secrets的get权限。AgentSight 后来新增了unix_socket_permission_check探针专门监控对/var/run/secrets/路径的open()调用errnoEACCES时立即告警。实操心得Unix Socket 权限问题是最难 debug 的一类“沉默”。因为它不走网络APM 看不见它不抛异常日志不记录它只返回一个 errno而大多数 Agent SDK 会把它吞掉。AgentSight 的uprobe到open()和connect()是解决这类问题的终极武器。5. 进阶技巧与避坑指南让 AgentSight 发挥最大价值5.1 探针性能调优如何在 1000 QPS 下保持 0.1% 事件丢失率eBPF 的强大伴随着精细调优的需求。我们总结了 5 个关键参数它们决定了 AgentSight 在高压下的稳定性参数默认值推荐值1000 QPS作用调优逻辑percpu_map_size10244096存储每个 CPU 的临时事件缓冲防止多核竞争导致 map fullbpf_map_update_elem()失败perf_event_array_pages128512Perf Ring Buffer 大小页1 页 4KB512 页 2MB足够容纳 1000 QPS * 10ms * 100 字节/事件max_tracing_depth35uprobe 调用栈最大深度深度不够会丢失tool.run()→requests.post()的调用链但过深增加开销event_flush_interval_ms105Rust daemon 从 Perf Buffer 读取事件的间隔缩短可降低事件延迟但太短3ms会增加 syscall 开销batch_process_size100250每次处理的事件数批量处理提升 Rust daemon 效率但过大500导致内存峰值调整方法编辑 Helm values.yaml 中的collector.ebpfConfigcollector: ebpfConfig: percpu_map_size: 4096 perf_event_array_pages: 512 max_tracing_depth: 5 event_flush_interval_ms: 5 batch_process_size: 250注意perf_event_array_pages是最易被忽视的。我们曾遇到客户在 5000 QPS 下perf_buffer_poll()返回EBUSY原因是 Ring Buffer 满了来不及消费。增大 pages 后问题消失。建议用bpftool prog dump jited查看 eBPF 程序大小确保 pages * 4KB 程序大小 * 2。5.2 语义规则扩展如何为自定义 Tool 添加专属解析AgentSight 内置了对 LangChain、Llama.cpp、HuggingFace、Requests 的语义解析但你的 Agent 可能用了私有 Tool SDK。扩展规则很简单定义事件结构体C在ebpf-probe/tools/your_tool.c中添加uprobe到你的 SDK 函数SEC(uprobe/your_tool_execute) int BPF_UPROBE(your_tool_execute, void* input, void* output) { struct tool_event_t event {}; bpf_probe_read_user(event.input_len, sizeof(event.input_len), input-len); bpf_probe_read_user_str(event.tool_name, sizeof(event.tool_name), input-name); bpf_perf_event_output(ctx, events, BPF_F_CURRENT_CPU, event, sizeof(event)); return 0; }编写 Rust 解析器Rust在rust-daemon/src/semantic/your_tool.rs中pub fn parse_your_tool_event(event: ToolEvent) - OptionAgenticSpan { let mut span AgenticSpan::new(your_tool); span.set_attribute(tool.name, event.tool_name); span.set_attribute(tool.input_length, event.input_len as i64); // 添加你的业务逻辑如从 input 解析出 customer_id Some(span) }注册解析器在rust-daemon/src/main.rs的SemanticEngine::new()中添加your_tool::parse_your_tool_event到解析器列表。整个过程无需重启 AgentSight只需重新编译 eBPF 程序和 Rust daemonmake build然后滚动更新 DaemonSet。我们客户平均 2 小时就能为自己的私有 Tool SDK 添加完整可观测性。5.3 与现有生态集成如何让 AgentSight 数据进入你的 APMAgentSight 的设计原则是“不替代只增强”。它的 OTLP Exporter 支持无缝对接现有可观测栈对接 OpenTelemetry CollectorAgentSight 发送的是标准 OTLP/gRPC SpanCollector 只需配置otlpreceiver 和prometheusexporterreceivers: otlp: protocols: grpc: exporters: prometheus: endpoint: 0.0.0.0:9090 service: pipelines: traces: receivers: [otlp] exporters: [prometheus]对接 Datadog在 Collector 中启用datadogexporterAgentSight 的 Span 会自动带上dd.servicefinance-rag-agent、dd.envprod等 tag与 Datadog APM 的服务图完全融合。对接 Grafana LokiAgentSight 的 Rust daemon 会将原始 eBPF 事件以 JSON 格式写入 stdoutKubernetes 的 fluent-bit 可以将其收集为日志并用 LogQL 查询{jobagentsight-collector} | json | __error__ ! | line_format {{.event_type}} {{.pid}} {{.errno}}最关键的是TraceID 注入AgentSight 的 Rust daemon 会从/proc/[pid]/environ读取OTEL_TRACE_ID环境变量如果 Agent 启动时设置了并将该 TraceID 注入到所有生成的 Span 中。这样AgentSight 的llm_stuckSpan 就能与 OpenTelemetry 的llm_callSpan 关联形成端