1.背景
近期在尝试使用langchain来构建基于RAG的智能助手。期间了解了function calling (函数调用) 相关的概念,所以就想记录下自己在那一瞬间对它的理解。我怕随着时间的流逝,某些一闪而过的灵感会消失。
2.那么啥是Function calling呢?
广义的function calling 是指让大模型能够调用外部工具的一种技术实现:先向大模型提供可用函数的列表及说明,由大模型在对话过程中智能判断是否需要调用函数,并自动生成调用所需的参数,最终用文字返回符合约定格式的函数调用请求。
狭义的function calling,大模型提供商在模型内部和API层面做了支持的一种能力
在模型层面:大模型提供商需要对大模型进行特别的强化训练,使其具备根据上下文正确选择合适函数,生成有效参数的能力
在API层面:你得开放出一个参数来支持function calling 。早起openai 提供一个functions的参数
3.Function calling有几种实现方式?
1基于提示词的Function calling
将函数列表和描述通过系统提示词的方式是给到大模型,让大模型在决定调用函数的时候,返回约定好的格式,便于后端应用去解析。
所以存在一些问题:
1.输出格式不稳定,返回的aimessage中可能存在多余的自然语言,大模型天生话痨。
2.对开发者要求还挺高,函数描述,调用的指令格式,提示词得有开发者设计
3.上下文冗长浪费token,在系统提示词中增加了大量的调用说明
4.还容易幻觉
2基于API的function calling
通过json schema的方式 传递工具。这个就要求大模型厂商对模型进行优化,支持函数调用能力。
模型智能判断是否需要调用函数,选择合适的参数,并基于上下文自动生成结构化的调用指令
所谓结构化调用指令,其实就是json格式,因为后端应用程序好能解析出函数名和参数
这种存在的唯一问题就是:
如果不同的大模型厂商 要求的函数描述的格式规定不同,以及返回来的调用指令的格式不同,那么应用每次接一个大模型,就需要自己去适配一套新的。 而且你没法要求所有大模型提供商都花费人力财力对大模型做训练。
4.❌ 错误理解(常见误区):
“大模型(LLM)自己会主动调用函数、执行代码。”
✅ 正确理解:
大模型本身不能、也不会直接调用任何函数或API。
所谓的 Function Calling,其实是:
模型输出一段结构化的文本(通常是JSON格式),描述“应该调用哪个函数、传什么参数”,然后由外部程序(你的代码)去解析这个文本,并真正执行函数调用。
官方文档中有一段这样的描述
Even though we typically refer to tool calling as a model capability, it is actually up to the client application to provide the tool calling logic. The model can only request a tool call and provide the input arguments, whereas the application is responsible for executing the tool call from the input arguments and returning the result. The model never gets access to any of the APIs provided as tools, which is a critical security consideration.
它大体的意思是说:尽管我们通常将 tool calling 视为模型能力,但实际上提供工具调用逻辑的是客户端应用程序。模型解析用户的意图,大模型只负责“决策”和“建议调用”,不负责“执行” 。也就是说大模型只会返回你可以调用哪个函数,调用的参数是什么。具体调用的逻辑需要客户端来实现。大模型永远没有权限去调用某个api的能力,这是 安全问题
5.function calling的流程:
官方文档中描述:
- When we want to make a tool available to the model, we include its definition in the chat request. Each tool definition comprises of a name, a description, and the schema of the input parameters.
- When the model decides to call a tool, it sends a response with the tool name and the input parameters modeled after the defined schema.
- The application is responsible for using the tool name to identify and execute the tool with the provided input parameters.
- The result of the tool call is processed by the application.
- The application sends the tool call result back to the model.
- The model generates the final response using the tool call result as additional context.
大体意思是:
-
当我们希望使一个工具对模型可用时,我们会将其定义包含在聊天请求中。每个工具的定义包括名称、描述和输入参数的schema。
-
当模型决定调用工具时,它会发送一个响应,其中包含工具名称和根据定义的模式建模的输入参数。
-
该应用程序负责使用工具名称来识别并执行具有提供输入参数的工具。
-
工具调用的结果由应用程序处理。
-
应用程序将工具调用结果返回给模型。
-
模型使用工具调用结果作为额外的上下文来生成最终的响应。
在openai的官方文档中我们看到一个全流程的flow
-
Make a request to the model with tools it could call
-
Receive a tool call from the model
-
Execute code on the application side with input from the tool call
-
Make a second request to the model with the tool output
-
Receive a final response from the model (or more tool calls)
首先就是发送请求给LLM的时候需要告诉LLM你可以调用哪些工具,
然后LLM在响应的时候会返回一个tool call,(就是告诉你调用那个功能,调用参数是什么)。
应用程序就会执行这段逻辑拿到输出结果。
接下来会再发一个请求,但是本次请求会使用到工具的输出结果。
大模型根据工具的输出结果,给出最终的相应。