@ -542,6 +542,10 @@ class ChatAnthropic(BaseChatModel):
def bind_tools (
self ,
tools : Sequence [ Union [ Dict [ str , Any ] , Type [ BaseModel ] , Callable , BaseTool ] ] ,
* ,
tool_choice : Optional [
Union [ Dict [ str , str ] , Literal [ " any " , " auto " ] , str ]
] = None ,
* * kwargs : Any ,
) - > Runnable [ LanguageModelInput , BaseMessage ] :
""" Bind tool-like objects to this chat model.
@ -551,6 +555,15 @@ class ChatAnthropic(BaseChatModel):
Can be a dictionary , pydantic model , callable , or BaseTool . Pydantic
models , callables , and BaseTools will be automatically converted to
their schema dictionary representation .
tool_choice : Which tool to require the model to call .
Options are :
name of the tool ( str ) : calls corresponding tool ;
" auto " or None : automatically selects a tool ( including no tool ) ;
" any " : force at least one tool to be called ;
or a dict of the form :
{ " type " : " tool " , " name " : " tool_name " } ,
or { " type: " any " },
or { " type: " auto " };
* * kwargs : Any additional parameters to bind .
Example :
@ -564,9 +577,14 @@ class ChatAnthropic(BaseChatModel):
location : str = Field ( . . . , description = " The city and state, e.g. San Francisco, CA " )
class GetPrice ( BaseModel ) :
''' Get the price of a specific product. '''
product : str = Field ( . . . , description = " The product to look up. " )
llm = ChatAnthropic ( model = " claude-3-opus-20240229 " , temperature = 0 )
llm_with_tools = llm . bind_tools ( [ GetWeather ] )
llm_with_tools = llm . bind_tools ( [ GetWeather , GetPrice ])
llm_with_tools . invoke ( " what is the weather like in San Francisco " , )
# -> AIMessage(
# content=[
@ -576,8 +594,64 @@ class ChatAnthropic(BaseChatModel):
# response_metadata={'id': 'msg_01GM3zQtoFv8jGQMW7abLnhi', 'model': 'claude-3-opus-20240229', 'stop_reason': 'tool_use', 'stop_sequence': None, 'usage': {'input_tokens': 487, 'output_tokens': 145}},
# id='run-87b1331e-9251-4a68-acef-f0a018b639cc-0'
# )
Example — force tool call with tool_choice ' any ' :
. . code - block : : python
from langchain_anthropic import ChatAnthropic
from langchain_core . pydantic_v1 import BaseModel , Field
class GetWeather ( BaseModel ) :
''' Get the current weather in a given location '''
location : str = Field ( . . . , description = " The city and state, e.g. San Francisco, CA " )
class GetPrice ( BaseModel ) :
''' Get the price of a specific product. '''
product : str = Field ( . . . , description = " The product to look up. " )
llm = ChatAnthropic ( model = " claude-3-opus-20240229 " , temperature = 0 )
llm_with_tools = llm . bind_tools ( [ GetWeather , GetPrice ] , tool_choice = " any " )
llm_with_tools . invoke ( " what is the weather like in San Francisco " , )
Example — force specific tool call with tool_choice ' <name_of_tool> ' :
. . code - block : : python
from langchain_anthropic import ChatAnthropic
from langchain_core . pydantic_v1 import BaseModel , Field
class GetWeather ( BaseModel ) :
''' Get the current weather in a given location '''
location : str = Field ( . . . , description = " The city and state, e.g. San Francisco, CA " )
class GetPrice ( BaseModel ) :
''' Get the price of a specific product. '''
product : str = Field ( . . . , description = " The product to look up. " )
llm = ChatAnthropic ( model = " claude-3-opus-20240229 " , temperature = 0 )
llm_with_tools = llm . bind_tools ( [ GetWeather , GetPrice ] , tool_choice = " GetWeather " )
llm_with_tools . invoke ( " what is the weather like in San Francisco " , )
""" # noqa: E501
formatted_tools = [ convert_to_anthropic_tool ( tool ) for tool in tools ]
if not tool_choice :
pass
elif isinstance ( tool_choice , dict ) :
kwargs [ " tool_choice " ] = tool_choice
elif isinstance ( tool_choice , str ) and tool_choice in ( " any " , " auto " ) :
kwargs [ " tool_choice " ] = { " type " : tool_choice }
elif isinstance ( tool_choice , str ) :
kwargs [ " tool_choice " ] = { " type " : " tool " , " name " : tool_choice }
else :
raise ValueError (
f " Unrecognized ' tool_choice ' type { tool_choice =} . Expected dict, "
f " str, or None. "
)
return self . bind ( tools = formatted_tools , * * kwargs )
def with_structured_output (
@ -683,7 +757,7 @@ class ChatAnthropic(BaseChatModel):
# }
""" # noqa: E501
llm = self . bind_tools ( [ schema ] )
llm = self . bind_tools ( [ schema ] , tool_choice = " any " )
if isinstance ( schema , type ) and issubclass ( schema , BaseModel ) :
output_parser = ToolsOutputParser (
first_tool_only = True , pydantic_schemas = [ schema ]