基于 RAG 的聊天机器人的追踪、日志和指标:结合 Elastic 的 OpenTelemetry 分发

194 阅读8分钟

作者:来自 Elastic Bahubali Shetti

如何使用 Elasticsearch 观察基于 OpenAI RAG 的应用程序。使用 OpenTelemetry 对应用程序进行检测,收集日志、跟踪、指标,并了解 LLM 在 Kubernetes 和 Docker 上使用 OpenTelemetry 的 Elastic 分发的表现。

正如以下文章所讨论的,Elastic 在 EDOT(Elastic Distribution of OpenTelemetry)中为基于 OpenAI 的应用程序添加了监控功能。最常使用大语言模型(large language modes - LLMs)的应用程序通常被称为聊天机器人(Chatbot)。这些聊天机器人不仅使用大语言模型,还结合了如 LangChain 等框架和搜索功能,通过 RAG(Retrieval Augmented Generation - 检索增强生成)技术在对话中改进上下文信息。Elastic 的示例 RAG 聊天机器人应用程序展示了如何使用 Elasticsearch 和包含嵌入数据的本地数据,实现搜索以便在与所选 LLM 连接的聊天机器人查询时准确提取最相关的上下文信息。这是一个使用 Elasticsearch 构建 RAG 应用程序的绝佳案例。

现在,该应用程序也通过 EDOT 实现了监控功能。你可以可视化聊天机器人对 OpenAI 的追踪信息,以及应用程序生成的相关日志和指标。按照 GitHub 仓库中使用 Docker 的说明运行该应用程序后,你可以在本地堆栈上查看这些追踪信息。那么,如何将其运行在 serverless 环境、Elastic Cloud 甚至 Kubernetes 上呢?

在这篇博客中,我们将逐步讲解如何通过 Elastic Cloud 和 Kubernetes 设置 Elastic 的 RAG 聊天机器人应用程序。

先决条件:

为了跟上进度,需要满足以下几个先决条件

  • Elastic Cloud 帐户 — 立即注册,并熟悉 Elastic 的 OpenTelemetry 配置。使用 Serverless 时不需要版本。常规云最低 8.17
  • Git 克隆基于 RAG 的聊天机器人应用程序,并按照教程了解如何启动它并熟悉它以及如何使用 Docker 启动该应用程序。
  • 具有 API 密钥的 OpenAI 帐户
  • Kubernetes 集群运行基于 RAG 的 Chatbot 应用程序
  • 本博客中的说明也可在 github 中的 observability-examples 中找到。

Elastic 中的 OpenTelemetry 应用程序输出

Chatbot-rag-app

启动并运行所需的第一个项目是 ChatBotApp,启动后你应该看到以下内容:

当你选择一些问题时,你将根据应用程序初始化时在 Elasticsearch 中创建的索引设置答案。此外,还会有针对 LLMs 的查询。

:如果你想在在自己的电脑上运行 chatbot 应用程序,请详细阅读文章 “Elasticsearch:聊天机器人教程(一)”。

Elastic 中 EDOT 的跟踪、日志和指标

一旦你的应用程序在 K8s 集群或 Docker 上运行,并且 Elastic Cloud 启动并运行,你应该看到以下内容:

日志:

在 Discover 中,你将看到来自 Chatbotapp 的日志,并能够分析应用程序日志和任何特定的日志模式,从而节省你的分析时间。

踪迹:

在 Elastic Observability APM 中,你还可以看到聊天机器人的详细信息,其中包括 transactions、依赖项、日志、错误等。

当你查看跟踪时,你将能够在跟踪中看到聊天机器人的交互。

  • 你将看到端到端 http 调用
  • 单独调用 elasticsearch
  • 特定调用,例如调用操作和对 ​​LLM 的调用

你还可以获取跟踪的单独详细信息,并查看相关日志以及与该跟踪相关的指标,

指标:

除了日志和跟踪之外,任何被检测的指标也将被纳入 Elastic 中。

使用 Docker 进行所有设置

为了在 Docker 上正确设置 Chatbot-app 并将遥测数据发送到 Elastic,必须设置以下内容:

  • Git 克隆 chatbot-rag-app
  • 按照 github README 中所述修改 env 文件,但有以下例外:

改用你自己 Elastic 云的 OTEL_EXPORTER_OTLP_ENDPOINT 和 OTEL_EXPORTER_OTLP_HEADER 参数值。

你可以在 Elastic Cloud 的 integrations->APM 下找到这些内容



1.  OTEL_EXPORTER_OTLP_ENDPOINT="https://123456789.apm.us-west-2.aws.cloud.es.io:443"
2.  OTEL_EXPORTER_OTLP_HEADERS="Authorization=Bearer%20xxxxx"


注意标题中的 %20。这需要考虑凭证中的空格。

  • 将以下内容设置为 false - OTEL_SDK_DISABLED=false
  • 设置 LLMs 的环境

在这个例子中,我们使用 OpenAI,因此只需要三个变量。



1.  LLM_TYPE=openai
2.  OPENAI_API_KEY=XXXX
3.  CHAT_MODEL=gpt-4o-mini


  • 按照说明运行 docker 容器
docker compose up --build --force-recreate 
  • 在 localhost:4000 上使用应用程序
  • 然后登录 Elastic 云并查看如前所示的输出。

在 K8s 上运行 chatbot-rag-app

为了进行此项设置,你可以按照 Observability-examples 上的以下 repo 进行操作,其中包含正在使用的 Kubernetes yaml 文件。这些也将指向 Elastic Cloud。

  • 设置 Kubernetes 集群(我们使用 EKS)
  • 使用来自 repo 的 Dockerfile 创建 docker 镜像。但是使用以下构建命令来确保它可以在任何 K8s 环境上运行。
docker buildx build --platform linux/amd64 -t chatbot-rag-app . 
  • 将镜像推送到你喜欢的容器存储库
  • 获取适当的 ENV 变量:
    • 找到 Docker 中先前提到的 OTEL_EXPORTER_OTLP_ENDPOINT/HEADER 变量。
    • 获取你的 OpenAI 密钥
    • Elasticsearch URL、用户名和密码。
  • 按照以下 GitHub 仓库中的 Observability Examples 提供的说明运行两个 Kubernetes YAML 文件。

基本上,你只需将下方标注为 红色 的项目替换为你的实际值,然后运行即可。



1.  kubectl create -f k8s-deployment.yaml
2.  kubectl create -f init-index-job.yaml


Init-index-job.yaml



1.  apiVersion: batch/v1
2.  kind: Job
3.  metadata:
4.    name: init-elasticsearch-index-test
5.  spec:
6.    template:
7.      spec:
8.        containers:
9.        - name: init-index
10.          <span style={

12.    { color: 'red', fontWeight: 'bold' }}>image: yourimagelocation:latest</span>
13.          workingDir: /app/api
14.          command: ["python3", "-m", "flask", "--app", "app", "create-index"]
15.          env:
16.          - name: FLASK_APP
17.            value: "app"
18.          - name: LLM_TYPE
19.            value: "openai"
20.          - name: CHAT_MODEL
21.            value: "gpt-4o-mini"
22.          - name: ES_INDEX
23.            value: "workplace-app-docs"
24.          - name: ES_INDEX_CHAT_HISTORY
25.            value: "workplace-app-docs-chat-history"
26.          - name: ELASTICSEARCH_URL
27.            valueFrom:
28.              secretKeyRef:
29.                name: chatbot-regular-secrets
30.                key: ELASTICSEARCH_URL
31.          - name: ELASTICSEARCH_USER
32.            valueFrom:
33.              secretKeyRef:
34.                name: chatbot-regular-secrets
35.                key: ELASTICSEARCH_USER
36.          - name: ELASTICSEARCH_PASSWORD
37.            valueFrom:
38.              secretKeyRef:
39.                name: chatbot-regular-secrets
40.                key: ELASTICSEARCH_PASSWORD
41.          envFrom:
42.          - secretRef:
43.              name: chatbot-regular-secrets
44.        restartPolicy: Never
45.    backoffLimit: 4


k8s-deployment.yaml



1.  apiVersion: v1
2.  kind: Secret
3.  metadata:
4.    name: chatbot-regular-secrets
5.  type: Opaque
6.  stringData:
7.    ELASTICSEARCH_URL: "https://yourelasticcloud.es.us-west-2.aws.found.io"
8.    ELASTICSEARCH_USER: "elastic"
9.    ELASTICSEARCH_PASSWORD: "elastic"
10.    OTEL_EXPORTER_OTLP_HEADERS: "Authorization=Bearer%20xxxx"
11.    OTEL_EXPORTER_OTLP_ENDPOINT: "https://12345.apm.us-west-2.aws.cloud.es.io:443"
12.    OPENAI_API_KEY: "YYYYYYYY"

14.  ---
15.  apiVersion: apps/v1
16.  kind: Deployment
17.  metadata:
18.    name: chatbot-regular
19.  spec:
20.    replicas: 2
21.    selector:
22.      matchLabels:
23.        app: chatbot-regular
24.    template:
25.      metadata:
26.        labels:
27.          app: chatbot-regular
28.      spec:
29.        containers:
30.        - name: chatbot-regular
31.          image: yourimagelocation:latest
32.          ports:
33.          - containerPort: 4000
34.          env:
35.          - name: LLM_TYPE
36.            value: "openai"
37.          - name: CHAT_MODEL
38.            value: "gpt-4o-mini"
39.          - name: OTEL_RESOURCE_ATTRIBUTES
40.            value: "service.
41.          - name: OTEL_SDK_DISABLED
42.            value: "false"
43.          - name: OTEL_INSTRUMENTATION_GENAI_CAPTURE_MESSAGE_CONTENT
44.            value: "true"
45.          - name: OTEL_EXPERIMENTAL_RESOURCE_DETECTORS
46.            value: "process_runtime,os,otel,telemetry_distro"
47.          - name: OTEL_EXPORTER_OTLP_PROTOCOL
48.            value: "http/protobuf"
49.          - name: OTEL_METRIC_EXPORT_INTERVAL
50.            value: "3000"
51.          - name: OTEL_BSP_SCHEDULE_DELAY
52.            value: "3000"
53.          envFrom:
54.          - secretRef:
55.              name: chatbot-regular-secrets
56.          resources:
57.            requests:
58.              memory: "512Mi"
59.              cpu: "250m"
60.            limits:
61.              memory: "1Gi"
62.              cpu: "500m"

64.  ---
65.  apiVersion: v1
66.  kind: Service
67.  metadata:
68.    name: chatbot-regular-service
69.  spec:
70.    selector:
71.      app: chatbot-regular
72.    ports:
73.    - port: 80
74.      targetPort: 4000
75.    type: LoadBalancer


使用 LoadBalancer URL 打开应用程序

运行 kubectl get services 命令并获取聊天机器人应用程序的 URL



1.  % kubectl get services
2.  NAME                                 TYPE           CLUSTER-IP    EXTERNAL-IP                                                               PORT(S)                                                                     AGE
3.  chatbot-regular-service            LoadBalancer   10.100.130.44    xxxxxxxxx-1515488226.us-west-2.elb.amazonaws.com   80:30748/TCP                                                                6d23h


  • 在 Elastic 中试用应用程序并查看遥测数据
  • 一旦你转到该 URL,你应该会看到我们在此博客开头描述的所有屏幕。

结论

通过 Elastic 的 Chatbot-rag-app,你可以了解如何构建基于 OpenAI 驱动的 RAG 聊天应用程序的示例,但是,你仍然需要了解它的性能如何、是否正常运行等。使用 OTel 和 Elastic 的 EDOT 可以让你实现这一点。此外,你通常会在 Kubernetes 上运行此应用程序。希望本博客能够提供如何实现这一目标的概要。以下是其他追踪博客:

使用 LLM 实现应用程序可观察性(跟踪)-

LLM 可观察性 -

原文:Tracing, logs, and metrics for a RAG based Chatbot with Elastic Distributions of OpenTelemetry — Elastic Observability Labs