作者:CSDN博客
本教程将介绍如何使用 LangChain 库中的工具(Tool)功能。通过一系列示例代码,我们将展示如何定义、使用和扩展工具。
1. 定义简单的工具
首先,我们从定义一个简单的乘法工具开始。- from langchain_core.tools import tool
- @tooldefmultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
- # 查看工具的属性print(multiply.name)print(multiply.description)print(multiply.args)
复制代码 输出:- multiply
- Multiply two numbers.
- {'a': {'title': 'A', 'type': 'integer'}, 'b': {'title': 'B', 'type': 'integer'}}
复制代码 解释
@tool 装饰器用于将函数定义为一个工具。multiply 函数接受两个整数参数 a 和 b,返回它们的乘积。通过打印工具的属性,我们可以看到工具的名称、描述和参数信息。
2. 定义异步工具
接下来,我们定义一个异步的乘法工具。- from langchain_core.tools import tool
- @toolasyncdefamultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
复制代码 解释
使用 async 关键字定义异步函数 amultiply。其他部分与同步工具定义相同。
3. 使用注解定义工具参数
我们可以使用注解来更详细地描述工具的参数。- from typing import Annotated, List
- @tooldefmultiply_by_max(
- a: Annotated[str,"scale factor"],
- b: Annotated[List[int],"list of ints over which to take maximum"],)->int:"""Multiply a by the maximum of b."""return a *max(b)print(multiply_by_max.args_schema.schema())
复制代码 输出:- {'description': 'Multiply a by the maximum of b.',
- 'properties': {'a': {'description': 'scale factor',
- 'title': 'A',
- 'type': 'string'},
- 'b': {'description': 'list of ints over which to take maximum',
- 'items': {'type': 'integer'},
- 'title': 'B',
- 'type': 'array'}},
- 'required': ['a', 'b'],
- 'title': 'multiply_by_max',
- 'type': 'object'}
复制代码 解释
使用 Annotated 类型注解来添加参数的描述。multiply_by_max 函数接受一个字符串 a 和一个整数列表 b,返回 a 与 b 中最大值的乘积。通过打印参数模式(schema),我们可以看到详细的参数描述。
4. 使用 Pydantic 定义工具参数
我们可以使用 Pydantic 库来更严格地定义工具的参数。- from pydantic import BaseModel, Field
- classCalculatorInput(BaseModel):
- a:int= Field(description="first number")
- b:int= Field(description="second number")@tool("multiplication-tool", args_schema=CalculatorInput, return_direct=True)defmultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
- # 查看工具的属性print(multiply.name)print(multiply.description)print(multiply.args)print(multiply.return_direct)
复制代码 输出:- multiplication-tool
- Multiply two numbers.
- {'a': {'description': 'first number', 'title': 'A', 'type': 'integer'}, 'b': {'description': 'second number', 'title': 'B', 'type': 'integer'}}
- True
复制代码 解释
使用 Pydantic 的 BaseModel 和 Field 来定义参数模型 CalculatorInput。multiply 工具使用 CalculatorInput 作为参数模式,并设置 return_direct=True 表示直接返回结果。通过打印工具的属性,我们可以看到详细的工具信息。
5. 自动解析文档字符串
我们可以让 LangChain 自动解析函数的文档字符串来生成参数模式。- @tool(parse_docstring=True)deffoo(bar:str, baz:int)->str:"""The foo.
- Args:
- bar: The bar.
- baz: The baz.
- """return bar
- print(foo.args_schema.schema())
复制代码 输出:- {'description': 'The foo.',
- 'properties': {'bar': {'description': 'The bar.',
- 'title': 'Bar',
- 'type': 'string'},
- 'baz': {'description': 'The baz.', 'title': 'Baz', 'type': 'integer'}},
- 'required': ['bar', 'baz'],
- 'title': 'foo',
- 'type': 'object'}
复制代码 解释
使用 parse_docstring=True 参数,LangChain 会自动解析函数的文档字符串来生成参数模式。foo 函数接受一个字符串 bar 和一个整数 baz,返回 bar。
6. 使用 StructuredTool
我们可以使用 StructuredTool 来创建工具实例。- from langchain_core.tools import StructuredTool
- defmultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
- asyncdefamultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
- calculator = StructuredTool.from_function(func=multiply, coroutine=amultiply)print(calculator.invoke({"a":2,"b":3}))print(await calculator.ainvoke({"a":2,"b":5}))
复制代码 输出:解释
StructuredTool.from_function 方法用于从同步和异步函数创建工具实例。invoke 方法用于同步调用工具,ainvoke 方法用于异步调用工具。
7. 自定义工具
我们可以自定义工具类。- classCalculatorInput(BaseModel):
- a:int= Field(description="first number")
- b:int= Field(description="second number")defmultiply(a:int, b:int)->int:"""Multiply two numbers."""return a * b
- calculator = StructuredTool.from_function(
- func=multiply,
- name="Calculator",
- description="multiply numbers",
- args_schema=CalculatorInput,
- return_direct=True,)print(calculator.invoke({"a":2,"b":3}))print(calculator.name)print(calculator.description)print(calculator.args)
复制代码 输出:- 6
- Calculator
- multiply numbers
- {'a': {'description': 'first number', 'title': 'A', 'type': 'integer'}, 'b': {'description': 'second number', 'title': 'B', 'type': 'integer'}}
复制代码 解释
使用 StructuredTool.from_function 方法创建自定义工具实例。可以指定工具的名称、描述、参数模式和是否直接返回结果。
8. 将链式调用转换为工具
我们可以将链式调用转换为工具。- from langchain_core.language_models import GenericFakeChatModel
- from langchain_core.output_parsers import StrOutputParser
- from langchain_core.prompts import ChatPromptTemplate
- prompt = ChatPromptTemplate.from_messages([("human","Hello. Please respond in the style of {answer_style}.")])# 占位符 LLM
- llm = GenericFakeChatModel(messages=iter(["hello matey"]))
- chain = prompt | llm | StrOutputParser()
- as_tool = chain.as_tool(
- name="Style responder", description="Description of when to use tool.")print(as_tool.args)
复制代码 输出:- {'answer_style': {'title': 'Answer Style', 'type': 'string'}}
复制代码 解释
使用 ChatPromptTemplate 创建提示模板。使用 GenericFakeChatModel 作为占位符语言模型。将提示模板、语言模型和输出解析器链式调用,并转换为工具。
9. 处理工具错误
我们可以定义工具错误处理。- defget_weather(city:str)->int:"""Get weather for the given city."""raise ToolException(f"Error: There is no city by the name of {city}.")
- get_weather_tool = StructuredTool.from_function(
- func=get_weather,
- handle_tool_error=True,)print(get_weather_tool.invoke({"city":"foobar"}))
复制代码 输出:- Error: There is no city by the name of foobar.
复制代码 解释
get_weather 函数抛出 ToolException。使用 handle_tool_error=True 参数,工具会自动处理错误并返回错误信息。
10. 自定义错误信息
我们可以自定义工具错误信息。- get_weather_tool = StructuredTool.from_function(
- func=get_weather,
- handle_tool_error="There is no such city, but it's probably above 0K there!",)print(get_weather_tool.invoke({"city":"foobar"}))
复制代码 输出:- "There is no such city, but it's probably above 0K there!"
复制代码 解释
使用 handle_tool_error 参数自定义错误信息。
11. 生成随机数工具
我们可以定义生成随机数的工具。- import random
- from typing import List, Tuple
- @tool(response_format="content_and_artifact")defgenerate_random_ints(min:int,max:int, size:int)-> Tuple[str, List[int]]:"""Generate size random ints in the range [min, max]."""
- array =[random.randint(min,max)for _ inrange(size)]
- content =f"Successfully generated array of {size} random ints in [{min}, {max}]."return content, array
- print(generate_random_ints.invoke({"min":0,"max":9,"size":10}))
复制代码 输出:- 'Successfully generated array of 10 random ints in [0, 9].'
复制代码 解释
generate_random_ints 函数生成指定范围内的随机整数列表。使用 response_format="content_and_artifact" 参数,工具返回内容和结果列表。
12. 带有工具调用的生成随机数
我们可以使用工具调用格式生成随机数。- print(generate_random_ints.invoke({"name":"generate_random_ints","args":{"min":0,"max":9,"size":10},"id":"123",# required"type":"tool_call",# required}))
复制代码 输出:- ToolMessage(content='Successfully generated array of 10 random ints in [0, 9].', name='generate_random_ints', tool_call_id='123', artifact=[0, 4, 2, 7, 4, 3, 1, 7, 5, 1])
复制代码 解释
使用工具调用格式,工具返回 ToolMessage 对象,包含内容和结果列表。
13. 生成随机浮点数工具
我们可以定义生成随机浮点数的工具。- from langchain_core.tools import BaseTool
- classGenerateRandomFloats(BaseTool):
- name:str="generate_random_floats"
- description:str="Generate size random floats in the range [min, max]."
- response_format:str="content_and_artifact"
- ndigits:int=2def_run(self,min:float,max:float, size:int)-> Tuple[str, List[float]]:
- range_ =max-min
- array =[round(min+(range_ * random.random()), ndigits=self.ndigits)for _ inrange(size)]
- content =f"Generated {size} floats in [{min}, {max}], rounded to {self.ndigits} decimals."return content, array
- rand_gen = GenerateRandomFloats(ndigits=4)print(rand_gen.invoke({"name":"generate_random_floats","args":{"min":0.1,"max":3.3333,"size":3},"id":"123","type":"tool_call",}))
复制代码 输出:- ToolMessage(content='Generated 3 floats in [0.1, 3.3333], rounded to 4 decimals.', name='generate_random_floats', tool_call_id='123', artifact=[2.033, 2.6058, 2.5919])
复制代码 解释
GenerateRandomFloats 类定义了一个生成随机浮点数的工具。使用 _run 方法实现工具的逻辑。通过工具调用格式,返回 ToolMessage 对象,包含内容和结果列表。
通过以上示例,我们展示了如何使用 LangChain 库中的工具功能,包括定义工具、使用注解和 Pydantic、处理错误、生成随机数等。希望这些示例能帮助你更好地理解和应用 LangChain 工具。
参考链接:https://python.langchain.com/docs/how_to/custom_tools/
原文地址:https://blog.csdn.net/qq_41472205/article/details/144141262 |