
可观测性AI 评测LLMOpsAI 应用人工智能【免费下载链接】phoenixAI Observability Evaluation项目地址https://gitcode.com/gh_mirrors/phoenix13/phoenix点击查看免费下载本指南基于 Phoenix 仓库中的 Google ADK Java 追踪示例讲解如何让一个带函数工具的 Google ADKAgent Development KitJava 智能体在完全不修改业务代码的前提下通过 OpenInference Java Agent 在 JVM 启动时完成插桩把 OpenTelemetry 追踪数据发送到本地 Phoenix 实例进行可视化分析。读完本文你将掌握 Docker 启动 Phoenix、配置 Gemini API Key、注入 shaded agent JAR、理解WeatherAgent的完整工程结构以及openinference.project.name资源属性如何决定追踪数据归属项目等关键细节。一、方案概述Agent 代码零改动靠 JVM 启动期注入完成追踪Google ADKJava 版在运行智能体时会自动创建 OpenTelemetry spans。Phoenix 的 OpenInference Java Agent 则负责在 JVM 启动阶段通过-javaagent参数装饰这些 spans并把它们路由到 Phoenix 的 OTLP 端点。该示例的核心设计理念非常鲜明应用本身不调用任何 instrumentor API插桩完全由 Agent 在类加载层面完成。这带来两个直接收益智能体代码保持纯净与可观测性逻辑彻底解耦切换、升级或移除追踪能力时只需调整启动参数无需改动一行业务代码。这一点从仓库中 示例应用 的代码可以得到印证WeatherAgent中只包含 ADK 智能体构建、运行与 OpenTelemetry SDK 的全局注册没有任何手动 span 创建或插桩调用。二、运行前置条件根据 示例 README运行该示例需要以下环境依赖用途Java运行 JVM示例通过 Gradle toolchain 固定为 Java 17Gradle构建并启动示例应用Docker以容器方式快速启动本地 Phoenix 实例Gemini API KeyGoogle ADK 底层依赖 Google GenAI SDK需要调用 Gemini 模型OpenInference ADK Java Agentshaded JAR在 JVM 启动时对 ADK spans 进行 OpenInference 语义装饰其中 Java 版本要求可以从 build.gradle 确认项目通过java.toolchain.languageVersion JavaLanguageVersion.of(17)固定为 Java 17Gradle 会自动发现或下载匹配的 JDK。Gemini API Key 可以在 Google AI Studio 中申请示例通过环境变量GOOGLE_API_KEY注入供 Google GenAI SDK 在运行时读取。三、第一步用 Docker 启动本地 Phoenix在终端执行以下命令启动最新版 Phoenix 容器一次性映射两个关键端口docker run --rm -p 6006:6006 -p 4317:4317 arizephoenix/phoenix:latest端口含义6006Phoenix 的 Web 控制台端口浏览器访问http://localhost:6006即可打开追踪可视化界面4317OTLP gRPC 接收端点Java 示例中的OtlpGrpcSpanExporter默认就会向http://localhost:4317上报 spans。从 服务端 OTLP 入口 可以看到Phoenix 会解析ExportTraceServiceRequest中的每个ResourceSpans把 spans 解码后按项目名入队落库。容器以--rm启动退出即清理适合快速验证。四、第二步配置环境变量并运行示例在另一个终端中按顺序执行export GOOGLE_API_KEYyour-key export OPENINFERENCE_ADK_AGENT_JAR/path/to/adk-agent.jar cd java/examples/google-adk gradle -PagentJar$OPENINFERENCE_ADK_AGENT_JAR run三个关键点的详细说明GOOGLE_API_KEYGemini API KeyGoogle ADK 内部调用 Gemini 模型时使用OPENINFERENCE_ADK_AGENT_JAR指向 OpenInference ADK Java agent 的 shaded JAR即把所有依赖打包进单一 JAR 的-all.jargradle -PagentJar... run-P向 Gradle 传入项目属性agentJarrun任务在启动 JVM 前读取该属性并拼接-javaagent参数。run任务的这一逻辑定义在 build.gradle 中tasks.named(run) { doFirst { def agentJar providers.gradleProperty(agentJar).orNull if (agentJar null) { throw new GradleException( Pass the shaded OpenInference agent with -PagentJar/path/to/*-all.jar) } jvmArgs -javaagent:${file(agentJar).absolutePath} } }注意两点若未传agentJar任务会直接抛出GradleException提示避免静默启动一个没有插桩的进程传入的路径会被解析为绝对路径后拼接到-javaagent:后面这意味着 JAR 路径里即使包含空格或相对路径也能被正确处理。运行后如何验证浏览器打开http://localhost:6006在项目列表中选择google-adk-java项目应该能看到一次完整的智能体会话轨迹其中包含 LLM 调用 span 和getWeather函数工具调用 span。五、第三步覆盖默认配置的环境变量示例允许通过三个环境变量覆盖运行配置无需修改任何代码环境变量默认值作用GEMINI_MODELgemini-2.5-flash指定 ADK 智能体使用的 Gemini 模型PHOENIX_PROJECT_NAMEgoogle-adk-java设置openinference.project.name资源属性决定追踪在 Phoenix 中的项目归属OTEL_EXPORTER_OTLP_ENDPOINThttp://localhost:4317覆盖 OTLP gRPC 上报端点例如指向 Phoenix Cloud 或自建网关这三个变量的读取逻辑统一封装在 WeatherAgent.java 的environment(name, defaultValue)方法中private static String environment(String name, String defaultValue) { return System.getenv().getOrDefault(name, defaultValue); }即环境变量存在则取环境变量否则回落默认值。这也是该示例保持零配置即可运行的根基。六、深入剖析 WeatherAgent.java从 SDK 初始化到会话运行WeatherAgent.java 是完整示例应用包含 ADK 智能体与全部 OpenTelemetry 设置。我们按执行顺序拆解。6.1 函数工具定义public static MapString, Object getWeather( Schema(name city, description The city to look up) String city) { return Map.of( city, city, forecast, sunny, temperature_celsius, 21); }getWeather是注册给智能体的工具函数接收城市名返回城市、天气与温度。Schema注解来自com.google.adk.tools.AnnotationsADK 会据此把函数参数转换为模型可见的工具 schema。示例返回固定数据sunny、21 摄氏度目的是演示函数工具调用链路的追踪而非真实天气查询。6.2 先初始化 OpenTelemetry再碰任何 ADK 类这是整个示例最重要的时序约束。main方法第一行就调用initializeOpenTelemetry()代码注释明确给出了原因// Do this before touching an ADK class. ADK captures GlobalOpenTelemetry when // com.google.adk.Telemetry is first loaded. SdkTracerProvider tracerProvider initializeOpenTelemetry();ADK 在com.google.adk.Telemetry类首次加载时就会捕获当时的全局 OpenTelemetry 实例。如果在构建 ADK 对象之后才注册全局 SDKADK 拿到的就是空实现追踪数据将无处可去。因此顺序必须是构建并注册全局OpenTelemetrySdk再创建LlmAgent、InMemoryRunner等 ADK 对象。6.3 初始化 OpenTelemetry SDKResource resource Resource.getDefault() .merge(Resource.create(Attributes.of( AttributeKey.stringKey(service.name), google-adk-java-example, AttributeKey.stringKey(openinference.project.name), environment(PHOENIX_PROJECT_NAME, google-adk-java))));资源属性中两个关键字段service.name设为google-adk-java-example标识服务openinference.project.name默认google-adk-javaPhoenix 服务端会优先用它把 spans 归类到对应项目。OtlpGrpcSpanExporter exporter OtlpGrpcSpanExporter.builder() .setEndpoint(environment(OTEL_EXPORTER_OTLP_ENDPOINT, http://localhost:4317)) .setTimeout(Duration.ofSeconds(5)) .build(); SdkTracerProvider tracerProvider SdkTracerProvider.builder() .addSpanProcessor(BatchSpanProcessor.builder(exporter) .setScheduleDelay(Duration.ofSeconds(1)) .build()) .setResource(resource) .build(); OpenTelemetrySdk.builder() .setTracerProvider(tracerProvider) .setPropagators( ContextPropagators.create(W3CTraceContextPropagator.getInstance())) .buildAndRegisterGlobal(); return tracerProvider;实现要点OTLP gRPC 导出器默认端点http://localhost:4317并设置 5 秒超时避免导出阻塞主流程批量 span 处理器BatchSpanProcessor每 1 秒调度一次批量导出兼顾吞吐与延迟W3C TraceContext 传播器注册W3CTraceContextPropagator确保跨服务调用时 trace ID 能正确传递父 span 与子 span 关系完整buildAndRegisterGlobal()把 SDK 注册为GlobalOpenTelemetry这是 ADK 在类加载时能捕获到实例的前提。6.4 构建 ADK 智能体并运行会话LlmAgent agent LlmAgent.builder() .name(weather_agent) .model(environment(GEMINI_MODEL, gemini-2.5-flash)) .description(Answers weather questions with the getWeather tool.) .instruction(Always call getWeather before answering. Reply in one short sentence.) .tools(FunctionTool.create(WeatherAgent.class, getWeather)) .build(); InMemoryRunner runner new InMemoryRunner(agent); String userId visitor-123; Session session runner.sessionService().createSession(runner.appName(), userId).blockingGet();LlmAgent是 ADK 的核心智能体类这里命名为weather_agentmodel指定 Gemini 模型默认gemini-2.5-flash可用GEMINI_MODEL覆盖FunctionTool.create(WeatherAgent.class, getWeather)把静态方法注册为工具InMemoryRunner是 ADK 的内存态运行器createSession(appName, userId)创建会话blockingGet()同步等待完成。随后向会话发送一条自然语言消息并异步运行Content message Content.fromParts(Part.fromText(What is the weather in Paris right now?)); runner.runAsync(userId, session.id(), message).blockingForEach(event - { if (event.finalResponse()) { System.out.println(Agent: event.stringifyContent()); } });runAsync返回事件流示例只打印finalResponse事件的最终回复内容过程中智能体会按 instruction 的约束先调用getWeather(Paris)再基于结果作答而这两段调用LLM 调用与工具调用都会形成可追踪的 span 链。6.5 短生命周期应用的收尾tracerProvider.forceFlush().join(10, TimeUnit.SECONDS); tracerProvider.shutdown().join(10, TimeUnit.SECONDS);示例是一次性运行后立即退出的短生命周期进程因此在打印结果后forceFlush()强制将内存中尚未导出的 spans 立即发送到 Phoenixshutdown()关闭 tracer provider释放导出器资源。两处都使用join(10, TimeUnit.SECONDS)限时等待最多阻塞 10 秒。如果省略这一步进程可能在批量 span 处理器还没来得及导出时就退出导致追踪数据丢失。七、构建配置解读依赖、Java 版本与启动任务build.gradle 完整声明了示例的工程配置plugins { id application } repositories { mavenCentral() } dependencies { implementation com.google.adk:google-adk:0.4.0 implementation platform(io.opentelemetry:opentelemetry-bom:1.49.0) implementation io.opentelemetry:opentelemetry-sdk implementation io.opentelemetry:opentelemetry-exporter-otlp runtimeOnly org.slf4j:slf4j-simple:2.0.17 } application { mainClass com.arize.phoenix.examples.adk.WeatherAgent }google-adk:0.4.0Google ADK Java 版提供LlmAgent、InMemoryRunner、FunctionTool等核心类opentelemetry-bom:1.49.0BOMBill of Materials统一管理 OpenTelemetry 各组件版本后续的opentelemetry-sdk与opentelemetry-exporter-otlp均以 platform 方式引入、无需显式写版本号opentelemetry-exporter-otlp提供OtlpGrpcSpanExporter负责把 spans 序列化为 OTLP gRPC 请求slf4j-simple作为运行时日志实现仅runtimeOnly引入不会污染编译期依赖主类com.arize.phoenix.examples.adk.WeatherAgent由application插件在gradle run时启动。工程根目录的 settings.gradle 只有一行声明项目名为phoenix-google-adk-example表明这是一个独立可构建的 Gradle 单模块工程。八、追踪数据的项目归属openinference.project.name 的完整链路运行后你在 Phoenix 中看到的是google-adk-java项目而不是默认项目这背后是一条完整的解析链路理解它有助于排查追踪跑哪去了的问题。在 服务端 OTLP 接收逻辑 中项目名的解析优先级是HTTP 请求头x-project-name若提供每个ResourceSpans资源上的openinference.project.name属性服务端默认项目名DEFAULT_PROJECT_NAME。服务端通过 src/phoenix/utilities/project.py 中的get_project_name读取资源属性def get_project_name(attributes: Iterable[KeyValue]) - str: for kv in attributes: if kv.key ResourceAttributes.PROJECT_NAME and (v : kv.value.string_value): return str(v) return DEFAULT_PROJECT_NAME即遍历 OTLP 资源属性命中openinference.project.name且非空字符串时返回其值否则回落默认项目。而 src/phoenix/config.py 中默认项目名定义为default。因此若你在示例中设置了PHOENIX_PROJECT_NAMEmy-projectPhoenix 中会看到名为my-project的项目若不设置则回落到google-adk-java若连资源属性都没有例如跳过setResourcespans 才会进入default项目。这也是为什么本节标题中的 Java 代码里service.name与openinference.project.name要分开设置——前者标识服务后者决定项目归属。九、两个极易踩坑的实践要点时序全局 SDK 注册必须先于 ADK 类加载。ADK 的Telemetry类在首次加载时捕获GlobalOpenTelemetry顺序颠倒会导致静默无追踪。示例把initializeOpenTelemetry()放在main第一行正是为此。短生命周期进程必须 flush shutdown。示例进程运行数秒即退出BatchSpanProcessor默认按 1 秒调度批量导出若不主动forceFlush()进程退出时可能仍有 spans 滞留内存。十、与官方文档的对照阅读本示例在 Phoenix 官方文档体系中对应两个页面可作为进一步查阅的入口Google ADK 集成总览概述 Java 版 Google ADK 与 Phoenix 的集成方式Google ADK for Java 追踪指南详细讲解插桩原理、前置条件与手工注册 OpenTelemetry SDK 的代码模板。其中追踪指南还补充了一个本示例未覆盖的通用启动方式不依赖 Gradle直接使用java -javaagent:/path/to/adk-agent.jar -cp your-application-classpath com.example.Main启动任意应用原理与本例的gradle run完全一致——都是通过 JVM 启动期注入 shaded agent JAR 完成插桩。十一、小结通过本示例你可以完整跑通Google ADK Java 智能体 → OpenInference Java Agent → Phoenix的追踪链路Docker 一键拉起 Phoenixgradle -PagentJar run零代码注入插桩openinference.project.name自动完成项目归组。整个方案的核心价值在于追踪能力与应用代码彻底分离无论是接入、替换还是移除可观测性都只需要调整 JVM 启动参数。赞分享可观测性AI 评测LLMOpsAI 应用人工智能【免费下载链接】phoenixAI Observability Evaluation项目地址https://gitcode.com/gh_mirrors/phoenix13/phoenix点击查看免费下载相关推荐Phoenix 自动插桩实战用 arizeai/phoenix-otel 为 TypeScript LLM 应用零改动接入 OpenInference 追踪Phoenix 自动插桩实战用 arizeai/phoenix otel 为 TypeScript LLM 应用零改动接入 OpenInference 追踪可观测性AI 评测LLMOpsAI 应用人工智能Phoenix AGENT Span 完整指南OpenInference 自主推理追踪语义与实战Phoenix AGENT Span 完整指南OpenInference 自主推理追踪语义与实战 AGENT span 是 OpenInference 语义约可观测性AI 评测LLMOpsAI 应用人工智能Phoenix 自动插桩Auto-InstrumentationPython 实战指南零代码改动为 LLM 应用生成追踪 SpanPhoenix 自动插桩Auto InstrumentationPython 实战指南零代码改动为 LLM 应用生成追踪 Span 导读 本文以 Pho可观测性AI 评测LLMOpsAI 应用人工智能上一篇librespot 项目安装与使用教程下一篇Online Boutique 完整拆解11 个微服务如何撑起一个云原生电商 Demo创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考