> ## Documentation Index
> Fetch the complete documentation index at: https://cndoc-langchain.site/llms.txt
> Use this file to discover all available pages before exploring further.

# 使用 OpenTelemetry 网关架构脱敏敏感数据

> 使用 OpenTelemetry 收集器在追踪数据进入 LangSmith 之前脱敏敏感数据。

[LangChain](/langsmith/trace-with-langchain) 和 [LangGraph](/langsmith/trace-with-langgraph) 应用支持[基于 OpenTelemetry 的追踪](/langsmith/trace-with-opentelemetry)。您可以不直接将追踪数据发送到 LangSmith，而是通过您控制的 OpenTelemetry 收集器进行路由，应用脱敏规则以剥离敏感字段，然后将净化后的追踪数据转发到 LangSmith。

追踪数据通过 OTLP/HTTP 从您的应用流向收集器。收集器运行一个转换处理器，在将净化后的 span 转发到 LangSmith API 之前，脱敏敏感的 span 属性，例如提示输入和模型补全。

```mermaid theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
flowchart TD
    A["应用<br/>(LangChain / LangGraph)"]

    subgraph collector[":4318"]
        B["接收器<br/>OTLP/HTTP"]
        C["转换处理器<br/>PII 脱敏<br/>(邮箱、电话、SSN、信用卡)"]
        D["OTLP/HTTP 导出器"]
        B --> C --> D
    end

    E["LangSmith API<br/>api.smith.langchain.com"]

    A -->|"OTLP/HTTP"| B
    D -->|"OTLP/HTTP"| E
```

## 前提条件

以下两种方法都需要以下环境变量。将 `OTEL_EXPORTER_OTLP_ENDPOINT` 设置为您的收集器地址：

```bash theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
LANGSMITH_OTEL_ENABLED="true"
LANGSMITH_TRACING="true"
LANGSMITH_OTEL_ONLY="true"
LANGSMITH_PROJECT="my-project"
OTEL_EXPORTER_OTLP_ENDPOINT="http://<my-otel-collector-endpoint>:4318"
```

有关 `LANGSMITH_PROJECT` 的更多信息，请参阅[将追踪记录到特定项目](/langsmith/log-traces-to-project)。

## 配置收集器

两种方法都需要一个作为中介运行在您的应用和 LangSmith 之间的 OpenTelemetry 收集器。以下配置在端口 `4318` 上设置了一个 OTLP 接收器、一个脱敏 `gen_ai.prompt` 和 `gen_ai.completion` span 属性的转换处理器，以及一个将净化后的追踪数据转发到 LangSmith API 的导出器：

```yaml theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
receivers:
  otlp:
    protocols:
      http:
        endpoint: 0.0.0.0:4318


processors:
  transform/redact:
    error_mode: ignore
    trace_statements:
      - context: span
        statements:
          - replace_pattern(attributes["gen_ai.completion"], "[\\s\\S]*", "[REDACTED]")
          - replace_pattern(attributes["gen_ai.prompt"], "[\\s\\S]*", "[REDACTED]")

exporters:
  otlphttp/langsmith:
    traces_endpoint: "https://api.smith.langchain.com/otel/v1/traces"
    headers:
      x-api-key: "${env:LANGSMITH_API_KEY}"
      Langsmith-Project: "${env:LANGSMITH_PROJECT}"


service:
  pipelines:
    traces:
      receivers: [otlp]
      processors: [transform/redact]
      exporters: [otlphttp/langsmith]
```

## 使用 LangChain 或 LangGraph 进行追踪

如果您的应用已经使用 [LangChain](/langsmith/trace-with-langchain) 或 [LangGraph](/langsmith/trace-with-langgraph)，请使用此方法。追踪集成会根据您的环境变量自动处理 span 创建，因此无需额外的检测代码：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
from langchain.agents import create_agent
from langchain.tools import tool
from langchain_openai import ChatOpenAI


@tool
def tell_joke(topic: str) -> str:
   llm = ChatOpenAI()
   response = llm.invoke(f"Tell me a short, funny joke about {topic}.")
   return response.content


agent = create_agent(
   model=ChatOpenAI(),
   tools=[tell_joke],
   system_prompt="When the user asks for jokes, use the tell_joke tool for each topic.",
)


topics = ["programming", "python", "kubernetes", "machine learning"]


result = agent.invoke(
   {"messages": [{"role": "user", "content": f"Tell me jokes about these topics: {', '.join(topics)}"}]}
)


print(result["messages"][-1].content)
```

## 直接使用 OpenTelemetry SDK 进行追踪

如果您需要以编程方式控制追踪提供者和导出器，请使用此方法。例如，设置每个请求的项目名称或在运行时配置自定义头部。您在代码中显式配置提供者，而不是仅依赖环境变量：

```python theme={"theme":{"light":"catppuccin-latte","dark":"catppuccin-mocha"}}
import os

from langchain.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


project_name = os.environ["LANGSMITH_PROJECT"]
otlp_endpoint = os.environ["OTEL_EXPORTER_OTLP_ENDPOINT"]


provider = TracerProvider()
provider.add_span_processor(
   BatchSpanProcessor(
       OTLPSpanExporter(
           endpoint=otlp_endpoint+"/v1/traces",
           headers={"Langsmith-Project": project_name},
       )
   )
)
trace.set_tracer_provider(provider)


chain = ChatPromptTemplate.from_template("Tell me a joke about {topic}") | ChatOpenAI()


for topic in ["programming", "python", "databases", "kubernetes", "machine learning"]:
   print(f"Asking about {topic}...")
   result = chain.invoke({"topic": topic})
   print(f"  {result.content[:100]}\n")


provider.force_flush()
provider.shutdown()
```

<Note>
  如果您希望在不通过收集器路由的情况下脱敏敏感数据，请参阅[防止在追踪中记录敏感数据](/langsmith/mask-inputs-outputs)。
</Note>

***

<div className="source-links">
  <Callout icon="terminal-2">
    [将这些文档](/use-these-docs)通过 MCP 连接到 Claude、VSCode 等，以获取实时答案。
  </Callout>

  <Callout icon="edit">
    [在 GitHub 上编辑此页面](https://github.com/langchain-ai/docs/edit/main/src/langsmith/otel-gateway-trace-redaction.mdx) 或 [提交问题](https://github.com/langchain-ai/docs/issues/new/choose)。
  </Callout>
</div>
