深度学习

智能体6-LangSmith深度解析

2025-11-17  本文已影响0人  R7_Perfect

引言:AI Agent开发的范式变革

在大型语言模型(LLM)技术爆发的今天,AI Agent已从简单的问答工具演变为具备复杂认知能力的智能系统。这种进化对开发工具提出了全新要求:如何追踪智能体的思考过程?如何编排多步骤工作流?如何确保系统的可靠性和可观测性?LangSmith与LangGraph作为LangChain生态的核心组件,正是为解决这些问题而生。本文将深入解析这两个组件的设计哲学、技术架构与应用实践。

在理解LangSmith与LangGraph之前,需要明确它们在LangChain生态中的定位。假设读者已具备以下基础概念:

LangSmith与LangGraph并非独立存在,而是对LangChain核心能力的增强:

本文将通过对比演示,展现这两个组件如何将基础Agent进化为工业级智能系统。

一、LangSmith:AI Agent的可观测性中枢

1. 设计理念:让AI开发透明可见

LangSmith源于一个简单却深刻的认知:黑箱化是AI系统不可靠的根源。传统LLM应用开发中,开发者往往面临三大痛点:

开发者面临的核心痛点:

LangSmith通过全链路追踪和可视化分析,将AI Agent的"思维过程"转化为可解释的数据图谱,实现了开发范式的根本转变。

1.1 只需添加几行配置即获得全维度观测能力

pip install langchain_openai langchain_core
export LANGCHAIN_TRACING_V2=true
export LANGSMITH_API_KEY=<your-api-key>
# This example uses OpenAI, but you can use any LLM provider of choice
export OPENAI_API_KEY=<your-openai-api-key>

1.2 无需额外代码即可将Trace(痕迹)记录到 LangSmith

import os

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

os.environ['LANGSMITH_API_KEY'] = 'your-api-key'
# os.environ['LANGSMITH_TRACING'] = "True"
os.environ['LANGCHAIN_TRACING_V2'] = 'true'

prompt = ChatPromptTemplate.from_messages([
    ("system", "您是一位得力的智能助手。请仅根据给定的上下文,使用合适的语言响应用户的请求。"),
    ("user", "问题: {question}\n上下文: {context}")
])
model = ChatOpenAI(
    model='deepseek-chat',
    openai_api_key=os.getenv('DEEPSEEK_API_KEY'),
    openai_api_base='https://api.deepseek.com/v1',
    temperature=0
)
output_parser = StrOutputParser()

chain = prompt | model | output_parser

question = "你能总结一下今天上午的会议吗?"
context = "在今天上午的会议上,我们解决了世界上所有的冲突。"
result = chain.invoke({"question": question, "context": context})
print(result)

1.3 查看Trace

9e6131c0-148d-4b02-baee-f4983ef58626.png

上面展示了如何通过设置单个环境变量来跟踪应用程序中 LangChain 可运行对象的所有调用。虽然这是一种便捷的入门方法,但你可能只想跟踪应用程序的特定调用或部分内容。

1.4 手动传入LangChainTracer实例作为回调来跟踪

from langchain.callbacks.tracers import LangChainTracer

# 取消设置 LANGSMITH_TRACING
# os.environ['LANGCHAIN_TRACING_V2'] = 'true'

# 可以设置LANGSMITH_PROJECT环境变量,为整个应用程序运行配置自定义项目名称
os.environ['LANGSMITH_PROJECT'] = 'default'

tracer = LangChainTracer()
chain.invoke({"question": "我是否正在使用回调?", "context": "我正在使用回调。"}, config={"callbacks": [tracer]})
5112a876-9b3e-4f7f-ad63-115b5c39aef2.png

1.5 使用tracing_v2_enabled上下文管理器来跟踪

from langchain_core.tracers.context import tracing_v2_enabled

with tracing_v2_enabled():
    chain.invoke({"question": "我是否正在使用上下文管理器?", "context": "我正在使用上下文管理器。"})
5bcd9444-a63e-45ee-9d87-eed2578dac82.png

1.6 单独设置项目名称参数

from langchain.callbacks.tracers import LangChainTracer

tracer = LangChainTracer(project_name='default')
chain.invoke({"question": "我是否正在使用回调?", "context": "我正在使用回调。"}, config={"callbacks": [tracer]})

from langchain_core.tracers.context import tracing_v2_enabled

with tracing_v2_enabled(project_name='default'):
    chain.invoke({"question": "我是否正在使用上下文管理器?", "context": "我正在使用上下文管理器。"})
0576219f-f9a9-4a73-8c19-d5c4e139d909.png

1.7 在Config中提供任意元数据和标签,从而为跟踪添加注释

这有助于将其他信息与跟踪关联起来,例如跟踪的执行环境或发起跟踪的用户。

import os

from langchain_openai import ChatOpenAI
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.output_parsers import StrOutputParser

os.environ['LANGCHAIN_TRACING_V2'] = 'true'

prompt = ChatPromptTemplate.from_messages([
    ("system", "你是一个乐于助人的人工智能。"),
    ("user", "{input}")
])

# 标签“model-tag”和元数据 {“model-key”:“model-value”} 将仅附加到 ChatOpenAI 运行
chat_model = ChatOpenAI(
    model='deepseek-chat',
    openai_api_key=os.getenv('DEEPSEEK_API_KEY'),
    openai_api_base='https://api.deepseek.com/v1',
    temperature=0
).with_config({"tags": ["model-tag"], "metadata": {"model-key": "model-value"}})
output_parser = StrOutputParser()

# 可以使用 RunnableConfig 配置标签和元数据
chain = (prompt | chat_model | output_parser).with_config(
    {"tags": ["config-tag"], "metadata": {"config-key": "config-value"}})

# 标签和元数据也可以在运行时传递
chain.invoke({"input": "生命的意义是什么?"},
             {"tags": ["invoke-tag"], "metadata": {"invoke-key": "invoke-value"}})
3dc2347d-0349-47bb-84ac-6dbded8e0cf5.png
97cec764-ac79-4c6d-824c-ea9e8d5ab26a.png

1.8 通过在Config中提供名称来自定义给定运行的名称

# 在 LangChain 内跟踪时,运行名称默认为被跟踪对象的类名(例如,“ChatOpenAI”)。
configured_chain = chain.with_config({"run_name": "MyCustomChain1"})
configured_chain.invoke({"input": "生命的意义是什么?"})

# 您还可以在调用时配置运行名称,如下所示
chain.invoke({"input": "生命的意义是什么?"}, {"run_name": "MyCustomChain2"})
a5757414-cf07-488c-8b3f-177e422ab49b.png

MyCustomChain1会被后面的MyCustomChain2覆盖掉

1.9 通过在Config中提供 ID 来自定义特定运行的 ID

import uuid

my_uuid = uuid.uuid4()
print(f"my_uuid:{my_uuid}")
# You can configure the run ID at invocation time:
chain.invoke({"input": "What is the meaning of life?"}, {"run_id": my_uuid})
8da8dbbe-8312-4ecc-aead-bfc787a2e0f7.png

2. 核心功能全景

在LangSmith控制台中可分析:

功能模块 技术实现 应用场景
调用链追踪 异步日志采集系统 调试复杂Agent逻辑
性能监控 时序数据库+指标计算引擎 成本优化与资源调配
数据标注 人工反馈集成接口 构建高质量微调数据集
回归测试 版本对比+差异分析 保障系统迭代稳定性

3. 深度集成实践

(1) 全链路追踪配置
import os
from langsmith import RunTree
from langchain_openai import ChatOpenAI

# ------------------ 环境变量配置 ------------------
# 确保在环境变量或 .env 文件中配置了以下内容:
# LANGCHAIN_API_KEY: LangSmith 的 API Key
# DEEPSEEK_API_KEY: deepseek 模型的 API Key
os.environ["LANGCHAIN_ENDPOINT"] = os.getenv("LANGCHAIN_ENDPOINT", "https://api.smith.langchain.com")

# ------------------ 初始化 LLM ------------------
llm = ChatOpenAI(
    model="deepseek-chat",
    openai_api_key=os.getenv("DEEPSEEK_API_KEY"),
    openai_api_base="https://api.deepseek.com/v1",
    temperature=0,
)

# ------------------ 用户输入 ------------------
user_query = "我忘记了登录密码,怎么才能尽快重新设置?"

# ------------------ 顶层追踪节点 ------------------
run_tree = RunTree(
    name="customer_service_agent_trace",
    inputs={"user_query": user_query},
    tags=["langsmith-demo", "run_tree", "full_trace"]
)

try:
    # ------------------ 子任务 1:调用 LLM 生成回复 ------------------
    prompt = (
        "请为用户生成一段简洁友好的密码重置指引,"
        "说明操作步骤,并提醒用户注意账户安全。"
    )
    llm_child = RunTree(
        name="llm_inference",
        inputs={"prompt": prompt},
        parent_id=run_tree.id  # 👈 建立层级
    )
    response = llm.invoke(prompt)
    llm_child.add_outputs({"response": response})
    llm_child.post()  # 👈 上传子节点

    # ------------------ 子任务 2:格式化输出 ------------------
    format_child = RunTree(
        name="format_response",
        inputs={"raw_response": response},
        parent_id=run_tree.id
    )
    formatted = f"您好,{response} 如有疑问请联系人工客服协助处理。"
    format_child.add_outputs({"formatted_response": formatted})
    format_child.post()

    # ------------------ 顶层输出 ------------------
    run_tree.add_outputs({"final_response": formatted})

except Exception as e:
    run_tree.add_outputs({"error": str(e)})
    raise

finally:
    run_tree.post()  # 👈 上传主节点到 LangSmith 平台

# 控制台展示最终结果
print(formatted)
7276cbd5-dd61-4a7c-ab0a-4f072fcee2e0.png

这个示例展示了如何使用 LangChain 与 LangSmith 搭建一个“客服智能体”的原型,并通过 RunTree 工具对整个执行过程进行结构化的全链路追踪。追踪的内容不仅包括最终结果,还详细记录了每一步中 LLM 的调用和响应处理。

当你在网站上向客服机器人提问,比如“我忘记密码了怎么办?”,背后其实是一个小程序在帮你处理:
- 它会把你的问题转化成一句清晰的“提示语”,比如:“请生成密码重置流程的说明”;
- 然后它调用一个智能模型来写出这段说明;
- 最后它把这段说明稍微润色一下,再发给你。
为了让开发者能“看清楚”这个机器人到底每一步做了什么,我们用 LangSmith 提供的“追踪系统”记录了整个过程——就像一张“处理流程图”,可以在平台上回放每一步的输入和输出。

上一篇 下一篇

猜你喜欢

热点阅读