Mistral Responses API: configurar Large 4 y migrar desde OpenAI
Empieza con una solicitud a Mistral Large 4 y adapta tu integración de OpenAI Responses al funcionamiento sin estado de Mistral. Revisa los parámetros incompatibles, los niveles de razonamiento, el envío del historial completo, los resultados de funciones y el recuento de tokens de entrada. Elige Conversations si necesitas continuar conversaciones guardadas o usar herramientas alojadas.
Índice

Usa Mistral Responses API con mistral-large-4 y envía el historial de conversación en input en cada solicitud. Elimina los parámetros de continuación en el servidor, mantén desactivado el almacenamiento y elige un esfuerzo de razonamiento compatible con el modelo. A fecha de 2026-11-01, la Responses API de Mistral está en versión preliminar pública.
Ejecuta una solicitud mínima a Mistral Large 4
Usa la versión actual del SDK de Python de Mistral y una clave de API de Mistral para la primera solicitud. Así tendrás un punto de partida documentado antes de adaptar un cliente de Responses existente.
Necesitas Python 3.10 o posterior. Crea una clave en Studio → API keys y ejecuta estos comandos en Bash. Cuando read espere una entrada, pega la clave y pulsa Intro. La clave no se muestra en pantalla.
python3 -m pip install -U mistralai
read -rs MISTRAL_API_KEY && export MISTRAL_API_KEY
Guarda el siguiente código en mistral_responses.py. La función auxiliar mantiene las mismas instrucciones y opciones de solicitud en los ejemplos posteriores.
import os
from mistralai.client import Mistral
client = Mistral(api_key=os.environ["MISTRAL_API_KEY"])
MODEL = "mistral-large-4"
INSTRUCTIONS = "Answer concisely."
def create_response(history, **options):
result = client.responses.create(
model=MODEL,
input=history,
instructions=INSTRUCTIONS,
reasoning={"effort": "high"},
max_output_tokens=4096,
additional_properties={
"store": False,
"background": False,
"truncation": "disabled",
},
**options,
)
if result.status != "completed":
raise RuntimeError(
f"{result.status}: {result.error or result.incomplete_details}"
)
return result
def answer_text(result):
return "".join(
part.text
for item in result.output if item.type == "message"
for part in item.content if part.type == "output_text"
)
history = [{"role": "user", "content": "Explain a stateless API in one sentence."}]
response = create_response(history)
print(response.status)
print(answer_text(response))
Ejecútalo desde la misma sesión de Bash:
python3 mistral_responses.py
En este ejemplo, el resultado correcto es completed seguido de una explicación que no esté vacía. La redacción puede variar. El código selecciona el texto de la respuesta porque output también puede contener razonamiento y llamadas a funciones.
El endpoint HTTP es https://api.mistral.ai/v1/responses. Las solicitudes HTTP directas usan el encabezado Authorization: Bearer $MISTRAL_API_KEY. Si el cliente añade /responses, configura la URL base como https://api.mistral.ai/v1.
Los demás ejemplos de Python reutilizan las variables y funciones de este archivo. Añade los ejemplos que necesites al final. Cada nueva ejecución del archivo repetirá todas las llamadas de generación que hayas incluido.
¿Qué parámetros de OpenAI Responses debes cambiar?
Aplica estos requisitos a los campos JSON de la solicitud HTTP antes de reutilizar una solicitud de OpenAI Responses. La referencia de Responses API de Mistral define estos valores admitidos a fecha de 2026-11-01.
| Parámetro de la solicitud Responses | Requisito de Mistral | Cambio necesario |
|---|---|---|
previous_response_id | Omítelo o envía null. | Vuelve a enviar los elementos de respuestas anteriores en input. |
conversation | Omítelo o envía null. | Conserva el historial de conversación en tu aplicación. |
store | Omítelo o envía false o null. | Elimina true; no dependas de respuestas almacenadas. |
background | Debe ser false; su valor predeterminado es false. | Elimina la ejecución en segundo plano y el sondeo de su estado. |
truncation | Debe ser "disabled"; también es el valor predeterminado. | Controla el tamaño del contexto antes de enviar la solicitud. |
prompt | Omítelo o envía null. | Coloca el contenido del prompt en input e instructions. |
moderation | Omítelo o envía null. | Elimina el valor enviado en este campo de compatibilidad. |
top_logprobs | Omítelo o envía 0 o null. | Elimina cualquier valor positivo. |
max_tool_calls | Se acepta, pero actualmente se ignora. | Impón los límites de ejecución en tu aplicación. |
reasoning.effort | Debe ser compatible con el modelo seleccionado. | Usa los valores específicos de cada modelo indicados más abajo. |
tools | Funciones ejecutadas por el cliente, que pueden agruparse en espacios de nombres. | Sustituye las dependencias de herramientas alojadas por el proveedor. |
max_output_tokens | Incluye tanto los tokens de razonamiento como el texto de la respuesta. | Reserva un presupuesto de salida suficiente para ambos. |
Los argumentos con nombre del SDK de Python no reflejan todos los campos HTTP. Su implementación actual de Responses acepta store, background y truncation mediante additional_properties. El primer ejemplo usa ese mecanismo.
Ten en cuenta estas diferencias en la configuración del proveedor. Cambiar el endpoint no confirma que todas las herramientas, formas de continuación o manejadores de streaming sean compatibles. La guía de compatibilidad entre Messages, Chat Completions y Responses explica por qué conviene comprobar un ciclo completo de llamada a una función.
¿Qué modelos y capacidades puedes usar?
Usa mistral-large-4 en estos ejemplos y vuelve a comprobar las capacidades cuando cambies de modelo. El anuncio de lanzamiento de Mistral indica que admite todos los modelos de chat que aloja, incluido Large 4.
La lista de capacidades admitidas incluye entrada y salida de texto, salida estructurada, streaming, funciones y razonamiento según el modelo. La entrada de imágenes requiere un modelo con visión y acepta URLs de imágenes o URLs de datos en base64. La entrada de archivos admite URLs HTTPS, URLs de datos en base64 o identificadores de archivos cargados; la compatibilidad depende del modelo.
La salida estructurada usa text.format para el modo JSON o JSON Schema. Las funciones se ejecutan en tu aplicación. La implementación publicada solo admite funciones ejecutadas por el cliente, por lo que no puedes trasladar una herramienta alojada como web_search sin modificarla.
Para el razonamiento, usa el campo anidado reasoning.effort de Responses. Estos valores siguen la guía de razonamiento de Mistral, consultada el 2026-11-01:
| Modelo | Valores de esfuerzo admitidos | Cómo elegir |
|---|---|---|
mistral-large-4 / mistral-large-4-0 | low, medium, high | Empieza con high para el ejemplo. Compara valores inferiores si te importan la latencia o el consumo de tokens. |
mistral-small-2603 | none, high | Usa high cuando necesites su modo de razonamiento. |
mistral-medium-3-5 | none, high | Para integraciones existentes; el modelo está marcado como obsoleto. |
Large 4 no acepta none, minimal, xhigh ni max. Si copiaste ejemplos de las primeras versiones preliminares de Large 4, sustituye none por low. Que un valor figure en una enumeración compartida del SDK no significa que todos los modelos lo admitan.
La ficha de Large 4 también indica que el modelo está en versión preliminar pública. La ficha de Medium 3.5 señala el 2026-10-31 como fecha de deprecación y recomienda Large 4 para nuevas integraciones.
Crea la entrada de varios turnos y devuelve resultados de funciones
Conserva el historial completo de elementos, incluidos el razonamiento y las llamadas a funciones. El texto de la respuesta sirve para mostrarlo al usuario, pero no constituye un registro completo de la conversación.
Continúa una conversación
Añade todos los elementos del output anterior y, después, el siguiente mensaje del usuario. Coloca este fragmento después del primer ejemplo:
history.extend(response.output)
history.append({"role": "user", "content": "What must the client send next time?"})
response = create_response(history)
print(answer_text(response))
history.extend(response.output)
La segunda solicitud contiene el primer mensaje del usuario, la primera respuesta completa y la pregunta de seguimiento. La función auxiliar también vuelve a enviar instructions.
Este es el método documentado para sustituir previous_response_id. Conservar solo un identificador de respuesta no aporta el historial a este endpoint sin estado. Guardar únicamente la respuesta impresa descarta los demás elementos devueltos.
Devuelve el resultado de una función
Ejecuta la función localmente y devuelve su resultado con el call_id correspondiente. El ejemplo de llamadas a funciones de Mistral coloca type, name, description y parameters en un mismo objeto de herramienta. El siguiente ejemplo usa esa estructura para realizar una suma local y mantiene un historial independiente.
import json
TOOLS = [{
"type": "function",
"name": "add",
"description": "Add two integers.",
"parameters": {
"type": "object",
"properties": {
"a": {"type": "integer"},
"b": {"type": "integer"},
},
"required": ["a", "b"],
"additionalProperties": False,
},
}]
tool_history = [{"role": "user", "content": "Use add to calculate 19 + 23."}]
response = create_response(
tool_history,
tools=TOOLS,
tool_choice={"type": "function", "name": "add"},
parallel_tool_calls=False,
)
tool_history.extend(response.output)
calls = [item for item in response.output if item.type == "function_call"]
if len(calls) != 1 or calls[0].name != "add":
raise RuntimeError("Expected exactly one add call.")
call = calls[0]
args = json.loads(call.arguments)
if (
not isinstance(args, dict)
or set(args) != {"a", "b"}
or any(type(args[name]) is not int for name in ("a", "b"))
):
raise ValueError("Expected two integer arguments.")
result = args["a"] + args["b"]
print("Local result:", result)
tool_history.append({
"type": "function_call_output",
"call_id": call.call_id,
"output": json.dumps({"result": result}),
})
response = create_response(
tool_history,
tools=TOOLS,
tool_choice="none",
parallel_tool_calls=False,
)
print(answer_text(response))
tool_history.extend(response.output)
Comprueba que aparezca Local result: 42, seguido de una respuesta que use ese resultado. La redacción del modelo puede variar.
La primera solicitud fuerza la llamada a add; la segunda usa "none" para desactivar nuevas llamadas, según la referencia de la API. Esto limita el ejemplo a dos pasos de generación y una ejecución local. En un bucle de agente sin un número fijo de pasos, impón tus propios límites de iteraciones y ejecuciones, porque max_tool_calls se ignora.
Conserva toda la salida devuelta antes de añadir los resultados de las funciones. Asocia los resultados mediante call_id, no mediante el id del elemento de salida. Si permites varias llamadas a funciones, valida y devuelve cada resultado antes de solicitar la siguiente respuesta.
Cuenta los tokens de entrada antes de que crezca el historial
Cuenta la siguiente solicitud completa, incluidos el historial, las instrucciones y las definiciones de herramientas. Si cuentas solo el mensaje más reciente, omitirás contenido que tu aplicación volverá a enviar.
Después del ejemplo de la función, usa:
next_input = tool_history + [
{"role": "user", "content": "Explain that calculation in one sentence."}
]
count = client.responses.count_input_tokens(
model=MODEL,
input=next_input,
instructions=INSTRUCTIONS,
tools=TOOLS,
reasoning={"effort": "high"},
parallel_tool_calls=False,
tool_choice="auto",
)
print(count.input_tokens)
Este código llama a POST /v1/responses/input_tokens e imprime input_tokens. Cuenta la entrada sin generar una respuesta. Usa el mismo modelo, entrada, instrucciones y herramientas cuando generes la respuesta posterior.
Compara ese recuento con la ventana de contexto del modelo seleccionado y reserva espacio para la salida. Como truncation debe permanecer en "disabled", tu aplicación tiene que decidir cuándo reducir el historial.
Al gestionar el historial, conserva las llamadas a funciones junto con sus resultados correspondientes. Evita eliminar elementos arbitrarios del medio de un intercambio con herramientas.
El recuento de tokens no es una estimación monetaria. Consulta los precios actuales de la API de Mistral al estimar los costes de turnos sucesivos y el efecto de la caché.
Diagnostica los fallos de migración
Revisa primero la configuración de la solicitud y, después, el estado y los elementos de salida. Elige la comprobación que corresponda al síntoma.
- El SDK rechaza un argumento con nombre antes de enviar la solicitud. Comprueba el SDK instalado y la firma del método. En la versión usada aquí, coloca
store,backgroundytruncationdentro deadditional_properties. - La API rechaza la solicitud. Vuelve al primer ejemplo de texto. Revisa el identificador del modelo, el esfuerzo de razonamiento admitido y la tabla de compatibilidad. Cuando funcione, reincorpora los campos opcionales uno por uno.
- El modelo pierde el contexto anterior. Revisa el siguiente arreglo
input. Debe contener los mensajes anteriores y los elementos completos de salida, no solo un identificador de respuesta. - La respuesta no contiene texto. Revisa
status,erroreincomplete_details. Comprueba si hay una llamada a función pendiente de ejecución. Si la generación agotó el presupuesto de salida, auméntalo o reduce el esfuerzo de razonamiento a otro valor admitido por el modelo. - La solicitud llega a una ruta incorrecta. Compara la URL final con
https://api.mistral.ai/v1/responses. La guía sobre URL base, endpoints y diagnóstico de errores explica los errores habituales al construir la ruta.
Para usar streaming, establece stream=True y procesa los eventos de Responses. El ejemplo oficial de streaming en Python lee cada evento mediante frame.data. El texto llega en response.output_text.delta; response.completed indica que la respuesta ha terminado.
Gestiona también los eventos response.failed, response.incomplete y error. Recibir un fragmento de texto no confirma por sí solo que la generación haya terminado correctamente. La generación en segundo plano está desactivada, por lo que esta configuración no necesita un bucle de sondeo.
Elige Responses, Chat Completions o Conversations
Elige Responses cuando su formato de elementos encaje con tu aplicación y quieras controlar el historial y la ejecución de funciones.
| Qué necesita tu aplicación | Por dónde empezar | Motivo |
|---|---|---|
| Elementos de entrada y salida de Responses y sus eventos de streaming | Responses API | Mantiene ese formato mientras tu aplicación gestiona el estado y las funciones. |
| Mantener una integración existente basada en mensajes | Chat Completions | Puedes conservar el procesamiento de solicitudes y respuestas orientado a mensajes. |
| Continuar conversaciones guardadas o usar herramientas alojadas por Mistral | Conversations API | Ofrece identificadores de conversación y una interfaz separada para herramientas alojadas. |
La guía de Chat Completions de Mistral describe el formato basado en mensajes. La referencia de Conversations documenta cómo continuar mediante conversation_id.
Para la búsqueda alojada, Mistral documenta web_search y web_search_premium en Conversations y Agents. Esa capacidad es independiente de las funciones de Responses que ejecuta el cliente.
Si tu aplicación necesita continuar conversaciones almacenadas o usar herramientas alojadas, evalúa Conversations antes de migrar el contenido de sus solicitudes. Si ya gestiona esas responsabilidades, valida la solicitud de texto, el siguiente turno y el ciclo completo de función antes de conectar el agente completo.