函数调用
函数调用使 Mistral 模型能够连接到外部工具。通过将 Mistral 模型与用户定义的函数或 API 等外部工具集成,用户可以轻松构建适用于特定用例和实际问题的应用程序。例如,在本指南中,我们编写了两个函数用于跟踪支付状态和支付日期。我们可以使用这两个工具来提供与支付相关的查询的答案。
可用模型
目前,以下模型支持函数调用
- Mistral Large
- Mistral Medium
- Mistral Small
- Codestral
- Ministral 8B
- Ministral 3B
- Pixtral 12B
- Pixtral Large
- Mistral Nemo
四个步骤
概述来说,函数调用有四个步骤
- 用户:指定工具和查询
- 模型:生成函数参数(如适用)
- 用户:执行函数以获取工具结果
- 模型:生成最终答案

在本指南中,我们将通过一个简单的例子来演示函数调用如何在 Mistral 模型中通过这四个步骤工作。
在开始之前,我们假设有一个包含支付交易的数据帧(dataframe)。当用户询问有关此数据帧的问题时,他们可以使用某些工具来回答有关此数据的问题。这只是一个模拟 LLM 无法直接访问的外部数据库的示例。
- python
- typescript
import pandas as pd
# Assuming we have the following data
data = {
'transaction_id': ['T1001', 'T1002', 'T1003', 'T1004', 'T1005'],
'customer_id': ['C001', 'C002', 'C003', 'C002', 'C001'],
'payment_amount': [125.50, 89.99, 120.00, 54.30, 210.20],
'payment_date': ['2021-10-05', '2021-10-06', '2021-10-07', '2021-10-05', '2021-10-08'],
'payment_status': ['Paid', 'Unpaid', 'Paid', 'Paid', 'Pending']
}
# Create DataFrame
df = pd.DataFrame(data)
// Assuming we have the following data
const data = {
transactionId: ['T1001', 'T1002', 'T1003', 'T1004', 'T1005'],
customerId: ['C001', 'C002', 'C003', 'C002', 'C001'],
paymentAmount: [125.50, 89.99, 120.00, 54.30, 210.20],
paymentDate: ['2021-10-05', '2021-10-06', '2021-10-07', '2021-10-05', '2021-10-08'],
paymentStatus: ['Paid', 'Unpaid', 'Paid', 'Paid', 'Pending']
};
// Convert data into an array of objects for easier manipulation
const transactions = data.transactionId.map((id, index) => ({
transactionId: id,
customerId: data.customerId[index],
paymentAmount: data.paymentAmount[index],
paymentDate: data.paymentDate[index],
paymentStatus: data.paymentStatus[index]
}));
步骤 1. 用户:指定工具和查询

工具
用户可以为他们的用例定义所有必要的工具。
- 在许多情况下,我们可能有多个工具可供使用。例如,假设我们有两个函数作为工具:
retrieve_payment_status
用于获取支付状态,retrieve_payment_date
用于获取给定交易 ID 的支付日期。
- python
- typescript
def retrieve_payment_status(df: data, transaction_id: str) -> str:
if transaction_id in df.transaction_id.values:
return json.dumps({'status': df[df.transaction_id == transaction_id].payment_status.item()})
return json.dumps({'error': 'transaction id not found.'})
def retrieve_payment_date(df: data, transaction_id: str) -> str:
if transaction_id in df.transaction_id.values:
return json.dumps({'date': df[df.transaction_id == transaction_id].payment_date.item()})
return json.dumps({'error': 'transaction id not found.'})
function retrievePaymentStatus(transactions, transactionId) {
const transaction = transactions.find(t => t.transactionId === transactionId);
if (transaction) {
return JSON.stringify({ status: transaction.paymentStatus });
}
return JSON.stringify({ error: 'transaction id not found.' });
}
function retrievePaymentDate(transactions, transactionId) {
const transaction = transactions.find(t => t.transactionId === transactionId);
if (transaction) {
return JSON.stringify({ date: transaction.paymentDate });
}
return JSON.stringify({ error: 'transaction id not found.' });
}
- 为了让 Mistral 模型理解这些函数,我们需要使用 JSON schema 来定义函数规范。具体来说,我们需要描述函数的类型、函数名、函数描述、函数参数以及函数所需的参数。由于这里有两个函数,我们将列出两个函数的规范。
- python
- typescript
tools = [
{
"type": "function",
"function": {
"name": "retrieve_payment_status",
"description": "Get payment status of a transaction",
"parameters": {
"type": "object",
"properties": {
"transaction_id": {
"type": "string",
"description": "The transaction id.",
}
},
"required": ["transaction_id"],
},
},
},
{
"type": "function",
"function": {
"name": "retrieve_payment_date",
"description": "Get payment date of a transaction",
"parameters": {
"type": "object",
"properties": {
"transaction_id": {
"type": "string",
"description": "The transaction id.",
}
},
"required": ["transaction_id"],
},
},
}
]
const tools = [
{
type: "function",
function: {
name: "retrievePaymentStatus",
description: "Get payment status of a transaction",
parameters: {
type: "object",
properties: {
transactionId: {
type: "string",
description: "The transaction id.",
}
},
required: ["transactionId"],
},
},
},
{
type: "function",
function: {
name: "retrievePaymentDate",
description: "Get payment date of a transaction",
parameters: {
type: "object",
properties: {
transactionId: {
type: "string",
description: "The transaction id.",
}
},
required: ["transactionId"],
},
},
}
];
- 然后我们将这两个函数组织到一个字典中,其中键表示函数名,值是定义了
df
的函数。这使得我们可以根据函数名调用每个函数。
- python
- typescript
import functools
names_to_functions = {
'retrieve_payment_status': functools.partial(retrieve_payment_status, df=df),
'retrieve_payment_date': functools.partial(retrieve_payment_date, df=df)
}
const namesToFunctions = {
'retrievePaymentStatus': (transactionId) => retrievePaymentStatus(transactions, transactionId),
'retrievePaymentDate': (transactionId) => retrievePaymentDate(transactions, transactionId)
};
用户查询
假设用户提出以下问题:“我的交易状态是什么?” 一个独立的 LLM 无法回答这个问题,因为它需要查询业务逻辑后端来访问必要的数据。但如果我们有一个可以用来回答这个问题的工具呢?我们就有可能提供一个答案!
- python
- typescript
messages = [{"role": "user", "content": "What's the status of my transaction T1001?"}]
const messages = [{"role": "user", "content": "What's the status of my transaction T1001?"}];
步骤 2. 模型:生成函数参数

Mistral 模型如何知道这些函数以及使用哪个函数?我们将用户查询和工具规范都提供给 Mistral 模型。这一步骤的目标不是让 Mistral 模型直接运行函数。而是 1) 确定要使用的适当函数,2) 识别函数是否缺少任何必要信息,以及 3) 为所选函数生成必要的参数。
tool_choice
用户可以使用 tool_choice
来指定如何使用工具
- "auto":默认模式。模型决定是否使用该工具。
- "any":强制使用工具。
- "none":阻止使用工具。
parallel_tool_calls
用户可以使用 parallel_tool_calls
来指定是否允许并行工具调用。
- true:默认模式。模型决定是否使用并行工具调用。
- false:强制模型使用单个工具调用。
- python
- typescript
import os
from mistralai import Mistral
api_key = os.environ["MISTRAL_API_KEY"]
model = "mistral-large-latest"
client = Mistral(api_key=api_key)
response = client.chat.complete(
model = model,
messages = messages,
tools = tools,
tool_choice = "any",
parallel_tool_calls = False,
)
response
我们得到包含 tool_calls 的响应,其中包含选定的函数名 retrieve_payment_status
和该函数的参数。
输出
ChatCompletionResponse(id='7cbd8962041442459eb3636e1e3cbf10', object='chat.completion', model='mistral-large-latest', usage=Usage(prompt_tokens=94, completion_tokens=30, total_tokens=124), created=1721403550, choices=[Choices(index=0, finish_reason='tool_calls', message=AssistantMessage(content='', tool_calls=[ToolCall(function=FunctionCall(name='retrieve_payment_status', arguments='{"transaction_id": "T1001"}'), id='D681PevKs', type='function')], prefix=False, role='assistant'))])
import { Mistral } from '@mistralai/mistralai';
const apiKey = process.env.MISTRAL_API_KEY;
const model = "mistral-large-latest";
const client = new Mistral({ apiKey: apiKey });
let response = await client.chat.complete({
model: model,
messages: messages,
tools: tools,
toolChoice: "any",
parallelToolCalls: false,
});
我们得到包含 toolCalls 的响应,其中包含选定的函数名 retrievePaymentStatus
和该函数的参数。
我们将响应消息添加到 messages
列表中。
- python
- typescript
messages.append(response.choices[0].message)
messages.push(response.choices[0].message);
步骤 3. 用户:执行函数以获取工具结果

我们如何执行函数?目前,执行这些函数是用户的责任,并且函数执行发生在用户端。将来,我们可能会引入一些可以在服务器端执行的有用函数。
让我们从模型响应中提取一些有用的函数信息,包括 function_name
和 function_params
。这里清楚地表明,我们的 Mistral 模型选择了使用函数 retrieve_payment_status
,并将参数 transaction_id
设置为 T1001。
- python
- typescript
import json
tool_call = response.choices[0].message.tool_calls[0]
function_name = tool_call.function.name
function_params = json.loads(tool_call.function.arguments)
print("\nfunction_name: ", function_name, "\nfunction_params: ", function_params)
输出
function_name: retrieve_payment_status
function_params: {'transaction_id': 'T1001'}
const toolCall = response.choices[0].message.toolCalls[0];
const functionName = toolCall.function.name;
const functionParams = JSON.parse(toolCall.function.arguments);
console.log("\nfunction_name: ", functionName, "\nfunction_params: ", functionParams);
输出
function_name: retrievePaymentStatus
function_params: { transactionId: 'T1001' }
现在我们可以执行函数并获得函数输出 '{"status": "Paid"}'
。
- python
- typescript
function_result = names_to_functions[function_name](**function_params)
function_result
输出
'{"status": "Paid"}'
const functionResult = namesToFunctions[functionName](functionParams.transactionId);
console.log(functionResult);
输出
{"status":"Paid"}
步骤 4. 模型:生成最终答案

现在我们可以将工具的输出提供给 Mistral 模型,作为回报,Mistral 模型可以为特定用户生成定制的最终响应。
- python
- typescript
messages.append({
"role":"tool",
"name":function_name,
"content":function_result,
"tool_call_id":tool_call.id
})
response = client.chat.complete(
model = model,
messages = messages
)
response.choices[0].message.content
输出
The status of your transaction with ID T1001 is "Paid". Is there anything else I can assist you with?
messages.push({
role: "tool",
name: functionName,
content: functionResult,
toolCallId: toolCall.id
});
response = await client.chat.complete({
model: model,
messages: messages
});
console.log(response.choices[0].message.content);
输出
The status of your transaction with ID T1001 is "Paid". Is there anything else I can assist you with?