Mistral AI API Integration
Integrates Mistral AI API using the mistralai Python SDK for chat completions, embeddings, function calling, code generation (Codestral), and agent building. When loaded, this skill makes the model implement Mistral API calls with proper authentication, streaming, and error handling.
Core Workflow
- Initialize the Client: Create a
MistralClient() (sync) or MistralAsyncClient() (async) with the API key from the MISTRAL_API_KEY environment variable. The SDK provides typed request/response models with Pydantic. Checkpoint: Verify by listing models with client.list_models().
- Send a Chat Completion: Use
client.chat() with model (e.g., "mistral-large-latest"), messages (list of role/content dicts), and optional temperature and max_tokens. Mistral supports system, user, and assistant roles. Checkpoint: Verify response.choices[0].message.content is non-empty.
- Implement Function Calling: Define tools with
type: "function" containing name, description, and parameters JSON schema. Pass them to client.chat() with tools parameter. Handle tool_calls in the response and return results via additional messages. Checkpoint: Check response.choices[0].finish_reason — "tool_calls" means the model wants to execute tools.
- Generate Embeddings: Use
client.embeddings() with model (e.g., "mistral-embed") and input (string or list of strings). Mistral embeddings produce 1024-dimensional vectors suitable for semantic search and RAG. Checkpoint: Verify vector dimensions via len(embedding).
- Generate Code with Codestral: Use
client.chat() with the codestral-latest model for code generation tasks. Codestral supports fill-in-the-middle via the codestral endpoint with prompt and suffix parameters. Checkpoint: For fill-in-the-middle, verify the generated code correctly bridges the prefix and suffix.
Implementation Patterns
Pattern 1: Chat Completion with Streaming
from __future__ import annotations
from mistralai import Mistral
# ❌ BAD — no error handling, no streaming, no async
from mistralai.client import MistralClient
client = MistralClient(api_key="...")
response = client.chat(model="mistral-large-latest", messages=[{"role": "user", "content": "Hi"}])
print(response.choices[0].message.content)
# ✅ GOOD — env-based auth, streaming, typed error handling
client = Mistral() # reads MISTRAL_API_KEY from environment
def chat(
prompt: str,
model: str = "mistral-large-latest",
temperature: float = 0.7,
) -> str:
"""Send a chat message and get a complete response.
Args:
prompt: User message.
model: Mistral model identifier.
temperature: Sampling temperature (0.0 to 1.0).
Returns:
The model's response text.
Raises:
ValueError: On authentication errors.
RuntimeError: On API failures.
"""
try:
response = client.chat.complete(
model=model,
messages=[{"role": "user", "content": prompt}],
temperature=temperature,
)
return response.choices[0].message.content
except Exception as e:
error_str = str(e)
if "401" in error_str or "unauthorized" in error_str.lower():
raise ValueError("Invalid Mistral API key.") from e
raise RuntimeError(f"Mistral API error: {e}") from e
def chat_stream(
prompt: str,
model: str = "mistral-large-latest",
) -> str:
"""Stream a chat response from Mistral.
Args:
prompt: User message.
model: Mistral model identifier.
Returns:
Accumulated response text.
"""
accumulated = ""
stream = client.chat.stream(
model=model,
messages=[{"role": "user", "content": prompt}],
)
for chunk in stream:
if chunk.data.choices[0].delta.content:
content = chunk.data.choices[0].delta.content
print(content, end="", flush=True)
accumulated += content
return accumulated
Pattern 2: Function Calling
from __future__ import annotations
from typing import Any
from mistralai import Mistral
client = Mistral()
def get_weather(location: str) -> dict[str, Any]:
"""Mock weather function."""
return {"location": location, "temperature": 72, "condition": "sunny"}
TOOLS: list[dict[str, Any]] = [
{
"type": "function",
"function": {
"name": "get_weather",
"description": "Get current weather for a location",
"parameters": {
"type": "object",
"properties": {
"location": {
"type": "string",
"description": "City name, e.g., Paris",
}
},
"required": ["location"],
},
},
}
]
def ask_with_tools(prompt: str) -> str:
"""Ask a question with tool use capabilities.
Args:
prompt: User's question that may require function calling.
Returns:
Final response after any tool calls are resolved.
"""
messages: list[dict[str, Any]] = [
{"role": "user", "content": prompt}
]
response = client.chat.complete(
model="mistral-large-latest",
messages=messages,
tools=TOOLS,
temperature=0,
)
assistant = response.choices[0].message
if assistant.tool_calls:
messages.append({
"role": "assistant",
"content": assistant.content,
"tool_calls": assistant.tool_calls,
})
for tc in assistant.tool_calls:
if tc.function.name == "get_weather":
import json
args = json.loads(tc.function.arguments)
result = get_weather(**args)
messages.append({
"role": "tool",
"name": "get_weather",
"content": json.dumps(result),
"tool_call_id": tc.id,
})
final = client.chat.complete(
model="mistral-large-latest",
messages=messages,
tools=TOOLS,
)
return final.choices[0].message.content
return assistant.content
Pattern 3: Embeddings
from __future__ import annotations
from mistralai import Mistral
client = Mistral()
def embed_texts(
texts: list[str],
model: str = "mistral-embed",
) -> list[list[float]]:
"""Generate embeddings for a list of texts.
Args:
texts: List of text strings to embed.
model: Embedding model name.
Returns:
List of embedding vectors (1024-dimensional).
"""
response = client.embeddings.create(
model=model,
inputs=texts,
)
return [data.embedding for data in response.data]
Constraints
MUST DO
- Read API key from
MISTRAL_API_KEY environment variable
- Use the
mistralai package (v1.0+) with the Mistral() constructor
- Use
client.chat.stream() for streaming responses and client.chat.complete() for single responses
- Use
codestral-latest model for code generation and fill-in-the-middle tasks
- Handle
tool_calls in the response to support function calling workflows
MUST NOT DO
- Hardcode API keys in source files
- Use the deprecated
MistralClient(api_key=...) constructor — use Mistral() instead
- Skip temperature setting for function calling (set to 0 for deterministic behavior)
- Use the default model without specifying an explicit model version (use
-latest or pin a version)
Live References
Related Skills
| Skill |
Purpose |
| coding-openai-api |
Alternative LLM provider |
| coding-cohere-api |
Alternative embedding and reranking provider |
| coding-langchain |
LangChain integration with Mistral models |
1---2name: mistral-api3description: Integrates Mistral AI API (Chat, Embeddings, Function Calling, Codestral, Agents) using the mistralai Python SDK for LLM and code generation applications.4license: MIT5---678910# Mistral AI API Integration11Integrates Mistral AI API using the `mistralai` Python SDK for chat completions, embeddings, function calling, code generation (Codestral), and agent building. When loaded, this skill makes the model implement Mistral API calls with proper authentication, streaming, and error handling.1213## Core Workflow14151. **Initialize the Client:** Create a `MistralClient()` (sync) or `MistralAsyncClient()` (async) with the API key from the `MISTRAL_API_KEY` environment variable. The SDK provides typed request/response models with Pydantic. **Checkpoint:** Verify by listing models with `client.list_models()`. 162. **Send a Chat Completion:** Use `client.chat()` with `model` (e.g., `"mistral-large-latest"`), `messages` (list of role/content dicts), and optional `temperature` and `max_tokens`. Mistral supports system, user, and assistant roles. **Checkpoint:** Verify `response.choices[0].message.content` is non-empty. 173. **Implement Function Calling:** Define tools with `type: "function"` containing name, description, and `parameters` JSON schema. Pass them to `client.chat()` with `tools` parameter. Handle `tool_calls` in the response and return results via additional messages. **Checkpoint:** Check `response.choices[0].finish_reason` — `"tool_calls"` means the model wants to execute tools. 184. **Generate Embeddings:** Use `client.embeddings()` with `model` (e.g., `"mistral-embed"`) and `input` (string or list of strings). Mistral embeddings produce 1024-dimensional vectors suitable for semantic search and RAG. **Checkpoint:** Verify vector dimensions via `len(embedding)`. 195. **Generate Code with Codestral:** Use `client.chat()` with the `codestral-latest` model for code generation tasks. Codestral supports fill-in-the-middle via the `codestral` endpoint with `prompt` and `suffix` parameters. **Checkpoint:** For fill-in-the-middle, verify the generated code correctly bridges the prefix and suffix.2021---22## Implementation Patterns2324### Pattern 1: Chat Completion with Streaming25```python26from __future__ import annotations2728from mistralai import Mistral2930# ❌ BAD — no error handling, no streaming, no async31from mistralai.client import MistralClient32client = MistralClient(api_key="...")33response = client.chat(model="mistral-large-latest", messages=[{"role": "user", "content": "Hi"}])34print(response.choices[0].message.content)3536# ✅ GOOD — env-based auth, streaming, typed error handling37client = Mistral() # reads MISTRAL_API_KEY from environment3839def chat(40 prompt: str,41 model: str = "mistral-large-latest",42 temperature: float = 0.7,43) -> str:44 """Send a chat message and get a complete response.4546 Args:47 prompt: User message.48 model: Mistral model identifier.49 temperature: Sampling temperature (0.0 to 1.0).5051 Returns:52 The model's response text.5354 Raises:55 ValueError: On authentication errors.56 RuntimeError: On API failures.57 """58 try:59 response = client.chat.complete(60 model=model,61 messages=[{"role": "user", "content": prompt}],62 temperature=temperature,63 )64 return response.choices[0].message.content65 except Exception as e:66 error_str = str(e)67 if "401" in error_str or "unauthorized" in error_str.lower():68 raise ValueError("Invalid Mistral API key.") from e69 raise RuntimeError(f"Mistral API error: {e}") from e707172def chat_stream(73 prompt: str,74 model: str = "mistral-large-latest",75) -> str:76 """Stream a chat response from Mistral.7778 Args:79 prompt: User message.80 model: Mistral model identifier.8182 Returns:83 Accumulated response text.84 """85 accumulated = ""86 stream = client.chat.stream(87 model=model,88 messages=[{"role": "user", "content": prompt}],89 )90 for chunk in stream:91 if chunk.data.choices[0].delta.content:92 content = chunk.data.choices[0].delta.content93 print(content, end="", flush=True)94 accumulated += content95 return accumulated96```9798### Pattern 2: Function Calling99```python100from __future__ import annotations101102from typing import Any103from mistralai import Mistral104105client = Mistral()106107def get_weather(location: str) -> dict[str, Any]:108 """Mock weather function."""109 return {"location": location, "temperature": 72, "condition": "sunny"}110111112TOOLS: list[dict[str, Any]] = [113 {114 "type": "function",115 "function": {116 "name": "get_weather",117 "description": "Get current weather for a location",118 "parameters": {119 "type": "object",120 "properties": {121 "location": {122 "type": "string",123 "description": "City name, e.g., Paris",124 }125 },126 "required": ["location"],127 },128 },129 }130]131132def ask_with_tools(prompt: str) -> str:133 """Ask a question with tool use capabilities.134135 Args:136 prompt: User's question that may require function calling.137138 Returns:139 Final response after any tool calls are resolved.140 """141 messages: list[dict[str, Any]] = [142 {"role": "user", "content": prompt}143 ]144145 response = client.chat.complete(146 model="mistral-large-latest",147 messages=messages,148 tools=TOOLS,149 temperature=0,150 )151152 assistant = response.choices[0].message153154 if assistant.tool_calls:155 messages.append({156 "role": "assistant",157 "content": assistant.content,158 "tool_calls": assistant.tool_calls,159 })160161 for tc in assistant.tool_calls:162 if tc.function.name == "get_weather":163 import json164 args = json.loads(tc.function.arguments)165 result = get_weather(**args)166 messages.append({167 "role": "tool",168 "name": "get_weather",169 "content": json.dumps(result),170 "tool_call_id": tc.id,171 })172173 final = client.chat.complete(174 model="mistral-large-latest",175 messages=messages,176 tools=TOOLS,177 )178 return final.choices[0].message.content179180 return assistant.content181```182183### Pattern 3: Embeddings184```python185from __future__ import annotations186187from mistralai import Mistral188189client = Mistral()190191def embed_texts(192 texts: list[str],193 model: str = "mistral-embed",194) -> list[list[float]]:195 """Generate embeddings for a list of texts.196197 Args:198 texts: List of text strings to embed.199 model: Embedding model name.200201 Returns:202 List of embedding vectors (1024-dimensional).203 """204 response = client.embeddings.create(205 model=model,206 inputs=texts,207 )208 return [data.embedding for data in response.data]209```210211---212## Constraints213### MUST DO214- Read API key from `MISTRAL_API_KEY` environment variable215- Use the `mistralai` package (v1.0+) with the `Mistral()` constructor216- Use `client.chat.stream()` for streaming responses and `client.chat.complete()` for single responses217- Use `codestral-latest` model for code generation and fill-in-the-middle tasks218- Handle `tool_calls` in the response to support function calling workflows219### MUST NOT DO220- Hardcode API keys in source files221- Use the deprecated `MistralClient(api_key=...)` constructor — use `Mistral()` instead222- Skip temperature setting for function calling (set to 0 for deterministic behavior)223- Use the default model without specifying an explicit model version (use `-latest` or pin a version)224---225## Live References226| Resource | URL |227|----------|-----|228| Mistral AI Python SDK (PyPI) | https://pypi.org/project/mistralai/ |229| Mistral API Documentation | https://docs.mistral.ai/ |230| Mistral API Reference | https://docs.mistral.ai/api/ |231| Mistral Function Calling | https://docs.mistral.ai/capabilities/function-calling/ |232| Codestral Documentation | https://docs.mistral.ai/capabilities/code-generation/ |233| Mistral GitHub | https://github.com/mistralai/client-python |234---235## Related Skills236| Skill | Purpose |237|-------|---------|238| coding-openai-api | Alternative LLM provider |239| coding-cohere-api | Alternative embedding and reranking provider |240| coding-langchain | LangChain integration with Mistral models |