简介
工具是应用开发者提供的函数,供语言模型在特定情境中调用,用于完成模型本身无法直接完成的任务。
模型会基于上下文生成调用某个工具的结构化请求,LangChain 会识别调用请求,执行函数并返回结果。
工具是 LangChain 智能体构建中的重要一环,扩展了模型的“行动能力”。
流程:
graph LR
A["用户输入"] --> B["模型生成工具调用"]
B --> C["执行工具函数"]
C --> D["返回结果给模型"]
D --> E["生成最终响应"]
使用原理 大语言模型根据当下应用场景进行判断,是否应该使用此工具。所以工具的描述至关重要,如果工具描述不清晰,则可能会导致大语言模型无法很好的将这些工具应用在适用的场景之上。
作用
对应字段名
工具名称。
name
该工具是什么的描述。
description
工具输入内容的 JSON 架构。
args_schema
工具的结果是否应直接返回给用户。
return_direct
要调用的函数。
无
LangChain中的工具(Tool)是一个封装了特定功能的类,它包含四个核心组成部分:
名称(name):名称是工具在工具集合中的唯一标识符 ,必须确保在同一工具集中不重复
描述(description):描述用于说明工具的功能,为LLM或代理提供上下文信息,帮助模型理解何时以及如何调用该工具
参数模式(args_schema):是使用Pydantic BaseModel定义的输入参数结构,用于验证和解析工具调用的参数
是否直接返回(return_direct):布尔值属性,当设置为True时,智能体会在调用工具后立即返回结果给用户,而不继续调用其他工具
将工具函数转为LangChain Tool对象的两种方式
使用Tool.from_function生成
1 2 3 4 5 add_tools = Tool.from_function( func=add, name="add" , description="计算两个数相加" )
使用@tool装饰器生成(推荐),使用该方式,函数必须要有函数的注释信息1 2 3 4 @tool def add (a, b ): """add two numbers""" return a + b
直接上代码示例
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplatefrom langchain_core.tools import Tooldef add (a, b ): return a + b add_tools = Tool.from_function( func=add, name="add" , description="add two numbers" ) tools_dict = { "add" : add } import osfrom dotenv import load_dotenvload_dotenv() from langchain_openai import ChatOpenAIqv_llm = ChatOpenAI( model=os.getenv("LLM_MODEL" ), base_url=os.getenv("LLM_BASE_URL" ), api_key=os.getenv("LLM_API_KEY" ), streaming=True , ) llm_with_tools = qv_llm.bind_tools([add_tools]) system_message_template = ChatMessagePromptTemplate.from_template( template="你是一位{role}专家,擅长回答{domain}领域的问题" , role="system" , ) human_message_template = ChatMessagePromptTemplate.from_template( template="用户问题:{question}" , role="user" , ) chat_prompt_template = ChatPromptTemplate.from_messages([ system_message_template, human_message_template, ]) chain = chat_prompt_template | llm_with_tools response = chain.invoke(input ={"role" : "计算" , "domain" : "数学计算" , "question" : "100+100=?" }) print ('-----------------------------response-------------------------' )print (response)for tool_calls in response.tool_calls: print ('-----------------------------tool_calls-------------------------' ) print (tool_calls) args = tool_calls["args" ] print ('-----------------------------args-------------------------' ) print (args) func_name = tool_calls['name' ] print ('-----------------------------func_name-------------------------' ) print (func_name) tool_func = tools_dict[func_name] tool_content = tool_func(int (args["__arg1" ]), int (args["__arg2" ])) print ('-----------------------------tool_content-------------------------' ) print (tool_content)
@tool装饰器的使用
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 from langchain_core.prompts import ChatPromptTemplate, ChatMessagePromptTemplatefrom langchain_core.tools import tool@tool def add (a, b ): """add two numbers""" return a + b tools_dict = { "add" : add } import osfrom dotenv import load_dotenvload_dotenv() from langchain_openai import ChatOpenAIqv_llm = ChatOpenAI( model=os.getenv("LLM_MODEL" ), base_url=os.getenv("LLM_BASE_URL" ), api_key=os.getenv("LLM_API_KEY" ), streaming=True , ) llm_with_tools = qv_llm.bind_tools([add]) system_message_template = ChatMessagePromptTemplate.from_template( template="你是一位{role}专家,擅长回答{domain}领域的问题" , role="system" , ) human_message_template = ChatMessagePromptTemplate.from_template( template="用户问题:{question}" , role="user" , ) chat_prompt_template = ChatPromptTemplate.from_messages([ system_message_template, human_message_template, ]) chain = chat_prompt_template | llm_with_tools response = chain.invoke(input ={"role" : "计算" , "domain" : "数学计算" , "question" : "使用工具计算:100+100=?" }) print ('-----------------------------response-------------------------' )print (response)for tool_calls in response.tool_calls: print ('-----------------------------tool_calls-------------------------' ) print (tool_calls) args = tool_calls["args" ] print ('-----------------------------args-------------------------' ) print (args) func_name = tool_calls['name' ] print ('-----------------------------func_name-------------------------' ) print (func_name) tool_func = tools_dict[func_name] tool_content = tool_func.invoke(args) print ('-----------------------------tool_content-------------------------' ) print (tool_content)
使用args_schema精确控制工具入参,@tools装饰器定义的工具如下:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 from pydantic import BaseModelclass AddInputArgs (BaseModel ): a: str = Field(description="first number" ) b: str = Field(description="second number" ) @tool( description="add two numbers" , args_schema=AddInputArgs, return_direct=True , )def add (a, b ): """add two numbers""" return a + b
LangChain内置工具 Langchain内置了一些常用的工具,供我们使用,具体内置了哪些工具,可以详细的到官方文档上查看
Tool使用方法:https://python.langchain.com/docs/integrations/tools/
内置Tooltiks:https://api.python.langchain.com/en/latest/community/agent_toolkits.html
示例一:使用内置的维基百科工具进行搜索操作 1 2 3 4 5 6 7 8 9 10 11 12 13 14 from langchain_community.tools import WikipediaQueryRunfrom langchain_community.utilities import WikipediaAPIWrapperapi_wrapper = WikipediaAPIWrapper(top_k_results=1 , doc_content_chars_max=100 ) tool = WikipediaQueryRun(api_wrapper=api_wrapper) tool.run({"query" : "langchain" })
示例二:Python REPL执行python代码 工具介绍,查看官网:https://python.langchain.com/docs/integrations/tools/python/
需要安装依赖:pip install langchain_experimental,结合智能体开发使用
1 2 3 4 5 from langchain_experimental.utilities import PythonREPLpython_repl = PythonREPL() res = python_repl.run("print(1+1)" ) print (res)