Cómo usar Function Calling con la API de DeepSeek V4 Pro

Guía práctica sobre la llamada a funciones de DeepSeek V4 Pro: esquemas de herramientas, el ciclo completo del agente Python, llamadas a herramientas en paralelo, modo de pensamiento, manejo de errores, costos de caché y pruebas de llamadas a herramientas en Apidog.

INEZA Felin-Michel

INEZA Felin-Michel

13 August 2026

Cómo usar Function Calling con la API de DeepSeek V4 Pro

Apidog para empresas

Despliegue local

SSO & RBAC

Conforme con SOC 2

Explorar Apidog Enterprise

DeepSeek sacó V4 Pro de la vista previa el 12 de agosto de 2026, y la cobertura del lanzamiento destaca los flujos de trabajo basados en agentes: codificación, uso de herramientas y tareas de largo horizonte que encadenan docenas de pasos sin perder el hilo. Ese posicionamiento hace que una característica de la API sea más importante que cualquier otra, la llamada a funciones, y es la única característica que las guías de la semana de lanzamiento no han abordado. Todos los tutoriales hasta ahora se detienen en las finalizaciones de chat.

Este va más allá: defina un esquema de herramienta, realice su primera llamada a herramienta con el SDK estándar de Python openai, construya el bucle completo del agente, y luego pruebe todo en Apidog antes de que su agente se implemente. Si aún no tiene una clave API de DeepSeek, configúrela con nuestra guía sobre cómo usar la API de DeepSeek V4, y luego regrese.

botón

En resumen (TL;DR)

Por qué la llamada a herramientas es el caso de uso principal de V4 Pro

DeepSeek construyó V4 Pro para agentes, y la hoja de especificaciones se lee como una lista de verificación de tiempo de ejecución de agentes:

Especificación DeepSeek V4 Pro
Arquitectura MoE disperso: 1,6T parámetros totales, 49B activos por token
Ventana de contexto 1M de tokens
Salida máxima 384K tokens
Precio de entrada 0,435 $/M tokens (fallo de caché), 0,003625 $/M (acierto de caché)
Precio de salida 0,87 $/M tokens
Llamada a funciones Array tools compatible con OpenAI y respuestas tool_calls
Otras interfaces Formato de mensajes Anthropic, API de respuestas de DeepSeek

Cada línea se asigna a un problema de agente: la ventana de 1M de tokens lleva el historial completo de resultados de herramientas de un agente largo, el límite de salida de 384K deja espacio para grandes cargas útiles estructuradas, y el almacenamiento en caché de prefijos hace que la economía del bucle funcione. El modelo aparece en OpenRouter como deepseek-v4-pro-0813 para comparaciones de proveedores.

Una advertencia antes del código. En la discusión de lanzamiento de Hacker News, los desarrolladores informaron que el rendimiento de la llamada a herramientas es muy sensible al arnés: el mismo modelo obtuvo mejores o peores resultados dependiendo del marco, el andamiaje del prompt y el estilo del esquema. Los puntos de referencia no le dirán cómo maneja *sus* esquemas de herramientas. Pruebe con sus definiciones reales.

Cómo funciona la llamada a funciones de DeepSeek

La llamada a funciones no significa que el modelo ejecute nada. Responde con una solicitud estructurada, "llama a get_order con {"order_id": "ORD-10442"}", en lugar de prosa. Su código ejecuta la función, devuelve el resultado y el modelo continúa con datos reales. El ciclo:

  1. Usted envía messages más un array tools que describe cada función en JSON Schema.
  2. El modelo decide que se necesita una herramienta y responde con tool_calls y finish_reason: "tool_calls".
  3. Su código analiza los argumentos y ejecuta la función real.
  4. Usted agrega el resultado como un mensaje con role: "tool" vinculado al ID de la llamada.
  5. El modelo solicita otra herramienta o produce su respuesta final.

Si ha trabajado con la llamada a funciones de OpenAI, este es el mismo formato de conexión; la mayoría del código de agente se porta cambiando la URL base y el nombre del modelo. Los documentos oficiales de DeepSeek también cubren un endpoint de Mensajes compatible con Anthropic y una API de Respuestas, pero esta guía se adhiere a la interfaz compatible con OpenAI.

Paso 1: Configurar el cliente

Instale el SDK y apúntelo a DeepSeek:

pip install openai
export DEEPSEEK_API_KEY="sk-..."
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

Esa es toda la configuración. Cada ejemplo usa model="deepseek-v4-pro", que se resuelve en la versión GA DeepSeek-V4-Pro-0813.

Paso 2: Definir un esquema de herramienta

Construiremos un agente de soporte para una tienda en línea. Su primera herramienta busca pedidos. Una definición de herramienta tiene tres partes: un nombre, una descripción y un JSON Schema para los parámetros.

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order",
            "description": (
                "Busca el pedido de un cliente por su ID. Devuelve el estado del pedido, "
                "el transportista, el número de seguimiento y la fecha de entrega estimada. "
                "Utilice esto siempre que el usuario pregunte dónde está un pedido o en qué estado se encuentra."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "El ID del pedido, con formato 'ORD-10442'."
                    }
                },
                "required": ["order_id"],
            },
        },
    }
]

La descripción no es decoración: el modelo decide cuándo llamar a una herramienta leyéndola. Las descripciones vagas son la principal razón por la que un modelo ignora una herramienta o elige la incorrecta.

La función local que describe el esquema, simulada para un servicio de pedidos real:

def get_order(order_id: str) -> dict:
    """Stub para su servicio de pedidos real."""
    fake_db = {
        "ORD-10442": {
            "status": "shipped",
            "carrier": "DHL",
            "tracking_number": "4281337005",
            "estimated_delivery": "2026-08-15",
        },
        "ORD-10587": {
            "status": "processing",
            "estimated_ship_date": "2026-08-14",
        },
    }
    return fake_db.get(order_id, {"error": f"ID de pedido desconocido: {order_id}"})

Paso 3: Realizar su primera llamada a herramienta

Envíe una pregunta que el modelo no pueda responder sin la herramienta:

messages = [
    {"role": "system", "content": "Eres un agente de soporte para una tienda en línea."},
    {"role": "user", "content": "¿Dónde está mi pedido ORD-10442?"},
]

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)

message = response.choices[0].message
print(message.tool_calls[0].function.name) # get_order
print(message.tool_calls[0].function.arguments) # {"order_id": "ORD-10442"}

En lugar de responder, el modelo le pide que ejecute get_order. La carga útil de la respuesta sin procesar tiene este aspecto:

{
  "id": "chatcmpl-8f3a1c",
  "object": "chat.completion",
  "model": "deepseek-v4-pro",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_0_f1c29a44",
            "type": "function",
            "function": {
              "name": "get_order",
              "arguments": "{\"order_id\": \"ORD-10442\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 312,
    "completion_tokens": 24,
    "total_tokens": 336,
    "prompt_cache_hit_tokens": 0,
    "prompt_cache_miss_tokens": 312
  }
}

Tres detalles importan. finish_reason es "tool_calls", lo que le indica a su bucle que el modelo quiere ejecución. Cada llamada lleva un id que debe devolver con el resultado. Y arguments es una *cadena* JSON que usted mismo analiza, así que espere que ocasionalmente esté mal formada.

Paso 4: Ejecutar la función y devolver el resultado

Ejecute la función y luego agregue dos mensajes: el turno del asistente que contiene tool_calls, y un mensaje tool que lleva su resultado.

import json

tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_order(args)

messages.append(message) # el turno del asistente que contiene tool_calls
messages.append({
    "role": "tool",
    "tool_call_id": tool_call.id, # debe coincidir con el id de la respuesta
    "content": json.dumps(result),
})

final = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)
# Su pedido ORD-10442 fue enviado con DHL y se estima que llegará
# antes del 15 de agosto de 2026. Número de seguimiento: 4281337005.

El enlace tool_call_id es estricto: cada entrada de tool_calls necesita un mensaje tool coincidente antes del siguiente turno del modelo, o la solicitud fallará.

Paso 5: El bucle completo del agente

Los agentes reales encadenan llamadas: buscar un pedido, verificar una política de reembolso, redactar un correo electrónico, cada paso dependiendo del anterior. El patrón: seguir llamando al modelo y ejecutando lo que solicite hasta que devuelva una respuesta normal.

TOOLS_BY_NAME = {"get_order": get_order}

def run_agent(client, messages, tools, max_rounds=10):
    """Ejecuta el modelo hasta que produce una respuesta final o alcanza el límite."""
    for _ in range(max_rounds):
        response = client.chat.completions.create(
            model="deepseek-v4-pro",
            messages=messages,
            tools=tools,
        )
        message = response.choices[0].message
        messages.append(message)

        if not message.tool_calls: # no hay solicitudes de herramientas: hemos terminado
            return message.content

        for tool_call in message.tool_calls:
            fn = TOOLS_BY_NAME.get(tool_call.function.name)
            try:
                if fn is None:
                    raise ValueError(f"Herramienta desconocida: {tool_call.function.name}")
                args = json.loads(tool_call.function.arguments)
                result = fn(args)
            except Exception as exc:
                result = {"error": str(exc)} # devuelve los fallos al modelo
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            })

    raise RuntimeError(f"El agente no terminó dentro de {max_rounds} rondas")

Los frameworks y los SDK de agentes son elaboraciones de este bucle. El límite max_rounds convierte un modelo que se queda atascado reintentando una herramienta fallida en un fallo limpio en lugar de una factura abierta.

Llamadas a herramientas paralelas

Pida dos búsquedas, "compare el estado de ORD-10442 y ORD-10587", y V4 Pro a menudo agrupará ambas en un solo turno:

"tool_calls": [
  {
    "id": "call_0_a7d1",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10442\"}" }
  },
  {
    "id": "call_1_b3e9",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10587\"}" }
  }
]

El bucle run_agent ya maneja esto: el bucle for interno responde a cada llamada con su propio tool_call_id (cada llamada necesita un resultado coincidente antes del siguiente turno), y usted es libre de ejecutar el lote de forma concurrente. Es una filosofía diferente a la llamada programática a herramientas de GPT-5.6, donde el modelo escribe código de orquestación en un entorno aislado; DeepSeek mantiene la ejecución y el límite de confianza en su tiempo de ejecución.

Modo de pensamiento más herramientas

V4 Pro viene con tres modos de pensamiento, para que pueda aumentar el esfuerzo de razonamiento para los turnos de planificación difíciles y omitirlo para las búsquedas rutinarias (consulte la documentación oficial para conocer los nombres y valores predeterminados de los modos). Con el pensamiento habilitado, la API devuelve el rastro del modelo como reasoning_content junto con cualquier llamada a herramientas:

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
    extra_body={"thinking": {"type": "enabled"}},
)

message = response.choices[0].message
print(message.reasoning_content) # el rastro de planificación
print(message.tool_calls) # las llamadas en las que se basó

El rastro muestra por qué el modelo eligió una herramienta, que es donde generalmente se revela un esquema incorrecto. Elimine reasoning_content antes de agregar el turno del asistente al historial, y reserve el pensamiento para los turnos que requieren mucha planificación, ya que el razonamiento se factura como salida a 0,87 $/M.

Manejo de errores: cuando el modelo se equivoca en una llamada

Las llamadas a herramientas mal formadas son raras, pero un bucle de agente amplifica cada modo de fallo. El patrón esencial: nunca se bloquee por una llamada incorrecta, devuelva el problema como resultado de la herramienta y deje que el modelo lo reintente. Esto cubre los argumentos que fallan json.loads, así como los valores que rompen sus reglas de negocio:

from jsonschema import ValidationError, validate

schema = tools[0]["function"]["parameters"]

try:
    args = json.loads(tool_call.function.arguments)
    validate(instance=args, schema=schema)
    result = get_order(**args)
except (json.JSONDecodeError, ValidationError) as exc:
    result = {
        "error": f"Argumentos inválidos: {exc}",
        "hint": "Vuelve a llamar a get_order con una cadena order_id como 'ORD-10442'.",
    }

El campo hint importa: una corrección de una línea generalmente produce un reintento corregido en la siguiente ronda. Trate los errores del agente también como eventos de seguridad. Un modelo convencido de llamar a delete_order con argumentos proporcionados por un atacante es tan peligroso como la clave que lo respalda, el caso de las claves API con el mínimo privilegio para agentes de IA. Alcance las credenciales para que una llamada incorrecta no se convierta en un incidente.

Pruebe y depure las llamadas a herramientas con Apidog antes de implementar

Cada herramienta es un envoltorio delgado alrededor de una API, y el modelo es ahora un consumidor de esa API. Si el endpoint de respaldo es ambiguo o inestable, el modelo hereda todo eso. Aquí es donde Apidog se gana su lugar en el bucle:

  1. Diseñe la API de respaldo primero. Defina GET /orders/{order_id} como una especificación en el diseñador visual de Apidog; el JSON Schema de su herramienta surge directamente de la especificación, por lo que los dos no pueden divergir silenciosamente.
  2. Simúlela antes de que exista el backend. El mock inteligente de Apidog sirve respuestas realistas desde el esquema, por lo que el bucle del agente se ejecuta contra get_order mientras el servicio real aún se está construyendo.
  3. Inspeccione las cargas útiles sin procesar. Envíe el mismo cuerpo messages + tools a https://api.deepseek.com desde Apidog y lea directamente el JSON tool_calls sin procesar; un properties mal anidado o argumentos doblemente codificados aparecen en una sola inspección.
  4. Convierta las conversaciones en escenarios de prueba. Afirme sobre finish_reason y las formas de los argumentos, y ejecute el conjunto en cada cambio de esquema; dada la sensibilidad del arnés reportada en Hacker News, un conjunto de regresión sobre sus esquemas reales es el punto de referencia que predice la producción. Consulte cómo conectar un agente de IA a un arnés de prueba de Apidog para ver un patrón más profundo.

Descargue Apidog gratis para seguir los pasos; el servidor mock y los escenarios de prueba están incluidos en el nivel gratuito.

Cuánto cuestan los bucles de agente (y por qué el almacenamiento en caché lo decide)

Los bucles del agente releen toda la conversación en cada ronda: en la décima ronda, su prompt de sistema, esquemas de herramientas y nueve rondas de resultados se facturan por décima vez. El almacenamiento en caché automático de prefijos de V4 Pro rompe esa curva, la entrada de cada ronda es la de la ronda anterior más un poco más, por lo que casi todo el prefijo se factura a 0,003625 $/M en lugar de 0,435 $/M. Releer una conversación de 100K tokens cuesta alrededor de 0,0435 $ sin caché, pero alrededor de 0,0004 $ con caché; prompt_cache_hit_tokens en el bloque de uso muestra su tasa de aciertos real.

Para mantener esa tasa alta, nunca modifique mensajes anteriores y mantenga el array tools byte-estable en todas las rondas. Nuestra introducción a qué es el almacenamiento en caché de prompts cubre los mecanismos. Y si deepseek-v4-flash a 0,14 $/0,28 $ parece tentador: está bien para el enrutamiento de herramientas de un solo disparo, pero retrocede en bucles que encadenan más de 10 llamadas, por lo que los reintentos se comen los ahorros, Pro es la opción predeterminada más segura para los agentes.

Preguntas frecuentes

¿Las definiciones de herramientas cuestan tokens?

Sí, el array tools es entrada en cada solicitud. Manténgalo estable y se unirá al prefijo en caché después de la primera ronda, facturándose a la tasa de acierto de caché a partir de entonces.

¿Puedo combinar la llamada a funciones con salidas estructuradas?

Sí. Un patrón común: las herramientas obtienen los datos intermedios, un esquema de salida estructurada formatea la respuesta final, para que el código posterior nunca analice la prosa.

Conclusión

La llamada a funciones en DeepSeek V4 Pro es deliberadamente poco emocionante de implementar: esquemas compatibles con OpenAI, un array tool_calls, un mensaje tool con un ID. El bucle del Paso 5 es toda la arquitectura, y el precio por acierto de caché lo hace más barato de lo que la mayoría de los equipos esperan. Lo que los puntos de referencia no pueden decirte es cómo se comporta el modelo frente a *tus* esquemas; diseña las API de respaldo deliberadamente, simúlelas temprano y mantén un conjunto de regresión de escenarios de llamadas a herramientas en Apidog para que los cambios de esquema no puedan romper silenciosamente tu agente.

botón

Practica el diseño de API en Apidog

Descubre una forma más fácil de construir y usar APIs