LangSmith 支持基于 OpenTelemetry 的追踪,允许您从任何兼容 OpenTelemetry 的应用程序发送追踪数据。本指南涵盖了 LangChain 应用程序的自动检测以及其他框架的手动检测。
了解如何使用 OpenTelemetry 与 LangSmith 追踪您的 LLM 应用程序。
对于自托管安装或区域 SaaS,请在下面的请求中相应地更新 LangSmith URL:欧盟 (GCP) 使用 eu.api.smith.langchain.com;AWS 托管的美国 SaaS 使用 aws.api.smith.langchain.com。
追踪 LangChain 应用程序
如果您使用 LangChain 或 LangGraph,请使用内置集成来追踪您的应用程序:
安装支持 OpenTelemetry 的 LangSmith 包:
pip install "langsmith[otel]"
pip install langchain
需要 Python SDK 版本 langsmith>=0.3.18。我们推荐 langsmith>=0.4.25 以获得重要的 OpenTelemetry 修复。
在您的 LangChain/LangGraph 应用程序中,通过设置 LANGSMITH_OTEL_ENABLED 环境变量启用 OpenTelemetry 集成:
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 应用程序。例如:
import os
from langchain_openai import ChatOpenAI
from langchain_core . prompts import ChatPromptTemplate
# 创建一个链
prompt = ChatPromptTemplate . from_template ( "Tell me a joke about {topic} " )
model = ChatOpenAI ()
chain = prompt | model
# 运行链
result = chain . invoke ({ "topic" : "programming" })
print ( result . content )
应用程序运行后,在 LangSmith 仪表板中查看追踪数据(示例 )。
追踪非 LangChain 应用程序
对于非 LangChain 应用程序或自定义检测,您可以使用标准的 OpenTelemetry 客户端在 LangSmith 中追踪您的应用程序。(我们推荐 langsmith ≥ 0.4.25 。)
安装 OpenTelemetry SDK、OpenTelemetry 导出器包以及 OpenAI 包:
pip install openai
pip install opentelemetry-sdk
pip install opentelemetry-exporter-otlp
设置端点的环境变量,替换为您特定的值:
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” 的自定义项目名称:
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 属性。
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-5.4-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 环境变量来自定义:
OTEL_EXPORTER_OTLP_ENDPOINT: 覆盖端点 URL
OTEL_EXPORTER_OTLP_HEADERS: 添加自定义头(LangSmith API 密钥和项目会自动添加)
OTEL_SERVICE_NAME: 设置自定义服务名称(默认为 "langsmith")
LangSmith 默认使用 HTTP 追踪导出器。如果您想使用自己的追踪提供程序,可以:
如上所示设置 OTEL 环境变量,或者
在初始化 LangChain 组件之前设置全局追踪提供程序,LangSmith 将检测并使用它,而不是创建自己的。
配置备用 OTLP 端点
要将追踪发送到不同的提供程序,请使用提供程序的端点配置 OTLP 导出器:
import os
from langchain_core . prompts import ChatPromptTemplate
from langchain_openai import ChatOpenAI
from opentelemetry import trace
from opentelemetry . exporter . otlp . proto . http . trace_exporter import OTLPSpanExporter
from opentelemetry . sdk . trace import TracerProvider
from opentelemetry . sdk . trace . export import BatchSpanProcessor
# 为 LangChain 设置环境变量
os . environ [ " LANGSMITH_OTEL_ENABLED " ] = "true"
os . environ [ " LANGSMITH_TRACING " ] = "true"
# 为您的自定义端点配置 OTLP 导出器
provider = TracerProvider ()
otlp_exporter = OTLPSpanExporter (
# 更改为您的提供程序端点
endpoint = "https://otel.your-provider.com/v1/traces" ,
# 添加任何所需的认证头
headers = { "api-key" : "your-api-key" },
)
processor = BatchSpanProcessor ( otlp_exporter )
provider . add_span_processor ( processor )
trace . set_tracer_provider ( provider )
# 创建并运行 LangChain 应用程序
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运行名称 覆盖运行的 span 名称 langsmith.span.kind运行类型 值:llm、chain、tool、retriever、embedding、prompt、parser langsmith.trace.session_id会话 ID 相关追踪的会话标识符 langsmith.trace.session_name会话名称 会话的名称 langsmith.span.tags标签 附加到 span 的自定义标签(逗号分隔) langsmith.metadata.{key}metadata.{key}带有 langsmith 前缀的自定义元数据
GenAI 标准属性
OpenTelemetry 属性 LangSmith 字段 备注 gen_ai.systemmetadata.ls_providerGenAI 系统(例如 “openai”、“anthropic”) gen_ai.operation.name运行类型 将 “chat”/“completion” 映射为 “llm”,“embedding” 映射为 “embedding” gen_ai.promptinputs发送给模型的输入提示 gen_ai.completionoutputs模型生成的输出 gen_ai.prompt.{n}.roleinputs.messages[n].role第 n 个输入消息的角色 gen_ai.prompt.{n}.contentinputs.messages[n].content第 n 个输入消息的内容 gen_ai.prompt.{n}.message.roleinputs.messages[n].role角色的替代格式 gen_ai.prompt.{n}.message.contentinputs.messages[n].content内容的替代格式 gen_ai.completion.{n}.roleoutputs.messages[n].role第 n 个输出消息的角色 gen_ai.completion.{n}.contentoutputs.messages[n].content第 n 个输出消息的内容 gen_ai.completion.{n}.message.roleoutputs.messages[n].role角色的替代格式 gen_ai.completion.{n}.message.contentoutputs.messages[n].content内容的替代格式 gen_ai.input.messagesinputs.messages输入消息数组 gen_ai.output.messagesoutputs.messages输出消息数组 gen_ai.tool.nameinvocation_params.tool_name工具名称,同时将运行类型设置为 “tool”
GenAI 请求参数
OpenTelemetry 属性 LangSmith 字段 备注 gen_ai.request.modelinvocation_params.model用于请求的模型名称 gen_ai.response.modelinvocation_params.model响应中返回的模型名称 gen_ai.request.temperatureinvocation_params.temperature温度设置 gen_ai.request.top_pinvocation_params.top_pTop-p 采样设置 gen_ai.request.max_tokensinvocation_params.max_tokens最大 token 数设置 gen_ai.request.frequency_penaltyinvocation_params.frequency_penalty频率惩罚设置 gen_ai.request.presence_penaltyinvocation_params.presence_penalty存在惩罚设置 gen_ai.request.seedinvocation_params.seed用于生成的随机种子 gen_ai.request.stop_sequencesinvocation_params.stop停止生成的序列 gen_ai.request.top_kinvocation_params.top_kTop-k 采样参数 gen_ai.request.encoding_formatsinvocation_params.encoding_formats输出编码格式
GenAI 使用指标
OpenTelemetry 属性 LangSmith 字段 备注 gen_ai.usage.input_tokensusage_metadata.input_tokens使用的输入 token 数 gen_ai.usage.output_tokensusage_metadata.output_tokens使用的输出 token 数 gen_ai.usage.total_tokensusage_metadata.total_tokens使用的总 token 数 gen_ai.usage.prompt_tokensusage_metadata.input_tokens使用的输入 token 数(已弃用) gen_ai.usage.completion_tokensusage_metadata.output_tokens使用的输出 token 数(已弃用) gen_ai.usage.details.reasoning_tokensusage_metadata.reasoning_tokens使用的推理 token 数
TraceLoop 属性
OpenTelemetry 属性 LangSmith 字段 备注 traceloop.entity.inputinputs来自 TraceLoop 的完整输入值 traceloop.entity.outputoutputs来自 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.valueinputs完整输入值,可以是字符串或 JSON output.valueoutputs完整输出值,可以是字符串或 JSON openinference.span.kind运行类型 将各种类型映射到 LangSmith 运行类型 llm.systemmetadata.ls_providerLLM 系统提供程序 llm.model_namemetadata.ls_model_name来自 OpenInference 的模型名称 tool.name运行名称 当 span 类型为 “TOOL” 时的工具名称 metadatametadata.*要合并的元数据的 JSON 字符串
LLM 属性
OpenTelemetry 属性 LangSmith 字段 备注 llm.input_messagesinputs.messages输入消息 llm.output_messagesoutputs.messages输出消息 llm.token_count.promptusage_metadata.input_tokens提示 token 计数 llm.token_count.completionusage_metadata.output_tokens完成 token 计数 llm.token_count.totalusage_metadata.total_tokens总 token 计数 llm.usage.total_tokensusage_metadata.total_tokens替代的总 token 计数 llm.invocation_parametersinvocation_params.*调用参数的 JSON 字符串 llm.presence_penaltyinvocation_params.presence_penalty存在惩罚 llm.frequency_penaltyinvocation_params.frequency_penalty频率惩罚 llm.request.functionsinvocation_params.functions函数定义
提示模板属性
OpenTelemetry 属性 LangSmith 字段 备注 llm.prompt_template.variables运行类型 将运行类型设置为 “prompt”,与 input.value 一起使用
检索器属性
OpenTelemetry 属性 LangSmith 字段 备注 retrieval.documents.{n}.document.contentoutputs.documents[n].page_content第 n 个检索文档的内容 retrieval.documents.{n}.document.metadataoutputs.documents[n].metadata第 n 个检索文档的元数据(JSON)
工具属性
OpenTelemetry 属性 LangSmith 字段 备注 toolsinvocation_params.tools工具定义数组 tool_argumentsinvocation_params.tool_arguments工具参数,作为 JSON 或键值对
Logfire 属性
OpenTelemetry 属性 LangSmith 字段 备注 promptinputsLogfire 提示输入 all_messages_eventsoutputsLogfire 消息事件输出 eventsinputs/outputsLogfire 事件数组,分割输入/选择事件
OpenTelemetry 事件映射
事件名称 LangSmith 字段 备注 gen_ai.content.promptinputs从事件属性中提取提示内容 gen_ai.content.completionoutputs从事件属性中提取完成内容 gen_ai.system.messageinputs.messages[]对话中的系统消息 gen_ai.user.messageinputs.messages[]对话中的用户消息 gen_ai.assistant.messageoutputs.messages[]对话中的助手消息 gen_ai.tool.messageoutputs.messages[]工具响应消息 gen_ai.choiceoutputs带有完成原因的模型选择/响应 exceptionstatus, error将状态设置为 “error” 并提取异常消息/堆栈跟踪
事件属性提取
对于消息事件,提取以下属性:
content → 消息内容
role → 消息角色
id → tool_call_id(用于工具消息)
gen_ai.event.content → 完整消息 JSON
对于选择事件:
finish_reason → 选择完成原因
message.content → 选择消息内容
message.role → 选择消息角色
tool_calls.{n}.id → 工具调用 ID
tool_calls.{n}.function.name → 工具函数名称
tool_calls.{n}.function.arguments → 工具函数参数
tool_calls.{n}.type → 工具调用类型
对于异常事件:
exception.message → 错误消息
exception.stacktrace → 错误堆栈跟踪(附加到消息)
实现示例
使用 LangSmith SDK 进行追踪
使用 LangSmith SDK 的 OpenTelemetry 辅助工具配置导出。以下示例追踪一个 Google ADK 代理 :
import asyncio
from langsmith . integrations . otel import configure
from google . adk import Runner
from google . adk . agents import LlmAgent
from google . adk . sessions import InMemorySessionService
from google . genai import types
# 配置 LangSmith OpenTelemetry 导出(无需 OTEL 环境变量或头)
configure ( project_name = "adk-otel-demo" )
async def main ():
agent = LlmAgent (
name = "travel_assistant" ,
model = "gemini-2.5-flash-lite" ,
instruction = "You are a helpful travel assistant." ,
)
session_service = InMemorySessionService ()
runner = Runner ( app_name = "travel_app" , agent = agent , session_service = session_service )
user_id = "user_123"
session_id = "session_abc"
await session_service . create_session ( app_name = "travel_app" , user_id = user_id , session_id = session_id )
new_message = types . Content ( parts = [ types . Part ( text = "Hi! Recommend a weekend trip to Paris." )], role = "user" )
for event in runner . run ( user_id = user_id , session_id = session_id , new_message = new_message ):
print ( event )
if __name__ == "__main__" :
asyncio . run ( main ())
您无需设置 OTEL 环境变量或导出器。configure() 会自动为 LangSmith 配置它们;检测器(如 GoogleADKInstrumentor)创建 span。
这是在 LangSmith 中生成的追踪数据的示例 。
向追踪添加附件
LangSmith 支持向追踪附加文件 。这在构建具有多模态输入或输出的代理时非常有用。使用 OpenTelemetry 追踪时也支持附件。
下面的示例追踪一个 Google ADK 代理 并向追踪添加附件。它结合使用了 LangSmith 的 OtelSpanProcessor 和一个自定义的 AttachmentSpanProcessor,后者使用 on_end() 向父 span 添加图像附件。
import asyncio
import base64
import json
from pathlib import Path
from dotenv import load_dotenv
from google . adk import Runner
from google . adk . agents import LlmAgent
from google . adk . sessions import InMemorySessionService
from google . genai import types
from opentelemetry import trace
from opentelemetry . sdk . trace import TracerProvider , SpanProcessor
from langsmith . integrations . otel import OtelSpanProcessor
class AttachmentSpanProcessor ( SpanProcessor ):
"""自定义 SpanProcessor,用于向调用 span 添加附件。"""
def __init__ ( self ):
self . attachment_data = None
def set_attachment ( self , attachment_data ):
self . attachment_data = attachment_data
def on_end ( self , span ):
if span . name == "invocation" and self . attachment_data :
attachments_json = json . dumps ([ self . attachment_data ])
span . _attributes [ " langsmith.attachments " ] = attachments_json
load_dotenv ()
# 手动设置 TracerProvider
provider = TracerProvider ()
trace . set_tracer_provider ( provider )
# 首先添加附件处理器(在 LangSmith 处理器之前运行)
attachment_processor = AttachmentSpanProcessor ()
provider . add_span_processor ( attachment_processor )
# 其次添加 LangSmith 处理器(接收已修改的 span)
langsmith_processor = OtelSpanProcessor ( project = "travel-assistant" )
provider . add_span_processor ( langsmith_processor )
def get_flight_info ( destination : str , departure_date : str ) -> dict :
"""获取目的地的航班信息。"""
return {
"destination" : destination ,
"departure_date" : departure_date ,
"price" : "$450" ,
"duration" : "5h 30m" ,
"airline" : "Example Airways"
}
def get_hotel_recommendations ( city : str , check_in : str ) -> dict :
"""获取城市的酒店推荐。"""
return {
"city" : city ,
"check_in" : check_in ,
"hotels" : [
{ "name" : "Grand Plaza Hotel" , "rating" : 4.5 , "price" : "$120/night" },
{ "name" : "City Center Inn" , "rating" : 4.2 , "price" : "$95/night" }
]
}
async def main ():
# 准备附件
receipt_path = Path ( "receipt-template-example.png" )
with open ( receipt_path , "rb" ) as img_file :
image_bytes = img_file . read ()
image_base64 = base64 . b64encode ( image_bytes ). decode ( "ascii" )
attachment_data = {
"name" : "receipt-template-example" ,
"content" : image_base64 ,
"mime_type" : "image/jpeg" ,
}
attachment_processor . set_attachment ( attachment_data )
# 创建 ADK 代理
agent = LlmAgent (
name = "travel_assistant" ,
tools = [ get_flight_info , get_hotel_recommendations ],
model = "gemini-2.0-flash-exp" ,
instruction = "You are a helpful travel assistant that can help with flights and hotels." ,
)
# 设置会话和运行器
session_service = InMemorySessionService ()
runner = Runner (
app_name = "travel_app" ,
agent = agent ,
session_service = session_service
)
await session_service . create_session (
app_name = "travel_app" ,
user_id = "traveler_456" ,
session_id = "session_789"
)
# 向代理发送消息
new_message = types . Content (
parts = [ types . Part ( text = "I need to book a flight to Paris for March 15th and find a good hotel." )],
role = "user" ,
)
# 运行代理并处理事件
events = runner . run (
user_id = "traveler_456" ,
session_id = "session_789" ,
new_message = new_message ,
)
for event in events :
print ( event )
if __name__ == "__main__" :
asyncio . run ( main ())
这是在 LangSmith 中生成的追踪数据的示例 。
高级配置
使用 OpenTelemetry collector 进行扇出
当您需要 OTEL 扇出时,请使用 LANGSMITH_OTEL_ENABLED=true。配置您的应用程序发出一次 OTEL span,然后使用 OpenTelemetry Collector 将它们路由到 LangSmith 和任何其他可观测性后端。
当您正在追踪应用程序并希望进行多目标路由时,请使用此方法。如果您正在操作 LangSmith 平台基础设施遥测(来自 Kubernetes 上自托管 LangSmith 服务的日志、指标、追踪),请改用为 LangSmith 遥测配置您的 collector 指南。
对于更高级的场景,您可以使用 OpenTelemetry Collector 将您的遥测数据扇出到多个目标。这比在应用程序代码中配置多个导出器更具可扩展性。
为您的环境安装 OpenTelemetry Collector 。
创建一个配置文件(例如 otel-collector-config.yaml),导出到多个目标:
receivers :
otlp :
protocols :
grpc :
endpoint : 0.0.0.0:4317
http :
endpoint : 0.0.0.0:4318
processors :
batch :
exporters :
otlphttp/langsmith :
endpoint : https://api.smith.langchain.com/otel/v1/traces
headers :
x-api-key : ${env:LANGSMITH_API_KEY}
Langsmith-Project : my_project
otlphttp/other_provider :
endpoint : https://otel.your-provider.com/v1/traces
headers :
api-key : ${env:OTHER_PROVIDER_API_KEY}
service :
pipelines :
traces :
receivers : [ otlp ]
processors : [ batch ]
exporters : [ otlphttp/langsmith , otlphttp/other_provider ]
配置您的应用程序发送到 collector:
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
# 指向您的本地 OpenTelemetry Collector
otlp_exporter = OTLPSpanExporter (
endpoint = "http://localhost:4318/v1/traces"
)
provider = TracerProvider ()
processor = BatchSpanProcessor ( otlp_exporter )
provider . add_span_processor ( processor )
trace . set_tracer_provider ( provider )
# 为 LangChain 设置环境变量
os . environ [ " LANGSMITH_OTEL_ENABLED " ] = "true"
os . environ [ " LANGSMITH_TRACING " ] = "true"
# 创建并运行 LangChain 应用程序
prompt = ChatPromptTemplate . from_template ( "Tell me a joke about {topic} " )
model = ChatOpenAI ()
chain = prompt | model
result = chain . invoke ({ "topic" : "programming" })
print ( result . content )
此方法具有以下几个优点:
所有遥测目标的集中配置
减少应用程序代码中的开销
更好的可扩展性和弹性
无需更改应用程序代码即可添加或删除目标
使用 LangChain 和 OpenTelemetry 进行分布式追踪
当您的 LLM 应用程序跨越多个服务或进程时,分布式追踪至关重要。OpenTelemetry 的上下文传播功能确保追踪在服务边界之间保持连接。
分布式追踪中的上下文传播
在分布式系统中,上下文传播在服务之间传递追踪元数据,以便将相关的 span 链接到同一追踪:
Trace ID :整个追踪的唯一标识符
Span ID :当前 span 的唯一标识符
采样决策 :指示是否应采样此追踪
使用 LangChain 设置分布式追踪
要启用跨多个服务的分布式追踪:
import os
from opentelemetry import trace
from opentelemetry . propagate import inject , extract
from opentelemetry . sdk . trace import TracerProvider
from opentelemetry . sdk . trace . export import BatchSpanProcessor
from opentelemetry . exporter . otlp . proto . http . trace_exporter import OTLPSpanExporter
import requests
from langchain_openai import ChatOpenAI
from langchain_core . prompts import ChatPromptTemplate
# 设置 OpenTelemetry 追踪提供程序
provider = TracerProvider ()
otlp_exporter = OTLPSpanExporter (
endpoint = "https://api.smith.langchain.com/otel/v1/traces" ,
headers = { "x-api-key" : os . getenv ( "LANGSMITH_API_KEY" ), "Langsmith-Project" : "my_project" }
)
processor = BatchSpanProcessor ( otlp_exporter )
provider . add_span_processor ( processor )
trace . set_tracer_provider ( provider )
tracer = trace . get_tracer ( __name__ )
# 服务 A:创建一个 span 并将上下文传播到服务 B
def service_a ():
with tracer . start_as_current_span ( "service_a_operation" ) as span :
# 创建一个链
prompt = ChatPromptTemplate . from_template ( "Summarize: {text} " )
model = ChatOpenAI ()
chain = prompt | model
# 运行链
result = chain . invoke ({ "text" : "OpenTelemetry is an observability framework" })
# 将上下文传播到服务 B
headers = {}
inject ( headers ) # 将追踪上下文注入到头中
# 使用追踪上下文调用服务 B
response = requests . post (
"http://service-b.example.com/process" ,
headers = headers ,
json = { "summary" : result . content }
)
return response . json ()
# 服务 B:提取上下文并继续追踪
from flask import Flask , request , jsonify
app = Flask ( __name__ )
@app . route ( "/process" , methods = [ "POST" ])
def service_b_endpoint ():
# 从请求头中提取追踪上下文
context = extract ( request . headers )
with tracer . start_as_current_span ( "service_b_operation" , context = context ) as span :
data = request . json
summary = data . get ( "summary" , "" )
# 使用另一个 LLM 链处理摘要
prompt = ChatPromptTemplate . from_template ( "Analyze the sentiment of: {text} " )
model = ChatOpenAI ()
chain = prompt | model
result = chain . invoke ({ "text" : summary })
return jsonify ({ "analysis" : result . content })
if __name__ == "__main__" :
app . run ( port = 5000 )
将这些文档连接 到 Claude、VSCode 等,通过 MCP 获取实时答案。