Curso
GPT-5 ya está aquí y está transformando la forma en que utilizamos las herramientas de IA. Destaca en codificación, llamada de herramientas, seguimiento de instrucciones y automatización. De hecho, es tan capaz que algunos están dando la voz de alarma: GPT‑5 puede sustituir fácilmente a un programador junior o de nivel medio.
Si deseas profundizar en las capacidades de GPT-5, consulta GPT-5: Nuevas funciones, pruebas, comparativas y mucho más | DataCamp. También puedes echar un vistazo a 7 ejemplos de GPT-5 que puedes probar en el chat.
En este tutorial, no nos centraremos en las capacidades generales del modelo. En su lugar, exploraremos y probaremos lasnuevas funciones de la API GPT-5 introducidas con el nuevo modelo. Repasaremos cada función y ejecutaremos código de ejemplo para que puedas verlas en acción.
Hay algunas características especiales aquí que ningún otro proveedor de API ofrece actualmente. Con el SDK de OpenAI, ahora puedes crear una aplicación basada en agentes totalmente funcional sin necesidad de integrar ningún marco externo. Funciona nada más sacarlo de la caja.

Imagen del autor
1. Esfuerzo de razonamiento
GPT-5 introduce un nuevo parámetro de esfuerzo de razonamiento que te permite controlar la profundidad con la que piensa el modelo antes de responder. Puedes elegir entre niveles de esfuerzo mínimos, bajos, medios o altos ( ), según tus necesidades.
El esfuerzo mínimo es perfecto para tareas en las que la rapidez es importante, como la codificación rápida o el seguimiento de instrucciones sencillas, mientras que el medio y el alto permiten un razonamiento más exhaustivo y paso a paso. Esta flexibilidad te permite equilibrar la latencia, el coste y la precisión.
Primero, instala el SDK de Python de OpenAI y configura tu clave API como variable de entorno:
pip install openai
Configura tu clave API (sustitúyela por tu clave real):
- Linux/macOS:
export OPENAI_API_KEY="your_api_key_here" - Windows (PowerShell):
setx OPENAI_API_KEY "your_api_key_here"
Usemos la API de respuesta para generar texto con un esfuerzo de razonamiento «mínimo». Esto significa que el modelo responderá directamente, sin asignar tokens para el razonamiento interno.
import os
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
resp = client.responses.create(
model="gpt-5",
input="Who is the father of Python?",
reasoning={"effort": "minimal"},
)
print(resp.output_text)
Salida:
Guido van Rossum is known as the father (creator) of Python. He first released Python in 1991.
También puedes consultar el resumen de uso de tokens para comprender cómo el modelo ha procesado tu solicitud:
print(f"Input tokens: {resp.usage.input_tokens}")
print(f" - Cached tokens: {resp.usage.input_tokens_details.cached_tokens}")
print(f"Output tokens: {resp.usage.output_tokens}")
print(f" - Reasoning tokens: {resp.usage.output_tokens_details.reasoning_tokens}")
print(f"Total tokens: {resp.usage.total_tokens}")
Como se muestra, no se utilizaron tokens para el razonamiento cuando el esfuerzo se estableció en mínimo.
Input tokens: 13
- Cached tokens: 0
Output tokens: 31
- Reasoning tokens: 0
Total tokens: 44
Ahora, aumentemos el esfuerzo de razonamiento a «alto» para ver cómo cambia el razonamiento interno del modelo:
resp = client.responses.create(
model="gpt-5",
input="Who is the father of Python?",
reasoning={"effort": "high"},
)
print(resp.output_text)
Salida:
Guido van Rossum. He created Python and first released it in 1991.
Comprueba de nuevo el uso del token:
print(f"Input tokens: {resp.usage.input_tokens}")
print(f" - Cached tokens: {resp.usage.input_tokens_details.cached_tokens}")
print(f"Output tokens: {resp.usage.output_tokens}")
print(f" - Reasoning tokens: {resp.usage.output_tokens_details.reasoning_tokens}")
print(f"Total tokens: {resp.usage.total_tokens}")
Incluso para una pregunta sencilla, el modelo utilizó 192 tokens para razonar con un esfuerzo elevado. Esto demuestra cómo ahora puedes controlar la profundidad del razonamiento para optimizar el coste, la velocidad o la precisión según sea necesario.
Input tokens: 13
- Cached tokens: 0
Output tokens: 216
- Reasoning tokens: 192
Total tokens: 229
2. Verbosidad
Con GPT-5, ahora puedes controlar directamente cuánto dice el modelo utilizando el parámetro de verbosidad. Configúralo en« » (bajo) para obtener respuestas concisas, en «medium» (medio ) para obtener detalles equilibrados o en «high» (alto ) para obtener explicaciones detalladas. Esto resulta especialmente útil para la generación de código: una verbosidad baja produce código breve y limpio, mientras que una verbosidad alta incluye comentarios en línea y razonamientos detallados.
Puedes combinar el parámetro de verbosidad con los controlesde razonamiento para adaptar las respuestas exactamente a tus necesidades. Tanto si deseas una frase breve, una respuesta más larga o un informe completo, tienes total flexibilidad.
La verbosidad «baja» produce una respuesta breve y directa.
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
resp = client.responses.create(
model="gpt-5",
input="Who is the father of Python?",
reasoning={"effort": "minimal"},
text={"verbosity": "low"},
)
print(resp.output_text)
Salida:
Guido van Rossum.
La verbosidad «alta» genera una respuesta mucho más detallada y explicativa.
resp = client.responses.create(
model="gpt-5",
input="Who is the father of Python?",
reasoning={"effort": "minimal"},
text={"verbosity": "high"},
)
print(resp.output_text)
Salida:
Guido van Rossum is known as the "father of Python." He created Python in the late 1980s and released the first version (Python 0.9.0) in 1991. He also served for many years as Python's "Benevolent Dictator For Life" (BDFL), guiding the language's development.
3. Multivuelta con transferencia de cadena de pensamiento
Una de las mayores mejoras de GPT-5 es su capacidad para pasar el razonamiento de cadena de pensamiento (CoT) entre turnos en la API de respuestas. Esto significa que el modelo recuerda su razonamiento interno de los pasos anteriores, lo que evita replanteamientos redundantes y mejora tanto la velocidad como la precisión.
En conversaciones con varios turnos, especialmente cuando se utilizan herramientas, simplemente pasa el previous_response_id para mantener vivo el contexto del razonamiento.
La primera solicitud pregunta «¿Quién es el padre de Python?», y la segunda solicitud, vinculada a la primera a través de previous_response_id, pide al modelo que «Escriba un blog sobre ello» sin repetir el tema. Al pasar el ID de la respuesta anterior, el modelo conserva el contexto del razonamiento.
from openai import OpenAI
client = OpenAI(api_key=os.getenv("OPENAI_API_KEY"))
first = client.responses.create(
model="gpt-5",
input="Who is the father of Python?",
reasoning={"effort": "minimal"},
text={"verbosity": "low"},
)
followup = client.responses.create(
model="gpt-5",
previous_response_id=first.id,
input="Write a blog on it.",
reasoning={"effort": "medium"},
text={"verbosity": "high"},
)
print(followup.output_text)
Como resultado, obtuvimos un blog sobre el padre de Python.

4. Entrada libre
Las herramientas personalizadas de GPT-5 ahora admiten entradas de formato libre, lo que permite al modelo enviar texto sin formato, como código, consultas SQL o comandos de terminal, directamente a tus herramientas. Esto supone un gran avance con respecto al antiguo enfoque estructurado basado únicamente en JSON, ya que te ofrece más flexibilidad en la forma en que el modelo interactúa con tus sistemas. Tanto si estás creando un ejecutor de código, un motor de consultas o un intérprete DSL, la entrada de formato libre hace que GPT-5 sea mucho más adaptable a tareas reales y no estructuradas.
En el código siguiente, hemos definido un ejecutor SQL falso, lo hemos registrado como herramienta personalizada y hemos realizado una solicitud inicial en la que el modelo responde con una consulta SQL de formato libre. Esa consulta se extrae, se ejecuta localmente y el resultado se envía de vuelta al modelo utilizando el mismo call_id para mantener el contexto de la llamada a la herramienta. Por último, GPT-5 convierte el resultado bruto de la herramienta en una respuesta en lenguaje natural.
from openai import OpenAI
import random
client = OpenAI()
def run_sql_query(sql: str) -> str:
print("\n[FAKE DB] Executing SQL:\n", sql)
categories = ["Electronics", "Clothing", "Furniture", "Toys", "Books"]
result = "category | total_sales\n" + "-" * 28 + "\n"
for cat in categories:
result += f"{cat:<11} | {random.randint(5000, 200000)}\n"
return result
tools = [
{
"type": "custom",
"name": "sql_query_runner",
"description": "Runs raw SQL queries on the company sales database.",
}
]
messages = [
{
"role": "user",
"content": "Show me the total sales for each product category last month.",
}
]
# 1) First call - model emits a freeform tool call
resp = client.responses.create(model="gpt-5", tools=tools, input=messages)
# IMPORTANT: carry the tool call into the next turn
messages += resp.output # <-- this preserves the tool_call with its call_id
# Find the tool call from the response output
tool_call = next(
(
x
for x in resp.output
if getattr(x, "type", "") in ("custom_tool_call", "function_call", "tool_call")
),
None,
)
assert tool_call is not None, "No tool call found."
# Freeform text is in `input` (fallback to `arguments` for safety)
raw_text = getattr(tool_call, "input", None) or getattr(tool_call, "arguments", "")
sql_text = raw_text.strip()
# 2) Execute the tool locally
fake_result = run_sql_query(sql_text)
# 3) Send tool result back, referencing the SAME call_id
messages.append(
{
"type": "function_call_output",
"call_id": tool_call.call_id,
"output": fake_result,
}
)
# 4) Final call - model turns tool output into a natural answer
final = client.responses.create(model="gpt-5", tools=tools, input=messages)
print("\nFinal output text:\n", final.output_text)
Salida:
[FAKE DB] Executing SQL:
SELECT table_schema, table_name
FROM information_schema.tables
WHERE table_schema NOT IN ('information_schema','pg_catalog')
ORDER BY 1,2;
Final output text:
Here are the total sales by category for last month (July 2025):
- Electronics: 31,766
- Clothing: 90,266
- Furniture: 55,471
- Toys: 124,625
- Books: 74,263
Want this as a CSV or chart?
5. Restricción de los resultados
Para situaciones en las que la precisión es fundamental, GPT-5 admite gramáticas libres de contexto (CFG) para controlar estrictamente los formatos de salida. Al añadir una gramática como la sintaxis SQL o un lenguaje específico del dominio, puedes garantizar que las respuestas del modelo siempre se ajusten a la estructura requerida. Esto resulta especialmente valioso paraflujos de trabajo automatizados o de alto riesgo ( ), en los que incluso pequeñas desviaciones en el formato podrían provocar errores.
En el código de ejemplo, hemos creado un sql_query_runner y hemos definido su sintaxis SQL utilizando una gramática Lark, lo que garantiza que cualquier SQL que genere el modelo sea siempre válido y siga nuestra estructura exacta.
En la primera llamada al modelo, GPT-5 utiliza esta herramienta para generar una consulta SQL que cumple con las reglas gramaticales para obtener las ventas del mes pasado por categoría. A continuación, ejecutamos esa consulta localmente, enviamos los resultados al modelo utilizando el mismo call_id y realizamos una segunda llamada en la que GPT‑5 convierte los datos sin procesar en una respuesta clara y en lenguaje natural.
from openai import OpenAI
import random
client = OpenAI()
def run_sql_query(sql: str) -> str:
cats = ["Electronics", "Clothing", "Furniture", "Toys", "Books"]
rows = [f"{c:<11} | {random.randint(5_000, 200_000)}" for c in cats]
return "category | total_sales\n" + "-" * 28 + "\n" + "\n".join(rows)
tools = [
{
"type": "custom",
"name": "sql_query_runner",
"description": "Runs raw SQL on the sales DB.",
"format": {
"type": "grammar",
"syntax": "lark",
"definition": r"""
start: SELECT CATEGORY COMMA SUM LPAREN SALES RPAREN AS TOTAL_SALES FROM ORDERS WHERE ORDER_MONTH EQ ESCAPED_STRING GROUP BY CATEGORY ORDER BY TOTAL_SALES (DESC|ASC)?
SELECT: "SELECT"
CATEGORY: "category"
COMMA: ","
SUM: "SUM"
LPAREN: "("
SALES: "sales"
RPAREN: ")"
AS: "AS"
TOTAL_SALES: "total_sales"
FROM: "FROM"
ORDERS: "orders"
WHERE: "WHERE"
ORDER_MONTH: "order_month"
EQ: "="
GROUP: "GROUP"
BY: "BY"
ORDER: "ORDER"
DESC: "DESC"
ASC: "ASC"
%import common.ESCAPED_STRING
%ignore /[ \t\r\n]+/
""",
},
}
]
msgs = [
{
"role": "user",
"content": "Show me the total sales for each product category last month.",
}
]
print("\n=== 1) First Model Call ===")
resp = client.responses.create(
model="gpt-5", input=msgs, tools=tools, text={"format": {"type": "text"}}
)
print("Raw model output objects:\n", resp.output)
msgs += resp.output
tool_call = next(
x
for x in resp.output
if getattr(x, "type", "") in ("custom_tool_call", "function_call", "tool_call")
)
sql = (getattr(tool_call, "input", None) or getattr(tool_call, "arguments", "")).strip()
print("\nExtracted SQL from tool call:\n", sql)
print("\n=== 2) Local Tool Execution ===")
tool_result = run_sql_query(sql)
print(tool_result)
msgs.append(
{
"type": "function_call_output",
"call_id": getattr(tool_call, "call_id", None) or tool_call["call_id"],
"output": tool_result,
}
)
print("\n=== 3) Second Model Call ===")
final = client.responses.create(
model="gpt-5", input=msgs, tools=tools, text={"format": {"type": "text"}}
)
print("\nFinal natural-language answer:\n", final.output_text)
Como podemos ver, el modelo generó primero una consulta SQL que cumplía con la gramática y, a continuación, ejecutó la función para recuperar los datos de ventas. Por último, GPT-5 convirtió esos datos en un resumen claro y clasificado en lenguaje natural de las ventas del mes pasado por categoría.
=== 1) First Model Call ===
Raw model output objects:
[ResponseReasoningItem(id='rs_6897acee8afc819f9e7ae0f675bfa4ee0d5175a46255063b', summary=[], type='reasoning', content=None, encrypted_content=None, status=None), ResponseCustomToolCall(call_id='call_vzcHPT7EGvb7QbhF2djVIJZA', input='SELECT category, SUM(sales) AS total_sales FROM orders WHERE order_month = "2025-07" GROUP BY category ORDER BY total_sales DESC', name='sql_query_runner', type='custom_tool_call', id='ctc_6897acf67a34819f84a085191e4ca1fb0d5175a46255063b', status='completed')]
Extracted SQL from tool call:
SELECT category, SUM(sales) AS total_sales FROM orders WHERE order_month = "2025-07" GROUP BY category ORDER BY total_sales DESC
=== 2) Local Tool Execution ===
category | total_sales
----------------------------
Electronics | 52423
Clothing | 59976
Furniture | 172713
Toys | 69667
Books | 14633
=== 3) Second Model Call ===
Final natural-language answer:
Here are the total sales by category for last month (2025-07):
- Furniture: 172,713
- Toys: 69,667
- Clothing: 59,976
- Electronics: 52,423
- Books: 14,633
Want this as a chart or need a different month?
6. Herramientas permitidas
El nuevo parámetro allowed_tools te permite definir un subconjunto de herramientas que el modelo puede utilizar de tu kit de herramientas completo. Puedes configurar el modo en automático (el modelo puede elegir) o obligatorio (el modelo debe usar uno). Esto mejorala seguridad, la previsibilidad y el almacenamiento en caché rápido deun , ya que evita que el modelo llame a herramientas no deseadas, al tiempo que le ofrece flexibilidad para elegir la mejor opción del conjunto permitido.
Un kit completo contiene tanto get_weather y send_email, pero solo hemos permitido get_weather y hemos establecido el modo en «obligatorio», lo que obliga al modelo a utilizarlo.
Cuando se le preguntó «¿Qué tiempo hace en Oslo?», GPT-5 respondió con una llamada a la función get_weather y el argumento correcto {"city": "Oslo"}.
from openai import OpenAI
client = OpenAI()
# Full toolset (N)
tools = [
{
"type": "function",
"name": "get_weather",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
},
},
{
"type": "function",
"name": "send_email",
"parameters": {
"type": "object",
"properties": {"to": {"type": "string"}, "body": {"type": "string"}},
"required": ["to", "body"],
},
},
]
# Allowed subset (M < N), mode=required → must call get_weather
resp = client.responses.create(
model="gpt-5",
input="What's the weather in Oslo?",
tools=tools,
tool_choice={
"type": "allowed_tools",
"mode": "required", # use "auto" to let it decide
"tools": [{"type": "function", "name": "get_weather"}],
},
)
for item in resp.output:
if getattr(item, "type", None) in ("function_call", "tool_call", "custom_tool_call"):
print("Tool name:", getattr(item, "name", None))
print("Arguments:", getattr(item, "arguments", None))
Salida:
Tool name: get_weather
Arguments: {"city":"Oslo"}
7. Preámbulos
Los preámbulos son explicaciones breves y visibles para el usuario que GPT-5 puede generar antes de llamar a una herramienta, explicando por qué está realizando esa llamada. Esto aumenta la transparencia, la confianza de los usuarios y la facilidad de depuración, especialmente en flujos de trabajo complejos. Con solo indicar al modelo que «explique antes de llamar a una herramienta», puedes hacer que las interacciones parezcan máse es, humanas e intencionadas sin añadir una latencia significativa.
En el código siguiente, hemos definido una get_weather y hemos añadido una instrucción del sistema que indica al modelo que genere una frase breve y visible para el usuario, precedida de «Preámbulo:», antes de llamar a la herramienta.
Cuando se le preguntó «¿Qué tiempo hace en Oslo?», GPT-5 primero generó un preámbulo explicando que estaba consultando un servicio meteorológico en directo y, a continuación, llamó a la herramienta get_weather con el argumento correcto {"city": "Oslo"}. Después de ejecutar la herramienta localmente y devolver el resultado, el modelo dio la respuesta final en lenguaje natural.
from openai import OpenAI
client = OpenAI()
def get_weather(city: str):
return {"city": city, "temperature_c": 12}
# Tool
tools = [{
"type": "function",
"name": "get_weather",
"description": "Get current temperature for a city.",
"parameters": {
"type": "object",
"properties": {"city": {"type": "string"}},
"required": ["city"],
"additionalProperties": False
},
"strict": True,
}]
# Messages (enable preamble via system instruction)
msgs = [
{"role": "system", "content": "Before you call a tool, explain why you are calling it in ONE short sentence prefixed with 'Preamble:'."},
{"role": "user", "content": "What's the weather in Oslo?"}
]
# 1) Model call → expect a visible preamble + a tool call
resp = client.responses.create(model="gpt-5", input=msgs, tools=tools)
print("=== First response objects ===")
for item in resp.output:
t = getattr(item, "type", None)
if t == "message": # preamble is a normal assistant message
print("PREAMBLE:", getattr(item, "content", None))
if t in ("function_call","tool_call","custom_tool_call"):
print("TOOL:", getattr(item, "name", None))
print("ARGS:", getattr(item, "arguments", None))
tool_call = next(x for x in resp.output if getattr(x, "type", None) in ("function_call","tool_call","custom_tool_call"))
msgs += resp.output # keep context
# 2) Execute tool locally (fake)
import json
args = json.loads(getattr(tool_call, "arguments", "{}"))
city = args.get("city", "Unknown")
tool_result = get_weather(city)
# 3) Return tool result
msgs.append({"type": "function_call_output", "call_id": tool_call.call_id, "output": json.dumps(tool_result)})
# 4) Final model call → natural answer
final = client.responses.create(model="gpt-5", input=msgs, tools=tools)
print("\n=== Final answer ===")
print(final.output_text)
Como podemos ver, el modelo primero dio un breve preámbulo explicando su intención, luego llamó correctamente a la herramienta get_weather con {"city": "Oslo"} y, finalmente, devolvió la temperatura en lenguaje natural.
=== First response objects ===
PREAMBLE: [ResponseOutputText(annotations=[], text='Preamble: I'm checking a live weather service to get the current conditions for Oslo.', type='output_text', logprobs=[])]
TOOL: get_weather
ARGS: {"city":"Oslo"}
=== Final answer ===
It's currently about 12°C in Oslo.
8. Optimización rápida
GPT-5 está diseñado para destacar con indicaciones bien elaboradas, y OpenAI proporciona un Optimizador de indicaciones para ayudarte a perfeccionarlas. Esta herramienta adapta automáticamente tus indicaciones al estilo de razonamiento de GPT-5, mejorando la precisión y la eficiencia.
Ve a la Editar solicitud - API de OpenAI y escribe un mensaje sencillo, como «Crear una aplicación web clon de Netflix». Desglosará tu indicación en una estructura detallada, optimizada para el modelo GPT-5.

Fuente: Optimizador rápido
Solo tienes que copiar el mensaje y añadirlo al chat de ChatGPT para empezar a crear tu propio servicio web de Netflix.
9. Migración a modelos GPT-5
OpenAI recomienda encarecidamente a los programadores que migren de los modelos antiguos a la nueva familia GPT-5 para reducir costes, mejorar la precisión y aumentar la calidad de la respuesta.
La migración es muy sencilla; solo tienes que seguir la tabla siguiente para elegir el modelo GPT‑5 y el nivel de razonamiento adecuados para tu caso de uso.
|
Modelo actual |
Modelo GPT-5 recomendado |
Nivel de razonamiento inicial |
Notas sobre migración |
|
o3 |
GPT-5 |
Medio |
Comienza con un razonamiento medio + ajuste rápido; aumenta a alto si es necesario. |
|
gpt-4.1 |
GPT-5 |
Mínimo |
Comienza con un razonamiento mínimo + ajuste rápido; aumenta a bajo para obtener un mejor rendimiento. |
|
o4-mini |
GPT-5-mini |
Medio |
Utiliza GPT-5-mini con ajuste rápido. |
|
gpt-4.1-mini |
GPT-5-mini |
Mínimo |
Utiliza GPT-5-mini con ajuste rápido. |
|
gpt-4.1-nano |
GPT-5-nano |
Mínimo |
Utiliza GPT-5-nano con ajuste rápido. |
Reflexiones finales
GPT-5 es más que un modelo más inteligente; es un kit de herramientas para programadores que permite crear sistemas de IA inteligentes, fiables y eficientes. Con un control preciso sobre el razonamiento, la verbosidad, el uso de herramientas y los formatos de salida, se adapta a todo, desde tareas de codificación rápidas hasta flujos de trabajo complejos de varios pasos.
Al aprovechar sus nuevas funciones y prácticas recomendadas, puedes desarrollar aplicaciones de IA listas para producción utilizando el SDK de OpenAI con un esfuerzo mínimo.
Si eres nuevo en el uso de OpenAI, no te pierdas los siguientes recursos:
- Trabajar con la API de OpenAI : Aprende los fundamentos de la interacción con los modelos de OpenAI.
- Programa Fundamentos de OpenAI : Un itinerario de aprendizaje completo para las tecnologías OpenAI.

Soy un científico de datos certificado que disfruta creando aplicaciones de aprendizaje automático y escribiendo blogs sobre ciencia de datos. Actualmente me centro en la creación de contenidos, la edición y el trabajo con grandes modelos lingüísticos.