第九天!玩转langchain!回调处理器!一篇学会日志+监控+流式传输!9/10

news2024/11/17 11:46:39

原文:第九天!玩转langchain!回调处理器!一篇学会日志+监控+流式传输!9/10 - 知乎

在第九篇!跟着雄哥学langchain中的回调处理器!

时间飞快呀~已经第九课了,在更新的这10天时间,雄哥公众号的阅读量也来到了历史新低!太干了,以至于只有星球花钱的小朋友在坚持打卡!

雄哥每天都会看!你学习的有没有用心,有没有不懂的!越是认真的小朋友,进步越快!

人的专注力只有10分钟,通篇言简意赅,一看就懂!

①什么是回调处理器?

②如何使用?

③适用哪些场景?

langchain更新太快了,我们整个教程默认统一使用版本 0.0.235!

雄哥一直都说,一口吃不成胖子!成功都是一步步走出来的!

总共10篇,每篇都有任务,你只要跟着走!有条件的到星球打卡,你肯定有所获!那些只看不做的,最后也就一晃眼,啥都得不到!

以后你想看想学了,不好意思,一天一个大版本,你已经跟不上了!


第一部分:什么是回调处理器?

Callback 是 LangChain 提供的回调机制,允许我们在 LLM 应用程序的各个阶段使用 Hook(钩子)。这对于记录日志、监控、流式传输等任务非常有用。这些任务的执行逻辑由回调处理器(CallbackHandler)定义的。

在 Python 程序中, 回调处理器通过继承 BaseCallbackHandler 来实现。BaseCallbackHandler 接口对每一个可订阅的事件定义了一个回调函数。

BaseCallbackHandler 的子类可以实现这些回调函数来处理事件,当事件触发时,LangChain 的回调管理器 CallbackManager 会调用相应的回调函数。

以下是 BaseCallbackHandler 的源代码地址和定义:

源代码地址:https://github.com/langchain-ai/langchain/blob/v0.0.235/langchain/callbacks/base.py#L225

定义:

class BaseCallbackHandler:
    """Base callback handler that can be used to handle callbacks from langchain."""
​
    def on_llm_start(
        self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any
    )
 -> Any:
        """Run when LLM starts running."""
​
    def on_chat_model_start(
        self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs: Any
    )
 -> Any:
        """Run when Chat Model starts running."""
​
    def on_llm_new_token(self, token: str, **kwargs: Any) -> Any:
        """Run on new LLM token. Only available when streaming is enabled."""
​
    def on_llm_end(self, response: LLMResult, **kwargs: Any) -> Any:
        """Run when LLM ends running."""
​
    def on_llm_error(
        self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
    )
 -> Any:
        """Run when LLM errors."""
​
    def on_chain_start(
        self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs: Any
    )
 -> Any:
        """Run when chain starts running."""
​
    def on_chain_end(self, outputs: Dict[str, Any], **kwargs: Any) -> Any:
        """Run when chain ends running."""
​
    def on_chain_error(
        self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
    )
 -> Any:
        """Run when chain errors."""
​
    def on_tool_start(
        self, serialized: Dict[str, Any], input_str: str, **kwargs: Any
    )
 -> Any:
        """Run when tool starts running."""
​
    def on_tool_end(self, output: str, **kwargs: Any) -> Any:
        """Run when tool ends running."""
​
    def on_tool_error(
        self, error: Union[Exception, KeyboardInterrupt], **kwargs: Any
    )
 -> Any:
        """Run when tool errors."""
​
    def on_text(self, text: str, **kwargs: Any) -> Any:
        """Run on arbitrary text."""
​
    def on_agent_action(self, action: AgentAction, **kwargs: Any) -> Any:
        """Run on agent action."""
​
    def on_agent_finish(self, finish: AgentFinish, **kwargs: Any) -> Any:
        """Run on agent end."""


第二部分:如何使用?

LangChain 内置支持了一系列回调处理器,我们也可以按需求自定义处理器,以实现特定的业务。这里介绍两种:内置处理器、自定义处理器的用法!

2.1 内置处理器

StdOutCallbackHandler 是 LangChain 所支持的最基本的处理器。它将所有的回调信息打印到标准输出。这对于调是试非常有用。

LangChain 链的基类 Chain 提供了一个 callbacks 参数来指定要使用的回调处理器。请参考Chain源码,其中代码片段为:

class Chain(Serializable, ABC):
    """Abstract base class for creating structured sequences of calls to components.
    ...
    callbacks: Callbacks = Field(default=None, exclude=True)
    """Optional list of callback handlers (or callback manager). Defaults to None.
    Callback handlers are called throughout the lifecycle of a call to a chain,
    starting with on_chain_start, ending with on_chain_end or on_chain_error.
    Each custom chain can optionally call additional callback methods, see Callback docs
    for full details."""

用法如下:

from langchain.callbacks import StdOutCallbackHandler
from langchain.chains import LLMChain
from langchain.llms import OpenAI
from langchain.prompts import PromptTemplate
​
handler = StdOutCallbackHandler()
llm = OpenAI()
prompt = PromptTemplate.from_template("Who is {name}?")
chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
chain.run(name="Super Mario")

你应该得到如下输出:

​> Entering new LLMChain chain...
Prompt after formatting:
Who is Super Mario?
​
> Finished chain.
​
\n\nSuper Mario is the protagonist of the popular video game franchise of the same name created by Nintendo. He is a fictional character who stars in video games, television shows, comic books, and films. He is a plumber who is usually portrayed as a portly Italian-American, who is often accompanied by his brother Luigi. He is well known for his catchphrase "It\'s-a me, Mario!"

2.2 自定义处理器

我们可以通过继承 BaseCallbackHandler 来实现自定义的回调处理器。下面是一个简单的例子,TimerHandler 将跟踪 Chain 或 LLM 交互的起止时间,并统计每次交互的处理耗时。

from langchain.callbacks.base import BaseCallbackHandler
import time
​
class TimerHandler(BaseCallbackHandler):
​
    def __init__(self) -> None:
        super().__init__()
        self.previous_ms = None
        self.durations = []
​
    def current_ms(self):
        return int(time.time() * 1000 + time.perf_counter() % 1 * 1000)
​
    def on_chain_start(self, serialized, inputs, **kwargs) -> None:
        self.previous_ms = self.current_ms()
​
    def on_chain_end(self, outputs, **kwargs) -> None:
        if self.previous_ms:
          duration = self.current_ms() - self.previous_ms
          self.durations.append(duration)
​
    def on_llm_start(self, serialized, prompts, **kwargs) -> None:
        self.previous_ms = self.current_ms()
​
    def on_llm_end(self, response, **kwargs) -> None:
        if self.previous_ms:
          duration = self.current_ms() - self.previous_ms
          self.durations.append(duration)
​
llm = OpenAI()
timerHandler = TimerHandler()
prompt = PromptTemplate.from_template("What is the HEX code of color {color_name}?")
chain = LLMChain(llm=llm, prompt=prompt, callbacks=[timerHandler])
response = chain.run(color_name="blue")
print(response)
response = chain.run(color_name="purple")
print(response)
​
timerHandler.durations

你应该得到如下输出:

The HEX code for blue is #0000FF.
The HEX code of the color purple is #800080.
[1589, 1097]

第三部分:适用场景

通过 LLMChain 的构造函数参数设置 callbacks 仅仅是众多适用场景之一。接下来我们简明地列出其他使用场景和示例代码。

别走偏哦!前面我们介绍了回调处理器的场景,那我们对于 Model,Agent, Tool,以及 Chain 都可以通过以下方式设置回调处理器:

3.1 构造函数参数 callbacks 设置

关于 Chain,以 LLMChain 为例,请参考本讲上一部分内容。注意在 Chain 上的回调器监听的是 chain 相关的事件,因此回调器的如下函数会被调用:

1)on_chain_start

2)on_chain_end

3)on_chain_error

Agent, Tool,以及 Chain 上的回调器会分别被调用相应的回调函数。

下面分享关于 Model 与 callbacks 的使用示例:

timerHandler = TimerHandler()
llm = OpenAI(callbacks=[timerHandler])
response = llm.predict("What is the HEX code of color BLACK?")
print(response)
​
timerHandler.durations

你应该看到类似如下的输出:

['What is the HEX code of color BLACK?']
generations=[[Generation(text='\n\nThe hex code of black is #000000.', generation_info={'finish_reason': 'stop', 'logprobs': None})]] llm_output={'token_usage': {'prompt_tokens': 10, 'total_tokens': 21, 'completion_tokens': 11}, 'model_name': 'text-davinci-003'} run=None
​
​
The hex code of black is #000000.
​[1223]

3.2 通过运行时的函数调用

Model,Agent, Tool,以及 Chain 的请求执行函数都接受 callbacks 参数,比如 LLMChain 的 run 函数,OpenAI 的 predict 函数,等都能接受 callbacks 参数,在运行时指定回调处理器。

以 OpenAI 模型类为例:

timerHandler = TimerHandler()
llm = OpenAI()
response = llm.predict("What is the HEX code of color BLACK?", callbacks=[timerHandler])
print(response)
​
timerHandler.durations

你应该同样看到如下输出:

['What is the HEX code of color BLACK?']
generations=[[Generation(text='\n\nThe hex code of black is #000000.', generation_info={'finish_reason': 'stop', 'logprobs': None})]] llm_output={'token_usage': {'prompt_tokens': 10, 'total_tokens': 21, 'completion_tokens': 11}, 'model_name': 'text-davinci-003'} run=None
​
The hex code of black is #000000.
​
[1138]

关于 Agent,Tool 等的使用,请参考官方文档API。


作业部分!

跟着雄哥上面的代码,跑一个简单的实例,并且截图上来!

这是雄哥的colab地址(跑这里不算完成作业):

https://colab.research.google.com/drive/1ThngXhcwYlYeOlk8ausJNDyuyItFDlu_?usp=sharing

雄哥之前都说过,大模型落地有四种主流方法,LangChain就是其中之一(其他三种看下面)!

【先导篇】0基础大模型实战!开波!"这个老板真傻!吃饭的家伙都公开!

今天我们围绕落地一个LangChain应用为目标,展开一个为期10期的精讲!带大家0基础入门LangChain!

本篇是第八篇!整体内容框架和介绍如下:

【学前必看】0基础入门LangChain框架!手把手带你搭建全功能LLM应用+知识库!0/10

第一天:0基础学LangChain!价值20万!是什么?有什么用?1/10

第二天:0基础学LangChain!价值20万!跟大模型什么联系?两者是如何工作的?2/10

第三天:0基础学LangChain!价值20万!数据应该怎么处理?怎样做向量化?很干!很有用!3/10

第四天:玩转langchain!0基础做提示词模板+选择器!呆呆老板都学会了!

第五天:第五天!玩转langchain!0基础学输出解析器!

第六天:玩转langchain!链!非常重要!核心!把大模型们串联起来!一起工作!6/10

第七天:玩转langchain!记忆组件!如何将LLM中的历史对话组成链!如何查询?储存?7/10

第八天!玩转LangChain!让大模型自动推理工作?Agent就能实现了!8/10

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/1077689.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

电脑出现msvcp110.dll丢失的解决方法,快速解决msvcp110.dll丢失

电脑中经常会出现msvcp110.dll文件丢失的情况,所以如果电脑中缺失msvcp110.dll文件会让大家很苦恼,那么msvcp110.dll丢失有什么解决办法呢?今天就给大家介绍几种msvcp110.dll丢失的解决办法。 一.msvcp110.dll常出现的问题 1.当您尝试打开某…

Springcloud笔记(2)-Eureka服务注册

Eureka服务注册 服务注册,发现。 在Spring Cloud框架中,Eureka的核心作用是服务的注册和发现,并实现服务治理。 Eureka包含两个组件:Eureka Server和Eureka Client。 Eureka Server提供服务注册服务,各个节点启动后…

Spring AOP的失效场景

首先,Spring的AOP其实是通过动态代理实现的,所以,想要让AOP生效,前提必须是动态代理生效,并且可以调用到代理对象的方法什么情况下会不走代理对象的调用呢?首先就是类内部的调用,比如一些私有方…

中国人民大学与加拿大女王大学金融硕士——不忘初心,点燃梦想之火

人类所具有的种种力量中,最神奇的莫过于梦想的力量。梦想使人生更有意义,是人类的先锋,是前进的引路人。有梦想,才会有希望,才会激发我们内在的潜能,努力去求得光明的前途。让我们点燃梦想之火,…

Linux系统切换用户后只显示$问题解决

问题描述: unbantu操作系统切换为es用户后没有tab键没有补全功能 问题分析 创建用户的时候未指定shell类型,默认的shell为/bin/sh,而不是/bin/bash。 cat /etc/passwd查询结果 es:x:1001:1001::/home/es:/bin/sh解决方案 把对应用户的…

【Mysql实现递归树查询】

Mysql8实现递归查询 递归执行分析demo数据查询demo数据扩展字段扩展 大家好! 在我们日常工作中,经常会遇到一些问题,它们的一些解决方案通常会用到递归这一强大的技术手段。递归不仅能帮助我们更高效的解决问题,还可以使代码更简介、更易于理解, 今天我来给大家分享…

Can 通信-协议

概述 CAN 是 Controller Area Network 的缩写(以下称为 CAN),是 ISO国际标准化的串行通信协议。 在当前的汽车产业中,出于对安全性、舒适性、方便性、低公害、低成本的要求,各种各样的电子控制系统 被开发了出来。由于…

Spring中shutdown hook作用

在Spring框架中,Shutdown Hook(关闭钩子)是一种机制,用于在应用程序关闭时执行一些清理操作Spring会向JVM注册一个shutdown hook,在接收到关闭通知的时候,进行bean的销毁,容器的销毁处理等操作在…

代码随想录算法训练营第23期day17| 110.平衡二叉树、257. 二叉树的所有路径、404.左叶子之和

目录 一、(leetcode 110)平衡二叉树 二、(leetcode 257)二叉树的所有路径 三、(leetcode 404)左叶子之和 一、(leetcode 110)平衡二叉树 力扣题目链接 状态:已AC 求深…

【Qt】三种方式实现抽奖小游戏

简介 本文章是基本Qt与C实现一个抽奖小游戏,用到的知识点在此前发布的几篇文章。 下面是跳转链接: 【Qt控件之QLabel】用法及技巧链接: https://blog.csdn.net/MrHHHHHH/article/details/133691441?spm1001.2014.3001.5501 【Qt控件之QPus…

C++ 类和对象(一)

1.面向过程和面向对象初步认识 C语言是面向过程的,关注的是过程,分析出求解问题的步骤,通过函数调用逐步解决问题。 C是基于面向对象的,关注的是对象,将一件事情拆分成不同的对象,靠对象之间的交互完 成。 …

启山智软/商城源码

提示:文章写完后,目录可以自动生成,如何生成可参考右边的帮助文档 文章目录 启山智软一、五种商业模式赋能1.S2B2C供应链商城2.B2B2C多商户商城3.B2C单商户商城4.O2O外卖配送5.社区团购 二、过硬的编程实力1.前端2.后端 总结 启山智软 想要了…

【【萌新的SOC学习之AXI接口简介】】

萌新的SOC学习之AXI接口简介 AXI总线的初步介绍 AXI 总线是 ARM AMBA 一部分 (高级可扩展接口) AMBA(高级微控制器总线架构) :开放的片内互联的总线标准,能再多主机设计中实现多个控制器和外围设备之间的连接和管理。…

配置Hive使用Spark执行引擎

配置Hive使用Spark执行引擎 Hive引擎概述兼容问题安装SparkSpark配置Hive配置HDFS上传Spark的jar包执行测试速度对比 Hive引擎 概述 在Hive中,可以通过配置来指定使用不同的执行引擎。Hive执行引擎包括:默认MR、tez、spark MapReduce引擎: 早…

利用excel表格进行分包和组包

实际使用中,我们可能希望修改某几个数据之后,最终的数据包能够自动发动数据,类似于在给结构体变量修改数据,自动生成完整的结构体; excel语法 1:拆分数据 LEFT(A4,2) – 取A4单元格左边的两个数据 RIGHT(A4…

4.02 用户中心-上传头像功能开发

详细内容请看下面地址: 地址:http://www.gxcode.top/code

【JavaScript】浅拷贝与深拷贝

引言 浅拷贝、深拷贝是对引用类型而言的。 引用类型的变量对应一个栈区地址,这个栈区地址处存储的值是存放的真正的数据的堆区地址。 基本数据类型的变量也对应一个栈区地址,但是该地址存储的是其真正的值。 let a b发生了什么? let obj…

MAX30102心率血氧传感器

MAX30102心率血氧传感器介绍 背景基本功能基本结构基本原理采集方法直通式采集方法反射式采集方法 血氧采集原理Beer-Lambert 定理皮肤组织模型血氧测量过程AC / DC 的计算 心率采集原理 实验结果代码走读资源链接 背景 目前,基本上所有的可穿戴式设备都集成了心率…

leetcode:190. 颠倒二进制位

一、题目: 函数原型: uint32_t reverseBits(uint32_t n) 解释:uint32是无符号int或short的别称,传入的参数是一个32位二进制串,返回值是该32位二进制串逆序后的十进制值 二、思路: 实际上并不需要真的去逆…

竞赛 深度学习 YOLO 实现车牌识别算法

文章目录 0 前言1 课题介绍2 算法简介2.1网络架构 3 数据准备4 模型训练5 实现效果5.1 图片识别效果5.2视频识别效果 6 部分关键代码7 最后 0 前言 🔥 优质竞赛项目系列,今天要分享的是 🚩 基于yolov5的深度学习车牌识别系统实现 该项目较…