这里需要先介绍一下Function calling,什么是Function calling? 它提供了可以让我们把大模型和外部数据或系统进行连接的能力
举个具体的例子:我们现在有一些如查询订单等信息的接口,我们可以把这些接口工具及参数等详情信息提供给大模型,这样如果在上下文对话中,它判断出需要需要使用这个接口时,就会返回对应的接口及参数值**(注意:大模型只是会判断后返回工具名称和参数,并不会实际进行调用)**
我们可以据此在本地进行实际的调用,获取最终结果进行返回;如果大模型函数不需要这个能力,那么就可以以正常自然语言的方式进行对话内容返回
当然,我们也可以通过设置一些参数,强制大模型使用/不使用工具
这个Function calling能力,各个大模型提供的api可能有所差异,需要看各自对应的API,但是langchain帮我们整合了相关的功能,所以本次我们主要看一下通过它来实现
使用python 3.10.9 langchain0.3,以及百度千帆模型
环境准备
1 2 3 4 5 6 7 8 # 创建虚拟环境 $ python3 -m venv .venv # 激活虚拟环境 $ source .venv/bin/activate# 安装依赖 $ pip install langchain $ pip install langchain-community $ pip install qianfan
工具创建
提供给大模型的工具至少要有如下几个部分来说明它自己,以及让大模型判断如何使用,包含:名称、描述、参数(json schema)、以及是否在调用结束后直接返回给用户
langchain中支持如下三种方式创建工具:函数、Runnable (langchain_core.runnables) 以及 BaseTools(langchain_core.tools)子类
使用函数创建工具基本可以满足我们大部分的场景了,下面看一个具体的例子
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 from langchain_core.tools import tool@tool def add (a: int , b: int ) -> int : """Add tow integers. Args: a: First integer b: Second integer """ return a + b @tool def multiple (a: int , b: int ) -> int : """Multiple tow integers. Args: a: First integer b: Second integer """ return a * b print (add.name) print (add.description)print (add.args)print (add.return_direct)
将工具绑定到模型
1 2 3 4 5 6 7 8 9 10 os.environ["QIANFAN_AK" ] = "your-ak" os.environ["QIANFAN_SK" ] = "your-sk" llm = QianfanChatEndpoint(model="ERNIE-3.5-8K" ) tools = [add, multiple] llm_with_tools = llm.bind_tools(tools)
模型判断调用工具
大模型会根据问题来判断是否使用工具,以及使用何种工具
1 2 3 4 5 6 7 8 9 10 11 12 13 llm_with_tools.invoke("你好" ) response = llm_with_tools.invoke("3*15等于多少?" ) print (response.tool_calls)response = llm_with_tools.invoke("5+9等于多少?" ) print (response.tool_calls)
工具执行
有了如上信息后,我们就可以调用对应的工具进行最终的执行了
1 2 3 4 5 6 7 8 9 10 method_map = {"add" : add, "multiple" : multiple} response = llm_with_tools.invoke("5+9等于多少?" ) for call in response.tool_calls: selected_tool = method_map[call["name" ]] tool_res = selected_tool.invoke(call)
以上我们就完成了一个最简单的工具定义以及使用的流程,可以基于此完成更多更复杂,更有趣的功能~