主题
LangSmith 支持基于 OpenTelemetry 的追踪,允许您从任何兼容 OpenTelemetry 的应用程序发送追踪数据。本指南涵盖了 LangChain 应用程序的自动插桩以及其他框架的手动插桩。
了解如何使用 OpenTelemetry 与 LangSmith 追踪您的 LLM 应用程序。
对于自托管安装或欧盟地区的组织,请在下面的请求中适当更新 LangSmith URL。对于欧盟地区,请使用 eu.api.smith.langchain.com。
追踪 LangChain 应用程序
如果您使用 LangChain 或 LangGraph,请使用内置集成来追踪您的应用程序:
- 安装支持 OpenTelemetry 的 LangSmith 包:
bash
pip install "langsmith[otel]"
pip install langchain需要 Python SDK 版本 langsmith>=0.3.18。我们推荐使用 langsmith>=0.4.25 以受益于重要的 OpenTelemetry 修复。
- 在您的 LangChain/LangGraph 应用中,通过设置
LANGSMITH_OTEL_ENABLED环境变量来启用 OpenTelemetry 集成:
bash
LANGSMITH_OTEL_ENABLED=true
LANGSMITH_TRACING=true
LANGSMITH_ENDPOINT=https://api.smith.langchain.com
LANGSMITH_API_KEY=<your_langsmith_api_key>
# 对于链接到多个工作空间的 LangSmith API 密钥,设置 LANGSMITH_WORKSPACE_ID 环境变量以指定要使用的工作空间。- 创建一个带有追踪的 LangChain 应用程序。例如:
python
import os
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# Create a chain
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
model = ChatOpenAI()
chain = prompt | model
# Run the chain
result = chain.invoke({"topic": "programming"})
print(result.content)- 应用程序运行后,在您的 LangSmith 仪表板中查看追踪数据(示例)。
追踪非 LangChain 应用程序
对于非 LangChain 应用程序或自定义插桩,您可以使用标准的 OpenTelemetry 客户端在 LangSmith 中追踪您的应用程序。(我们推荐使用 langsmith ≥ 0.4.25。)
- 安装 OpenTelemetry SDK、OpenTelemetry 导出器包以及 OpenAI 包:
bash
pip install openai
pip install opentelemetry-sdk
pip install opentelemetry-exporter-otlp- 为端点设置环境变量,替换为您的具体值:
bash
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.smith.langchain.com/otel
OTEL_EXPORTER_OTLP_HEADERS="x-api-key=<your langsmith api key>"根据您的 otel 导出器配置方式,如果仅发送追踪数据,您可能需要在端点后追加 /v1/traces。
如果您是自托管 LangSmith,请将基础端点替换为您的 LangSmith API 端点并追加 /api/v1。例如:OTEL_EXPORTER_OTLP_ENDPOINT=https://ai-company.com/api/v1/otel
可选:指定一个非 "default" 的自定义项目名称:
bash
OTEL_EXPORTER_OTLP_ENDPOINT=https://api.smith.langchain.com/otel
OTEL_EXPORTER_OTLP_HEADERS="x-api-key=<your langsmith api key>,Langsmith-Project=<project name>"- 记录一个追踪。
此代码设置了一个 OTEL 追踪器和导出器,用于将追踪数据发送到 LangSmith。然后它调用 OpenAI 并发送所需的 OpenTelemetry 属性。
python
from openai import OpenAI
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import (
BatchSpanProcessor,
)
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
otlp_exporter = OTLPSpanExporter(
timeout=10,
)
trace.set_tracer_provider(TracerProvider())
trace.get_tracer_provider().add_span_processor(
BatchSpanProcessor(otlp_exporter)
)
tracer = trace.get_tracer(__name__)
def call_openai():
model = "gpt-4o-mini"
with tracer.start_as_current_span("call_open_ai") as span:
span.set_attribute("langsmith.span.kind", "LLM")
span.set_attribute("langsmith.metadata.user_id", "user_123")
span.set_attribute("gen_ai.system", "OpenAI")
span.set_attribute("gen_ai.request.model", model)
span.set_attribute("llm.request.type", "chat")
messages = [
{"role": "system", "content": "You are a helpful assistant."},
{
"role": "user",
"content": "Write a haiku about recursion in programming."
}
]
for i, message in enumerate(messages):
span.set_attribute(f"gen_ai.prompt.{i}.content", str(message["content"]))
span.set_attribute(f"gen_ai.prompt.{i}.role", str(message["role"]))
completion = client.chat.completions.create(
model=model,
messages=messages
)
span.set_attribute("gen_ai.response.model", completion.model)
span.set_attribute("gen_ai.completion.0.content", str(completion.choices[0].message.content))
span.set_attribute("gen_ai.completion.0.role", "assistant")
span.set_attribute("gen_ai.usage.prompt_tokens", completion.usage.prompt_tokens)
span.set_attribute("gen_ai.usage.completion_tokens", completion.usage.completion_tokens)
span.set_attribute("gen_ai.usage.total_tokens", completion.usage.total_tokens)
return completion.choices[0].message
if __name__ == "__main__":
call_openai()- 在您的 LangSmith 仪表板中查看追踪数据(示例)。
将追踪数据发送到其他提供商
虽然 LangSmith 是 OpenTelemetry 追踪的默认目的地,但您也可以配置 OpenTelemetry 将追踪数据发送到其他可观测性平台。
在 LangSmith Python SDK ≥ 0.4.1 中可用。我们推荐使用 ≥ 0.4.25 以获取改进 OTEL 导出和混合扇出稳定性的修复。
使用环境变量进行全局配置
默认情况下,LangSmith OpenTelemetry 导出器会将数据发送到 LangSmith API OTEL 端点,但这可以通过设置标准的 OTEL 环境变量来自定义:
bash
OTEL_EXPORTER_OTLP_ENDPOINT: 覆盖端点 URL
OTEL_EXPORTER_OTLP_HEADERS: 添加自定义头部(LangSmith API 密钥和项目会自动添加)
OTEL_SERVICE_NAME: 设置自定义服务名称(默认为 "langsmith")LangSmith 默认使用 HTTP 追踪导出器。如果您想使用自己的追踪提供商,您可以:
- 如上所示设置 OTEL 环境变量,或者
- 在初始化 LangChain 组件之前设置一个全局追踪提供程序,LangSmith 将检测并使用它,而不是创建自己的。
配置替代的 OTLP 端点
要将追踪数据发送到其他提供商,请使用您提供商的端点配置 OTLP 导出器:
python
import os
from opentelemetry import trace
from opentelemetry.sdk.trace import TracerProvider
from opentelemetry.sdk.trace.export import BatchSpanProcessor
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
# Set environment variables for LangChain
os.environ["LANGSMITH_OTEL_ENABLED"] = "true"
os.environ["LANGSMITH_TRACING"] = "true"
# Configure the OTLP exporter for your custom endpoint
provider = TracerProvider()
otlp_exporter = OTLPSpanExporter(
# Change to your provider's endpoint
endpoint="https://otel.your-provider.com/v1/traces",
# Add any required headers for authentication
headers={"api-key": "your-api-key"}
)
processor = BatchSpanProcessor(otlp_exporter)
provider.add_span_processor(processor)
trace.set_tracer_provider(provider)
# Create and run a LangChain application
prompt = ChatPromptTemplate.from_template("Tell me a joke about {topic}")
model = ChatOpenAI()
chain = prompt | model
result = chain.invoke({"topic": "programming"})
print(result.content)混合追踪在版本 ≥ 0.4.1 中可用。要仅将追踪数据发送到您的 OTEL 端点,请设置:
LANGSMITH_OTEL_ONLY="true" (推荐:使用 langsmith ≥ 0.4.25。)
支持的 OpenTelemetry 属性和事件映射
通过 OpenTelemetry 向 LangSmith 发送追踪数据时,以下属性会映射到 LangSmith 字段:
核心 LangSmith 属性
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
langsmith.trace.name | 运行名称 | 覆盖运行的跨度名称 |
langsmith.span.kind | 运行类型 | 值:llm, chain, tool, retriever, embedding, prompt, parser |
langsmith.trace.session_id | 会话 ID | 相关追踪的会话标识符 |
langsmith.trace.session_name | 会话名称 | 会话的名称 |
langsmith.span.tags | 标签 | 附加到跨度的自定义标签(逗号分隔) |
langsmith.metadata.{key} | metadata.{key} | 带有 langsmith 前缀的自定义元数据 |
GenAI 标准属性
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
gen_ai.system | metadata.ls_provider | GenAI 系统(例如,"openai", "anthropic") |
gen_ai.operation.name | 运行类型 | 将 "chat"/"completion" 映射到 "llm","embedding" 映射到 "embedding" |
gen_ai.prompt | inputs | 发送到模型的输入提示 |
gen_ai.completion | outputs | 模型生成的输出 |
gen_ai.prompt.{n}.role | inputs.messages[n].role | 第 n 个输入消息的角色 |
gen_ai.prompt.{n}.content | inputs.messages[n].content | 第 n 个输入消息的内容 |
gen_ai.prompt.{n}.message.role | inputs.messages[n].role | 角色的替代格式 |
gen_ai.prompt.{n}.message.content | inputs.messages[n].content | 内容的替代格式 |
gen_ai.completion.{n}.role | outputs.messages[n].role | 第 n 个输出消息的角色 |
gen_ai.completion.{n}.content | outputs.messages[n].content | 第 n 个输出消息的内容 |
gen_ai.completion.{n}.message.role | outputs.messages[n].role | 角色的替代格式 |
gen_ai.completion.{n}.message.content | outputs.messages[n].content | 内容的替代格式 |
gen_ai.input.messages | inputs.messages | 输入消息数组 |
gen_ai.output.messages | outputs.messages | 输出消息数组 |
gen_ai.tool.name | invocation_params.tool_name | 工具名称,同时将运行类型设置为 "tool" |
GenAI 请求参数
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
gen_ai.request.model | invocation_params.model | 请求使用的模型名称 |
gen_ai.response.model | invocation_params.model | 响应中返回的模型名称 |
gen_ai.request.temperature | invocation_params.temperature | 温度设置 |
gen_ai.request.top_p | invocation_params.top_p | Top-p 采样设置 |
gen_ai.request.max_tokens | invocation_params.max_tokens | 最大令牌数设置 |
gen_ai.request.frequency_penalty | invocation_params.frequency_penalty | 频率惩罚设置 |
gen_ai.request.presence_penalty | invocation_params.presence_penalty | 存在惩罚设置 |
gen_ai.request.seed | invocation_params.seed | 生成使用的随机种子 |
gen_ai.request.stop_sequences | invocation_params.stop | 停止生成的序列 |
gen_ai.request.top_k | invocation_params.top_k | Top-k 采样参数 |
gen_ai.request.encoding_formats | invocation_params.encoding_formats | 输出编码格式 |
GenAI 使用指标
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
gen_ai.usage.input_tokens | usage_metadata.input_tokens | 使用的输入令牌数 |
gen_ai.usage.output_tokens | usage_metadata.output_tokens | 使用的输出令牌数 |
gen_ai.usage.total_tokens | usage_metadata.total_tokens | 使用的总令牌数 |
gen_ai.usage.prompt_tokens | usage_metadata.input_tokens | 使用的输入令牌数(已弃用) |
gen_ai.usage.completion_tokens | usage_metadata.output_tokens | 使用的输出令牌数(已弃用) |
gen_ai.usage.details.reasoning_tokens | usage_metadata.reasoning_tokens | 使用的推理令牌数 |
TraceLoop 属性
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
traceloop.entity.input | inputs | 来自 TraceLoop 的完整输入值 |
traceloop.entity.output | outputs | 来自 TraceLoop 的完整输出值 |
traceloop.entity.name | 运行名称 | 来自 TraceLoop 的实体名称 |
traceloop.span.kind | 运行类型 | 映射到 LangSmith 运行类型 |
traceloop.llm.request.type | 运行类型 | "embedding" 映射到 "embedding",其他映射到 "llm" |
traceloop.association.properties.{key} | metadata.{key} | 带有 traceloop 前缀的自定义元数据 |
OpenInference 属性
| OpenTelemetry 属性 | LangSmith 字段 | 备注 |
|---|---|---|
input.value | inputs | 完整输入值,可以是字符串或 JSON |
output.value | outputs | 完整输出值,可以是字符串或 JSON |
openinference.span.kind | 运行类型 | 将各种类型映射到 LangSmith 运行类型 |
llm.system | metadata.ls_provider | LLM 系统提供商 |
llm.model_name | metadata.ls_model_name | 来自 OpenInference 的模型名称 |
tool.name | 运行名称 | 当跨度类型为 "TOOL" 时的工具名称 |
metadata | metadata.* | 要合并的元数据的 JSON 字符串 |
LLM 属性
| OpenTelemetry 属性 | LangSmith 字段 | 注释 |
|---|---|---|
llm.input_messages | inputs.messages | 输入消息 |
llm.output_messages | outputs.messages | 输出消息 |
llm.token_count.prompt | usage_metadata.input_tokens | 提示令牌计数 |
llm.token_count.completion | usage_metadata.output_tokens | 完成令牌计数 |