使用 EDOT 监测由 OpenAI 提供支持的 Python、Node.js 和 Java 应用程序

news2025/2/14 1:17:46

作者:来自 Elastic Adrian Cole

Elastic 很自豪地在我们的 Python、Node.js 和 Java EDOT SDK 中引入了 OpenAI 支持。它们为使用 OpenAI 兼容服务的应用程序添加日志、指标和跟踪,而无需任何代码更改。

介绍

去年,我们宣布了 OpenTelemetry(又名 Elastic Distribution of OpenTelemetry - EDOT)语言 SDK 的 Elastic 分发,它可以从应用程序收集日志、跟踪和指标。当宣布这一消息时,我们还不支持 OpenAI 等大型语言模型 (LLM) 提供商。这限制了开发人员对生成式人工智能 (GenAI) 应用程序的洞察力。

在之前的文章中,我们回顾了 LLM 可观察性的重点,例如 token 使用情况、聊天延迟以及了解你的应用程序使用哪些工具(如 DuckDuckGo)。通过正确的日志、跟踪和指标,开发人员可以回答诸如 “Which version of a model generated this response? - 哪个版本的模型生成了此响应?”之类的问题。或 “What was the exact chat prompt created by my RAG application? - 我的 RAG 应用程序创建的聊天提示的具体是什么?”

在过去的六个月中,Elastic 与 OpenTelemetry 社区的其他成员一起投入了大量精力来共享这些领域的规范,包括收集 LLM 相关日志、指标和跟踪的代码。我们的目标是扩展 EDOT 为 GenAI 用例带来的零代码(代理)方法。

今天,我们宣布了 EDOT 语言 SDK 中的第一个 GenAI 仪器功能:OpenAI。下面,你将看到如何使用我们的 Python、Node.js 和 Java EDOT SDK 观察 GenAI 应用程序。

示例应用程序

我们中的许多人可能熟悉 ChatGPT,它是 OpenAI GPT 模型系列的前端。使用这个,你可以提出一个问题,助手可能会根据你问的问题和 LLM 所训练的文本正确地回答。

以下是 ChatGPT 回答的一个深奥问题的示例:

我们的示例应用程序将简单地询问这个预定义的问题并打印结果。我们将使用三种语言编写它:Python、JavaScript 和 Java。

我们将采用“零代码”(代理)方法执行每个操作,以便在配置了 Kibana 和 APM 服务器的 Elastic Stack 中捕获和查看日志、指标和跟踪。如果你尚未运行堆栈,请使用 ElasticSearch Labs 的说明进行设置。

无论编程语言是什么,都需要三个变量:OpenAI API 密钥、Elastic APM 服务器的位置以及应用程序的服务名称。你将把这些写入名为 .env 的文件中。

OPENAI_API_KEY=sk-YOUR_API_KEY
OTEL_EXPORTER_OTLP_ENDPOINT=http://localhost:8200
OTEL_SERVICE_NAME=openai-example

每次应用程序运行时,它都会将日志、跟踪和指标发送到 APM 服务器,你可以通过像这样查询 Kibana 来找到应用程序 “openai-example”

http://localhost:5601/app/apm/services/openai-example/transactions

当你选择一个跟踪时,你将看到 OpenAI SDK 发出的 LLM 请求,以及由此引起的 HTTP 流量:

选择 logs 选项卡来查看对 OpenAI 的确切请求和响应。这些数据对于问答和评估用例至关重要。

你还可以转到 Metrics Explorer 并在运行应用程序的所有时间内绘制 “gen_ai.client.token.usage” 或 “gen_ai.client.operation.duration” 的图表:

http://localhost:5601/app/metrics/explorer

继续查看该应用程序在 Python、Java 和 Node.js 中的具体外观和运行方式。那些已经使用我们的 EDOT 语言 SDK 的人将会熟悉它的工作原理。

Python

假设你已经安装了 python,那么第一件事就是设置一个虚拟环境并安装所需的软件包:OpenAI 客户端、用于读取 .env 文件的辅助工具和我们的 EDOT Python 包:

python3 -m venv .venv
source .venv/bin/activate
pip install openai "python-dotenv[cli]" elastic-opentelemetry

接下来,运行 edot-bootstrap,它将分析代码以安装任何可用的相关工具:

edot-bootstrap —-action=install

现在,创建你的 .env 文件,如本文前面所述,以及 chat.py 中的以下源代码

import os

import openai

CHAT_MODEL = os.environ.get("CHAT_MODEL", "gpt-4o-mini")


def main():
  client = openai.Client()

  messages = [
    {
      "role": "user",
        "content": "Answer in up to 3 words: Which ocean contains Bouvet Island?",
    }
  ]

  chat_completion = client.chat.completions.create(model=CHAT_MODEL, messages=messages)
  print(chat_completion.choices[0].message.content)

if __name__ == "__main__":
  main()

现在你可以使用以下命令运行所有内容:

dotenv run -- opentelemetry-instrument python chat.py

最后,在 Kibana 中查找名为 “openai-example” 的服务的跟踪。你应该会看到一个名为 “chat gpt-4o-mini” 的交易。

你无需复制/粘贴上述内容,而是可以在此处的 Python EDOT 存储库中找到此示例的工作副本(以及说明)。

最后,如果你想尝试更全面的示例,请查看使用 OpenAI 和 ElasticSearch 的 Elser 检索模型的 chatbot-rag-app。

Java

初始化 Java 项目有几种流行的方法。由于我们使用的是 OpenAI,第一步是配置依赖项 com.openai:openai-java 并将以下源代码写为 Chat.java。

package openai.example;

import com.openai.client.OpenAIClient;
import com.openai.client.okhttp.OpenAIOkHttpClient;
import com.openai.models.*;


final class Chat {

  public static void main(String[] args) {
    String chatModel = System.getenv().getOrDefault("CHAT_MODEL", "gpt-4o-mini");

    OpenAIClient client = OpenAIOkHttpClient.fromEnv();

    String message = "Answer in up to 3 words: Which ocean contains Bouvet Island?";
    ChatCompletionCreateParams params = ChatCompletionCreateParams.builder()
        .addMessage(ChatCompletionUserMessageParam.builder()
          .content(message)
          .build())
        .model(chatModel)
        .build();

    ChatCompletion chatCompletion = client.chat().completions().create(params);
    System.out.println(chatCompletion.choices().get(0).message().content().get());
  }
}

构建项目使得所有依赖项都在一个 jar 中。例如,如果使用 Gradle,你将使用 com.gradleup.shadow 插件。

接下来,如前所述,创建 .env 文件,并下载我们将用来加载它的 shdotenv。

curl -O -L https://github.com/ko1nksm/shdotenv/releases/download/v0.14.0/shdotenv
chmod +x ./shdotenv

此时,你有一个 jar 和配置,可以用来运行 OpenAI 示例。下一步是下载 EDOT Java javaagent 二进制文件。这是记录和导出日志、指标和跟踪的部分。

curl -o elastic-otel-javaagent.jar -L 'https://oss.sonatype.org/service/local/artifact/maven/redirect?r=snapshots&g=co.elastic.otel&a=elastic-otel-javaagent&v=LATEST'

假设你组装了一个名为 openai-example-all.jar 的文件,请使用 EDOT 运行它,如下所示:

./shdotenv java -javaagent:elastic-otel-javaagent.jar -jar openai-example-all.jar

最后,在 Kibana 中查找名为 “openai-example” 的服务的跟踪。你应该会看到一个名为 “chat gpt-4o-mini” 的交易。

你无需复制/粘贴上述内容,而是可以在此处的 EDOT Java 源代码存储库中找到此示例的工作副本。

Node.js

假设你已经安装并配置了 npm,请运行以下命令来初始化示例项目。这包括 openai 包和 @elastic/opentelemetry-node (EDOT Node.js)

npm init -y
npm install openai @elastic/opentelemetry-node

接下来,创建 .env 文件,如本文前面所述以及 index.js 中的以下源代码:

const {OpenAI} = require('openai');

let chatModel = process.env.CHAT_MODEL ?? 'gpt-4o-mini';

async function main() {
 const client = new OpenAI();
 const completion = await client.chat.completions.create({
  model: chatModel,
  messages: [
   {
    role: 'user',
    content: 'Answer in up to 3 words: Which ocean contains Bouvet Island?',
   },
  ],
 });
 console.log(completion.choices[0].message.content);
}

main();

有了这个,使用 EDOT 运行上述源,如下所示:

node --env-file .env --require @elastic/opentelemetry-node index.js

最后,在 Kibana 中查找名为 “openai-example” 的服务的跟踪。你应该会看到一个名为 “chat gpt-4o-mini” 的交易。

你无需复制/粘贴上述内容,就可以在此处的 EDOT Node.js 源存储库中找到此示例的工作副本。

最后,如果你想尝试一个更全面的示例,请查看 openai-embeddings,它使用 OpenAI 和 Elasticsearch 作为向量数据库!

结束语

以上你已经了解了如何使用 OpenTelemetry 的弹性分布 (EDOT) 以三种不同的语言观察官方 OpenAI SDK。

值得注意的是,一些 OpenAI SDK 以及围绕生成式 AI 的 OpenTelemetry 规范都是实验性的。如果你发现这对你有帮助,或者发现故障,请加入我们的 Slack 并让我们知道。

通过设置 OPENAI_BASE_URL 并选择相关模型,多个 LLM 平台可以接受来自 OpenAI 客户端 SDK 的请求。在开发过程中,我们测试了 Azure OpenAI 服务并使用 Ollama 进行集成测试。事实上,我们将代码贡献给 Ollama 以改进其 OpenAI 支持。无论你选择哪种 OpenAI 兼容平台,我们都希望这个新工具可以帮助你了解 LLM 的使用情况。

最后,虽然第一个搭载 EDOT 的生成式 AI SDK 是 OpenAI,但你很快就会看到更多。我们已经在 Bedrock 上开展工作,并与 OpenTelemetry 社区的其他人合作开发其他平台。请继续关注此博客以获取令人兴奋的更新。

原文:Instrumenting your OpenAI-powered Python, Node.js, and Java Applications with EDOT — Elastic Observability Labs

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2297641.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测

CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测 代码下载:CNN-BiGRU卷积神经网络双向门控循环单元多变量多步预测,光伏功率预测 一、引言 1.1、研究背景及意义 随着全球能源危机和环境问题的日益严重,可再…

mysql8.0使用MGR实现高可用与利用MySQL Router构建读写分离MGR集群

MGR是MySQL Group Replication的缩写,即MySQL组复制。 在以往,我们一般是利用MySQL的主从复制或半同步复制来提供高可用解决方案,但这存在以下几个比较严重的问题: 主从复制间容易发生复制延迟,尤其是在5.6以前的版本…

保研考研机试攻略:python笔记(4)

🐨🐨🐨15各类查找 🐼🐼二分法 在我们写程序之前,我们要定义好边界,主要是考虑区间边界的闭开问题。 🐶1、左闭右闭 # 左闭右闭 def search(li, target): h = len(li) - 1l = 0#因为都是闭区间,h和l都可以取到并且相等while h >= l:mid = l + (h - l) // 2…

关于conda换镜像源,pip换源

目录 1. 查看当前下载源2. 添加镜像源2.1清华大学开源软件镜像站2.2上海交通大学开源镜像站2.3中国科学技术大学 3.删除镜像源4.删除所有镜像源,恢复默认5.什么是conda-forge6.pip换源 1. 查看当前下载源 conda config --show channels 如果发现多个 可以只保留1个…

分布式服务框架 如何设计一个更合理的协议

1、概述 前面我们聊了如何设计一款分布式服务框架的问题,并且编码实现了一个简单的分布式服务框架 cheese, 目前 cheese 基本具备分布式服务框架的基本功能。后面我们又引入了缓存机制,以及使用Socket替代了最开始的 RestTemplate。并且还学习了网络相关…

前端快速生成接口方法

大家好,我是苏麟,今天聊一下OpenApi。 官网 : umijs/openapi - npm 安装命令 npm i --save-dev umijs/openapi 在根目录(项目目录下)创建文件 openapi.config.js import { generateService } from umijs/openapi// 自…

mysql 学习12 存储引擎,mysql体系结构

mysql 体系结构 存储引擎简介 存储引擎 就是 存储数据,建立索引,更新/查询 数据等技术的实现方式。 存储引擎 是基于表的,而不是基于库的,所以存储引擎也可以称为 表类型 mysql默认的使用InnoDB 做为存储引擎 查看一下我们之前…

稀土抑烟剂——为汽车火灾安全增添防线

一、稀土抑烟剂的基本概念 稀土抑烟剂是一类基于稀土元素(如稀土氧化物和稀土金属化合物)开发的高效阻燃材料。它可以显著提高汽车内饰材料的阻燃性能,减少火灾发生时有毒气体和烟雾的产生。稀土抑烟剂不仅能提升火灾时的安全性,…

Unity进阶教程AOI算法原理详解

最新课程《全栈双客户端(Unity/Cocos) TurnKey方案》更新了AOI专题,今天分享一下AOI算法的实现原理。 AOI的功能和作用 在MMORPG网路游戏当中,单服同时在线一般都会有几千人。当有个玩家执行一个操作,理想情况下要把玩家的操作广播同步给单…

【C】链表算法题7 -- 环形链表||

leetcode链接https://leetcode.cn/problems/linked-list-cycle-ii/description/ 问题描述 给定一个链表的头节点 head ,返回链表开始入环的第一个节点。 如果链表无环,则返回 null。如果链表中有某个节点,可以通过连续跟踪 next 指针再次到…

STM32系统架构介绍

STM32系统架构 1. CM3/4系统架构2. CM3/4系统架构-----存储器组织结构2.1 寄存器地址映射(特殊的存储器)2.2 寄存器地址计算2.3 寄存器的封装 3. CM3/4系统架构-----时钟系统 STM32 和 ARM 以及 ARM7是什么关系? ARM 是一个做芯片标准的公司&#xff0c…

window patch按块分割矩阵

文章目录 1. excel 示意2. pytorch代码3. window mhsa 1. excel 示意 将一个三维矩阵按照window的大小进行拆分成多块2x2窗口矩阵,具体如下图所示 2. pytorch代码 pytorch源码 import torch import torch.nn as nn import torch.nn.functional as Ftorch.set_p…

机器学习(李宏毅)——BERT

一、前言 本文章作为学习2023年《李宏毅机器学习课程》的笔记,感谢台湾大学李宏毅教授的课程,respect!!! 读这篇文章必须先了解self-attention、Transformer,可参阅我其他文章。 二、大纲 BERT简介self-…

深度学习-111-大语言模型LLM之基于langchain的结构化输出功能实现文本分类

文章目录 1 langchain的结构化输出1.1 推荐的使用流程1.2 模式定义1.3 返回结构化输出1.3.1 工具调用(方式一)1.3.2 JSON模式(方式二)1.3.3 结构化输出法(方式三)2 文本分类2.1 定义分类模式2.2 配置分类提示模板2.3 初始化分类模型2.4 分类示例3 参考附录1 langchain的结构化输…

常见的排序算法:插入排序、选择排序、冒泡排序、快速排序

1、插入排序 步骤: 1.从第一个元素开始,该元素可以认为已经被排序 2.取下一个元素tem,从已排序的元素序列从后往前扫描 3.如果该元素大于tem,则将该元素移到下一位 4.重复步骤3,直到找到已排序元素中小于等于tem的元素…

C++17 中的 std::gcd:探索最大公约数的现代 C++ 实现

文章目录 一、std::gcd 的基本用法(一)包含头文件(二)函数签名(三)使用示例 二、std::gcd 的实现原理三、std::gcd 的优势(一)简洁易用(二)类型安全&#xff…

OpenWRT中常说的LuCI是什么——LuCI介绍(一)

我相信每个玩openwrt的小伙伴都或多或少看到过luci这个东西,但luci到底是什么东西,可能还不够清楚,今天就趁机来介绍下,openwrt中的luci,到底是个什么东西。 什么是LuCI? 首先,LuCI是OpenWRT中…

机器学习核心算法解析

机器学习核心算法解析 机器学习是人工智能的核心技术之一,它通过从数据中学习模式并做出预测或决策。本文将深入解析机器学习的核心算法,包括监督学习、无监督学习和强化学习,并通过具体案例和代码示例帮助读者理解这些算法的实际应用。 1. …

LVDS接口总结--(5)IDELAY3仿真

仿真参考资料如下: https://zhuanlan.zhihu.com/p/386057087 timescale 1 ns/1 ps module tb_idelay3_ctrl();parameter REF_CLK 2.5 ; // 400MHzparameter DIN_CLK 3.3 ; // 300MHzreg ref_clk ;reg …

微服务与网关

什么是网关 背景 单体项目中,前端只用访问指定的一个端口8080,就可以得到任何想要的数据 微服务项目中,ip是不断变化的,端口是多个的 解决方案:网关 网关:就是网络的关口,负责请求的路由、转发、身份校验。 前段还是访问之前的端口8080即可 后端对于前端来说是透明的 网…