Conectores, herramientas y agentes con las API de Completions
Usa conectores, herramientas integradas y agentes con la API de Chat Completions (/v1/chat/completions) y la API de Agent Completions (/v1/agents/completions).
Soporte del SDK: El SDK
mistralaies compatible con herramientas tipo conector enchat.complete(). Ten en cuenta que las respuestas usanmessages(array) en lugar demessage(objeto) cuando se invocan herramientas.
Requisitos previos
Instalar
# Python
pip install mistralai
# or with uv
uv add mistralai
# TypeScript / Node.js
npm install @mistralai/mistralai
Variables de entorno requeridas
Para completar este manual, necesitarás una clave API de Mistral. En Studio, navega a la sección de claves API y crea una nueva clave API.
Crea un .env en la raíz de tu proyecto y agrega tu clave API de Mistral:
MISTRAL_API_KEY=your-mistral-api-key
Lo que necesitas antes de empezar
La mayoría de las recetas asumen:
- Una
MISTRAL_API_KEYválida - Un conector existente para recetas de conectores personalizados — consulta Crear un agente asesor de bases de datos para ver un ejemplo completo del ciclo de vida de un conector, o crea uno en Studio
Conversaciones vs. Completions — Cuándo usar cada una
Mistral ofrece dos API para interactuar con modelos:
| Característica | API de Conversaciones | API de Chat Completions |
|---|---|---|
| Endpoint | /v1/conversations |
/v1/chat/completions |
| Soporte del SDK | client.beta.conversations |
client.chat.complete() |
| Formato de respuesta | outputs[] con type: "message.output" |
choices[] con messages (array) cuando se usan herramientas |
| Estado de múltiples turnos | Sin estado (envía el historial completo en cada llamada) | Sin estado (envía el historial completo en cada llamada) |
| Ejecución de herramientas | En el servidor (automática) | En el servidor con formato multi_completion |
| Mejor para | Nuevas integraciones, flujos de trabajo de agentes | Aplicaciones compatibles con OpenAI, implementaciones de chat existentes |
Usa Chat Completions cuando:
- Estás migrando desde OpenAI y quieres un formato de respuesta familiar
- Tu código existente usa la estructura
choices[].message - Necesitas compatibilidad con SDKs estilo OpenAI
Usa Conversaciones cuando:
- Estás creando nuevas integraciones desde cero
- Quieres la superficie de API recomendada y más reciente
- Estás usando las características beta del SDK
Lectura de respuestas de Completion
Las chat completions con herramientas devuelven respuestas en un formato multi_completion donde cada opción contiene un array messages en lugar de un solo message. El siguiente asistente maneja ambos formatos.
Python (SDK):
def display_response(response) -> None:
"""Display text content from SDK chat completion response.
When using connector tools, responses use `messages` array instead of `message`.
"""
for choice in response.choices:
# Handle multi_completion format (messages array) - used with connector tools
if hasattr(choice, 'messages') and choice.messages:
for message in choice.messages:
content = message.content
if content:
if isinstance(content, str):
print(content[:500] if len(content) > 500 else content)
elif isinstance(content, list):
for chunk in content:
if hasattr(chunk, 'type'):
if chunk.type == "text":
print(getattr(chunk, 'text', ''))
elif chunk.type == "image_url":
print(f"[Image: {getattr(chunk, 'image_url', '')[:80]}...]")
tool_calls = getattr(message, 'tool_calls', None)
if tool_calls:
print(f"Tool calls: {len(tool_calls)}")
for tc in tool_calls:
func = tc.function
print(f" - {func.name}: {func.arguments}")
# Handle standard completion format (single message)
elif hasattr(choice, 'message') and choice.message:
message = choice.message
content = message.content
if content:
print(content[:500] if len(content) > 500 else content)
tool_calls = getattr(message, 'tool_calls', None)
if tool_calls:
print(f"Tool calls: {len(tool_calls)}")
for tc in tool_calls:
func = tc.function
print(f" - {func.name}: {func.arguments}")
TypeScript:
function displayResponse(data: any): void {
for (const choice of data.choices ?? []) {
// Handle multi_completion format (messages array)
const messages = choice.messages ?? [];
if (messages.length > 0) {
for (const message of messages) {
const content = message.content;
if (content) {
if (typeof content === "string") {
console.log(content.length > 500 ? content.slice(0, 500) : content);
} else if (Array.isArray(content)) {
for (const chunk of content) {
if (chunk.type === "text") {
console.log(chunk.text ?? "");
} else if (chunk.type === "image_url") {
console.log(`[Image: ${(chunk.image_url ?? "").slice(0, 80)}...]`);
}
}
}
}
const toolCalls = message.tool_calls ?? [];
if (toolCalls.length > 0) {
console.log(`Tool calls: ${toolCalls.length}`);
for (const tc of toolCalls) {
const func = tc.function ?? {};
console.log(` - ${func.name}: ${func.arguments}`);
}
}
}
// Handle standard completion format (single message)
} else {
const message = choice.message ?? {};
const content = message.content;
if (content) {
console.log(typeof content === "string" && content.length > 500 ? content.slice(0, 500) : content);
}
const toolCalls = message.tool_calls ?? [];
if (toolCalls.length > 0) {
console.log(`Tool calls: ${toolCalls.length}`);
for (const tc of toolCalls) {
const func = tc.function ?? {};
console.log(` - ${func.name}: ${func.arguments}`);
}
}
}
}
}
Todas las recetas a continuación hacen referencia a este asistente. Cópialo en tu proyecto o integra la lógica.
Recetas
1. Hola Mundo — Chat Completion básica
Objetivo: Envía tu primera solicitud de chat completion — sin herramientas, sin conectores.
Cuándo usar:
- Verificar que tu configuración del SDK funciona de principio a fin
- Familiarizarte con la estructura de la respuesta antes de agregar conectores
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{"role": "user", "content": "What is the capital of France?"}
],
)
# Standard completion uses choice.message
print(response.choices[0].message.content)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{ role: "user", content: "What is the capital of France?" },
],
});
console.log(response.choices[0].message.content);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/chat/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"messages": [{"role": "user", "content": "What is the capital of France?"}]
}'
Ejemplo de salida:
The capital of France is Paris.
Cómo funciona:
/v1/chat/completionses el endpoint de chat estándar compatible con OpenAI- La respuesta contiene
choices[]con cada opción teniendo un objetomessage - No se requieren herramientas ni conectores para una completion básica
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
401 Unauthorized |
Clave API incorrecta | Verifica MISTRAL_API_KEY |
422 Unprocessable Entity |
Nombre de modelo inválido | Usa un modelo válido como mistral-small-latest |
2. Completion con generación de imágenes
Objetivo: Usa la herramienta integrada image_generation en una chat completion.
Cuándo usar:
- Generar imágenes basadas en prompts de usuario
- Integración rápida sin conectores personalizados
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": "Generate an image of a sunset over the ocean.",
}
],
tools=[
{"type": "image_generation"},
],
)
# With tools, use choice.messages (array) instead of choice.message
display_response(response)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{
role: "user",
content: "Generate an image of a sunset over the ocean.",
},
],
tools: [
{ type: "image_generation" },
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/chat/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"messages": [{"role": "user", "content": "Generate an image of a sunset over the ocean."}],
"tools": [{"type": "image_generation"}]
}'
Ejemplo de salida:
[Image: https://files.mistral.ai/generated/abc123...]
Here's a beautiful sunset over the ocean as requested.
Cómo funciona:
image_generationes un tipo de herramienta integrada — no se requiere la creación de conectores- El modelo decide invocar la herramienta basándose en la solicitud del usuario
- Las imágenes generadas se devuelven como URLs en el contenido de la respuesta
- Cuando se invocan herramientas, las respuestas usan
choice.messages(array) en lugar dechoice.message
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
422 Unprocessable Entity |
Tipo de herramienta inválido | Asegúrate de que el tipo sea exactamente "image_generation" |
3. Completion con un conector personalizado
Objetivo: Usar un Conector en una chat completion para que el modelo pueda llamar a herramientas externas.
Cuándo usar:
- Has registrado un conector (por ejemplo, DeepWiki) y quieres que el modelo use sus herramientas
- Conectar capacidades específicas del dominio al modelo en un contexto de chat completion
Requisitos previos:
- Un conector existente — consulta Crear un agente asesor de bases de datos para ver un ejemplo completo del ciclo de vida de un conector, o crea uno en Studio
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": "Using deepwiki, tell me about the structure of the sqlite/sqlite repository.",
}
],
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki", # name or UUID
},
],
)
# With connector tools, use choice.messages (array)
display_response(response)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{
role: "user",
content:
"Using deepwiki, tell me about the structure of the sqlite/sqlite repository.",
},
],
tools: [
{
type: "connector",
connectorId: "my_deepwiki", // name or UUID
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/chat/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"messages": [{"role": "user", "content": "Using deepwiki, tell me about the structure of the sqlite/sqlite repository."}],
"tools": [{"type": "connector", "connector_id": "my_deepwiki"}]
}'
Ejemplo de salida:
The sqlite/sqlite repository is organized into several key directories:
- src/ — core SQLite source code
- ext/ — extensions
- test/ — test suite
...
Cómo funciona:
- El campo
connector_idacepta el nombre o UUID del conector - El modelo descubre las herramientas expuestas por el servidor MCP y decide cuáles llamar
- Las llamadas a herramientas y los resultados se manejan en el servidor — tú solo ves la respuesta final
- Las respuestas usan
choice.messages(array) cuando se invocan herramientas
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
404 Not Found |
El nombre/ID del conector no existe | Verifica con la API de lista/obtener conector |
422 Unprocessable Entity |
El conector está inactivo o el servidor MCP es inalcanzable | Verifica la URL del servidor MCP |
4. Combinando múltiples herramientas
Objetivo: Dar al modelo acceso a herramientas integradas y conectores personalizados simultáneamente en una chat completion.
Cuándo usar:
- Quieres que el modelo elija la mejor herramienta para la tarea entre varias opciones
- Construir un asistente con múltiples capacidades
Requisitos previos:
- Un conector existente
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": "What tools do you have access to? List them briefly.",
}
],
tools=[
{"type": "image_generation"},
{
"type": "connector",
"connector_id": "my_deepwiki",
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{
role: "user",
content: "What tools do you have access to? List them briefly.",
},
],
tools: [
{ type: "image_generation" },
{
type: "connector",
connectorId: "my_deepwiki",
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/chat/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"messages": [{"role": "user", "content": "What tools do you have access to? List them briefly."}],
"tools": [
{"type": "image_generation"},
{"type": "connector", "connector_id": "my_deepwiki"}
]
}'
Ejemplo de salida:
I have access to the following tools:
1. Image Generation — create images from text descriptions
2. read_wiki_structure — explore repository wiki structure
3. read_wiki_contents — read specific wiki pages
4. ask_question — ask questions about a repository
Cómo funciona:
- El array
toolsacepta cualquier combinación de herramientas integradas (image_generation) y conectores personalizados - Cada conector expone su propio conjunto de herramientas MCP; el modelo las ve todas
- El modelo decide qué herramienta(s) invocar basándose en la pregunta del usuario
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
422 Unprocessable Entity |
IDs de conector duplicados en el array de herramientas | Cada conector debe aparecer solo una vez |
5. Creación de un agente con conectores
Objetivo: Crear un agente persistente preconfigurado con conectores e instrucciones personalizadas para usar con la API de Agent Completions.
Cuándo usar:
- Quieres un agente reutilizable que siempre tenga acceso a herramientas específicas
- Construir una característica de producto donde los usuarios interactúan con un asistente especializado
- Simplificar las llamadas a la API preconfigurando el modelo, las instrucciones y las herramientas
Requisitos previos:
- Un conector existente
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
agent_id: str | None = None
try:
# Create the agent
agent = await client.beta.agents.create_async(
name="deepwiki_completion_agent",
description="Agent with DeepWiki access for code repository exploration",
model="mistral-small-latest",
instructions="You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
tools=[
{
"type": "connector",
"connector_id": "my_deepwiki",
},
],
)
agent_id = str(agent.id)
print(f"Created agent: {agent.name} ({agent_id})")
finally:
# Clean up
if agent_id:
await client.beta.agents.delete_async(agent_id=agent_id)
print(f"Deleted agent: {agent_id}")
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
let agentId: string | undefined;
try {
// Create the agent
const agent = await client.beta.agents.create({
name: "deepwiki_completion_agent",
description: "Agent with DeepWiki access for code repository exploration",
model: "mistral-small-latest",
instructions:
"You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
tools: [
{
type: "connector",
connectorId: "my_deepwiki",
},
],
});
agentId = agent.id;
console.log(`Created agent: ${agent.name} (${agentId})`);
} finally {
// Clean up
if (agentId) {
await client.beta.agents.delete({ agentId });
console.log(`Deleted agent: ${agentId}`);
}
}
}
main();
curl:
# Create agent
curl -X POST "https://api.mistral.ai/v1/agents" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"name": "deepwiki_completion_agent",
"description": "Agent with DeepWiki access",
"model": "mistral-small-latest",
"instructions": "You are a helpful assistant that can explore code repositories using DeepWiki. Be concise.",
"tools": [{"type": "connector", "connector_id": "my_deepwiki"}]
}'
# Delete agent when done (use the agent ID from the response above)
curl -X DELETE "https://api.mistral.ai/v1/agents/<agent-id>" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}"
Ejemplo de salida:
Created agent: deepwiki_completion_agent (b2c3d4e5-6789-01ab-cdef-234567890abc)
Deleted agent: b2c3d4e5-6789-01ab-cdef-234567890abc
Cómo funciona:
- Los agentes son configuraciones persistentes: modelo + instrucciones + herramientas
- Una vez creado, usa el ID del agente con
/v1/agents/completionspara chatear - El array
toolsdel agente usa el mismo formato que el parámetrotoolsen las completions - Elimina los agentes cuando ya no sean necesarios
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
404 Not Found |
El conector referenciado en las herramientas del agente no existe | Crea el conector primero |
409 Conflict |
Ya existe un agente con este nombre | Elige un nombre diferente o elimina el agente existente |
6. Agent Completions
Objetivo: Chatear con un agente preconfigurado usando la API de Agent Completions.
Cuándo usar:
- Tienes un agente existente con herramientas configuradas
- Quieres evitar pasar el modelo, las instrucciones y las herramientas en cada solicitud
- Construir flujos conversacionales con un asistente especializado
Requisitos previos:
- Un ID de agente existente (consulta Receta 5)
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
agent_id = "your-agent-id" # From agent creation
response = await client.agents.complete_async(
agent_id=agent_id,
messages=[
{
"role": "user",
"content": "What is the main purpose of the sqlite repository?",
}
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const agentId = "your-agent-id"; // From agent creation
const response = await client.agents.complete({
agentId,
messages: [
{
role: "user",
content: "What is the main purpose of the sqlite repository?",
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/agents/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"agent_id": "<agent-id>",
"messages": [{"role": "user", "content": "What is the main purpose of the sqlite repository?"}]
}'
Ejemplo de salida:
SQLite is a self-contained, serverless, zero-configuration SQL database engine. It is the most widely deployed database in the world, embedded in countless applications including web browsers, mobile phones, and operating systems.
Cómo funciona:
/v1/agents/completionsusa el modelo, las instrucciones y las herramientas preconfiguradas del agente- Solo necesitas proporcionar
agent_idymessages— no es necesario repetir la configuración - El formato de respuesta es el mismo que
/v1/chat/completions - Para conversaciones de múltiples turnos, incluye el historial completo de mensajes en el array
messages
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
404 Not Found |
ID de agente inválido | El agente puede haber sido eliminado |
422 Unprocessable Entity |
Falta agent_id o formato de mensaje inválido |
Asegúrate de que se proporcione agent_id |
7. Conectores autenticados con OAuth (Gmail)
Objetivo: Usar un conector que requiere autenticación OAuth2 en una chat completion.
Cuándo usar:
- Integrar con servicios que requieren tokens OAuth a nivel de usuario (Gmail, Google Drive, Slack, etc.)
- Construir características donde el modelo accede a datos específicos del usuario
Requisitos previos:
- Un token de acceso OAuth2 válido para el servicio de destino
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
google_oauth_token = "your-google-oauth-token"
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": "What's the latest email I received?",
}
],
tools=[
{
"type": "connector",
"connector_id": "gmail",
"authorization": {
"type": "oauth2-token",
"value": google_oauth_token,
},
},
],
)
display_response(response)
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
const googleOauthToken = "your-google-oauth-token";
const response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{
role: "user",
content: "What's the latest email I received?",
},
],
tools: [
{
type: "connector",
connector_id: "gmail",
authorization: {
type: "oauth2-token",
value: googleOauthToken,
},
},
],
});
displayResponse(response);
}
main();
curl:
curl -X POST "https://api.mistral.ai/v1/chat/completions" \
-H "Authorization: Bearer ${MISTRAL_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"model": "mistral-small-latest",
"messages": [{"role": "user", "content": "What is the latest email I received?"}],
"tools": [{
"type": "connector",
"connector_id": "gmail",
"authorization": {
"type": "oauth2-token",
"value": "<your-google-oauth-token>"
}
}]
}'
Ejemplo de salida:
Your latest email is from John Doe with the subject "Q1 Report Review" received at 2:30 PM today...
Cómo funciona:
- El campo
authorizationse pasa por herramienta, no globalmente — diferentes conectores pueden usar diferentes tokens type: "oauth2-token"le indica al backend que reenvíe el token al servidor MCP- El token no es almacenado por Mistral — se usa solo durante la duración de la solicitud
- Los conectores integrados como
gmailestán preregistrados; no necesitas crearlos
Errores comunes y soluciones:
| Error | Causa | Solución |
|---|---|---|
401 Unauthorized |
El token OAuth ha expirado | Actualiza el token y vuelve a intentarlo |
403 Forbidden |
El token no tiene los scopes requeridos | Solicita los scopes correctos (por ejemplo, gmail.readonly) |
8. Ejemplo completo — Crear, completar y limpiar
Objetivo: Flujo de trabajo de principio a fin: crear un conector, usarlo en chat completions y con un agente, luego limpiar.
Cuándo usar:
- Pruebas de integración
- Conectores efímeros para tareas únicas
- Plantilla para flujos de trabajo de producción
Python:
import asyncio
from mistralai.client import Mistral
API_KEY = "your-api-key"
async def main() -> None:
client = Mistral(api_key=API_KEY)
connector_id: str | None = None
agent_id: str | None = None
try:
# 1. Create a connector
connector = await client.beta.connectors.create_async(
name="completions_deepwiki",
description="DeepWiki connector for completion testing",
server="https://mcp.deepwiki.com/mcp",
visibility="private",
)
connector_id = str(connector.id)
print(f"Created connector: {connector.name} ({connector_id})")
# 2. Use it in a chat completion
response = await client.chat.complete_async(
model="mistral-small-latest",
messages=[
{
"role": "user",
"content": "Using deepwiki, summarize the sqlite/sqlite repo in one sentence.",
}
],
tools=[
{"type": "connector", "connector_id": "completions_deepwiki"},
],
)
print("\nChat completion response:")
display_response(response)
# 3. Create an agent with the connector
agent = await client.beta.agents.create_async(
name="completions_test_agent",
description="Test agent for completion cookbook",
model="mistral-small-latest",
instructions="You are a helpful assistant. Be concise.",
tools=[
{"type": "connector", "connector_id": connector_id},
],
)
agent_id = str(agent.id)
print(f"\nCreated agent: {agent.name} ({agent_id})")
# 4. Use agent completions
response = await client.agents.complete_async(
agent_id=agent_id,
messages=[
{
"role": "user",
"content": "What programming language is SQLite written in?",
}
],
)
print("\nAgent completion response:")
display_response(response)
print("\n" + "=" * 60)
print(" SUCCESS")
print("=" * 60)
finally:
# Clean up
print("\nCleaning up...")
if agent_id:
try:
await client.beta.agents.delete_async(agent_id=agent_id)
print(f"Deleted agent: {agent_id}")
except Exception:
pass
if connector_id:
try:
await client.beta.connectors.delete_async(
connector_id=connector_id,
)
print(f"Deleted connector: {connector_id}")
except Exception:
pass
asyncio.run(main())
TypeScript:
import { Mistral } from "@mistralai/mistralai";
const client = new Mistral({ apiKey: "your-api-key" });
async function main(): Promise<void> {
let connectorId: string | undefined;
let agentId: string | undefined;
try {
// 1. Create a connector
const connector = await client.beta.connectors.create({
name: "completions_deepwiki",
description: "DeepWiki connector for completion testing",
server: "https://mcp.deepwiki.com/mcp",
visibility: "private",
});
connectorId = connector.id;
console.log(`Created connector: ${connector.name} (${connectorId})`);
// 2. Use it in a chat completion
let response = await client.chat.complete({
model: "mistral-small-latest",
messages: [
{
role: "user",
content: "Using deepwiki, summarize the sqlite/sqlite repo in one sentence.",
},
],
tools: [
{ type: "connector", connectorId: "completions_deepwiki" },
],
});
console.log("\nChat completion response:");
displayResponse(response);
// 3. Create an agent with the connector
const agent = await client.beta.agents.create({
name: "completions_test_agent",
description: "Test agent for completion cookbook",
model: "mistral-small-latest",
instructions: "You are a helpful assistant. Be concise.",
tools: [
{ type: "connector", connectorId },
],
});
agentId = agent.id;
console.log(`\nCreated agent: ${agent.name} (${agentId})`);
// 4. Use agent completions
response = await client.agents.complete({
agentId,
messages: [
{
role: "user",
content: "What programming language is SQLite written in?",
},
],
});
console.log("\nAgent completion response:");
displayResponse(response);
console.log("\n" + "=".repeat(60));
console.log(" SUCCESS");
console.log("=".repeat(60));
} finally {
// Clean up
console.log("\nCleaning up...");
if (agentId) {
try {
await client.beta.agents.delete({ agentId });
console.log(`Deleted agent: ${agentId}`);
} catch {
// ignore
}
}
if (connectorId) {
try {
await client.beta.connectors.delete({ connectorId });
console.log(`Deleted connector: ${connectorId}`);
} catch {
// ignore
}
}
}
}
main();
Salida:
Created connector: completions_deepwiki (c3d4e5f6-...)
Chat completion response:
SQLite is a self-contained, serverless SQL database engine used worldwide.
Created agent: completions_test_agent (d4e5f6a7-...)
Agent completion response:
SQLite is primarily written in C.
============================================================
SUCCESS
============================================================
Cleaning up...
Deleted agent: d4e5f6a7-...
Deleted connector: c3d4e5f6-...
Cómo funciona:
- El patrón
try/finallyasegura que los recursos siempre se limpien, incluso si las solicitudes fallan - Esta receta demuestra el flujo de trabajo completo: creación de conector → chat completion → creación de agente → agent completion
- Tanto
/v1/chat/completionscomo/v1/agents/completionsadmiten los mismos formatos de herramienta
Convenciones de nombres de Python / TypeScript
| Concepto | SDK de Python | SDK de TypeScript |
|---|---|---|
| ID de conector | connector_id |
connectorId |
| ID de agente | agent_id |
agentId |
| Tipo de herramienta | type |
type |
| Autorización OAuth | authorization.type, authorization.value |
authorization.type, authorization.value |
Solución de problemas
Error "Conector no encontrado"
- Verifica que el conector existe listando los conectores u obteniéndolos por nombre/ID
- Comprueba que el nombre/ID del conector esté escrito correctamente
- Asegúrate de que el conector fue creado en el mismo espacio de trabajo
"Las llamadas a herramientas no aparecen en la respuesta"
- El modelo decide si llamar a las herramientas basándose en el mensaje del usuario
- Intenta ser más explícito en tu prompt (por ejemplo, "Usa deepwiki para...")
- Asegúrate de que el tipo de herramienta sea válido (
connector,image_generation, etc.)
"Errores de tiempo de espera"
- Los servidores MCP pueden tardar en responder — aumenta el tiempo de espera
- Verifica si la URL del servidor MCP es accesible
- Intenta primero con una consulta más simple
"Token OAuth expirado"
- Los tokens OAuth tienen una vida útil limitada
- Implementa la lógica de actualización de tokens en tu aplicación
- Verifica la expiración del token antes de realizar solicitudes
"AttributeError: el objeto 'Unset' no tiene el atributo 'content'"
- Al usar herramientas de conector, las respuestas usan
choice.messages(array) en lugar dechoice.message - Usa la función auxiliar
display_responseo verifica ambos formatos - Accede al contenido a través de
response.choices[0].messages[0].content
Referencia de códigos de error
| Estado HTTP | Error | Causas comunes |
|---|---|---|
400 |
Solicitud incorrecta | JSON inválido, campos requeridos faltantes |
401 |
No autorizado | Clave API inválida o faltante, token OAuth expirado |
403 |
Prohibido | Permisos insuficientes, scopes OAuth inválidos |
404 |
No encontrado | El conector/agente no existe, ID incorrecto |
409 |
Conflicto | Ya existe un recurso con el mismo nombre |
422 |
Entidad no procesable | Nombre de modelo inválido, formato de herramienta inválido, servidor MCP inalcanzable |
429 |
Demasiadas solicitudes | Límite de tasa excedido |
500 |
Error interno del servidor | Problema del lado del servidor, reintenta con retroceso exponencial |
502 |
Bad Gateway | Servidor MCP inalcanzable o devolvió un error |
504 |
Gateway Timeout | El servidor MCP tardó demasiado en responder |
Resumen
Este manual cubrió ocho recetas para usar Conectores, herramientas integradas y agentes con las API de Chat Completions y Agent Completions — desde una completion básica hasta Conectores autenticados con OAuth y un ejemplo completo del ciclo de vida de creación, completion y limpieza.
Lo que cubre este manual:
- Completion de chat básica
- Completion con generación de imágenes
- Completion con un Conector personalizado
- Combinar múltiples herramientas en una completion
- Crear un agente con Conectores para usar con completions
- Agent completions
- Conectores autenticados con OAuth (Gmail)
- Ciclo de vida completo: crear un Conector, completar y limpiar
Características de Mistral usadas:
- API de Chat Completions
- API de Agent Completions
- API de Agentes (beta)
- Conectores (beta)
- Herramienta integrada de generación de imágenes
Otros servicios:
- DeepWiki — Servidor MCP para exploración de repositorios de GitHub
- Gmail — Conector autenticado con OAuth2
Consulta tus Conectores en Studio.