Skip to main content

How to attach callbacks to a module

Prerequisites

This guide assumes familiarity with the following concepts:

If you are composing a chain of runnables and want to reuse callbacks across multiple executions, you can attach callbacks with the .withConfig() method. This saves you the need to pass callbacks in each time you invoke the chain.

Here’s an example using LangChain’s built-in ConsoleCallbackHandler:

import { ConsoleCallbackHandler } from "@langchain/core/tracers/console";
import { ChatPromptTemplate } from "@langchain/core/prompts";
import { ChatAnthropic } from "@langchain/anthropic";

const handler = new ConsoleCallbackHandler();

const prompt = ChatPromptTemplate.fromTemplate(`What is 1 + {number}?`);
const model = new ChatAnthropic({
model: "claude-3-sonnet-20240229",
});

const chainWithCallbacks = prompt.pipe(model).withConfig({
callbacks: [handler],
});

await chainWithCallbacks.invoke({ number: "2" });
[chain/start] [1:chain:RunnableSequence] Entering Chain run with input: {
"number": "2"
}
[chain/start] [1:chain:RunnableSequence > 2:prompt:ChatPromptTemplate] Entering Chain run with input: {
"number": "2"
}
[chain/end] [1:chain:RunnableSequence > 2:prompt:ChatPromptTemplate] [1ms] Exiting Chain run with output: {
"lc": 1,
"type": "constructor",
"id": [
"langchain_core",
"prompt_values",
"ChatPromptValue"
],
"kwargs": {
"messages": [
{
"lc": 1,
"type": "constructor",
"id": [
"langchain_core",
"messages",
"HumanMessage"
],
"kwargs": {
"content": "What is 1 + 2?",
"additional_kwargs": {},
"response_metadata": {}
}
}
]
}
}
[llm/start] [1:chain:RunnableSequence > 3:llm:ChatAnthropic] Entering LLM run with input: {
"messages": [
[
{
"lc": 1,
"type": "constructor",
"id": [
"langchain_core",
"messages",
"HumanMessage"
],
"kwargs": {
"content": "What is 1 + 2?",
"additional_kwargs": {},
"response_metadata": {}
}
}
]
]
}
[llm/end] [1:chain:RunnableSequence > 3:llm:ChatAnthropic] [797ms] Exiting LLM run with output: {
"generations": [
[
{
"text": "1 + 2 = 3",
"message": {
"lc": 1,
"type": "constructor",
"id": [
"langchain_core",
"messages",
"AIMessage"
],
"kwargs": {
"content": "1 + 2 = 3",
"tool_calls": [],
"invalid_tool_calls": [],
"additional_kwargs": {
"id": "msg_01WvZAqTg2hZzC4AKyeUaADs",
"type": "message",
"role": "assistant",
"model": "claude-3-sonnet-20240229",
"stop_sequence": null,
"usage": {
"input_tokens": 16,
"output_tokens": 13
},
"stop_reason": "end_turn"
},
"response_metadata": {
"id": "msg_01WvZAqTg2hZzC4AKyeUaADs",
"model": "claude-3-sonnet-20240229",
"stop_sequence": null,
"usage": {
"input_tokens": 16,
"output_tokens": 13
},
"stop_reason": "end_turn"
}
}
}
}
]
],
"llmOutput": {
"id": "msg_01WvZAqTg2hZzC4AKyeUaADs",
"model": "claude-3-sonnet-20240229",
"stop_sequence": null,
"usage": {
"input_tokens": 16,
"output_tokens": 13
},
"stop_reason": "end_turn"
}
}
[chain/end] [1:chain:RunnableSequence] [806ms] Exiting Chain run with output: {
"lc": 1,
"type": "constructor",
"id": [
"langchain_core",
"messages",
"AIMessage"
],
"kwargs": {
"content": "1 + 2 = 3",
"tool_calls": [],
"invalid_tool_calls": [],
"additional_kwargs": {
"id": "msg_01WvZAqTg2hZzC4AKyeUaADs",
"type": "message",
"role": "assistant",
"model": "claude-3-sonnet-20240229",
"stop_sequence": null,
"usage": {
"input_tokens": 16,
"output_tokens": 13
},
"stop_reason": "end_turn"
},
"response_metadata": {
"id": "msg_01WvZAqTg2hZzC4AKyeUaADs",
"model": "claude-3-sonnet-20240229",
"stop_sequence": null,
"usage": {
"input_tokens": 16,
"output_tokens": 13
},
"stop_reason": "end_turn"
}
}
}
AIMessage {
lc_serializable: true,
lc_kwargs: {
content: "1 + 2 = 3",
tool_calls: [],
invalid_tool_calls: [],
additional_kwargs: {
id: "msg_01WvZAqTg2hZzC4AKyeUaADs",
type: "message",
role: "assistant",
model: "claude-3-sonnet-20240229",
stop_sequence: null,
usage: { input_tokens: 16, output_tokens: 13 },
stop_reason: "end_turn"
},
response_metadata: {}
},
lc_namespace: [ "langchain_core", "messages" ],
content: "1 + 2 = 3",
name: undefined,
additional_kwargs: {
id: "msg_01WvZAqTg2hZzC4AKyeUaADs",
type: "message",
role: "assistant",
model: "claude-3-sonnet-20240229",
stop_sequence: null,
usage: { input_tokens: 16, output_tokens: 13 },
stop_reason: "end_turn"
},
response_metadata: {
id: "msg_01WvZAqTg2hZzC4AKyeUaADs",
model: "claude-3-sonnet-20240229",
stop_sequence: null,
usage: { input_tokens: 16, output_tokens: 13 },
stop_reason: "end_turn"
},
tool_calls: [],
invalid_tool_calls: []
}

The bound callbacks will run for all nested module runs.

Next steps

You’ve now learned how to bind callbacks to a chain.

Next, check out the other how-to guides in this section, such as how to create your own custom callback handlers.


Was this page helpful?


You can leave detailed feedback on GitHub.