掘金 人工智能 前天 15:58
LangChain篇-自定义Callback组件
index_new5.html
../../../zaker_core/zaker_tpl_static/wap/tpl_guoji1.html

 

本文深入探讨了LangChain的回调系统,这是一个强大的工具,允许开发者连接到LLM应用程序的各个阶段。通过使用回调,可以实现日志记录、监控、流式处理等功能,极大地增强了LLM应用的灵活性和可定制性。文章详细介绍了回调事件、回调处理程序以及如何传递和自定义回调函数,提供了丰富的示例代码,帮助读者理解并应用这一关键特性。

💡LangChain的回调系统允许用户订阅LLM应用程序中的各种事件,例如模型启动、新token生成、链的开始与结束等。通过这种方式,开发者可以对LLM的运行过程进行细粒度的控制和监控。

🔑回调处理程序是实现了CallbackHandler接口的对象,它们定义了在特定事件触发时应该执行的操作。开发者可以创建自定义的回调处理程序,以实现特定的逻辑,如日志记录或性能监控。

🚀回调函数可以通过构造函数或请求的invoke方法传递。构造函数回调适用于对整个对象进行全局设置,而请求回调则允许针对特定的调用进行定制。在运行时传递回调函数提供了更大的灵活性。

🛠️文章提供了创建自定义回调处理程序的示例,展示了如何通过处理on_llm_new_token事件来实现流式处理。这演示了如何利用回调系统来扩展LangChain的功能,满足各种应用需求。

一、回调概念

LangChain 提供了一个回调系统,允许您连接到 LLM 应用程序的各个阶段。这对于日志记录、监控、流式处理和其他任务非常有用。 您可以通过使用 API 中的 callbacks 参数订阅这些事件。这个参数是处理程序对象的列表,这些处理程序对象应该实现下面更详细描述的一个或多个方法。

二、回调事件(Callback Events)

EventEvent TriggerAssociated Method
Chat model startWhen a chat model startson_chat_model_start
LLM startWhen a llm startson_llm_start
LLM new tokenWhen an llm OR chat model emits a new tokenon_llm_new_token
LLM endsWhen an llm OR chat model endson_llm_end
LLM errorsWhen an llm OR chat model errorson_llm_error
Chain startWhen a chain starts runningon_chain_start
Chain endWhen a chain endson_chain_end
Chain errorWhen a chain errorson_chain_error
Tool startWhen a tool starts runningon_tool_start
Tool endWhen a tool endson_tool_end
Tool errorWhen a tool errorson_tool_error
Agent actionWhen an agent takes an actionon_agent_action
Agent finishWhen an agent endson_agent_finish
Retriever startWhen a retriever startson_retriever_start
Retriever endWhen a retriever endson_retriever_end
Retriever errorWhen a retriever errorson_retriever_error
TextWhen arbitrary text is runon_text
RetryWhen a retry event is runon_retry

三、回调处理程序

CallbackHandlers 是实现了 CallbackHandler 接口的对象,该接口对应于可以订阅的每个事件都有一个方法。 当事件触发时,CallbackManager 将在每个处理程序上调用适当的方法。

参考:api.python.langchain.com/en/latest/c…

 #示例:callback_run.pyclass BaseCallbackHandler:    """可以用来处理langchain回调的基本回调处理程序。"""    def on_llm_start(        self, serialized: Dict[str, Any], prompts: List[str], **kwargs: Any    ) -> Any:        """LLM开始运行时运行。"""    def on_chat_model_start(        self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs: Any    ) -> Any:        """聊天模型开始运行时运行。"""    # 其他方法省略... 

四、传递回调函数

callbacks 属性在 API 的大多数对象(模型、工具、代理等)中都可用,在两个不同的位置上:

五、在运行时传递回调函数

许多情况下,当运行对象时,传递处理程序而不是回调函数会更有优势。当我们在执行运行时使用 callbacks 关键字参数传递 CallbackHandlers 时,这些回调函数将由执行中涉及的所有嵌套对象发出。例如,当通过一个处理程序传递给一个代理时,它将用于与代理相关的所有回调以及代理执行中涉及的所有对象,即工具和 LLM。

这样可以避免我们手动将处理程序附加到每个单独的嵌套对象上。以下是一个示例:

 # 示例:callback_run.py# 导入所需的类型提示和类from typing import Any, Dict, Listfrom langchain_core.callbacks import BaseCallbackHandlerfrom langchain_core.messages import BaseMessagefrom langchain_core.outputs import LLMResultfrom langchain_core.prompts import ChatPromptTemplatefrom langchain_openai import ChatOpenAI# 定义一个日志处理器类,继承自BaseCallbackHandlerclass LoggingHandler(BaseCallbackHandler):    # 当聊天模型开始时调用的方法    def on_chat_model_start(            self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs    ) -> None:        print("Chat model started")  # 打印“Chat model started”        # 当LLM结束时调用的方法    def on_llm_end(self, response: LLMResult, **kwargs) -> None:        print(f"Chat model ended, response: {response}")  # 打印“Chat model ended, response: {response}”            # 当链开始时调用的方法    def on_chain_start(            self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs) -> None:        print(f"Chain started, inputs:{inputs}")  # 打印“Chain {serialized.get('name')} started”            # 当链结束时调用的方法    def on_chain_end(            self, outputs: Dict[str, Any], **kwargs) -> None:        print(f"Chain ended, outputs: {outputs}")  # 打印“Chain ended, outputs: {outputs}”        # 创建一个包含LoggingHandler实例的回调列表callbacks = [LoggingHandler()]# 实例化一个ChatOpenAI对象,使用gpt-4模型llm = ChatOpenAI(model="gpt-4")# 创建一个聊天提示模板,模板内容为“What is 1 + {number}?”prompt = ChatPromptTemplate.from_template("What is 1 + {number}?")# 将提示模板和LLM组合成一个链chain = prompt | llm# 调用链的invoke方法,传入参数number为"2",并配置回调chain.invoke({"number": "2"}, config={"callbacks": callbacks})
Chain started, inputs:{'number': '2'}Chain started, inputs:{'number': '2'}Chain ended, outputs: messages=[HumanMessage(content='What is 1 + 2?', additional_kwargs={}, response_metadata={})]Chat model startedChat model ended, response: generations=[[ChatGeneration(text='3', generation_info={'finish_reason': 'stop', 'logprobs': None}, message=AIMessage(content='3', additional_kwargs={'refusal': None}, response_metadata={'token_usage': {'completion_tokens': 1, 'prompt_tokens': 15, 'total_tokens': 16, 'completion_tokens_details': {'audio_tokens': None, 'reasoning_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-4-0613', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None}, id='run-48925f3f-9bbf-4f13-8d48-b76757ffac32-0', usage_metadata={'input_tokens': 15, 'output_tokens': 1, 'total_tokens': 16, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 0}}))]] llm_output={'token_usage': {'completion_tokens': 1, 'prompt_tokens': 15, 'total_tokens': 16, 'completion_tokens_details': {'audio_tokens': None, 'reasoning_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-4-0613', 'system_fingerprint': None} run=None type='LLMResult'Chain ended, outputs: content='3' additional_kwargs={'refusal': None} response_metadata={'token_usage': {'completion_tokens': 1, 'prompt_tokens': 15, 'total_tokens': 16, 'completion_tokens_details': {'audio_tokens': None, 'reasoning_tokens': 0}, 'prompt_tokens_details': {'audio_tokens': None, 'cached_tokens': 0}}, 'model_name': 'gpt-4-0613', 'system_fingerprint': None, 'finish_reason': 'stop', 'logprobs': None} id='run-48925f3f-9bbf-4f13-8d48-b76757ffac32-0' usage_metadata={'input_tokens': 15, 'output_tokens': 1, 'total_tokens': 16, 'input_token_details': {'cache_read': 0}, 'output_token_details': {'reasoning': 0}}

六、自定义 callback handlers 自定义 Chat model

LangChain 具有一些内置的回调处理程序,但通常您会希望创建具有自定义逻辑的自定义处理程序。

要创建自定义回调处理程序,我们需要确定我们希望处理的 event(s),以及在触发事件时我们希望回调处理程序执行的操作。然后,我们只需将回调处理程序附加到对象上,例如通过构造函数运行时

在下面的示例中,我们将使用自定义处理程序实现流式处理。

在我们的自定义回调处理程序 MyCustomHandler 中,我们实现了 on_llm_new_token 处理程序,以打印我们刚收到的令牌。然后,我们将自定义处理程序作为构造函数回调附加到模型对象上。

 # 示例:callback_process.pyfrom langchain_openai import ChatOpenAIfrom langchain_core.callbacks import BaseCallbackHandlerfrom langchain_core.prompts import ChatPromptTemplateclass MyCustomHandler(BaseCallbackHandler):    def on_llm_new_token(self, token: str, **kwargs) -> None:        print(f"My custom handler, token: {token}")        prompt = ChatPromptTemplate.from_messages(["给我讲个关于{animal}的笑话,限制20个字"])# 为启用流式处理,我们在ChatModel构造函数中传入`streaming=True`# 另外,我们将自定义处理程序作为回调参数的列表传入model = ChatOpenAI(    model="gpt-4", streaming=True, callbacks=[MyCustomHandler()])chain = prompt | modelresponse = chain.invoke({"animal": "猫"})print(response.content)
My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: :"My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: "My custom handler, token:  主My custom handler, token: 人My custom handler, token: 摇My custom handler, token: 头My custom handler, token: ,My custom handler, token: 猫My custom handler, token: 说My custom handler, token: :"My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: 'My custom handler, token: 喵My custom handler, token: 'My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: My custom handler, token: "My custom handler, token: 猫对主人说:"你知道我为什么不笑吗?" 主人摇头,猫说:"因为我是'喵'星人,不是笑星人。"

可以查看此参考页面以获取您可以处理的事件列表。请注意,handle_chain_* 事件适用于大多数 LCEL 可运行对象。

api.python.langchain.com/en/latest/c…

Fish AI Reader

Fish AI Reader

AI辅助创作,多种专业模板,深度分析,高质量内容生成。从观点提取到深度思考,FishAI为您提供全方位的创作支持。新版本引入自定义参数,让您的创作更加个性化和精准。

FishAI

FishAI

鱼阅,AI 时代的下一个智能信息助手,助你摆脱信息焦虑

联系邮箱 441953276@qq.com

相关标签

LangChain 回调系统 LLM 回调处理程序
相关文章