mirror of
https://github.com/hwchase17/langchain.git
synced 2026-06-09 10:17:00 +00:00
anthropic[patch]: Release 0.1.13, tool_choice support (#21773)
This commit is contained in:
@@ -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]
|
||||
|
||||
Reference in New Issue
Block a user