LLM应用接入
LLM(Large Language Model)应用性能监控,可实时追踪应用中所使用LLM的推理时延、吞吐量、Token用量等核心指标,支持采集LLM领域特有的span类型,可视化展示端到端调用链路的详细信息,为应用的持续优化与高效运维提供精准的数据支撑。下面介绍如何接入LLM应用:
支持的 LLM 组件与框架
LLM 应用可以基于 Traceloop 开源的 OpenLLMetry 项目进行接入,该项目完全兼容 OpenTelemetry 协议标准,能够和其他使用 OpenTelemetry 方案接入的应用实现链路信息互通。 OpenLLMetry 项目支持众多 LLM 组件与框架的自动埋点,请前往项目主页获取所有支持的组件与框架,以下将列出其中一部分供您参考。
支持的 LLM 组件与框架 | 链接 |
---|---|
支持的 LLM 框架 | Ollama、LlamaIndex、LangChain、Haystack、LiteLLM、CrewAI |
支持的向量数据库 | Chroma、Pinecone、Qdrant、Weaviate、Milvus、Marqo、LanceDB |
支持向量操作的AI平台和服务 | VertexAI、OpenAI、MistralAI |
接入语言:Python
协议类型:OpenTelemetry
接入流程
Traceloop 是当下 Python 流行、规范的 SDK,它遥测的 Trace 数据更为规范和丰富,。下文将介绍 Traceloop 的接入方式。
步骤1:获取接入点与 Token(该信息因地域和用户而异,可在控制台“接入应用”页面获取,下方为示例)
- 接入点:apm-collector.bj.baidubce.com
- Authentication:UFSpMM***lnFrVBqtPDK
步骤2:安装 Traceloop-SDK
通过pip命令安装 Traceloop-SDK,其中包含了对 OpenLLMetry 以及 OpenTelemetry-SDK 的相关依赖。
1pip install traceloop-sdk
步骤3:初始化配置
在 Python 项目的入口文件中引入 Traceloop 和 OpenTelemetry-SDK,并根据前置步骤中获得的接入点以及 Authentication 进行初始化。
1# -*- coding: utf-8 -*-
2import os
3from traceloop.sdk import Traceloop
4
5
6os.environ['TRACELOOP_BASE_URL'] = "<endpoint>" # 替换接入获取的endpoint
7os.environ['TRACELOOP_HEADERS'] = "Authentication=<authentication>" # 替换为接入点获取的Authentication
8Traceloop.init(app_name='<server.name>', # 设置当前应用的名称
9 resource_attributes={
10 "host.name": "<host.name>" # 设置当前主机名称
11 })
12
13
对应的字段说明如下:
参数 | 描述 | 示例 |
---|---|---|
<serviceName> | 应用名,多个使用相同应用名接入的进程,在 APM 中会表现为相同应用下的多个实例。对于 Spring Cloud 或 Dubbo 应用,应用名通常和服务名保持一致 | csm |
<Authentication> | 步骤 1 中拿到业务系统 Authentication | UFSpMM***lnFrVBqtPDK |
<endpoint> | 步骤 1 中拿到的接入点 | http://10.169.25.203:8810 |
该实例的主机名,是应用实例的唯一标识,通常情况下可以设置为应用实例的 IP 地址。 | my-instance-host |
步骤4:接入验证
启动 Python 应用后。在有LLM调用的情况下,<LLM应用性能监控>→<应用列表> 中将展示接入的应用。由于数据的处理存在一定延时,如果接入后在控制台没有查询到应用,请等待 30 秒左右。
接入实战示例
示例一
通过 OpenAI SDK 访问千帆接口,并遥测该过程中的数据。
1import os
2from traceloop.sdk import Traceloop
3from openai import OpenAI
4
5
6ai_model = 'ernie-4.0-turbo-128k'
7api_key = "bce-v3/ALTAK-mTNsaNCr4********" #替换为千帆的 API-Key
8base_url = "https://qianfan.baidubce.com/v2" #千帆的endpoint
9
10os.environ['TRACELOOP_BASE_URL'] = "<endpoint>" # 替换接入获取的endpoint
11os.environ['TRACELOOP_HEADERS'] = "Authentication=<authentication>" # 替换为接入点获取的Authentication
12Traceloop.init(app_name='<server.name>', # 设置当前应用的名称
13 resource_attributes={
14 "host.name": "<host.name>" # 设置当前主机名称
15 })
16
17
18if __name__ == '__main__':
19 llm = OpenAI(
20 api_key=api_key,
21 base_url=base_url
22 )
23
24 response = llm.chat.completions.create(
25 model=ai_model,
26 messages=[
27 {
28 "role": "user",
29 "content": "hello"
30 },
31 ],
32 )
示例二
遥测使用 Langchain 框架的 LLM 数据
1import os
2from traceloop.sdk import Traceloop
3from langgraph.graph import StateGraph
4from typing import Dict, TypedDict
5from openai import OpenAI
6import langchain
7
8langchain.debug = True
9
10ai_model = 'ernie-4.0-turbo-128k'
11api_key = "bce-v3/ALTAK-mTNsaNCr4********" #替换为千帆的 API-Key
12base_url = "https://qianfan.baidubce.com/v2" #千帆的endpoint
13
14os.environ['TRACELOOP_BASE_URL'] = "<endpoint>" # 替换接入获取的endpoint
15os.environ['TRACELOOP_HEADERS'] = "Authentication=<authentication>" # 替换为接入点获取的Authentication
16Traceloop.init(app_name='<server.name>', # 设置当前应用的名称
17 resource_attributes={
18 "host.name": "<host.name>" # 设置当前主机名称
19 })
20
21
22class GraphState(TypedDict):
23 keys: Dict[str, any]
24
25
26def query(state):
27 print("---START----")
28 state_dict = state["keys"]
29 question = state_dict["question"]
30
31 llm = OpenAI(
32 api_key=api_key,
33 base_url=base_url
34 )
35
36 response = llm.chat.completions.create(
37 model=ai_model,
38 messages=[
39 {
40 "role": "user",
41 "content": question,
42 },
43 ],
44 )
45
46 return {"keys": {"content": response, "question": question}}
47
48def end(state):
49 print("---END----")
50 return {
51 "keys": {
52 "content": state["keys"]["content"],
53 "question": state["keys"]["question"],
54 }
55 }
56
57if __name__ == '__main__':
58 workflow = StateGraph(GraphState)
59 workflow.add_node("query", query)
60 workflow.add_node("end", end)
61 workflow.add_edge("query", "end")
62 workflow.set_entry_point("query")
63 app = workflow.compile()
64 app.invoke(input={"keys": {"question": "what is the weather today?"}}, debug=True)```
示例三:自定义埋点增强
如果需要跟踪 LLM 相关框架与类库之外的业务场景,可以参照下述内容,使用 OpenTelemetry API 添加自定义埋点。本文仅展示最基本的自定义埋点方式,OpenTelemetry 社区提供了更多灵活的自定义埋点方式,具体使用方法可参考 OpenTelemetry 社区提供的[Python 自定义埋点文档]。(https://opentelemetry.io/docs/languages/python/instrumentation/)
1import os
2from traceloop.sdk import Traceloop
3from openai import OpenAI
4from opentelemetry import trace # 导入链路相关 SDK
5
6
7ai_model = 'ernie-4.0-turbo-128k'
8api_key = "bce-v3/ALTAK-mTNsaNCr4********" #替换为千帆的 API-Key
9base_url = "https://qianfan.baidubce.com/v2" #千帆的endpoint
10
11os.environ['TRACELOOP_BASE_URL'] = "<endpoint>" # 替换接入获取的endpoint
12os.environ['TRACELOOP_HEADERS'] = "Authentication=<authentication>" # 替换为接入点获取的Authentication
13Traceloop.init(app_name='<server.name>', # 设置当前应用的名称
14 resource_attributes={
15 "host.name": "<host.name>" # 设置当前主机名称
16 })
17
18tracer = trace.get_tracer(__name__) # init tracer
19
20
21def chat():
22 llm = OpenAI(
23 api_key=api_key,
24 base_url=base_url
25 )
26
27 response = llm.chat.completions.create(
28 model=ai_model,
29 messages=[
30 {
31 "role": "user",
32 "content": "hello"
33 },
34 ],
35 )
36
37if __name__ == '__main__':
38 with tracer.start_as_current_span("entry func") as span: # create a span
39 span.set_attribute("user.id", "<userId>") # set span attributes: userId
40 span.set_attribute("session.id", "<sessionId>") # set span attributes: sessionId
41 chat()