1. Introducción a la Llamada de Funciones

En el modelo GPT, la Llamada de Funciones se refiere a proporcionar funciones descriptivas al modelo a través de una API, lo que le permite seleccionar e imprimir inteligentemente un objeto JSON que contiene parámetros para llamar a una o más funciones. Es importante tener en cuenta que la API de Completado de Chat no ejecuta directamente las llamadas de funciones, sino que genera JSON que se puede usar para ejecutar funciones en el código.

En términos sencillos, la funcionalidad de Llamada de Funciones implica proporcionar un conjunto de definiciones de funciones (incluidas descripciones de funciones y parámetros) al modelo GPT. El modelo luego decide qué función llamar basándose en la consulta del usuario. Dado que el modelo no puede ejecutar funciones externas, solo puede responder con una solicitud de qué función llamar (incluidos los parámetros de la llamada de la función). Después de recibir el resultado de la solicitud del modelo, nuestro programa ejecuta la llamada de la función localmente. El resultado de la llamada de la función se concatena con la indicación y se envía de vuelta al modelo para su posterior procesamiento antes de devolver el resultado final al usuario.

2. Escenarios de Aplicación de la Llamada de Funciones

Aquí hay algunos ejemplos de sus aplicaciones prácticas:

  • Crear un asistente para responder preguntas llamando a APIs externas, como definir funciones como enviar_email(para: string, cuerpo: string) o obtener_tiempo_actual(ubicación: string, unidad: 'celsius' | 'fahrenheit').
  • Convertir el lenguaje natural en llamadas de API, por ejemplo, traducir "¿Quiénes son mis mejores clientes?" a obtener_clientes(ingreso_mínimo: int, creado_antes: string, límite: int) y luego hacer una llamada de API interna.
  • Extraer datos estructurados del texto, por ejemplo, definir funciones como extraer_datos(nombre: string, cumpleaños: string) o consulta_sql(consulta: string).

Al utilizar la funcionalidad de Llamada de Funciones, podemos implementar agentes de IA que interactúen con nuestros sistemas locales y bases de datos, como hacer que la IA consulte el clima actual, verifique los precios de las acciones, haga pedidos para llevar o reserve vuelos.

3. Modelos que admiten la Llamada de Funciones

No todas las versiones del modelo han sido entrenadas con datos de llamadas de funciones. Actualmente, los modelos que admiten la llamada de funciones son: gpt-4, gpt-4-turbo-preview, gpt-4-0125-preview, gpt-4-1106-preview, gpt-4-0613, gpt-3.5-turbo, gpt-3.5-turbo-1106 y gpt-3.5-turbo-0613.

Además, los modelos gpt-4-turbo-preview, gpt-4-0125-preview, gpt-4-1106-preview y gpt-3.5-turbo-1106 admiten la llamada de funciones paralelas, lo que les permite ejecutar múltiples llamadas de funciones a la vez y manejar estas llamadas de funciones de manera concurrente para producir resultados efectivos y eficientes.

Nota: El riesgo potencial asociado con la funcionalidad de Llamada de Funciones es que puede llevar al modelo a producir parámetros erróneos (es decir, parámetros fantasma). Por lo tanto, antes de realizar acciones que afecten al mundo real (como enviar correos electrónicos, publicar en línea, realizar compras, etc.), es recomendable incorporar un proceso de confirmación del usuario a nivel de producto, asegurando que las funciones se ejecuten solo después de la confirmación del usuario.

4. Ejemplos de Llamada de Funciones

4.1 Ejemplo en Python

Implementar la Llamada de Funciones en la plataforma de OpenAI generalmente sigue los pasos básicos descritos a continuación. A continuación, se detallará todo el proceso utilizando un ejemplo de código en Python, centrándose en la consulta del clima.

Paso 1: Preparar funciones llamables y definiciones de funciones para el modelo

Primero, necesitamos definir una función que pueda ser llamada por el modelo GPT. Esto generalmente significa preparar nuestra propia función que puede realizar ciertas operaciones basadas en los parámetros de entrada, como comunicarse con una API de terceros.

import json

def obtener_tiempo_actual(ubicacion, unidad="fahrenheit"):
    return json.dumps({
        "ubicacion": ubicacion, 
        "temperatura": "18", 
        "unidad": unidad
    })

Paso 2: Llamar al modelo basado en el parámetro de consulta y herramientas

A continuación, necesitamos llamar al modelo GPT a través de la API de Completado de Chat y pasar la consulta del usuario (por ejemplo, "¿Cuál es el clima actual") así como el parámetro tools, que incluye la descripción de la función get_current_weather que acabamos de definir.

from openai import OpenAI

cliente = OpenAI()

herramientas = [{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Obtener el clima actual para una ubicación dada",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "Nombre de la ciudad, por ejemplo: 'San Francisco, CA'"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"]
                }
            },
            "required": ["location"]
        }
    }
}]

respuesta = cliente.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[{"role": "user", "content": "¿Cuál es el clima actual en San Francisco?"}],
    tools=herramientas
)

Paso 3: Ejecutar la función localmente

El resultado devuelto por el modelo incluirá información sobre la función que el modelo desea llamar, típicamente contenida en el parámetro de respuesta tool_calls. Luego podemos ejecutar la llamada a la función correspondiente localmente en base a la información de la llamada a la función descrita en el parámetro tool_calls.

tool_calls = respuesta.choices[0].message.tool_calls

if tool_calls:
    argumentos = json.loads(tool_calls[0].function.arguments)
    info_clima = get_current_weather(**argumentos)
    print(info_clima) # Aquí podemos ver la información del clima consultada por la llamada a la función

Paso 4: Llamar nuevamente al modelo con el resultado de la función

Ahora, podemos enviar el resultado de la función como un nuevo mensaje al modelo, para que el modelo pueda procesar estos resultados y generar una respuesta adaptada al usuario.

respuesta_seguimiento = cliente.chat.completions.create(
    model="gpt-3.5-turbo",
    messages=[
        {"role": "user", "content": "¿Cuál es el clima actual en San Francisco?"},
        {"role": "function", "name": "get_current_weather", "content": info_clima}
    ],
    tools=herramientas
)

Explicación: En el ejemplo anterior, el contenido de retorno de la función se envía al modelo GPT a través del mensaje de función de la siguiente manera:

{"role": "function", "name": "get_current_weather", "content": info_clima}

En la práctica, también puedes simplemente poner el contenido de retorno de la función como contenido de referencia en el mensaje del sistema para que la IA lo use como referencia al responder preguntas.

Paso 5: Obtener la respuesta final del modelo

Finalmente, podemos recuperar la respuesta final del modelo y proporcionarla al usuario. En este paso, el modelo producirá una respuesta amigable para el usuario basada en la información climática que proporcionamos.

salida_final = respuesta_seguimiento.choices[0].message.content
print(salida_final) # Esta salida es la información climática que queremos mostrar al usuario

Siguiendo los pasos anteriores, hemos completado un ejemplo completo de cómo consultar el clima usando el modelo GPT y llamadas a funciones.

4.2. Explicación de la función de llamada a la función de llamada de función

4.2.1 Significado de los Campos del Parámetro 'Tools'

Al hacer una llamada a función, es necesario definir la información relevante de la función en el parámetro tools. El parámetro tools es un array que contiene múltiples definiciones de funciones, y cada definición de función incluye los siguientes campos:

  1. type: Este campo representa el tipo de la herramienta. En una llamada a función, este campo debe establecerse como "function".
  2. function: Este campo contiene información detallada sobre la función y es un objeto con los siguientes campos específicos:
    • name: El nombre de la función, que es una cadena.
    • description: Una descripción del propósito de la función, que puede ayudar al modelo a generar parámetros que cumplan con las expectativas del usuario.
    • parameters: Describe las definiciones de parámetros de la función y es un objeto que contiene los siguientes subcampos:
      • type: Define el tipo de parámetro, que en su mayoría debería establecerse como "object".
      • properties: Las definiciones específicas de cada parámetro de la función, donde cada definición de parámetro es un objeto que típicamente contiene los siguientes subcampos:
        • type: El tipo de datos del parámetro (como "string", "integer", "boolean", etc.).
        • description: La descripción del parámetro para ayudar al modelo a entender su propósito.
        • enum (opcional): Cuando type es "string", el campo enum puede especificar un array de cadenas que representan el conjunto de valores válidos.
      • required: Un array de cadenas que contiene los nombres de los parámetros requeridos.

4.2.2 Ejemplos de Definición de Herramientas

Ahora vamos a proporcionar algunos ejemplos de definiciones de tools para ayudar a entender cómo se utiliza cada campo.

Ejemplo 1: Obtener Información Meteorológica Actual

{
    "type": "function",
    "function": {
        "name": "get_current_weather",
        "description": "Obtener información meteorológica actual para la ubicación especificada",
        "parameters": {
            "type": "object",
            "properties": {
                "location": {
                    "type": "string",
                    "description": "La ciudad para la cual se necesita consultar el clima, por ejemplo, 'San Francisco, CA'"
                },
                "unit": {
                    "type": "string",
                    "enum": ["celsius", "fahrenheit"],
                    "description": "Unidad de temperatura, 'celsius' para Celsius, 'fahrenheit' para Fahrenheit"
                }
            },
            "required": ["location", "unit"]
        }
    }
}

En el ejemplo anterior, hemos definido una función llamada get_current_weather para obtener el clima actual de una ubicación especificada. Los parámetros incluyen location y unit, donde unit tiene dos valores válidos: "celsius" (Celsius) y "fahrenheit" (Fahrenheit).

Ejemplo 2: Encontrar Álbumes de un Artista Específico

{
    "type": "function",
    "function": {
        "name": "find_artist_albums",
        "description": "Encontrar todos los álbumes de un artista específico",
        "parameters": {
            "type": "object",
            "properties": {
                "artist_name": {
                    "type": "string",
                    "description": "El nombre del artista"
                }
            },
            "required": ["artist_name"]
        }
    }
}

En este ejemplo, hemos creado una función llamada find_artist_albums para encontrar todos los álbumes de un artista específico. Esta función solo requiere un parámetro: artist_name (el nombre del artista).

4.3. Ejemplo de una Llamada a Función de Solicitud HTTP

OpenAI proporciona una API que es accesible a través del protocolo HTTP. A continuación, explicaremos cómo utilizar la función de llamada a través de la API HTTP. Los desarrolladores de otros lenguajes de programación pueden consultar este ejemplo.

4.3.1. Paso 1: Llamar al modelo con la consulta del usuario y la Declaración de la función

Primero, necesitamos enviar la consulta del usuario y la lista de funciones que admitimos al modelo GPT, para que el modelo pueda analizar automáticamente qué función llamar para responder a la consulta del usuario basándose en la pregunta del usuario.

En el siguiente ejemplo, informamos a GPT que tenemos una función get_current_weather que se puede utilizar para consultar la información meteorológica de una ciudad específica.

curl --location 'https://api.aiproxy.io/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer {OPENAI_KEY}' \
--data '{
    "model": "gpt-3.5-turbo",
    "messages": [
        {
            "role": "user",
            "content": "¿Cómo está el clima en Shanghai hoy?"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Obtener la información meteorológica actual para la ubicación especificada",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "La ciudad para la cual se necesita consultar el clima, por ejemplo 'San Francisco, CA'"
                        },
                        "unit": {
                            "type": "string",
                            "enum": [
                                "celsius",
                                "fahrenheit"
                            ],
                            "description": "Unidad de temperatura, 'celsius' para Celsius, 'fahrenheit' para Fahrenheit"
                        }
                    },
                    "required": [
                        "location",
                        "unit"
                    ]
                }
            }
        }
    ]
}'

Explicación de los parámetros de solicitud:

{
    "model": "gpt-3.5-turbo", // El modelo GPT que se va a llamar
    "messages": [ // Esta es la lista de mensajes para GPT, incluida la consulta del usuario
        {
            "role": "user",
            "content": "¿Cómo está el clima en Shanghai hoy?"
        }
    ],
    "tools": [
	  // Esta es tu definición de función, informando a GPT de las funciones disponibles
    ]
}

Consulta la sección 4.2.2 para la definición del parámetro tools.

En el procesamiento normal por el modelo GPT, recibirás una respuesta de la API similar a la siguiente:

{
    "model": "gpt-3.5-turbo-0613",
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 122,
        "completion_tokens": 27,
        "total_tokens": 149
    },
    "id": "chatcmpl-8mL4hS4zNMocyR2ajKyAvSTcbNaao",
    "created": 1706531447,
    "choices": [
        {
            "index": 0,
            "delta": null,
            "message": {
                "role": "assistant",
                "tool_calls": [ // El parámetro tool_calls representa la lista de funciones que GPT desea llamar
                    {
                        "id": "call_1iF09ttX1R9ESR18Ul2nLe1R",
                        "type": "function",
                        "function": {
                            "name": "get_current_weather",  // Indica que GPT desea responder a la consulta del usuario llamando a la función get_current_weather
                            "arguments": "{\n  \"location\": \"Shanghai, China\",\n  \"unit\": \"celsius\"\n}" // Este es el parámetro de entrada para llamar a la función get_current_weather
                        }
                    }
                ]
            },
            "finish_reason": "tool_calls"
        }
    ]
}

4.3.2. Paso 2: Ejecución de la llamada local a la función

Dado que el modelo GPT en sí no puede ejecutar llamadas específicas a funciones y solo nos informa qué función desea llamar, nuestro programa local debe ejecutar la llamada específica a la función basándose en el parámetro tool_calls devuelto por el modelo. La forma de ejecutar funciones locales varía en diferentes lenguajes de programación. Por ejemplo, en Python, puedes consultar la sección anterior.

4.3.3. Paso 3: Llamar al Modelo de Nuevo con el Resultado del Retorno de la Función

Debido a que la llamada a la función se ejecuta localmente, necesitamos pasar el resultado de la ejecución de la función y la pregunta del usuario de vuelta al modelo GPT para obtener la respuesta final.

curl --location 'https://api.aiproxy.io/v1/chat/completions' \
--header 'Content-Type: application/json' \
--header 'Authorization: Bearer sk-Roc5MX1zEuVxiuaMaETV6wZ2jXcCehjUCzwP9AcNErUiwppQ' \
--data '{
    "model": "gpt-3.5-turbo",
    "messages": [
        {
            "role": "user",
            "content": "¿Cómo está el clima en Shanghai hoy?"
        },
        {
            "role": "function",
            "name": "get_current_weather",
            "content": "{\"city\":\"Shanghai\", \"temperature\":\"25 grados Celsius\"}"
        }
    ],
    "tools": [
        {
            "type": "function",
            "function": {
                "name": "get_current_weather",
                "description": "Obtener la información meteorológica actual para la ubicación especificada",
                "parameters": {
                    "type": "object",
                    "properties": {
                        "location": {
                            "type": "string",
                            "description": "La ciudad para la cual consultar el clima, por ejemplo, 'San Francisco, CA'"
                        },
                        "unit": {
                            "type": "string",
                            "enum": [
                                "celsius",
                                "fahrenheit"
                            ],
                            "description": "La unidad de temperatura, 'celsius' para Celsius, 'fahrenheit' para Fahrenheit"
                        }
                    },
                    "required": [
                        "location",
                        "unit"
                    ]
                }
            }
        }
    ]
}'

Nota: La solicitud anterior incluye un mensaje de función adicional para informar al modelo GPT sobre el valor de retorno de la función. GPT responderá directamente la pregunta del usuario en función de la información de retorno de la función y no llamará nuevamente a la función.

El mensaje de función representa el valor de retorno de la función y sigue el siguiente formato:

{
    "role": "function", // El tipo de mensaje es función, lo que indica el valor de retorno de la función
    "name": "get_current_weather", // Informa a GPT que el mensaje actual es el valor de retorno de la función get_current_weather
    "content": "{\"city\":\"Shanghai\", \"temperature\":\"25 grados Celsius\"}" // Contenido de retorno de la función, puede estar en formato JSON u otro contenido de texto.
}

A continuación se muestra la respuesta final generada por GPT:

{
    "model": "gpt-3.5-turbo-0613",
    "object": "chat.completion",
    "usage": {
        "prompt_tokens": 144,
        "completion_tokens": 17,
        "total_tokens": 161
    },
    "id": "chatcmpl-8mLmvvKAjSql7rGF8fvQeddKhWYvr",
    "created": 1706534189,
    "choices": [
        {
            "index": 0,
            "delta": null,
            "message": {
                "role": "assistant",
                "content": "El clima en Shanghai hoy es de 25 grados Celsius."
            },
            "finish_reason": "stop"
        }
    ]
}