Skip to content

Commit 85927c0

Browse files
author
GitHub Actions
committed
Update version to v0.0.130
1 parent 6353ba9 commit 85927c0

File tree

6 files changed

+373
-92
lines changed

6 files changed

+373
-92
lines changed

docs/capabilities/function-calling.mdx

Lines changed: 256 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ title: Function calling
44
sidebar_position: 2.5
55
---
66

7+
import Tabs from '@theme/Tabs';
8+
import TabItem from '@theme/TabItem';
9+
710
<a target="_blank" href="https://colab.research.google.com/github/mistralai/cookbook/blob/main/mistral/function_calling/function_calling.ipynb">
811
<img src="https://colab.research.google.com/assets/colab-badge.svg" alt="Open In Colab"/>
912
</a>
@@ -38,6 +41,9 @@ In this guide, we will walk through a simple example to demonstrate how function
3841

3942
Before we get started, let’s assume we have a dataframe consisting of payment transactions. When users ask questions about this dataframe, they can use certain tools to answer questions about this data. This is just an example to emulate an external database that the LLM cannot directly access.
4043

44+
<Tabs groupId="code">
45+
<TabItem value="python" label="python" default>
46+
4147
```python
4248
import pandas as pd
4349

@@ -54,6 +60,32 @@ data = {
5460
df = pd.DataFrame(data)
5561
```
5662

63+
</TabItem>
64+
<TabItem value="typescript" label="typescript">
65+
66+
```typescript
67+
// Assuming we have the following data
68+
const data = {
69+
transactionId: ['T1001', 'T1002', 'T1003', 'T1004', 'T1005'],
70+
customerId: ['C001', 'C002', 'C003', 'C002', 'C001'],
71+
paymentAmount: [125.50, 89.99, 120.00, 54.30, 210.20],
72+
paymentDate: ['2021-10-05', '2021-10-06', '2021-10-07', '2021-10-05', '2021-10-08'],
73+
paymentStatus: ['Paid', 'Unpaid', 'Paid', 'Paid', 'Pending']
74+
};
75+
76+
// Convert data into an array of objects for easier manipulation
77+
const transactions = data.transactionId.map((id, index) => ({
78+
transactionId: id,
79+
customerId: data.customerId[index],
80+
paymentAmount: data.paymentAmount[index],
81+
paymentDate: data.paymentDate[index],
82+
paymentStatus: data.paymentStatus[index]
83+
}));
84+
```
85+
86+
</TabItem>
87+
</Tabs>
88+
5789
## Step 1. User: specify tools and query
5890

5991
<img src="/img/guides/functioncalling2.png" alt="drawing" width="600"/>
@@ -63,6 +95,9 @@ Users can define all the necessary tools for their use cases.
6395

6496
- In many cases, we might have multiple tools at our disposal. For example, let’s consider we have two functions as our two tools: `retrieve_payment_status` and `retrieve_payment_date` to retrieve payment status and payment date given transaction ID.
6597

98+
<Tabs groupId="code">
99+
<TabItem value="python" label="python" default>
100+
66101
```python
67102
def retrieve_payment_status(df: data, transaction_id: str) -> str:
68103
if transaction_id in df.transaction_id.values:
@@ -73,11 +108,36 @@ def retrieve_payment_date(df: data, transaction_id: str) -> str:
73108
if transaction_id in df.transaction_id.values:
74109
return json.dumps({'date': df[df.transaction_id == transaction_id].payment_date.item()})
75110
return json.dumps({'error': 'transaction id not found.'})
111+
```
112+
</TabItem>
113+
<TabItem value="typescript" label="typescript">
114+
115+
```typescript
116+
function retrievePaymentStatus(transactions, transactionId) {
117+
const transaction = transactions.find(t => t.transactionId === transactionId);
118+
if (transaction) {
119+
return JSON.stringify({ status: transaction.paymentStatus });
120+
}
121+
return JSON.stringify({ error: 'transaction id not found.' });
122+
}
123+
124+
function retrievePaymentDate(transactions, transactionId) {
125+
const transaction = transactions.find(t => t.transactionId === transactionId);
126+
if (transaction) {
127+
return JSON.stringify({ date: transaction.paymentDate });
128+
}
129+
return JSON.stringify({ error: 'transaction id not found.' });
130+
}
76131
```
77132

133+
</TabItem>
134+
</Tabs>
78135

79136
- In order for Mistral models to understand the functions, we need to outline the function specifications with a JSON schema. Specifically, we need to describe the type, function name, function description, function parameters, and the required parameter for the function. Since we have two functions here, let’s list two function specifications in a list.
80137

138+
<Tabs groupId="code">
139+
<TabItem value="python" label="python" default>
140+
81141
```python
82142
tools = [
83143
{
@@ -117,8 +177,56 @@ tools = [
117177
]
118178
```
119179

180+
</TabItem>
181+
<TabItem value="typescript" label="typescript">
182+
183+
```typescript
184+
const tools = [
185+
{
186+
type: "function",
187+
function: {
188+
name: "retrievePaymentStatus",
189+
description: "Get payment status of a transaction",
190+
parameters: {
191+
type: "object",
192+
properties: {
193+
transactionId: {
194+
type: "string",
195+
description: "The transaction id.",
196+
}
197+
},
198+
required: ["transactionId"],
199+
},
200+
},
201+
},
202+
{
203+
type: "function",
204+
function: {
205+
name: "retrievePaymentDate",
206+
description: "Get payment date of a transaction",
207+
parameters: {
208+
type: "object",
209+
properties: {
210+
transactionId: {
211+
type: "string",
212+
description: "The transaction id.",
213+
}
214+
},
215+
required: ["transactionId"],
216+
},
217+
},
218+
}
219+
];
220+
```
221+
222+
</TabItem>
223+
</Tabs>
224+
120225
- Then we organize the two functions into a dictionary where keys represent the function name, and values are the function with the `df` defined. This allows us to call each function based on its function name.
121226

227+
<Tabs groupId="code">
228+
<TabItem value="python" label="python" default>
229+
122230
```python
123231
import functools
124232

@@ -128,13 +236,39 @@ names_to_functions = {
128236
}
129237
```
130238

239+
</TabItem>
240+
<TabItem value="typescript" label="typescript">
241+
242+
```typescript
243+
const namesToFunctions = {
244+
'retrievePaymentStatus': (transactionId) => retrievePaymentStatus(transactions, transactionId),
245+
'retrievePaymentDate': (transactionId) => retrievePaymentDate(transactions, transactionId)
246+
};
247+
```
248+
249+
</TabItem>
250+
</Tabs>
251+
131252
### User query
132253
Suppose a user asks the following question: “What’s the status of my transaction?” A standalone LLM would not be able to answer this question, as it needs to query the business logic backend to access the necessary data. But what if we have an exact tool we can use to answer this question? We could potentially provide an answer!
133254

255+
<Tabs groupId="code">
256+
<TabItem value="python" label="python" default>
257+
134258
```python
135259
messages = [{"role": "user", "content": "What's the status of my transaction T1001?"}]
136260
```
137261

262+
</TabItem>
263+
<TabItem value="typescript" label="typescript">
264+
265+
```typescript
266+
const messages = [{"role": "user", "content": "What's the status of my transaction T1001?"}];
267+
```
268+
269+
</TabItem>
270+
</Tabs>
271+
138272
## Step 2. Model: Generate function arguments
139273

140274
<img src="/img/guides/functioncalling3.png" alt="drawing" width="600"/>
@@ -148,6 +282,13 @@ Users can use `tool_choice` to specify how tools are used:
148282
- "any": forces tool use.
149283
- "none": prevents tool use.
150284

285+
### parallel_tool_calls
286+
Users can use `parallel_tool_calls` to specify whether parallel tool calling is allowed.
287+
- true: default mode. The model decides if it uses parallel tool calls or not.
288+
- false: forces the model to use single tool calling.
289+
290+
<Tabs groupId="code">
291+
<TabItem value="python" label="python" default>
151292

152293
```python
153294
import os
@@ -162,6 +303,7 @@ response = client.chat.complete(
162303
messages = messages,
163304
tools = tools,
164305
tool_choice = "any",
306+
parallel_tool_calls = False,
165307
)
166308
response
167309
```
@@ -172,12 +314,51 @@ Output:
172314
```
173315
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'))])
174316
```
317+
318+
</TabItem>
319+
<TabItem value="typescript" label="typescript">
320+
321+
```typescript
322+
import { Mistral } from '@mistralai/mistralai';
323+
324+
const apiKey = process.env.MISTRAL_API_KEY;
325+
const model = "mistral-large-latest";
326+
327+
const client = new Mistral({ apiKey: apiKey });
328+
329+
let response = await client.chat.complete({
330+
model: model,
331+
messages: messages,
332+
tools: tools,
333+
toolChoice: "any",
334+
parallelToolCalls: false,
335+
});
336+
```
337+
338+
We get the response including toolCalls with the chosen function name `retrievePaymentStatus` and the arguments for this function.
339+
340+
</TabItem>
341+
</Tabs>
342+
175343
Let’s add the response message to the `messages` list.
176344

345+
<Tabs groupId="code">
346+
<TabItem value="python" label="python" default>
347+
177348
```python
178349
messages.append(response.choices[0].message)
179350
```
180351

352+
</TabItem>
353+
<TabItem value="typescript" label="typescript">
354+
355+
```typescript
356+
messages.push(response.choices[0].message);
357+
```
358+
359+
</TabItem>
360+
</Tabs>
361+
181362
## Step 3. User: Execute function to obtain tool results
182363

183364
<img src="/img/guides/functioncalling4.png" alt="drawing" width="600"/>
@@ -186,6 +367,10 @@ How do we execute the function? Currently, it is the user’s responsibility to
186367

187368

188369
Let’s extract some useful function information from model response including `function_name` and `function_params`. It’s clear here that our Mistral model has chosen to use the function `retrieve_payment_status` with the parameter `transaction_id` set to T1001.
370+
371+
<Tabs groupId="code">
372+
<TabItem value="python" label="python" default>
373+
189374
```python
190375
import json
191376

@@ -199,8 +384,30 @@ Output
199384
function_name: retrieve_payment_status
200385
function_params: {'transaction_id': 'T1001'}
201386
```
387+
388+
</TabItem>
389+
<TabItem value="typescript" label="typescript">
390+
391+
```typescript
392+
const toolCall = response.choices[0].message.toolCalls[0];
393+
const functionName = toolCall.function.name;
394+
const functionParams = JSON.parse(toolCall.function.arguments);
395+
console.log("\nfunction_name: ", functionName, "\nfunction_params: ", functionParams);
396+
```
397+
Output
398+
```
399+
function_name: retrievePaymentStatus
400+
function_params: { transactionId: 'T1001' }
401+
```
402+
403+
</TabItem>
404+
</Tabs>
405+
202406
Now we can execute the function and we get the function output `'{"status": "Paid"}'`.
203407

408+
<Tabs groupId="code">
409+
<TabItem value="python" label="python" default>
410+
204411
```python
205412
function_result = names_to_functions[function_name](**function_params)
206413
function_result
@@ -210,14 +417,37 @@ Output
210417
'{"status": "Paid"}'
211418
```
212419

420+
</TabItem>
421+
<TabItem value="typescript" label="typescript">
422+
423+
```typescript
424+
const functionResult = namesToFunctions[functionName](functionParams.transactionId);
425+
console.log(functionResult);
426+
```
427+
Output
428+
```
429+
{"status":"Paid"}
430+
```
431+
432+
</TabItem>
433+
</Tabs>
434+
213435
## Step 4. Model: Generate final answer
214436

215437
<img src="/img/guides/functioncalling5.png" alt="drawing" width="600"/>
216438

217439
We can now provide the output from the tools to Mistral models, and in return, the Mistral model can produce a customised final response for the specific user.
218440

441+
<Tabs groupId="code">
442+
<TabItem value="python" label="python" default>
443+
219444
```python
220-
messages.append({"role":"tool", "name":function_name, "content":function_result, "tool_call_id":tool_call.id})
445+
messages.append({
446+
"role":"tool",
447+
"name":function_name,
448+
"content":function_result,
449+
"tool_call_id":tool_call.id
450+
})
221451

222452
response = client.chat.complete(
223453
model = model,
@@ -230,3 +460,28 @@ Output:
230460
```
231461
The status of your transaction with ID T1001 is "Paid". Is there anything else I can assist you with?
232462
```
463+
464+
</TabItem>
465+
<TabItem value="typescript" label="typescript">
466+
467+
```typescript
468+
messages.push({
469+
role: "tool",
470+
name: functionName,
471+
content: functionResult,
472+
toolCallId: toolCall.id
473+
});
474+
475+
response = await client.chat.complete({
476+
model: model,
477+
messages: messages
478+
});
479+
console.log(response.choices[0].message.content);
480+
```
481+
482+
Output:
483+
```
484+
The status of your transaction with ID T1001 is "Paid". Is there anything else I can assist you with?
485+
```
486+
</TabItem>
487+
</Tabs>

docs/capabilities/structured-output/custom.mdx

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -196,6 +196,15 @@ curl --location "https://api.mistral.ai/v1/chat/completions" \
196196
</TabItem>
197197
</Tabs>
198198

199+
:::note
200+
To better guide the model, the following is being always prepended by default to the System Prompt when using this method:
201+
```
202+
Your output should be an instance of a JSON object following this schema: {{ json_schema }}
203+
```
204+
205+
However, it is recommended to add more explanations and iterate on your system prompt to better clarify the expected schema and behavior.
206+
:::
207+
199208
### FAQ
200209
**Q: Which models support custom Structured Outputs?**
201210
**A:** All currently available models except for `codestral-mamba` are supported.

0 commit comments

Comments
 (0)