[LangChain] 23. 回调机制

invoke/stream() 方法,方法签名如下:

invoke/stream(
  input: Input,
  options?: RunnableConfig
): AsyncGenerator<StreamEvent<Output>>

1. 输入参数 (input)

类型:Input

invoke() 方法保持一致:

  • 如果是 LLM:可以传字符串、BaseMessageBaseMessage[]
  • 如果是 Chain / Runnable:则是该 Chain 约定的输入对象(例如 { input: "..." }
  • 如果是 Embeddings:通常是字符串或字符串数组

换句话说,input 的类型由具体的 Runnable 实例 决定。

2. 配置参数

类型:RunnableConfig(可选)
常见字段包括:

  • configurable:运行时传入的上下文配置(例如用户 ID、对话 ID,用于内存/持久化关联)。
  • tags:给运行标记,用于调试、Tracing。
  • metadata:附加元信息,方便日志或监控。
  • callbacks:传入回调函数(如 handleLLMNewToken 等),可用于实时处理 token。类似于生命周期钩子方法。
  • maxConcurrency:并发控制。
  • timeout:超时设置。

对具体模型(如 ChatOpenAI)而言,它的 CallOptions 还会扩展出模型厂商特定的调用参数(例如 stoptools 等)。

callbacks 配置项对应的值是一个「回调对象数组」,允许你监听和响应模型执行过程中的关键事件。

{
  callbacks: [
    {
      handleLLMStart(llm, prompts) {
        console.log("模型开始运行", prompts);
      },
      handleLLMEnd(output) {
        console.log("模型运行完成", output);
      },
      handleLLMError(error) {
        console.error("模型出错", error);
      },
    }
  ]
}

这些对象中的函数就是回调钩子方法,每个钩子对应一个事件点:

钩子函数名 触发时机 说明
handleLLMStart(llm, prompts) 模型开始调用前 llm 为当前模型实例,prompts 是输入
handleLLMEnd(output) 模型生成成功返回结果时 output 是一个 LLMResult 对象
handleLLMError(error) 模型调用出错时 error 为异常对象
handleLLMNewToken 生成新token的时候 流式响应模式下,每个 token 输出时

课堂演示

演示 callbacks 的使用

import { ChatOpenAI } from "@langchain/openai";
import dotenv from "dotenv";
dotenv.config();
import { fileLoggingHandler } from "./fileLog.js";
import { consoleLoggingHandler } from "./consoleLog.js";

const llm = new ChatOpenAI({
  model: "gpt-4o-mini",
  temperature: 0,
  apiKey: process.env.API_KEY,
  streaming: true,
});

const stream = await llm.stream("你好", {
  callbacks: [
    fileLoggingHandler,
    consoleLoggingHandler,
  ],
});

for await (const chunk of stream) {
  process.stdout.write(chunk.content);
}
export const consoleLoggingHandler = {
  handleLLMStart() {
    console.log("模型即将开始运行...");
  },

  handleLLMEnd() {
    console.log("模型输出已完成。");
  },

  handleLLMError(err) {
    console.error("模型执行出错:", err.message);
  },
};
export const consoleLoggingHandler = {
  handleLLMStart() {
    console.log("模型即将开始运行...");
  },

  handleLLMEnd() {
    console.log("模型输出已完成。");
  },

  handleLLMError(err) {
    console.error("模型执行出错:", err.message);
  },
};

除了上面介绍的这些钩子方法以外,常用的钩子方法还有这些:

钩子名称 触发时机 典型用途
handleLLMStart 模型开始执行前 打印提示、启动计时器
handleLLMEnd 模型生成结束后 打印结果、计算时长
handleLLMError 模型执行中出错 捕获错误、上报日志
handleToolStart 工具调用前 查看参数、记录调用链
handleToolEnd 工具调用成功返回后 打印输出
handleChainStart 链条开始运行前 输出入口信息
handleChainEnd 链条运行完成 打印最终输出、分析执行树

插件化处理

可以将其做成一个插件,这样更清晰、可复用性更强。

posted @ 2025-11-26 22:54  Zhentiw  阅读(11)  评论(0)    收藏  举报