Skip to content

docs[patch]: Adds callback docs #5469

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 4 commits into from
May 19, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
10 changes: 10 additions & 0 deletions docs/core_docs/.gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -129,6 +129,8 @@ docs/how_to/example_selectors.md
docs/how_to/example_selectors.mdx
docs/how_to/custom_tools.md
docs/how_to/custom_tools.mdx
docs/how_to/custom_callbacks.md
docs/how_to/custom_callbacks.mdx
docs/how_to/code_splitter.md
docs/how_to/code_splitter.mdx
docs/how_to/chatbots_tools.md
Expand All @@ -141,6 +143,14 @@ docs/how_to/chat_streaming.md
docs/how_to/chat_streaming.mdx
docs/how_to/character_text_splitter.md
docs/how_to/character_text_splitter.mdx
docs/how_to/callbacks_runtime.md
docs/how_to/callbacks_runtime.mdx
docs/how_to/callbacks_constructor.md
docs/how_to/callbacks_constructor.mdx
docs/how_to/callbacks_binding.md
docs/how_to/callbacks_binding.mdx
docs/how_to/callbacks_backgrounding.md
docs/how_to/callbacks_backgrounding.mdx
docs/how_to/binding.md
docs/how_to/binding.mdx
docs/how_to/assign.md
Expand Down
85 changes: 85 additions & 0 deletions docs/core_docs/docs/concepts.mdx
Original file line number Diff line number Diff line change
Expand Up @@ -507,6 +507,91 @@ In order to solve that we built LangGraph to be this flexible, highly-controllab
If you are still using AgentExecutor, do not fear: we still have a guide on [how to use AgentExecutor](/docs/how_to/agent_executor).
It is recommended, however, that you start to transition to [LangGraph](https://github.com/langchain-ai/langgraphjs).

### Callbacks

LangChain provides a callbacks system that allows you to hook into the various stages of your LLM application. This is useful for logging, monitoring, streaming, and other tasks.

You can subscribe to these events by using the `callbacks` argument available throughout the API. This argument is list of handler objects, which are expected to implement one or more of the methods described below in more detail.

#### Callback handlers

`CallbackHandlers` are objects that implement the [`CallbackHandler`](https://api.js.langchain.com/interfaces/langchain_core_callbacks_base.CallbackHandlerMethods.html) interface, which has a method for each event that can be subscribed to.
The `CallbackManager` will call the appropriate method on each handler when the event is triggered.

```ts
interface CallbackHandlerMethods {
handleAgentAction?(action, runId, parentRunId?, tags?): void | Promise<void>;
handleAgentEnd?(action, runId, parentRunId?, tags?): void | Promise<void>;
handleChainEnd?(outputs, runId, parentRunId?, tags?, kwargs?): any;
handleChainError?(err, runId, parentRunId?, tags?, kwargs?): any;
handleChainStart?(
chain,
inputs,
runId,
parentRunId?,
tags?,
metadata?,
runType?,
name?
): any;
handleChatModelStart?(
llm,
messages,
runId,
parentRunId?,
extraParams?,
tags?,
metadata?,
name?
): any;
handleLLMEnd?(output, runId, parentRunId?, tags?): any;
handleLLMError?(err, runId, parentRunId?, tags?): any;
handleLLMNewToken?(token, idx, runId, parentRunId?, tags?, fields?): any;
handleLLMStart?(
llm,
prompts,
runId,
parentRunId?,
extraParams?,
tags?,
metadata?,
name?
): any;
handleRetrieverEnd?(documents, runId, parentRunId?, tags?): any;
handleRetrieverError?(err, runId, parentRunId?, tags?): any;
handleRetrieverStart?(
retriever,
query,
runId,
parentRunId?,
tags?,
metadata?,
name?
): any;
handleText?(text, runId, parentRunId?, tags?): void | Promise<void>;
handleToolEnd?(output, runId, parentRunId?, tags?): any;
handleToolError?(err, runId, parentRunId?, tags?): any;
handleToolStart?(
tool,
input,
runId,
parentRunId?,
tags?,
metadata?,
name?
): any;
}
```

#### Passing callbacks

The `callbacks` property is available on most objects throughout the API (Models, Tools, Agents, etc.) in two different places:

- **Constructor callbacks**: defined in the constructor, e.g. `new ChatAnthropic({ callbacks: [handler], tags: ["a-tag"] })`. In this case, the callbacks will be used for all calls made on that object, and will be scoped to that object only.
For example, if you initialize a chat model with constructor callbacks, then use it within a chain, the callbacks will only be invoked for calls to that model.
- **Request callbacks**: passed into the `invoke` method used for issuing a request. In this case, the callbacks will be used for that specific request only, and all sub-requests that it contains (e.g. a call to a sequence that triggers a call to a model, which uses the same handler passed in the `invoke()` method).
In the `invoke()` method, callbacks are passed through the config parameter.

## Techniques

### Function/tool calling
Expand Down
126 changes: 126 additions & 0 deletions docs/core_docs/docs/how_to/callbacks_backgrounding.ipynb
Original file line number Diff line number Diff line change
@@ -0,0 +1,126 @@
{
"cells": [
{
"cell_type": "markdown",
"metadata": {},
"source": [
"# How to make callbacks run in the background\n",
"\n",
":::info Prerequisites\n",
"\n",
"This guide assumes familiarity with the following concepts:\n",
"\n",
"- [Callbacks](/docs/concepts/#callbacks)\n",
"\n",
":::\n",
"\n",
"By default, LangChain.js callbacks are blocking. This means that execution will wait for the callback to either return or timeout before continuing. This is to help ensure that if you are running code in [serverless environments](https://en.wikipedia.org/wiki/Serverless_computing) such as [AWS Lambda](https://aws.amazon.com/pm/lambda/) or [Cloudflare Workers](https://workers.cloudflare.com/), these callbacks always finish before the execution context ends.\n",
"\n",
"However, this can add unnecessary latency if you are running in traditional stateful environments. If desired, you can set your callbacks to run in the background to avoid this additional latency by setting the `LANGCHAIN_CALLBACKS_BACKGROUND` environment variable to `\"true\"`. You can then import the global [`awaitAllCallbacks`](https://api.js.langchain.com/functions/langchain_core_callbacks_promises.awaitAllCallbacks.html) method to ensure all callbacks finish if necessary.\n",
"\n",
"To illustrate this, we'll create a [custom callback handler](/docs/how_to/custom_callbacks) that takes some time to resolve, and show the timing with and without `LANGCHAIN_CALLBACKS_BACKGROUND` set. Here it is without the variable set:"
]
},
{
"cell_type": "code",
"execution_count": 3,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Call finished\n",
"Elapsed time: 2005ms\n"
]
}
],
"source": [
"import { RunnableLambda } from \"@langchain/core/runnables\";\n",
"\n",
"Deno.env.set(\"LANGCHAIN_CALLBACKS_BACKGROUND\", \"false\");\n",
"\n",
"const runnable = RunnableLambda.from(() => \"hello!\");\n",
"\n",
"const customHandler = {\n",
" handleChainEnd: async () => {\n",
" await new Promise((resolve) => setTimeout(resolve, 2000));\n",
" console.log(\"Call finished\");\n",
" },\n",
"};\n",
"\n",
"const startTime = new Date().getTime();\n",
"\n",
"await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
"\n",
"console.log(`Elapsed time: ${new Date().getTime() - startTime}ms`);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"And here it is with backgrounding on:"
]
},
{
"cell_type": "code",
"execution_count": 5,
"metadata": {},
"outputs": [
{
"name": "stdout",
"output_type": "stream",
"text": [
"Initial elapsed time: 0ms\n",
"Call finished\n",
"Final elapsed time: 2098ms\n"
]
}
],
"source": [
"import { awaitAllCallbacks } from \"@langchain/core/callbacks/promises\";\n",
"\n",
"Deno.env.set(\"LANGCHAIN_CALLBACKS_BACKGROUND\", \"true\");\n",
"\n",
"const startTime = new Date().getTime();\n",
"\n",
"await runnable.invoke({ number: \"2\" }, { callbacks: [customHandler] });\n",
"\n",
"console.log(`Initial elapsed time: ${new Date().getTime() - startTime}ms`);\n",
"\n",
"await awaitAllCallbacks();\n",
"\n",
"console.log(`Final elapsed time: ${new Date().getTime() - startTime}ms`);"
]
},
{
"cell_type": "markdown",
"metadata": {},
"source": [
"## Next steps\n",
"\n",
"You've now learned how to run callbacks in the background to reduce latency.\n",
"\n",
"Next, check out the other how-to guides in this section, such as [how to create custom callback handlers](/docs/how_to/custom_callbacks)."
]
}
],
"metadata": {
"kernelspec": {
"display_name": "Deno",
"language": "typescript",
"name": "deno"
},
"language_info": {
"file_extension": ".ts",
"mimetype": "text/x.typescript",
"name": "typescript",
"nb_converter": "script",
"pygments_lexer": "typescript",
"version": "5.3.3"
}
},
"nbformat": 4,
"nbformat_minor": 2
}
Loading
Loading