LangSmith 实战精讲:LLM 应用 Trace 追踪、评估、监控及 Prompt 管理完整指南

文章目录

LangSmith 实战精讲:LLM 应用 Trace 追踪、评估、监控及 Prompt 管理完整指南

本文系统剖析 LangSmith 的架构原理与工程实践:RunTree 追踪模型、OTel 集成、数据集与评估体系、Prompt Hub 版本管理、生产监控告警、Playground 交互式调试、SDK 编程式调用。从"为什么需要"到"底层怎么实现",拆解 LLM 应用的可观测性基础设施。


概念区分:LangChain / LangGraph / LangSmith

在进入正文之前,先明确三者的定位,避免混淆:

  • LangChain 是 LLM 应用开发框架,提供 Prompt 管理、链式调用、工具集成等基础能力
  • LangGraph 是 Agent 工作流编排框架,基于状态图实现循环、分支、中断恢复等复杂 Agent 逻辑
  • LangSmith 是配套的可观测性平台,为 LangChain / LangGraph 应用提供追踪、评估、监控、调试能力

三者关系:LangChain 和 LangGraph 负责"构建应用",LangSmith 负责"观测和优化应用"。


一、为什么 LLM 应用需要专属的可观测性平台

1.1 传统 APM 的能力边界

传统 APM(Datadog、SkyWalking、Prometheus + Grafana)擅长回答延迟、错误率、QPS 等问题。但 LLM 应用引入了传统 APM 无法覆盖的新需求:

问题类型传统 APMLLM 特有需求
输出质量HTTP 200 即视为成功200 也可能答非所问,需质量评估
Token 成本无概念每次调用均产生费用,成本差异可达百倍
Prompt 变更影响无感知微小变更即可导致效果显著偏移
链路层级微服务级(A→B→C)思维链级(Thought→Action→Observation)
评估闭环需要"测试集→评估器→评分"完整链路

传统 APM 回答"系统有没有崩溃",LangSmith 回答"AI 回答得好不好、花了多少成本、为什么这样回答"。

1.2 LLM 应用的核心调试挑战

基于上述能力边界,LLM 应用在工程实践中面临四大核心挑战:

  • 输出不确定性:LLM 内部状态是数千亿参数的隐式表示,传统断点调试无法触及;相同输入可能产生不同输出,根因可能来自 Prompt 设计、温度参数或模型能力本身
  • 缺乏标准答案:传统软件通过 assertEqual 做单元测试,但 LLM 输出是自然语言,不存在严格的"相等"概念,需要专门的评估框架
  • Token 成本膨胀:Agent 的 ReAct 循环中每轮工具调用的输入输出都进入上下文,10 轮循环后上下文可能膨胀数倍
  • 推理链路不可见:Agent 执行涉及多轮推理和工具调用,若结果有误,缺少全链路追踪则难以定位是检索不准、解析遗漏还是推理偏差

1.3 LangSmith 的定位

LangSmith 覆盖开发、测试、上线、运维的完整闭环:

开发阶段                测试阶段              上线阶段              运维阶段
   │                      │                    │                    │
   ▼                      ▼                    ▼                    ▼
 Tracing 追踪          Datasets 数据集      Monitoring 监控       Alerting 告警
 调试链路问题           评估效果差异          生产流量追踪          异常自动通知
 发现 Bad Case          对比 Prompt 版本     Token 成本统计         延迟/错误告警

LangSmith 之于 LLM 应用,类似于 Datadog 之于微服务、Chrome DevTools 之于前端,是不可或缺的可观测性基础设施。


二、LangSmith 架构与核心组件

2.1 整体架构

LangSmith 采用 SaaS 平台 + 本地 SDK 的双层架构:

┌─────────────────────────────────────────────────────┐
│                    你的 LLM 应用                      │
│                                                      │
│   LangChain / LangGraph      原生 OpenAI / 其他框架    │
│        │                           │                  │
│        ▼                           ▼                  │
│   ┌─────────────────────────────────────────────┐    │
│   │          LangSmith SDK (langsmith)          │    │
│   │   RunTree 追踪     OTel 集成     环境变量    │    │
│   │   上下文注入        自动埋点      配置管理    │    │
│   └──────────────────────┬──────────────────────┘    │
│                          │                            │
│                     异步上报 (batch)                   │
└──────────────────────────┼─────────────────────────────┘
                           │ HTTPS
                           ▼
              ┌──────────────────────────┐
              │   LangSmith Cloud (SaaS)  │
              │                            │
              │  ┌──────┐ ┌──────┐         │
              │  │Trace │ │Datasets│       │
              │  │Store │ │ Store  │        │
              │  └──────┘ └──────┘         │
              │  ┌──────┐ ┌──────┐         │
              │  │Eval  │ │Prompt │        │
              │  │Engine│ │ Hub   │        │
              │  └──────┘ └──────┘         │
              │  ┌──────┐ ┌──────┐         │
              │  │Monitor│ │Playgrnd│      │
              │  │ing    │ │        │      │
              │  └──────┘ └──────┘         │
              └──────────────────────────┘

关键设计决策

  • 异步上报:追踪数据通过异步 batch 发送,不阻塞业务逻辑
  • 零侵入:LangChain 应用只需配置环境变量,零代码改动
  • 框架无关:通过 OTel(OpenTelemetry)标准,支持非 LangChain 应用

2.2 六大核心组件

组件功能对标传统工具
Tracing全链路追踪,可视化每次调用的层级结构分布式追踪(Jaeger/Zipkin)
Datasets测试数据集管理,从 Trace 一键导入测试用例管理系统
Evaluation自动评估器,量化 Prompt/模型效果CI/CD 质量门禁
Prompt HubPrompt 版本管理与动态加载Git for Prompts
Monitoring生产指标监控与告警APM(Datadog)
Playground交互式调试与 A/B 对比Postman for LLM

六者构成闭环协作关系:Tracing 采集数据 → Datasets 沉淀 Bad Case → Evaluation 自动评分 → Prompt Hub 管理版本 → Monitoring 监控生产 → Playground 调试优化。


三、快速接入:从零到看到追踪

3.1 环境变量配置

LangSmith 的设计理念是配置优先,代码零改

# 【实战代码】最小配置示例
import os

os.environ["LANGSMITH_TRACING"] = "true"                # 开启追踪(新版推荐)
os.environ["LANGSMITH_API_KEY"] = "your_langsmith_key"  # API 密钥
os.environ["LANGSMITH_PROJECT"] = "my-first-project"    # 项目名称

配置完成后,所有 LangChain 的调用都会自动上报,无需修改任何业务代码。API Key 在 smith.langchain.com 的 Settings → API Keys 中创建,格式为 ls__ 开头。

环境变量版本说明:新版 langsmith SDK 推荐使用 LANGSMITH_* 前缀变量(如 LANGSMITH_TRACINGLANGSMITH_API_KEYLANGSMITH_PROJECT)。旧版变量名 LANGCHAIN_TRACING_V2LANGCHAIN_API_KEYLANGCHAIN_PROJECT 仍作为兼容别名可正常使用,但官方文档已不再推荐。本文后续示例统一使用新版变量名。

关于自托管:LangSmith 提供自托管版本(Docker 部署),适合数据合规要求高的企业场景。自托管时将 LANGSMITH_ENDPOINT 指向私有服务器即可。

3.2 验证追踪生效

# 【实战代码】验证追踪是否生效
from langchain_openai import ChatOpenAI

llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
response = llm.invoke("用一句话解释什么是 RAG")
print(response.content)

打开 LangSmith 控制台,选择你的 Project,即可看到这条 Trace,包含:输入内容、输出内容、模型名称、Token 消耗、延迟、调用层级。

3.3 非 LangChain 应用的接入

通过 langsmith SDK,任何 Python 应用都能接入:

# 【实战代码】使用 @traceable 装饰器手动埋点
from langsmith import traceable

@traceable
def my_custom_function(question: str) -> str:
    result = call_your_model(question)
    return result

my_custom_function("什么是 RAG?")

@traceable 装饰器创建一个 Run 对象并上报到 LangSmith 平台。嵌套调用自动形成父子 Run 关系。


四、Tracing 追踪系统:LLM 应用的"X 光机"

4.1 RunTree:追踪的数据模型

LangSmith 追踪系统的底层数据结构叫 RunTree——一棵以 Run 为节点的树。

核心结论:理解 RunTree 是理解 LangSmith 的关键。RunTree 将 Agent 的每一步推理、每一次工具调用、每一轮 LLM 交互都结构化为树形数据,使不可见的推理过程变为可查询、可分析的结构化数据。

Run 的核心字段(伪代码结构,展示数据模型而非可运行代码):

# 【伪代码】Run 对象的数据结构
Run = {
    "id": "run_uuid",                       # 唯一标识
    "name": "ChatOpenAI",                   # Run 名称
    "run_type": "llm",                      # 类型:llm / chain / tool / retriever / embedding
    "inputs": {"messages": [...]},          # 输入内容
    "outputs": {"content": "..."},          # 输出内容
    "error": None,                          # 错误信息
    "start_time": "2026-08-23T10:00:00Z",    # 开始时间
    "end_time": "2026-08-23T10:00:01.5Z",    # 结束时间
    "parent_run_id": "parent_uuid",          # 父 Run ID(构建树形结构的关键)
    "extra": {                               # 额外元数据
        "model_name": "gpt-4o",
        "token_usage": {"prompt": 10, "completion": 20, "total": 30}
    },
    "tags": ["production", "v2"],            # 自定义标签
    "metadata": {"user_id": "user_123"},     # 自定义元数据
}

run_type 的五种类型

run_type含义典型来源
llm大模型调用ChatOpenAI.invoke()
chain链式组合prompt | llm | parser
tool工具调用@tool 定义的函数
retriever检索器调用向量库检索
embedding向量化调用Embedding 模型

4.2 RunTree 的树形结构

以一个 ReAct Agent 为例,它的 Trace 是一棵树:

Run (chain): AgentExecutor                      ← 根节点
├── Run (llm): ChatOpenAI.invoke                ← 第一轮 LLM 调用
│   ├── inputs: "计算 123+456 并搜索今天天气"
│   └── outputs: tool_calls=[calculator(123+456), search(今天天气)]
│
├── Run (tool): calculator                      ← 工具调用1
│   ├── inputs: {"expression": "123+456"}
│   └── outputs: "计算结果:579"
│
├── Run (tool): search                          ← 工具调用2
│   ├── inputs: {"query": "今天天气"}
│   └── outputs: "北京今天晴,25°C"
│
├── Run (llm): ChatOpenAI.invoke                ← 第二轮 LLM 调用
│   ├── inputs: [历史消息 + 工具结果]
│   └── outputs: "123+456=579。今天北京天气晴朗,25°C。"
│
└── Run (chain): 最终输出
    └── outputs: "123+456=579。今天北京天气晴朗,25°C。"

核心结论:RunTree 的层级结构完整映射了 Agent 的推理过程。在 LangSmith 界面展开这棵树,即可查看 Agent 每一步的思考内容、工具调用和返回结果——这正是"查看中间状态"能力的实现基础。

4.3 追踪数据的上报机制

追踪数据采用异步上报机制,不阻塞业务逻辑:

你的代码                           LangSmith SDK                     LangSmith Cloud
   │                                   │                               │
   │  llm.invoke("你好")               │                               │
   ├──────────────────────────────────►│                               │
   │                                   │ 创建 Run (start)              │
   │                                   ├──────────────────────────────►│
   │  返回结果                          │                               │
   │◄──────────────────────────────────┤                               │
   │                                   │ 更新 Run (end + outputs)      │
   │                                   │ → 放入 batch 队列              │
   │                                   │                               │
   │  下一次调用...                     │ ┌─ batch flush (每隔N秒)─────►│
   │                                   │ │  (批量异步发送)              │

设计要点

  • batch 队列:SDK 内部维护批量队列,每隔几秒或积累到 N 条后 flush 一次
  • 进程退出保护:SDK 注册 atexit 钩子,确保进程退出前 flush 剩余数据
  • 失败容错:上报失败不影响业务代码执行,仅记录 warning 日志

atexit 的局限atexit 钩子仅在 Python 正常退出时触发,无法处理 OOM(内存溢出)、SIGKILL(强制终止)等异常场景。生产环境中容器被强制杀掉时,最后一批 Trace 仍可能丢失。

flush 的正确用法:对追踪完整性要求高的场景(如评估测试),可在脚本末尾显式调用 client.flush(timeout=30) 确保数据落盘。flush() 接受 timeout 参数(秒),控制等待时长。不要在业务请求主线程中调用 flush()——它是同步阻塞操作,会导致请求延迟增大。

4.4 在 Trace 中添加自定义信息

追踪不仅是被动记录,还可以主动注入上下文信息,使 Trace 具有业务语义:

# 【实战代码】通过 config 注入 tags 和 metadata
from langchain_core.tracers.context import tracing_v2_enabled

# 方式一:with_config 添加 tags 和 metadata
chain = prompt | llm | parser
result = chain.invoke(
    {"input": "分析这份财报"},
    config={
        "tags": ["financial_analysis", "production"],
        "metadata": {
            "user_id": "user_123",
            "session_id": "sess_456",
            "version": "v2.1"
        }
    }
)

# 方式二:上下文管理器(自动给代码块内所有调用加追踪)
with tracing_v2_enabled(
    project_name="financial-analysis",
    tags=["batch_job", "v2"],
    metadata={"batch_id": "batch_20260823"}
):
    result1 = llm.invoke("分析营收")
    result2 = llm.invoke("分析利润")  # 两次调用归到同一个 Trace 树下

最佳实践:给每次调用打上 user_idsession_id,生产环境出问题时可按用户维度过滤 Trace,快速定位异常来源。

4.5 OpenTelemetry 集成

适用场景与落地价值

OTel 集成适用于以下场景:

  • 多语言技术栈:团队使用 Go、Java、Node.js 等非 Python 语言
  • 统一可观测性:已有 OTel 基础设施,希望 LLM 追踪与传统微服务追踪统一管理
  • 非 LangChain 框架:使用 LlamaIndex、Haystack 或原生 OpenAI SDK

OTel 是 CNCF 的可观测性标准。LangSmith 支持 OTel 协议接入意味着:

  • 一套后端管两套世界:同一套 Trace 后端同时查看 LLM 调用和传统微服务调用
  • 零供应商锁定:符合 OTel 标准的数据可随时切换后端
  • 生态复用:可直接复用已有的 OTel Collector、导出器和可视化工具链
接入方式

LangSmith 提供两种 OTel 集成路径,根据技术栈选择:

路径一:内置 OTel 模式(推荐,LangChain/LangGraph 应用)

安装 OTel 扩展包后,通过环境变量开启即可,无需手动创建 TracerProvider:

# 安装 OTel 扩展(必须先安装,否则 SDK 在导入 OTel 模块时会抛出 ImportError)
pip install "langsmith[otel]"

# 环境变量配置
export LANGSMITH_TRACING_MODE=hybrid   # 同时上报到 LangSmith 和 OTel(推荐)
export LANGSMITH_TRACING=true
export LANGSMITH_ENDPOINT=https://api.smith.langchain.com
export LANGSMITH_API_KEY=your_langsmith_api_key

OTel 开启原理:仅设环境变量不够,必须先安装 langsmith[otel]。SDK 在运行时动态导入 opentelemetry 包,若未安装会抛出 ImportError: To use OTEL tracing, you must install it with pip install langsmith[otel]LANGSMITH_TRACING_MODE 支持三个值:"langsmith"(仅 LangSmith,默认)、"otel"(仅 OTel)、"hybrid"(同时上报两者)。旧版变量 LANGSMITH_OTEL_ENABLED / LANGSMITH_OTEL_ONLY 仍可使用但属于 legacy,推荐统一用 LANGSMITH_TRACING_MODE

路径二:标准 OTLP 导出(非 LangChain 应用)

对于使用原生 OpenAI SDK 或其他框架的应用,通过标准的 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量将 OTel 数据导出到 LangSmith:

# 设置 OTLP 导出端点指向 LangSmith
export OTEL_EXPORTER_OTLP_ENDPOINT=https://api.smith.langchain.com/otel
export OTEL_EXPORTER_OTLP_HEADERS="x-api-key=your_langsmith_api_key"

应用中已有的 OTel instrumentation(如 OpenAI 的 gen_ai span)会自动通过此端点上报到 LangSmith。

端点说明api.smith.langchain.com/otel 是 LangSmith 接收 OTLP 协议数据的路径,通过标准的 OTEL_EXPORTER_OTLP_ENDPOINT 环境变量配置,而非在代码中手动创建 OTLPSpanExporter。自托管部署时,端点改为私有服务器地址。

适配框架
框架/场景集成方式备注
LangChain / LangGraph(Python)LANGSMITH_TRACING_MODE=hybrid需先安装 langsmith[otel],零代码
OpenAI SDK(Python)OTEL_EXPORTER_OTLP_ENDPOINT需配合 OTel instrumentation
OpenAI SDK(Node.js)@opentelemetry/sdk-trace-node通过 OTLP HTTP 导出
LangChain(Go)go.opentelemetry.io/otel社区支持
Spring AI(Java)io.opentelemetry:opentelemetry-sdk通过 OTLP exporter

选型建议:纯 Python + LangChain 技术栈优先用原生 SDK 或内置 OTel 模式(零配置)。只有在多语言技术栈或已有 OTel 基础设施时,才选择标准 OTLP 导出路径。


五、Datasets 数据集:从 Bad Case 到测试体系

5.1 为什么需要数据集

没有数据集,评估就是"跑几个例子看看感觉"——主观、不可复现、不可回归。数据集是将主观感受转化为量化指标的基础设施。

5.2 数据集的结构

LangSmith 数据集由 Examples(示例) 组成:

# 【伪代码】Example 的数据结构
Example = {
    "id": "example_uuid",
    "inputs": {"question": "什么是 RAG?"},
    "outputs": {"answer": "RAG 是检索增强生成技术..."},  # 可选,用于评估对比
    "metadata": {"category": "concept", "difficulty": "easy"},
    "dataset_id": "dataset_uuid",
}

outputs 是可选的:无标准答案的场景用 LLM-as-judge 评估器打分;有标准答案的场景用精确匹配或语义相似度评估。

5.3 三种创建数据集的方式

方式一:从 Trace 一键导入(推荐)

开发中发现 Bad Case,可直接将 Trace 转为测试用例。在 LangSmith 界面打开一条 Trace,点击 “Add to Dataset” 即可。也可通过 SDK 编程导入:

# 【实战代码】从 Trace 导入测试用例
from langsmith import Client

client = Client()
client.create_example(
    inputs={"question": "什么是闭包?"},
    outputs={"answer": "闭包是引用了自由变量的函数..."},
    dataset_id="your_dataset_id",
    source_run_id="trace_run_id",  # 从现有 trace 关联
)

方式二:从 CSV/JSON 批量导入

# 【实战代码】从 CSV 批量导入
import csv
from langsmith import Client

client = Client()
dataset = client.create_dataset("qa_test_set")

with open("test_cases.csv", "r", encoding="utf-8") as f:
    reader = csv.DictReader(f)
    for row in reader:
        client.create_example(
            inputs={"question": row["question"]},
            outputs={"answer": row["expected_answer"]},
            dataset_id=dataset.id,
        )

方式三:代码动态生成边界用例

# 【实战代码】程序化生成边界测试用例
edge_cases = [
    {"question": "", "expected": "应提示输入不能为空"},           # 空输入
    {"question": "a" * 10000, "expected": "应正常处理或截断"},    # 超长输入
    {"question": "帮我写个病毒", "expected": "应拒绝有害请求"},    # 安全测试
    {"question": "1+1=?" * 100, "expected": "不应被重复干扰"},     # 注入测试
]

for case in edge_cases:
    client.create_example(
        inputs={"question": case["question"]},
        outputs={"answer": case["expected"]},
        dataset_id=dataset.id,
    )

最佳实践:数据集是持续沉淀的过程。每次用户反馈"这个回答不好"、每次发现 Bad Case,都向数据集添加一条。日积月累,测试集的覆盖度会持续提升。

5.4 数据集分层规范

单一数据集难以满足不同阶段的测试需求。建议按照以下分层规范管理:

数据集类型用途数据来源运行频率典型规模
测试集验证核心功能正确性人工标注的黄金标准每次 PR50-200 条
回归集防止已知问题复现历史 Bad Case 沉淀每次 PR + 每日100-500 条
边界集验证极端输入处理程序化生成 + 安全测试每周30-100 条
用户 BadCase 集覆盖真实用户问题模式生产 Trace 自动提取每周更新持续增长

核心原则:测试集关注"功能是否正常",回归集关注"历史问题是否复现",边界集关注"极端情况是否安全",BadCase 集关注"真实场景是否覆盖"。四者互补,缺一不可。


六、Evaluation 评估框架:把"感觉"变成"指标"

6.1 评估的核心三要素

  • Target:被评估的对象——可以是函数、Chain 或 Agent
  • Dataset:测试用例集(第五章的 Datasets)
  • Evaluator:评估器——给定预测输出和(可选的)期望输出,给出分数或判断

6.2 运行评估

API 演进说明:以下示例使用 RunEvalConfig + client.run_on_dataset() 模式,该模式在 langsmith SDK 中仍可运行。但自 SDK 0.5.0 起,官方推荐使用 client.evaluate() 方法替代 run_on_dataset(),LLM 类评估器推荐迁移到 openevals 项目。下方代码保持兼容写法,读者可查阅 官方文档 了解 client.evaluate() 的最新用法。

# 【实战代码】运行评估
from langsmith import Client, RunEvalConfig
from langchain_openai import ChatOpenAI

client = Client()
llm = ChatOpenAI(model="gpt-4o", temperature=0)

eval_config = RunEvalConfig(
    evaluators=[
        "exact_match",           # 精确匹配
        "string_distance",       # 字符串相似度
        RunEvalConfig.LLMCriteria(
            criteria="回答是否准确且有帮助?",
            llm=ChatOpenAI(model="gpt-4o", temperature=0)
        ),
    ],
)

results = client.run_on_dataset(
    dataset_name="qa_test_set",
    llm_or_chain_factory=lambda input: llm.invoke(input["question"]),
    evaluation=eval_config,
    project_name="eval_run_20260823",
)

6.3 内置评估器详解

评估器类型适用场景工作原理
exact_match字符串事实问答预测与期望完全一致
string_distance字符串近似匹配编辑距离/Levenshtein
embedding_distance语义语义相似向量余弦相似度
LLMCriteriaLLM判断质量评估用 LLM 按标准打分
LLMJudgeLLM判断综合评估可自定义 Prompt 的 LLM 评判
QAELLM判断问答对判断回答是否正确
CoTQALLM判断推理问答带思维链的问答评估
LabeledCriteriaLLM判断有参考答案对比参考答案打分

LLM 评估器演进LLMCriteriaLLMJudge 等 LLM 类评估器自 SDK 0.5.0 起标记为 deprecated,官方推荐迁移到 openevals 项目获取更多预置评估器。字符串类和语义类评估器(exact_matchstring_distanceembedding_distance)不受影响。

LLM-as-Judge 的局限与解决方案

核心结论:用 LLM 评估 LLM 存在"同源偏见"——GPT-4o 评估 GPT-4o 的输出可能系统性偏高。这是 LLM-as-Judge 最大的信任危机,必须通过工程手段缓解。

方案一:跨模型评估

使用不同厂商的模型做评估,缓解同源偏见:

# 【实战代码】生产模型与评估模型使用不同厂商
production_llm = ChatOpenAI(model="gpt-4o", temperature=0.7)
judge_llm = ChatAnthropic(model="claude-3-sonnet", temperature=0)

eval_config = RunEvalConfig(
    evaluators=[
        RunEvalConfig.LLMCriteria(
            criteria="回答是否准确且有帮助?",
            llm=judge_llm,  # 使用不同厂商的模型做评估
        ),
    ],
)

方案二:人工标注黄金标准校准

建立人工标注的基准数据集,定期校准 LLM 评估器的准确性:

# 【实战代码】校准 LLM 评估器
def calibrate_judge(judge_llm, golden_set):
    """对比 LLM 评分与人工评分的一致性"""
    llm_scores = []
    human_scores = []
    for item in golden_set:
        llm_score = run_judge(judge_llm, item)
        llm_scores.append(llm_score)
        human_scores.append(item["human_score"])

    correlation = pearson_correlation(llm_scores, human_scores)
    if correlation < 0.7:
        print(f"评估器准确度不足(相关系数 {correlation:.2f}),需调整评估 Prompt")
    return correlation

方案三:多评估器加权打分

使用多个不同维度的评估器,加权综合得分:

# 【实战代码】多评估器加权
eval_config = RunEvalConfig(
    evaluators=[
        "embedding_distance",                                    # 语义相似度(权重 0.3)
        RunEvalConfig.LLMCriteria(
            criteria="回答是否包含关键信息?",
            llm=ChatAnthropic(model="claude-3-sonnet")           # 跨模型(权重 0.3)
        ),
        # custom_evaluator 返回 0/1                                # 人工规则(权重 0.4)
    ],
)
# 最终分数 = 0.3 * embedding_score + 0.3 * llm_score + 0.4 * rule_score

最佳实践:跨模型评估只能缓解同源偏见,不能彻底消除——不同厂商的模型可能共享相似的训练数据分布,导致偏见残留。生产环境中建议同时使用方案一和方案二——跨模型评估缓解偏见,人工校准验证可靠性。校准频率建议每月一次,模型版本更新后立即校准。

6.4 A/B 对比评估

评估最重要的应用场景之一是 A/B 对比——改了 Prompt 后效果是否提升:

# 【实战代码】A/B 对比评估
from langsmith.evaluation import evaluate

def target_v1(input):
    llm_v1 = ChatOpenAI(model="gpt-4o", temperature=0.7)
    return llm_v1.invoke(input["question"]).content

def target_v2(input):
    llm_v2 = ChatOpenAI(model="gpt-4o", temperature=0.3)  # 降低温度
    return llm_v2.invoke(input["question"]).content

results_v1 = evaluate(target_v1, data="qa_test_set",
                      evaluators=["exact_match", "string_distance"],
                      experiment_prefix="prompt_v1")
results_v2 = evaluate(target_v2, data="qa_test_set",
                      evaluators=["exact_match", "string_distance"],
                      experiment_prefix="prompt_v2")

在 LangSmith 界面的 Experiments 视图中,可并排查看两个版本在每个测试用例上的得分差异。

6.5 评估的工程化:CI/CD 集成

核心结论:将评估集成到 CI/CD 流程中,是 LLM 应用从"手工作坊"走向"工程化"的关键标志。每次 Prompt 变更都自动跑评估,分数不达标阻止合并,实现从"凭感觉改 Prompt"到"用数据驱动 Prompt 迭代"的转变。

# 【实战代码】GitHub Actions 评估门禁
name: LLM Evaluation Gate
on:
  pull_request:
    paths: ['prompts/**', 'src/chain/**']

jobs:
  evaluate:
    runs-on: ubuntu-latest
    steps:
      - uses: actions/checkout@v4
      - name: Install deps
        run: pip install langchain langsmith
      - name: Run evaluation
        env:
          LANGSMITH_API_KEY: ${{ secrets.LANGSMITH_API_KEY }}
          LANGSMITH_TRACING: "true"
        run: python scripts/run_eval.py
      - name: Check gate
        run: |
          SCORE=$(python scripts/get_eval_score.py)  # 注意:此脚本需自行实现,SDK 不内置
          if [ $(echo "$SCORE < 0.8" | bc -l) -eq 1 ]; then
            echo "Evaluation score below threshold!"
            exit 1
          fi

最佳实践:CI/CD 门禁阈值不要设得太高(0.8 是合理起点),避免频繁阻塞开发流程。同时配置"质量回归"检测——当前分数比上次基线下降超过 5% 时也触发告警,防止渐进式退化。

脚本说明scripts/get_eval_score.pyscripts/run_eval.py 并非 langsmith SDK 内置脚本,需开发者自行实现。get_eval_score.py 的典型实现是调用 client.list_runs() 查询最近评估实验的 aggregate score,或读取 evaluate() 返回的 ExperimentResults 对象提取综合分数。


七、Prompt Hub:Prompt 的 Git

7.1 为什么 Prompt 需要版本管理

Prompt 工程实践中,文件命名方式(prompt_v1.txtprompt_v3_final2.txt)难以维护。Prompt 版本管理需要:版本历史、回滚能力、动态加载、A/B 测试。

7.2 使用与动态加载

# 【实战代码】推送和拉取 Prompt
from langsmith import Client

client = Client()

# 推送 Prompt 到 Hub
client.push_prompt(
    "my-assistant-prompt",
    object=ChatPromptTemplate.from_messages([
        ("system", "你是一个{role},请用{style}风格回答。"),
        ("human", "{question}")
    ]),
    description="助手角色的对话 Prompt",
    tags=["v2", "production"],
    is_public=False,
)

# 从 Hub 拉取最新版本
prompt = client.pull_prompt("my-assistant-prompt", include_model=False)
chain = prompt | llm | parser

Prompt Hub 最大的价值在于运行时动态加载——线上 Prompt 更新后应用自动使用新版本,无需重新部署。更优雅的方式是使用 LangChain 的 HubRunnable

# 【实战代码】动态加载 Prompt
from langchain.hub import pull
prompt = pull("my-assistant-prompt")
chain = prompt | llm | parser

八、Monitoring 生产监控:从开发到运维

8.1 开发 vs 生产:追踪的不同策略

维度开发阶段生产阶段
采样率100%(全量追踪)1-10%(采样追踪,控制成本)
关注点链路细节、中间状态聚合指标、趋势告警
数据量小(调试时几条)大(生产流量成千上万)
延迟容忍无所谓必须低延迟告警

8.2 生产监控核心指标

LangSmith 监控仪表盘提供以下关键指标:总请求数、错误率、P99 延迟、Token 消耗、每日成本、活跃用户数。

8.3 采样策略

采样优先级

核心结论:生产环境不建议 100% 追踪(数据量太大 + 上报成本高)。分层采样是平衡成本与可观测性的关键策略——按请求类型设置不同采样率,确保关键事件不遗漏,正常请求低成本采样。

优先级请求类型建议采样率理由
P0(必采)错误请求100%用于问题排查,不可遗漏
P0(必采)高成本请求(Token > 1000)100%成本异常需实时感知
P0(必采)慢请求(延迟 > 5s)100%性能问题需及时定位
P1首次用户请求100%新用户体验保障
P2正常请求1-5%控制成本,保留采样基线
采样实现
# 【实战代码】分层采样策略
import os
import random

# 方式一:环境变量配置采样率(LangSmith 原生支持)
os.environ["LANGSMITH_TRACING_SAMPLE_RATE"] = "0.1"  # 10% 采样

# 方式二:代码层采样(更灵活的控制)
def should_trace(request_data):
    """分层采样策略"""
    if request_data.get("error"):                          # 错误请求
        return True
    if request_data.get("token_count", 0) > 1000:           # 高成本请求
        return True
    if request_data.get("is_new_user"):                    # 首次用户
        return True
    return random.random() < 0.05                          # 其余 5% 采样
生产踩坑案例

踩坑场景:某团队将生产环境采样率设为 1%,某用户报告偶发性回答错误(约每 500 次出现 1 次)。由于采样率过低,该问题在生产 Trace 中几乎无法捕获,导致无法复现和定位根因。

教训:对于已知存在偶发问题的场景,应临时提升采样率至 100%,或针对特定用户/特定错误模式开启全量追踪。采样策略不是一成不变的,需要根据问题排查需求动态调整。

8.4 告警配置

LangSmith 后台实操步骤

步骤一:进入告警设置

  1. 登录 LangSmith 控制台 → 选择目标 Project
  2. 左侧导航栏点击 SettingsAlerts & Notifications

步骤二:创建告警规则

  1. 点击 Create Alert Rule
  2. 配置告警参数:
配置项说明示例值
Alert Name告警名称Error Rate Spike
Metric监控指标error_rate / p99_latency / total_tokens
Condition触发条件> 5% / > 5s / > 1M/day
Window时间窗口5min / 10min / 24h
Notification Channel通知渠道Slack Webhook / Email

步骤三:配置通知渠道

  • Slack:在 Slack 侧创建 Incoming Webhook,将 URL 粘贴到 LangSmith 配置中
  • Email:直接输入接收告警的邮箱地址
  • 自定义 Webhook:支持发送到企业自建的消息系统

步骤四:验证告警

  • 点击 Test Alert 发送测试通知,确认通知渠道可达

最佳实践:告警阈值应基于历史基线设定,而非凭经验拍脑袋。建议先运行 1-2 周收集基线数据,再设定告警阈值(如 P99 基线的 1.5 倍作为告警线)。


九、Playground 交互式调试

9.1 Playground 核心能力

Playground 是 LangSmith 提供的交互式调试工具,可在界面上直接修改 Prompt、调整参数、对比输出,无需编写代码。

核心能力包括:参数调优(实时调整 model、temperature 等)、Prompt 编辑、多 Run 对比、历史记录回溯。

9.2 从 Trace 到 Playground 的调试闭环

Playground 最实用的功能是从 Trace 一键打开——在 Trace 列表发现可疑调用后,直接点 “Open in Playground” 修改参数重新运行:

发现 Trace 异常 → 打开 Playground → 查看完整输入
→ 发现 temperature=1.5(过高)→ 调整为 0.3 重新运行
→ 输出质量改善 → 推送到 Prompt Hub

最佳实践:Playground 是"快速试错"工具,评估是"量化验证"工具。两者配合使用:先在 Playground 快速探索方向,再用评估体系做严格验证。


十、SDK 编程式使用

10.1 实用场景:自动提取 Bad Case

# 【实战代码】自动从生产 Trace 提取低分 Bad Case
from langsmith import Client
from datetime import datetime, timedelta

client = Client()

end_time = datetime.now()
start_time = end_time - timedelta(hours=24)

low_score_runs = client.list_runs(
    project_name="production",
    start_time=start_time,
    end_time=end_time,
    filter='has(eq(metadata.score, 0))',
    limit=50,
)

dataset = client.create_dataset(f"bad_cases_{end_time.strftime('%Y%m%d')}")

for run in low_score_runs:
    client.create_example(
        inputs=run.inputs,
        outputs=run.outputs,
        dataset_id=dataset.id,
        metadata={"source": "auto_collected", "original_run_id": str(run.id)},
    )

print(f"自动收集了 {len(low_score_runs)} 个 Bad Case")

10.2 成本分析报告

核心结论:Token 成本是 LLM 应用运维的核心指标。通过 SDK 编程式查询生产 Trace 的 Token 用量,按模型维度聚合成本,是成本管控的基础能力。

# 【实战代码】按模型维度统计成本
from langsmith import Client
from collections import defaultdict
from datetime import datetime, timedelta

client = Client()

runs = client.list_runs(
    project_name="production",
    run_type="llm",
    start_time=datetime.now() - timedelta(days=7),
    limit=10000,  # 注意:limit 过大会导致内存暴涨,SDK 自动游标翻页每页最多 100 条
)

model_stats = defaultdict(lambda: {
    "calls": 0, "input_tokens": 0, "output_tokens": 0, "total_tokens": 0,
})

# 模型定价表(示例,需按官方最新定价更新)
pricing = {
    "gpt-4o": {"input": 0.0025 / 1000, "output": 0.01 / 1000},
    "gpt-4o-mini": {"input": 0.00015 / 1000, "output": 0.0006 / 1000},
    "deepseek-chat": {"input": 0.001 / 1000, "output": 0.002 / 1000},
}

for run in runs:
    model = run.extra.get("model_name", "unknown")
    usage = run.extra.get("token_usage", {})
    model_stats[model]["calls"] += 1
    model_stats[model]["input_tokens"] += usage.get("prompt_tokens", 0)
    model_stats[model]["output_tokens"] += usage.get("completion_tokens", 0)
    model_stats[model]["total_tokens"] += usage.get("total_tokens", 0)

total_cost = 0
for model, stats in sorted(model_stats.items(), key=lambda x: x[1]["total_tokens"], reverse=True):
    price = pricing.get(model, {"input": 0, "output": 0})
    cost = stats["input_tokens"] * price["input"] + stats["output_tokens"] * price["output"]
    total_cost += cost
    print(f"{model}: {stats['calls']} calls, {cost:.2f} USD")

print(f"Total: {total_cost:.2f} USD")
价格更新风险与自定义定价适配

价格更新风险:上述定价表为示例值,各模型厂商可能随时调整定价。硬编码定价表存在定价过期、新增模型未及时加入、批量折扣未计入等风险。

自定义定价适配方案

# 【实战代码】外部配置文件管理定价(推荐)
import json
from datetime import datetime

def load_pricing(config_path="pricing.json"):
    """从外部配置加载定价表,支持版本标记和更新时间"""
    with open(config_path, "r") as f:
        config = json.load(f)
    updated_at = datetime.fromisoformat(config["updated_at"])
    if (datetime.now() - updated_at).days > 30:
        print(f"警告:定价表已超过 30 天未更新,最后更新于 {config['updated_at']}")
    return config["models"]

# 【实战代码】支持缓存定价(如 OpenAI Prompt Caching)
pricing_with_cache = {
    "gpt-4o": {
        "input": 0.0025 / 1000,
        "cached_input": 0.00125 / 1000,  # 缓存命中价(半价)
        "output": 0.01 / 1000,
    },
}

def calculate_cost_with_cache(usage, pricing):
    """支持缓存定价的成本计算(OpenAI 专用字段)"""
    input_tokens = usage.get("prompt_tokens", 0)
    # prompt_tokens_details.cached_tokens 是 OpenAI 特有字段,其他模型不会返回
    # 已用 .get() 链式调用做容错:字段缺失时 cached_tokens 为 0
    cached_tokens = usage.get("prompt_tokens_details", {}).get("cached_tokens", 0)
    non_cached_input = input_tokens - cached_tokens
    output_tokens = usage.get("completion_tokens", 0)
    return (non_cached_input * pricing["input"] +
            cached_tokens * pricing.get("cached_input", pricing["input"]) +
            output_tokens * pricing["output"])

最佳实践:将定价表抽离为独立配置文件(pricing.json),加入更新时间戳和过期提醒机制。对于使用 API 网关的团队,可利用网关(如 LiteLLM)提供的 pricing 查询接口实现自动化。


十一、与 LangChain / LangGraph 的深度集成

11.1 LangChain 的自动追踪

LangChain 的所有 Runnable 组件都内置了追踪埋点。当 LANGSMITH_TRACING=true 时,链式调用自动生成 Trace:

# 【实战代码】LangChain 链式调用自动追踪
from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是{role}"),
    ("human", "{question}")
])
llm = ChatOpenAI(model="gpt-4o")
parser = StrOutputParser()

chain = prompt | llm | parser
result = chain.invoke({"role": "Python专家", "question": "什么是装饰器"})

# Trace 结构:
# Run (chain): RunnableSequence
#   ├── Run (prompt): ChatPromptTemplate
#   ├── Run (llm): ChatOpenAI
#   └── Run (parser): StrOutputParser

11.2 LangGraph 的图级追踪

LangGraph 应用在 LangSmith 中会展示更丰富的图结构追踪:

# 【实战代码】LangGraph 图执行追踪
from langgraph.graph import StateGraph, END

graph = StateGraph(AgentState)
graph.add_node("agent", agent_node)
graph.add_node("tools", tool_node)
graph.add_edge("agent", "tools")
graph.add_conditional_edges("agent", should_continue, {"continue": "tools", "end": END})
graph.add_edge("tools", "agent")  # 循环回 agent

app = graph.compile()
result = app.invoke({"input": "帮我算 123+456 然后搜索今天新闻"})
LangSmith Trace 视图(图执行路径):

Run (chain): LangGraph
├── Superstep 1: [agent] → 决定调用 calculator + search
├── Superstep 2: [tools] → 并行执行 calculator, search
│   ├── Run (tool): calculator → "579"
│   └── Run (tool): search → "今日新闻..."
├── Superstep 3: [agent] → 综合工具结果,生成回答
└── Run (chain): 最终输出 → "123+456=579。今日新闻..."

核心结论:LangGraph 的图执行模型解决了 Agent 的循环/分支问题,LangSmith 的追踪让图执行过程的每一步都可见。两者深度协同,使 Agent 开发从"黑盒"变为"白盒"。

11.3 LangGraph 的中断与恢复追踪

基本用法

LangGraph 支持在执行中断(interrupt),并在 LangSmith 中追踪中断前后的状态:

# 【实战代码】LangGraph 中断与恢复
from langgraph.checkpoint.memory import MemorySaver

# ⚠️ 重要:interrupt_before 是 compile() 时的参数,不是 invoke() 时的参数
# 不能在 graph.invoke({"input": "..."}, config={"interrupt_before": [...]}) 中传入
graph = builder.compile(
    checkpointer=MemorySaver(),
    interrupt_before=["human_approval"],  # 在 human_approval 节点前中断
)
config = {"configurable": {"thread_id": "thread_1"}}

result = graph.invoke(
    {"input": "帮我发送邮件给老板"},
    config=config,
)

# LangSmith Trace 显示:
# Run: graph
#   ├── Run: agent (决策)
#   ├── Run: compose_email (生成邮件)
#   └── [INTERRUPT] human_approval ← 中断在这里

# 恢复执行
result = graph.invoke(None, config=config)
# LangSmith 新的 Run 会关联到同一个 thread
生产环境使用场景
场景说明中断节点
人工审核Agent 生成邮件/消息后需人工确认再发送human_approval
多轮对话等待Agent 需要用户提供额外信息后继续执行await_user_input
高风险操作确认执行删除、支付等不可逆操作前暂停risk_check
工具调用审批调用外部 API 前需审批(如发短信、调支付接口)tool_approval
生产避坑要点
  • thread_id 必须唯一且可追溯:每个用户会话应使用唯一的 thread_id(如 user_{user_id}_session_{session_id}),避免复用已完成的 thread,否则中断状态可能被覆盖

  • 中断超时处理:生产环境中人工审核可能长时间未响应,需设置超时机制,超时后自动终止该 thread 并记录超时 Trace

  • 恢复时的状态一致性:中断到恢复期间,Agent 的系统状态可能已变化(如知识库更新),恢复执行前应校验上下文是否仍然有效

  • 检查点存储选型MemorySaver 仅适用于开发环境,生产环境应使用持久化存储:

# 【实战代码】生产环境使用 PostgreSQL 持久化检查点
from langgraph.checkpoint.postgres import PostgresSaver

graph = builder.compile(checkpointer=PostgresSaver.from_conn_string(
    "postgresql://user:pass@localhost:5432/langgraph"
))

十二、LangSmith vs 其他可观测方案

12.1 横向对比

维度LangSmithLangfuse(开源自托管)Arize Phoenix自建方案
部署方式SaaS 为主开源自托管开源 + SaaS全自研
追踪深度LLM + Chain + ToolLLM + ChainLLM + Chain取决于自研深度
评估系统内置丰富评估器基础评估强大的评估需自建
Prompt 管理Hub 版本管理Prompt 管理基础管理需自建
生产监控内置仪表盘基础监控强大监控需自建
LangChain 集成原生(零配置)需配置需配置需开发
数据隐私SaaS 有合规风险可完全私有可私有完全私有
成本免费额度 + 付费开源免费开源 + SaaS开发成本高
适合规模中小团队 → 企业中大团队中大团队大厂自研

12.2 选型建议

你的情况                              推荐方案
──────────────────────              ──────────
小团队 + LangChain 技术栈             → LangSmith(零配置,开箱即用)
数据合规要求高(医疗/金融)            → Langfuse 自托管
需要深度自定义评估                    → Arize Phoenix + 自定义评估器
大厂 + 特殊需求 + 有研发能力           → 自建(OTel + 自研后端)
混合方案                            → LangSmith 开发 + Langfuse 生产

十三、最佳实践:从入门到精通

13.1 开发阶段

实践一:尽早接入,全量追踪

项目初始化时第一件事就是配置 LangSmith 环境变量,从第一天开始全量追踪,能看到每次迭代的演进过程。

实践二:用 tracing context 组织相关调用

# 【实战代码】按用户会话组织 Trace
from langchain_core.tracers.context import tracing_v2_enabled

def handle_user_session(user_id, session_id, messages):
    with tracing_v2_enabled(
        project_name="user_sessions",
        tags=[f"user:{user_id}", f"session:{session_id}"],
        metadata={"user_id": user_id, "session_id": session_id},
    ):
        for msg in messages:
            response = chain.invoke({"input": msg})

实践三:Bad Case 即时沉淀

# 【实战代码】用户反馈不好时自动存入 Bad Case 数据集
from langsmith import Client

client = Client()

def handle_user_feedback(trace_id, feedback_score, feedback_text):
    if feedback_score < 3:
        run = client.read_run(trace_id)
        client.create_example(
            inputs=run.inputs,
            dataset_name="bad_cases",
            metadata={"feedback": feedback_text, "trace_id": trace_id}
        )

13.2 生产阶段

实践一:分层采样

# 【实战代码】分层采样规则
SAMPLING_RULES = {
    "error_requests": 1.0,      # 错误请求 100%
    "high_cost_requests": 1.0,   # Token > 1000 的 100%
    "slow_requests": 1.0,        # 延迟 > 5s 的 100%
    "normal_requests": 0.05,     # 正常请求 5%
}

def should_trace(run_metadata):
    rule_key = classify_request(run_metadata)
    rate = SAMPLING_RULES.get(rule_key, 0.05)
    return random.random() < rate

实践二:成本预算告警

# 【实战代码】每日成本预算检查
DAILY_BUDGET = 50.0  # 每日预算 $50

def check_daily_budget():
    today_runs = client.list_runs(
        project_name="production",
        start_time=datetime.now().replace(hour=0, minute=0, second=0),
        run_type="llm",
    )
    total_cost = sum(
        run.extra.get("token_usage", {}).get("total_tokens", 0) *
        get_price(run.extra.get("model_name", ""))
        for run in today_runs
    )
    if total_cost > DAILY_BUDGET * 0.8:
        send_alert(f"日成本已达预算的 {total_cost/DAILY_BUDGET*100:.1f}%")
    if total_cost > DAILY_BUDGET:
        send_critical_alert(f"日成本超额!当前: ${total_cost:.2f}")

实践三:定期质量回归

# 【实战代码】每周质量回归评估
from langsmith import Client
from langsmith.evaluation import evaluate  # 自 SDK 0.5.0 起 deprecated,推荐用 client.evaluate()

def weekly_regression():
    client = Client()
    results = client.evaluate(  # 推荐用 client.evaluate() 替代独立 evaluate 函数
        target=production_chain.invoke,
        data="weekly_regression_set",
        evaluators=[
            "exact_match",
            "string_distance",
            # LLM 类评估器推荐使用 openevals 项目
            # 详见 https://github.com/langchain-ai/openevals
        ],
        experiment_prefix=f"weekly_{datetime.now().strftime('%Y%m%d')}",
    )
    last_week_score = get_last_week_score()  # 自定义函数,从数据库或文件读取上周分数
    this_week_score = results.get_aggregate_score()
    if this_week_score < last_week_score - 0.05:
        send_alert(f"质量回归!{last_week_score:.2%}{this_week_score:.2%}")

13.3 典型使用流程总结

═══════════════════════════════════════════════════════
                   LangSmith 使用全流程
═══════════════════════════════════════════════════════

【开发阶段】
  1. 配置环境变量,开启 Tracing
  2. 在 Trace 中调试链路问题,定位异常步骤
  3. 发现 Bad Case → 保存到 Datasets
  4. 用 Datasets 跑 Evaluation,量化当前效果
  5. 在 Playground 调整 Prompt/参数,多版本对比
  6. 将优化后的 Prompt 推送到 Prompt Hub

【测试阶段】
  7. CI/CD 集成评估,每次 PR 自动跑评估
  8. 质量门禁:分数不达标阻止合并

【上线阶段】
  9. 配置生产采样策略(分层采样控制成本)
  10. 配置监控仪表盘(Token / 延迟 / 错误率)
  11. 配置告警规则(异常自动通知)

【运维阶段】
  12. 每日检查监控仪表盘,关注趋势变化
  13. 每周跑回归评估,发现质量退化
  14. 持续从生产 Trace 沉淀新 Bad Case
  15. 定期审查成本报告,优化 Token 消耗

═══════════════════════════════════════════════════════

核心总结

LangSmith 解决的核心问题是 LLM 应用的不可见性——让每一次模型调用、每一个工具执行、每一步推理思考都变得可追踪、可评估、可优化。

本文核心要点回顾

  1. 架构层面:RunTree 追踪模型将 Agent 推理链路结构化为树形数据;异步上报机制保证零性能损耗;OTel 标准集成打通了多语言技术栈的可观测性壁垒
  2. 评估体系:评估三要素(Target-Dataset-Evaluator)构建了量化闭环;LLM-as-Judge 需通过跨模型评估、人工校准、多评估器加权来缓解同源偏见
  3. 数据集分层:测试集、回归集、边界集、用户 BadCase 集四层互补,覆盖从功能验证到真实场景兜底的完整需求
  4. Prompt 管理:Hub 版本管理 + 动态加载实现"改 Prompt 不改代码"的运维模式
  5. 生产运维:分层采样策略(P0 必采、P2 低采)平衡成本与可观测性;告警阈值应基于历史基线设定
  6. 成本管理:定价表应外部化管理并设置过期提醒;需适配缓存定价等新计费模式
  7. 深度集成:LangGraph 图级追踪 + 中断恢复追踪覆盖了复杂 Agent 工作流的全链路可观测性需求
  8. 横向对比:LangSmith 适合 LangChain 技术栈快速落地,Langfuse 适合合规要求高的自托管场景,选型需综合合规、成本、团队规模三维度
  9. 企业级能力:隐私脱敏、日志过滤、用户维度追踪、批量回溯、异常根因自动分析是企业落地不可或缺的能力
  10. 国内落地:网络延迟通过代理或自托管解决,数据合规优先选择自托管方案,自托管需关注 PG 性能和版本升级兼容性

LangSmith 的价值不仅在于工具本身,更在于它提供了一套 LLM 应用全生命周期的工程方法论:开发时用 Tracing 调试 → 测试时用 Datasets + Evaluation 做回归 → 上线时用 Monitoring 监控 → 运维时用告警 + 自动分析持续优化。

这套方法论不绑定 LangSmith——即使使用 Langfuse 或自建方案,核心思路(追踪 → 数据集 → 评估 → 监控 → 优化)是一致的。LangSmith 的优势在于将这条路铺设得最为完整,与 LangChain 生态整合得最为深入。


时效性声明

重要提示:本文基于 LangSmith 当前版本撰写,文中的模型定价、API 接口路径、页面操作路径均为示例数据。LangSmith 的界面布局、接口定义、各 LLM 厂商定价会随产品迭代而变化。示例内容仅作参考,具体操作请以 LangSmith 官方文档 和各厂商最新官方定价为准。

特别是:

  • 模型定价:各厂商可能随时调整定价(如 OpenAI 多次降价、推出缓存定价),请以官方最新定价为准
  • API 接口:OTel 端点、Client 构造器参数等可能随版本更新调整
  • 界面操作:Settings → Alerts 等页面路径可能随产品迭代调整
  • 环境变量:推荐使用 LANGSMITH_TRACINGLANGSMITH_TRACING_MODE 等新版变量名,旧版 LANGCHAIN_TRACING_V2LANGSMITH_OTEL_ENABLED 仅作兼容别名
  • SDK APIClienthide_inputs/hide_outputs/hide_metadata 参数(支持 boolCallable)、list_runs()limit 分页行为、评估 API 推荐使用 client.evaluate() 替代 RunEvalConfig + run_on_dataset()

建议定期对照 LangSmith SDK 源码 和官方文档验证本文内容的准确性。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值