核心模块(Modules)
回调(Callbacks)
索引(Index)

回调(Callbacks)

注意:关于与第三方工具的内置回调集成,请前往 集成 (opens in a new tab)。

LangChain 提供了一个回调系统,允许你挂钩到 LLM 应用的各个阶段。这对于日志记录、监控、流式输出和其他任务都很有用。

你可以通过整个 API 中可用的 callbacks 参数来订阅这些事件。该参数是处理程序对象的列表,这些对象预期实现下文更详细描述的一个或多个方法。

回调处理程序

CallbackHandler 是实现 CallbackHandler 接口的对象,该接口为每个可订阅的事件都提供了一个方法。当事件被触发时,CallbackManager 会在每个处理程序上调用相应的方法。

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: Any, **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 提供了几个内置处理程序供你入门。它们位于 langchain_core/callbacks 模块中。最基本的处理程序是 StdOutCallbackHandler,它只是把所有事件记录到 stdout。

注意:当对象上的 verbose 标志设置为 true 时,即使没有显式传入,StdOutCallbackHandler 也会被调用。

from langchain_core.callbacks import StdOutCallbackHandler
from langchain.chains import LLMChain
from langchain_openai import OpenAI
from langchain_core.prompts import PromptTemplate
 
handler = StdOutCallbackHandler()
llm = OpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")
 
# 构造函数回调:首先,让我们在初始化链时显式设置 StdOutCallbackHandler
chain = LLMChain(llm=llm, prompt=prompt, callbacks=[handler])
chain.invoke({"number":2})
 
# 使用 verbose 标志:然后,让我们使用 `verbose` 标志来达到相同结果
chain = LLMChain(llm=llm, prompt=prompt, verbose=True)
chain.invoke({"number":2})
 
# 请求回调:最后,让我们使用请求 `callbacks` 来达到相同结果
chain = LLMChain(llm=llm, prompt=prompt)
chain.invoke({"number":2}, {"callbacks":[handler]})
 
> Entering new LLMChain chain...
Prompt after formatting:
1 + 2 = 

> Finished chain.


> Entering new LLMChain chain...
Prompt after formatting:
1 + 2 = 

> Finished chain.


> Entering new LLMChain chain...
Prompt after formatting:
1 + 2 = 

> Finished chain.

在哪里传入回调

整个 API 中的大多数对象(链、模型、工具、代理等)都可以在两个不同的地方使用 callbacks:

  • 构造函数回调:在构造函数中定义,例如 LLMChain(callbacks=[handler], tags=['a-tag'])。在这种情况下,回调将用于在该对象上进行的所有调用,并且只作用于该对象。例如,如果你向 LLMChain 构造函数传入一个处理程序,它不会被子链所挂接的模型使用。
  • 请求回调:在用于发出请求的 'invoke' 方法中定义。在这种情况下,回调只用于该特定请求以及它包含的所有子请求(例如,对 LLMChain 的调用会触发对模型的调用,后者使用传入 invoke() 方法的同一个处理程序)。在 invoke() 方法中,回调通过 config 参数传入。 使用 'invoke' 方法的示例(注意:batch、ainvoke 和 abatch 方法也可以使用相同的方式):
handler = StdOutCallbackHandler()
llm = OpenAI()
prompt = PromptTemplate.from_template("1 + {number} = ")
 
config = {
    'callbacks' : [handler]
}
 
chain = prompt | chain
chain.invoke({"number":2}, config=config)

注意: chain = prompt | chain 等价于 chain = LLMChain(llm=llm, prompt=prompt)(更多细节请查看 LangChain 表达式语言(LCEL)文档)

verbose 参数在 API 中的大多数对象(链、模型、工具、代理等)上都可以作为构造函数参数使用,例如 LLMChain(verbose=True),它等价于向该对象及所有子对象的 callbacks 参数传入一个 ConsoleCallbackHandler。这对于调试很有用,因为它会把所有事件记录到控制台。

什么时候该用哪种方式?

  • 构造函数回调最适合日志记录、监控等场景,这些场景_并非针对单个请求_,而是针对整个链。例如,如果你想记录对某个 LLMChain 发出的所有请求,你会向构造函数传入一个处理程序。
  • 请求回调最适合流式输出等场景,你希望把单个请求的输出流式传输到特定的 websocket 连接,或其他类似场景。例如,如果你想将单个请求的输出流式传输到 websocket,你会向 invoke() 方法传入一个处理程序。