fix: links (#33691)

* X-ref to new docs
* Formatting updates
This commit is contained in:
Mason Daugherty
2025-10-27 19:04:29 -04:00
committed by GitHub
parent 60a0ff8217
commit f94108b4bc
23 changed files with 103 additions and 49 deletions

View File

@@ -86,6 +86,6 @@ def create_message(*, message: str, error_code: ErrorCode) -> str:
""" """
return ( return (
f"{message}\n" f"{message}\n"
"For troubleshooting, visit: https://python.langchain.com/docs/" "For troubleshooting, visit: https://docs.langchain.com/oss/python/langchain"
f"troubleshooting/errors/{error_code.value} " f"/errors/{error_code.value} "
) )

View File

@@ -1391,11 +1391,6 @@ class LLM(BaseLLM):
`astream` will use `_astream` if provided, otherwise it will implement `astream` will use `_astream` if provided, otherwise it will implement
a fallback behavior that will use `_stream` if `_stream` is implemented, a fallback behavior that will use `_stream` if `_stream` is implemented,
and use `_acall` if `_stream` is not implemented. and use `_acall` if `_stream` is not implemented.
Please see the following guide for more information on how to
implement a custom LLM:
https://python.langchain.com/docs/how_to/custom_llm/
""" """
@abstractmethod @abstractmethod

View File

@@ -124,6 +124,10 @@ class UsageMetadata(TypedDict):
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
""" """
input_tokens: int input_tokens: int
@@ -131,7 +135,7 @@ class UsageMetadata(TypedDict):
output_tokens: int output_tokens: int
"""Count of output (or completion) tokens. Sum of all output token types.""" """Count of output (or completion) tokens. Sum of all output token types."""
total_tokens: int total_tokens: int
"""Total token count. Sum of input_tokens + output_tokens.""" """Total token count. Sum of `input_tokens` + `output_tokens`."""
input_token_details: NotRequired[InputTokenDetails] input_token_details: NotRequired[InputTokenDetails]
"""Breakdown of input token counts. """Breakdown of input token counts.
@@ -141,7 +145,6 @@ class UsageMetadata(TypedDict):
"""Breakdown of output token counts. """Breakdown of output token counts.
Does *not* need to sum to full output token count. Does *not* need to have all keys. Does *not* need to sum to full output token count. Does *not* need to have all keys.
""" """
@@ -153,7 +156,6 @@ class AIMessage(BaseMessage):
This message represents the output of the model and consists of both This message represents the output of the model and consists of both
the raw output as returned by the model and standardized fields the raw output as returned by the model and standardized fields
(e.g., tool calls, usage metadata) added by the LangChain framework. (e.g., tool calls, usage metadata) added by the LangChain framework.
""" """
tool_calls: list[ToolCall] = [] tool_calls: list[ToolCall] = []

View File

@@ -11,9 +11,8 @@ from langchain_core.utils._merge import merge_dicts
class Generation(Serializable): class Generation(Serializable):
"""A single text generation output. """A single text generation output.
Generation represents the response from an Generation represents the response from an "old-fashioned" LLM (string-in,
`"old-fashioned" LLM <https://python.langchain.com/docs/concepts/text_llms/>__` that string-out) that generates regular text (not chat messages).
generates regular text (not chat messages).
This model is used internally by chat model and will eventually This model is used internally by chat model and will eventually
be mapped to a more general `LLMResult` object, and then projected into be mapped to a more general `LLMResult` object, and then projected into

View File

@@ -218,7 +218,7 @@ def _build_model_kwargs(
values: dict[str, Any], values: dict[str, Any],
all_required_field_names: set[str], all_required_field_names: set[str],
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Build "model_kwargs" param from Pydantic constructor values. """Build `model_kwargs` param from Pydantic constructor values.
Args: Args:
values: All init args passed in by user. values: All init args passed in by user.
@@ -228,8 +228,8 @@ def _build_model_kwargs(
Extra kwargs. Extra kwargs.
Raises: Raises:
ValueError: If a field is specified in both values and extra_kwargs. ValueError: If a field is specified in both `values` and `extra_kwargs`.
ValueError: If a field is specified in model_kwargs. ValueError: If a field is specified in `model_kwargs`.
""" """
extra_kwargs = values.get("model_kwargs", {}) extra_kwargs = values.get("model_kwargs", {})
for field_name in list(values): for field_name in list(values):
@@ -267,6 +267,10 @@ def build_extra_kwargs(
) -> dict[str, Any]: ) -> dict[str, Any]:
"""Build extra kwargs from values and extra_kwargs. """Build extra kwargs from values and extra_kwargs.
!!! danger "DON'T USE"
Kept for backwards-compatibility but should never have been public. Use the
internal `_build_model_kwargs` function instead.
Args: Args:
extra_kwargs: Extra kwargs passed in by user. extra_kwargs: Extra kwargs passed in by user.
values: Values passed in by user. values: Values passed in by user.
@@ -276,9 +280,10 @@ def build_extra_kwargs(
Extra kwargs. Extra kwargs.
Raises: Raises:
ValueError: If a field is specified in both values and extra_kwargs. ValueError: If a field is specified in both `values` and `extra_kwargs`.
ValueError: If a field is specified in model_kwargs. ValueError: If a field is specified in `model_kwargs`.
""" """
# DON'T USE! Kept for backwards-compatibility but should never have been public.
for field_name in list(values): for field_name in list(values):
if field_name in extra_kwargs: if field_name in extra_kwargs:
msg = f"Found {field_name} supplied twice." msg = f"Found {field_name} supplied twice."
@@ -292,6 +297,7 @@ def build_extra_kwargs(
) )
extra_kwargs[field_name] = values.pop(field_name) extra_kwargs[field_name] = values.pop(field_name)
# DON'T USE! Kept for backwards-compatibility but should never have been public.
invalid_model_kwargs = all_required_field_names.intersection(extra_kwargs.keys()) invalid_model_kwargs = all_required_field_names.intersection(extra_kwargs.keys())
if invalid_model_kwargs: if invalid_model_kwargs:
msg = ( msg = (
@@ -300,6 +306,7 @@ def build_extra_kwargs(
) )
raise ValueError(msg) raise ValueError(msg)
# DON'T USE! Kept for backwards-compatibility but should never have been public.
return extra_kwargs return extra_kwargs

View File

@@ -1319,6 +1319,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -2726,6 +2731,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({

View File

@@ -1743,6 +1743,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({

View File

@@ -3259,6 +3259,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -4728,6 +4733,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -6209,6 +6219,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -7546,6 +7561,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -9057,6 +9077,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -10439,6 +10464,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -11869,6 +11899,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({
@@ -13300,6 +13335,11 @@
!!! warning "Behavior changed in 0.3.9" !!! warning "Behavior changed in 0.3.9"
Added `input_token_details` and `output_token_details`. Added `input_token_details` and `output_token_details`.
!!! note "LangSmith SDK"
The LangSmith SDK also has a `UsageMetadata` class. While the two share fields,
LangSmith's `UsageMetadata` has additional fields to capture cost information
used by the LangSmith platform.
''', ''',
'properties': dict({ 'properties': dict({
'input_token_details': dict({ 'input_token_details': dict({

View File

@@ -11,7 +11,8 @@ When developing an application, developers should inspect the capabilities and
permissions of the tools that underlie the given agent toolkit, and determine permissions of the tools that underlie the given agent toolkit, and determine
whether permissions of the given toolkit are appropriate for the application. whether permissions of the given toolkit are appropriate for the application.
See [Security](https://python.langchain.com/docs/security) for more information. See [Security](https://docs.langchain.com/oss/python/security-policy) for more
information.
""" """
from pathlib import Path from pathlib import Path

View File

@@ -68,8 +68,8 @@ try:
class APIChain(Chain): class APIChain(Chain):
"""Chain that makes API calls and summarizes the responses to answer a question. """Chain that makes API calls and summarizes the responses to answer a question.
*Security Note*: This API chain uses the requests toolkit **Security Note**: This API chain uses the requests toolkit
to make GET, POST, PATCH, PUT, and DELETE requests to an API. to make `GET`, `POST`, `PATCH`, `PUT`, and `DELETE` requests to an API.
Exercise care in who is allowed to use this chain. If exposing Exercise care in who is allowed to use this chain. If exposing
to end users, consider that users will be able to make arbitrary to end users, consider that users will be able to make arbitrary
@@ -80,7 +80,8 @@ try:
Control access to who can submit issue requests using this toolkit and Control access to who can submit issue requests using this toolkit and
what network access it has. what network access it has.
See https://python.langchain.com/docs/security for more information. See https://docs.langchain.com/oss/python/security-policy for more
information.
!!! note !!! note
This class is deprecated. See below for a replacement implementation using This class is deprecated. See below for a replacement implementation using
@@ -90,7 +91,7 @@ try:
- Support for both token-by-token and step-by-step streaming; - Support for both token-by-token and step-by-step streaming;
- Support for checkpointing and memory of chat history; - Support for checkpointing and memory of chat history;
- Easier to modify or extend - Easier to modify or extend
(e.g., with additional tools, structured responses, etc.) (e.g., with additional tools, structured responses, etc.)
Install LangGraph with: Install LangGraph with:
@@ -206,7 +207,6 @@ try:
* For example, to limit to just the domain `https://www.example.com`, set * For example, to limit to just the domain `https://www.example.com`, set
`limit_to_domains=["https://www.example.com"]`. `limit_to_domains=["https://www.example.com"]`.
* The default value is an empty tuple, which means that no domains are * The default value is an empty tuple, which means that no domains are
allowed by default. By design this will raise an error on instantiation. allowed by default. By design this will raise an error on instantiation.
* Use a None if you want to allow all domains by default -- this is not * Use a None if you want to allow all domains by default -- this is not

View File

@@ -40,7 +40,7 @@ class NatBotChain(Chain):
access and use this chain, and isolate the network access of the server access and use this chain, and isolate the network access of the server
that hosts this chain. that hosts this chain.
See https://python.langchain.com/docs/security for more information. See https://docs.langchain.com/oss/python/security-policy for more information.
Example: Example:
```python ```python

View File

@@ -58,7 +58,7 @@ class Crawler:
Make sure to scope permissions to the minimal permissions necessary for Make sure to scope permissions to the minimal permissions necessary for
the application. the application.
See https://python.langchain.com/docs/security for more information. See https://docs.langchain.com/oss/python/security-policy for more information.
""" """
def __init__(self) -> None: def __init__(self) -> None:

View File

@@ -50,13 +50,7 @@ Passage:
"LangChain has introduced a method called `with_structured_output` that" "LangChain has introduced a method called `with_structured_output` that"
"is available on ChatModels capable of tool calling." "is available on ChatModels capable of tool calling."
"You can read more about the method here: " "You can read more about the method here: "
"<https://docs.langchain.com/oss/python/langchain/models#structured-outputs>. " "<https://docs.langchain.com/oss/python/langchain/models#structured-outputs>."
"Please follow our extraction use case documentation for more guidelines"
"on how to do information extraction with LLMs."
"<https://python.langchain.com/docs/use_cases/extraction/>. "
"If you notice other issues, please provide "
"feedback here:"
"<https://github.com/langchain-ai/langchain/discussions/18154>"
), ),
removal="1.0", removal="1.0",
alternative=( alternative=(

View File

@@ -53,7 +53,7 @@ def create_sql_query_chain(
Control access to who can submit requests to this chain. Control access to who can submit requests to this chain.
See https://python.langchain.com/docs/security for more information. See https://docs.langchain.com/oss/python/security-policy for more information.
Args: Args:
llm: The language model to use. llm: The language model to use.

View File

@@ -807,7 +807,7 @@ class ChatAnthropic(BaseChatModel):
See `ChatAnthropic.with_structured_output()` for more. See `ChatAnthropic.with_structured_output()` for more.
Image input: Image input:
See [multimodal guides](https://python.langchain.com/docs/how_to/multimodal_inputs/) See [multimodal guides](https://docs.langchain.com/oss/python/langchain/models#multimodal)
for more detail. for more detail.
```python ```python
@@ -875,7 +875,7 @@ class ChatAnthropic(BaseChatModel):
``` ```
PDF input: PDF input:
See [multimodal guides](https://python.langchain.com/docs/how_to/multimodal_inputs/) See [multimodal guides](https://docs.langchain.com/oss/python/langchain/models#multimodal)
for more detail. for more detail.
```python ```python
@@ -1221,7 +1221,7 @@ class ChatAnthropic(BaseChatModel):
!!! note title="Token-efficient tool use (beta)" !!! note title="Token-efficient tool use (beta)"
See LangChain [docs](https://python.langchain.com/docs/integrations/chat/anthropic/) See LangChain [docs](https://docs.langchain.com/oss/python/integrations/chat/anthropic)
for more detail. for more detail.
```python ```python
@@ -1278,7 +1278,7 @@ class ChatAnthropic(BaseChatModel):
!!! note title="Built-in tools" !!! note title="Built-in tools"
See LangChain [docs](https://python.langchain.com/docs/integrations/chat/anthropic/#built-in-tools) See LangChain [docs](https://docs.langchain.com/oss/python/integrations/chat/anthropic#built-in-tools)
for more detail. for more detail.
??? note "Web search" ??? note "Web search"

View File

@@ -1418,7 +1418,7 @@ def test_web_fetch() -> None:
"role": "user", "role": "user",
"content": ( "content": (
"Fetch https://docs.langchain.com and then try to fetch " "Fetch https://docs.langchain.com and then try to fetch "
"https://python.langchain.com" "https://langchain.com"
), ),
} }
max_uses_response = llm_with_tools.invoke([multi_fetch_message]) max_uses_response = llm_with_tools.invoke([multi_fetch_message])

View File

@@ -156,7 +156,8 @@ class ChatDeepSeek(BaseChatOpenAI):
```python ```python
{"input_tokens": 28, "output_tokens": 5, "total_tokens": 33} {"input_tokens": 28, "output_tokens": 5, "total_tokens": 33}
``` ```
Response metadata
Response metadata:
```python ```python
ai_msg = model.invoke(messages) ai_msg = model.invoke(messages)
ai_msg.response_metadata ai_msg.response_metadata

View File

@@ -115,7 +115,7 @@ def test__convert_dict_to_message_tool_call() -> None:
name="GenerateUsername", name="GenerateUsername",
args="oops", args="oops",
id="call_wm0JY6CdwOMZ4eTxHWUThDNz", id="call_wm0JY6CdwOMZ4eTxHWUThDNz",
error="Function GenerateUsername arguments:\n\noops\n\nare not valid JSON. Received JSONDecodeError Expecting value: line 1 column 1 (char 0)\nFor troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE ", # noqa: E501 error="Function GenerateUsername arguments:\n\noops\n\nare not valid JSON. Received JSONDecodeError Expecting value: line 1 column 1 (char 0)\nFor troubleshooting, visit: https://docs.langchain.com/oss/python/langchain/errors/OUTPUT_PARSING_FAILURE ", # noqa: E501
type="invalid_tool_call", type="invalid_tool_call",
), ),
], ],

View File

@@ -219,7 +219,7 @@ def test__convert_dict_to_message_tool_call() -> None:
InvalidToolCall( InvalidToolCall(
name="GenerateUsername", name="GenerateUsername",
args="oops", args="oops",
error="Function GenerateUsername arguments:\n\noops\n\nare not valid JSON. Received JSONDecodeError Expecting value: line 1 column 1 (char 0)\nFor troubleshooting, visit: https://python.langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE ", # noqa: E501 error="Function GenerateUsername arguments:\n\noops\n\nare not valid JSON. Received JSONDecodeError Expecting value: line 1 column 1 (char 0)\nFor troubleshooting, visit: https://docs.langchain.com/oss/python/langchain/errors/OUTPUT_PARSING_FAILURE ", # noqa: E501
id="ssAbar4Dr", id="ssAbar4Dr",
type="invalid_tool_call", type="invalid_tool_call",
), ),

View File

@@ -2777,7 +2777,7 @@ class ChatOpenAI(BaseChatOpenAI): # type: ignore[override]
**Use `extra_body` for:** **Use `extra_body` for:**
- Custom parameters specific to OpenAI-compatible providers (vLLM, LM Studio, - Custom parameters specific to OpenAI-compatible providers (vLLM, LM Studio,
etc.) OpenRouter, etc.)
- Parameters that need to be nested under `extra_body` in the request - Parameters that need to be nested under `extra_body` in the request
- Any non-standard OpenAI API parameters - Any non-standard OpenAI API parameters

View File

@@ -257,8 +257,8 @@ def test__convert_dict_to_message_tool_call() -> None:
error=( error=(
"Function GenerateUsername arguments:\n\noops\n\nare not " "Function GenerateUsername arguments:\n\noops\n\nare not "
"valid JSON. Received JSONDecodeError Expecting value: line 1 " "valid JSON. Received JSONDecodeError Expecting value: line 1 "
"column 1 (char 0)\nFor troubleshooting, visit: https://python" "column 1 (char 0)\nFor troubleshooting, visit: https://docs"
".langchain.com/docs/troubleshooting/errors/OUTPUT_PARSING_FAILURE " ".langchain.com/oss/python/langchain/errors/OUTPUT_PARSING_FAILURE "
), ),
type="invalid_tool_call", type="invalid_tool_call",
) )

View File

@@ -420,7 +420,7 @@ class ChatModelIntegrationTests(ChatModelTests):
`usage_metadata` is an optional dict attribute on `AIMessage` objects that track `usage_metadata` is an optional dict attribute on `AIMessage` objects that track
input and output tokens. input and output tokens.
[See more](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.UsageMetadata.html). [See more](https://reference.langchain.com/python/langchain_core/language_models/#langchain_core.messages.ai.UsageMetadata).
```python ```python
@property @property
@@ -537,7 +537,7 @@ class ChatModelIntegrationTests(ChatModelTests):
`usage_metadata` is an optional dict attribute on `AIMessage` objects that track `usage_metadata` is an optional dict attribute on `AIMessage` objects that track
input and output tokens. input and output tokens.
[See more](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.UsageMetadata.html). [See more](https://reference.langchain.com/python/langchain_core/language_models/#langchain_core.messages.ai.UsageMetadata).
It includes optional keys `input_token_details` and `output_token_details` It includes optional keys `input_token_details` and `output_token_details`
that can track usage details associated with special types of tokens, such as that can track usage details associated with special types of tokens, such as

View File

@@ -530,7 +530,7 @@ class ChatModelUnitTests(ChatModelTests):
`usage_metadata` is an optional dict attribute on `AIMessage` objects that track `usage_metadata` is an optional dict attribute on `AIMessage` objects that track
input and output tokens. input and output tokens.
[See more](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.UsageMetadata.html). [See more](https://reference.langchain.com/python/langchain_core/language_models/#langchain_core.messages.ai.UsageMetadata).
```python ```python
@property @property
@@ -652,7 +652,7 @@ class ChatModelUnitTests(ChatModelTests):
`usage_metadata` is an optional dict attribute on `AIMessage` objects that track `usage_metadata` is an optional dict attribute on `AIMessage` objects that track
input and output tokens. input and output tokens.
[See more](https://python.langchain.com/api_reference/core/messages/langchain_core.messages.ai.UsageMetadata.html). [See more](https://reference.langchain.com/python/langchain_core/language_models/#langchain_core.messages.ai.UsageMetadata).
It includes optional keys `input_token_details` and `output_token_details` It includes optional keys `input_token_details` and `output_token_details`
that can track usage details associated with special types of tokens, such as that can track usage details associated with special types of tokens, such as