langchain学习总结-利用回调功能调试链应用

3 阅读3分钟

一、这是什么

LangChain 回调功能是一种监控和调试链式应用执行过程的机制。通过在链的执行过程中注册回调处理器,可以实时捕获各个阶段的状态信息、输入输出数据以及性能指标。

回调机制基于事件驱动模式,当链式应用执行到特定节点时(如模型开始、模型结束、链开始、链结束等),会自动触发对应的回调函数。

二、有什么用

1. 执行过程可视化

  • 实时查看链的执行流程
  • 监控每个环节的输入输出
  • 追踪数据在链中的传递路径

2. 性能监控

  • 统计各环节执行耗时
  • 识别性能瓶颈
  • 优化链的执行效率

3. 调试与问题定位

  • 记录详细的执行日志
  • 快速定位错误发生位置
  • 分析失败原因

4. 自定义监控告警

  • 集成日志系统
  • 实现监控指标上报
  • 设置异常告警机制

三、核心概念

回调处理器类型

  1. 内置回调处理器

    • StdOutCallbackHandler: 将执行过程输出到控制台
    • FileCallbackHandler: 将执行日志写入文件
    • 其他内置处理器
  2. 自定义回调处理器

    • 继承 BaseCallbackHandler 基类
    • 实现特定的事件处理方法
    • 根据需求定制监控逻辑

常用回调方法

  • on_chat_model_start: 聊天模型开始执行
  • on_chat_model_end: 聊天模型执行结束
  • on_llm_start: LLM 开始执行
  • on_llm_end: LLM 执行结束
  • on_chain_start: 链开始执行
  • on_chain_end: 链执行结束
  • on_tool_start: 工具开始调用
  • on_tool_end: 工具调用结束

四、使用示例

示例代码

import time
from typing import Dict, Any, List, Optional
from uuid import UUID

import dotenv
from langchain_core.callbacks import StdOutCallbackHandler, BaseCallbackHandler
from langchain_core.messages import BaseMessage
from langchain_core.output_parsers import StrOutputParser
from langchain_core.outputs import LLMResult
from langchain_core.prompts import ChatPromptTemplate
from langchain_core.runnables import RunnablePassthrough
from langchain_openai import ChatOpenAI

dotenv.load_dotenv()


class LLMOpsCallbackHandler(BaseCallbackHandler):
    """自定义LLMOps回调处理器"""

    start_at: float = 0

    def on_chat_model_start(
        self,
        serialized: Dict[str, Any],
        messages: List[List[BaseMessage]],
        *,
        run_id: UUID,
        parent_run_id: Optional[UUID] = None,
        tags: Optional[List[str]] = None,
        metadata: Optional[Dict[str, Any]] = None,
        **kwargs: Any,
    ) -> Any:
        """聊天模型开始执行时触发"""
        print("聊天模型开始执行了")
        print("serialized:", serialized)
        print("messages:", messages)
        self.start_at = time.time()

    def on_llm_end(
        self,
        response: LLMResult,
        *,
        run_id: UUID,
        parent_run_id: Optional[UUID] = None,
        **kwargs: Any,
    ) -> Any:
        """LLM执行完成时触发"""
        end_at: float = time.time()
        print("完整输出:", response)
        print("程序消耗:", end_at - self.start_at)


# 1. 编排prompt
prompt = ChatPromptTemplate.from_template("{query}")

# 2. 创建大语言模型
llm = ChatOpenAI(model="moonshot-v1-8k")

# 3. 构建链
chain = {"query": RunnablePassthrough()} | prompt | llm | StrOutputParser()

# 4. 调用链并执行(配置回调处理器)
resp = chain.stream(
    "你好,你是?",
    config={"callbacks": [StdOutCallbackHandler(), LLMOpsCallbackHandler()]}
)

for chunk in resp:
    pass

代码说明

  1. 自定义回调处理器 LLMOpsCallbackHandler

    • 继承 BaseCallbackHandler
    • 实现 on_chat_model_start 方法:记录模型开始执行的时间戳、序列化信息和输入消息
    • 实现 on_llm_end 方法:计算并输出完整结果和执行耗时
  2. 使用多个回调处理器

    • StdOutCallbackHandler(): 内置的标准输出处理器,打印详细执行日志
    • LLMOpsCallbackHandler(): 自定义处理器,专注于性能统计
  3. 配置回调

    • 通过 config 参数的 callbacks 字段传入回调处理器列表
    • 支持同时注册多个回调处理器

执行效果

当运行上述代码时,会输出类似以下内容:

聊天模型开始执行了
serialized: {'name': 'ChatOpenAI', ...}
messages: [[HumanMessage(content='你好,你是?')]]
完整输出: generations=[[ChatGeneration(text='我是AI助手...')]] 等信息
程序消耗: 1.234567

五、实际应用场景

1. 开发调试阶段

  • 快速定位问题
  • 查看中间结果
  • 验证链的执行逻辑

2. 性能优化

  • 识别耗时环节
  • 对比不同实现的性能
  • 监控生产环境性能指标

3. 日志审计

  • 记录所有调用记录
  • 追踪用户操作
  • 满足合规要求

4. 监控告警

  • 集成到监控系统(如 Prometheus)
  • 设置异常阈值告警
  • 实现自动化运维