docs: add support for mistral tool calling (#467)

This commit is contained in:
Ashank Tomar
2024-02-26 10:03:50 -08:00
committed by GitHub
parent 135229d554
commit 043a51eebe
5 changed files with 111 additions and 7 deletions
+74
View File
@@ -0,0 +1,74 @@
---
draft: False
date: 2024-02-26
slug: mistral
tags:
- patching
authors:
- shanktt
---
# Structured Outputs with Mistral Large
If you want to try this example using `instructor hub`, you can pull it by running
```bash
instructor hub pull --slug mistral --py > mistral_example.py
```
Mistral Large is the flagship model from Mistral AI, supporting 32k context windows and functional calling abilities. Mistral Large's addition of [function calling](https://docs.mistral.ai/guides/function-calling/) makes it possible to obtain structured outputs using JSON schema.
By the end of this blog post, you will learn how to effectively utilize Instructor with Mistral Large.
<!-- more -->
## Patching
Instructor's patch enhances the mistral api with the following features:
- `response_model` in `create` calls that returns a pydantic model
- `max_retries` in `create` calls that retries the call if it fails by using a backoff strategy
!!! note "Learn More"
To learn more, please refer to the [docs](../index.md). To understand the benefits of using Pydantic with Instructor, visit the tips and tricks section of the [why use Pydantic](../why.md) page.
## Mistral Client
The Mistral client employs a different client than OpenAI, making the patching process slightly different than other examples
!!! note "Getting access"
If you want to try this out for yourself check out the [Mistral AI](https://mistral.ai/) website. You can get started [here](https://docs.mistral.ai/).
```python
from pydantic import BaseModel
from mistralai.client import MistralClient
from instructor.patch import patch
from instructor.function_calls import Mode
class UserDetails(BaseModel):
name: str
age: int
# enables `response_model` in chat call
client = MistralClient()
patched_chat = patch(create=client.chat, mode=Mode.MISTRAL_TOOLS)
resp = patched_chat(
model="mistral-large-latest",
response_model=UserDetails,
messages=[
{
"role": "user",
"content": f'Extract the following entities: "Jason is 20"',
},
],
)
print(resp)
#> name='Jason' age=20
```
+26
View File
@@ -0,0 +1,26 @@
from pydantic import BaseModel
from mistralai.client import MistralClient
from instructor.patch import patch
from instructor.function_calls import Mode
class UserDetails(BaseModel):
name: str
age: int
# enables `response_model` in chat call
client = MistralClient()
patched_chat = patch(create=client.chat, mode=Mode.MISTRAL_TOOLS)
resp = patched_chat(
model="mistral-large-latest",
response_model=UserDetails,
messages=[
{
"role": "user",
"content": f'Extract the following entities: "Jason is 20"',
},
],
)
print(resp)
+2 -1
View File
@@ -15,6 +15,7 @@ class Mode(enum.Enum):
FUNCTIONS: str = "function_call"
PARALLEL_TOOLS: str = "parallel_tool_call"
TOOLS: str = "tool_call"
MISTRAL_TOOLS: str = "mistral_tools"
JSON: str = "json_mode"
MD_JSON: str = "markdown_json_mode"
JSON_SCHEMA: str = "json_schema_mode"
@@ -114,7 +115,7 @@ class OpenAISchema(BaseModel): # type: ignore[misc]
context=validation_context,
strict=strict,
)
elif mode == Mode.TOOLS:
elif mode in {Mode.TOOLS, Mode.MISTRAL_TOOLS}:
assert (
len(message.tool_calls) == 1
), "Instructor does not support multiple tool calls, use List[Model] instead."
+8 -5
View File
@@ -116,17 +116,20 @@ def handle_response_model(
if mode == Mode.FUNCTIONS:
new_kwargs["functions"] = [response_model.openai_schema] # type: ignore
new_kwargs["function_call"] = {"name": response_model.openai_schema["name"]} # type: ignore
elif mode == Mode.TOOLS:
elif mode in {Mode.TOOLS, Mode.MISTRAL_TOOLS}:
new_kwargs["tools"] = [
{
"type": "function",
"function": response_model.openai_schema,
}
]
new_kwargs["tool_choice"] = {
"type": "function",
"function": {"name": response_model.openai_schema["name"]},
}
if mode == Mode.MISTRAL_TOOLS:
new_kwargs["tool_choice"] = "any"
else:
new_kwargs["tool_choice"] = {
"type": "function",
"function": {"name": response_model.openai_schema["name"]},
}
elif mode in {Mode.JSON, Mode.MD_JSON, Mode.JSON_SCHEMA}:
# If its a JSON Mode we need to massage the prompt a bit
# in order to get the response we want in a json format
+1 -1
View File
@@ -177,7 +177,7 @@ nav:
- Action Items: 'hub/action_items.md'
- Partial Streaming: 'hub/partial_streaming.md'
- Extract Contact Info: 'hub/extract_contact_info.md'
- Using Mistral Large: 'hub/mistral.md'
- Tutorials:
- Tutorials (Notebooks): 'tutorials/1-introduction.ipynb'
- Tips and Tricks: 'tutorials/2-tips.ipynb'