How to attach callbacks to a runnable
Source: langchain

# How to attach callbacks to a runnable:::info PrerequisitesThis guide assumes familiarity with the following concepts:- [Callbacks](/docs/concepts/#callbacks)- [Custom callback handlers](/docs/how_to/custom_callbacks)- [Chaining runnables](/docs/how_to/sequence)- [Attach runtime arguments to a Runnable](/docs/how_to/binding):::If you are composing a chain of runnables and want to reuse callbacks across multiple executions, you can attach callbacks with the [`.with_config()`](https://python.langchain.com/v0.2/api_reference/core/runnables/langchain_core.runnables.base.Runnable.html#langchain_core.runnables.base.Runnable.with_config) method. This saves you the need to pass callbacks in each time you invoke the chain.:::{.callout-important}`with_config()` binds a configuration which will be interpreted as **runtime** configuration. So these callbacks will propagate to all child components.:::Here's an example:```python# | output: false# | echo: false%pip install -qU langchain langchain_anthropicimport getpassimport osos.environ["ANTHROPIC_API_KEY"] = getpass.getpass()``````pythonfrom typing import Any, Dict, Listfrom langchain_anthropic import ChatAnthropicfrom langchain_core.callbacks import BaseCallbackHandlerfrom langchain_core.messages import BaseMessagefrom langchain_core.outputs import LLMResultfrom langchain_core.prompts import ChatPromptTemplateclass LoggingHandler(BaseCallbackHandler):    def on_chat_model_start(        self, serialized: Dict[str, Any], messages: List[List[BaseMessage]], **kwargs    ) -> None:        print("Chat model started")    def on_llm_end(self, response: LLMResult, **kwargs) -> None:        print(f"Chat model ended, response: {response}")    def on_chain_start(        self, serialized: Dict[str, Any], inputs: Dict[str, Any], **kwargs    ) -> None:        print(f"Chain {serialized.get('name')} started")    def on_chain_end(self, outputs: Dict[str, Any], **kwargs) -> None:        print(f"Chain ended, outputs: {outputs}")callbacks = [LoggingHandler()]llm = ChatAnthropic(model="claude-3-sonnet-20240229")prompt = ChatPromptTemplate.from_template("What is 1 + {number}?")chain = prompt | llmchain_with_callbacks = chain.with_config(callbacks=callbacks)chain_with_callbacks.invoke({"number": "2"})```    Chain RunnableSequence started    Chain ChatPromptTemplate started    Chain ended, outputs: messages=[HumanMessage(content='What is 1 + 2?')]    Chat model started    Chat model ended, response: generations=[[ChatGeneration(text='1 + 2 = 3', message=AIMessage(content='1 + 2 = 3', response_metadata={'id': 'msg_01NTYMsH9YxkoWsiPYs4Lemn', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 16, 'output_tokens': 13}}, id='run-d6bcfd72-9c94-466d-bac0-f39e456ad6e3-0'))]] llm_output={'id': 'msg_01NTYMsH9YxkoWsiPYs4Lemn', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 16, 'output_tokens': 13}} run=None    Chain ended, outputs: content='1 + 2 = 3' response_metadata={'id': 'msg_01NTYMsH9YxkoWsiPYs4Lemn', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 16, 'output_tokens': 13}} id='run-d6bcfd72-9c94-466d-bac0-f39e456ad6e3-0'    AIMessage(content='1 + 2 = 3', response_metadata={'id': 'msg_01NTYMsH9YxkoWsiPYs4Lemn', 'model': 'claude-3-sonnet-20240229', 'stop_reason': 'end_turn', 'stop_sequence': None, 'usage': {'input_tokens': 16, 'output_tokens': 13}}, id='run-d6bcfd72-9c94-466d-bac0-f39e456ad6e3-0')The bound callbacks will run for all nested module runs.## Next stepsYou've now learned how to attach callbacks to a chain.Next, check out the other how-to guides in this section, such as how to [pass callbacks in at runtime](/docs/how_to/callbacks_runtime).