Trabajo con los modelos GPT-3.5-Turbo, GPT-4 y GPT-4o

Los modelos de la aserie GPT-3.5-Turbo, GPT-4 y GPT-4o son modelos de lenguaje optimizados para interfaces conversacionales. Los modelos se comportan de forma diferente a los modelos GPT-3 anteriores. Estos eran de entrada y salida de texto, lo que significa que aceptaban una cadena de solicitud y devolvían una finalización para anexar a la solicitud. Sin embargo, los modelos más recientes son de entrada de conversación y salida de mensajes. Los modelos esperan la entrada con un formato específico de transcripción similar al de un chat. Devuelven una finalización que representa un mensaje escrito por el modelo en el chat. Este formato se diseñó específicamente para conversaciones multiturno, pero también puede funcionar bien para escenarios que no son de chat.

En este artículo se explica cómo empezar a trabajar con los modelos de finalizaciones de chat. Para obtener los mejores resultados, use las técnicas que se describen aquí. No intente interactuar con los modelos de la misma manera que hizo con la serie de modelos anterior, ya que los modelos generalmente suelen ser detallados y proporcionan respuestas menos útiles.

Trabajo con modelos de finalizaciones de chat

El siguiente fragmento de código muestra la manera más básica de interactuar con modelos que usan la API de finalización de chat. Si esta es la primera vez que usa estos modelos mediante programación, se recomienda comenzar con el inicio rápido de finalizaciones de chat.

Nota:

En la documentación de Azure OpenAI, nos referimos a GPT-3.5-Turbo y GPT-35-Turbo indistintamente. El nombre oficial del modelo en OpenAI es gpt-3.5-turbo. Para Azure OpenAI, debido a restricciones de caracteres específicas de Azure, el nombre del modelo subyacente es gpt-35-turbo.

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")
)

response = client.chat.completions.create(
    model="gpt-35-turbo", # model = "deployment_name".
    messages=[
        {"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
        {"role": "user", "content": "Who were the founders of Microsoft?"}
    ]
)

#print(response)
print(response.model_dump_json(indent=2))
print(response.choices[0].message.content)
{
  "id": "chatcmpl-8GHoQAJ3zN2DJYqOFiVysrMQJfe1P",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.",
        "role": "assistant",
        "function_call": null
      },
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ],
  "created": 1698892410,
  "model": "gpt-35-turbo",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 73,
    "prompt_tokens": 29,
    "total_tokens": 102
  },
  "prompt_filter_results": [
    {
      "prompt_index": 0,
      "content_filter_results": {
        "hate": {
          "filtered": false,
          "severity": "safe"
        },
        "self_harm": {
          "filtered": false,
          "severity": "safe"
        },
        "sexual": {
          "filtered": false,
          "severity": "safe"
        },
        "violence": {
          "filtered": false,
          "severity": "safe"
        }
      }
    }
  ]
}
Microsoft was founded by Bill Gates and Paul Allen. They established the company on April 4, 1975. Bill Gates served as the CEO of Microsoft until 2000 and later as Chairman and Chief Software Architect until his retirement in 2008, while Paul Allen left the company in 1983 but remained on the board of directors until 2000.

Nota:

Los parámetros siguientes no están disponibles con los nuevos modelos GPT-35-Turbo and GPT-4: logprobs, best_of y echo. Si establece cualquiera de estos parámetros, obtendrá un error.

Cada respuesta incluye finish_reason. Los valores posibles para finish_reason son:

  • stop: la API devolvió la salida completa del modelo.
  • length: salida incompleta del modelo debido al parámetro max_tokens o al límite del token.
  • content_filter: contenido omitido debido a una marca de nuestros filtros de contenido.
  • null: la respuesta de la API sigue en curso o está incompleta.

Considere la posibilidad de establecer max_tokens en un valor ligeramente superior al normal, como 300 o 500. Un valor superior garantiza que el modelo no deje de generar texto antes de que llegue al final del mensaje.

Control de versiones de los modelos

Nota:

La versión gpt-35-turbo es equivalente al modelo gpt-3.5-turbo de OpenAI.

A diferencia de los modelos anteriores GPT-3 y GPT-3.5, tanto el modelo gpt-35-turbo como los modelos gpt-4 y gpt-4-32k seguirán actualizándose. Al crear una implementación de estos modelos, también debe especificar una versión del modelo.

Puede encontrar las fechas de retiro de estos modelos en la página de modelos.

Trabajar con la API de finalización de chat

OpenAI entrenó los modelos GPT-35-Turbo y GPT-4 para aceptar la entrada con formato de conversación. El parámetro de mensajes toma una matriz de objetos de mensaje con una conversación organizada por roles. Cuando se usa la API de Python, se usa una lista de diccionarios.

El formato de una finalización básica de chat es:

{"role": "system", "content": "Provide some context and/or instructions to the model"},
{"role": "user", "content": "The users messages goes here"}

Una conversación con una respuesta de ejemplo seguida de una pregunta tendría el siguiente aspecto:

{"role": "system", "content": "Provide some context and/or instructions to the model."},
{"role": "user", "content": "Example question goes here."},
{"role": "assistant", "content": "Example answer goes here."},
{"role": "user", "content": "First question/message for the model to actually respond to."}

Rol del sistema

El rol del sistema, también conocido como mensaje del sistema, se incluye al principio de la matriz. Este mensaje proporciona las instrucciones iniciales para el modelo. Puede proporcionar varias informaciones en el rol del sistema, como:

  • Una breve descripción del asistente.
  • Rasgos de personalidad del asistente.
  • Instrucciones o reglas que quiere que siga el asistente.
  • Datos o información necesarios para el modelo, como preguntas relevantes provenientes de preguntas frecuentes.

Puede personalizar el rol del sistema para su caso de uso o incluir instrucciones básicas. El rol/mensaje del sistema es opcional, pero se recomienda incluir al menos uno básico para obtener los mejores resultados.

Mensajes

Después del rol del sistema, puede incluir una serie de mensajes entre el user y el assistant.

 {"role": "user", "content": "What is thermodynamics?"}

Para desencadenar una respuesta del modelo, finalice con un mensaje de usuario para indicar que es el turno de responder del asistente. También se puede incluir una serie de mensajes de ejemplo entre el usuario y el asistente como una forma de realizar un aprendizaje de pocas etapas.

Ejemplos de solicitud de mensaje

En la siguiente sección, se muestran ejemplos de diferentes estilos de solicitudes que puede utilizar con los modelos GPT-35-Turbo y GPT-4. Estos ejemplos son solo un punto de partida. Puede experimentar con diferentes solicitudes para personalizar el comportamiento de sus propios casos de uso.

Ejemplo básico

Si desea que el modelo GPT-35-Turbo se comporte de forma similar a chat.openai.com, puede usar un mensaje básico del sistema como Assistant is a large language model trained by OpenAI.

{"role": "system", "content": "Assistant is a large language model trained by OpenAI."},
{"role": "user", "content": "Who were the founders of Microsoft?"}

Ejemplo con instrucciones

En algunos escenarios, puede que desee proporcionar más instrucciones al modelo para definir límites de protección para lo que el modelo puede hacer.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions.
Instructions: 
- Only answer questions related to taxes. 
- If you're unsure of an answer, you can say "I don't know" or "I'm not sure" and recommend users go to the IRS website for more information. "},
{"role": "user", "content": "When are my taxes due?"}

Usar datos para la conexión a tierra

También puede incluir información o datos relevantes en el mensaje del sistema para dar al modelo contexto adicional para la conversación. Si necesita incluir solo una pequeña cantidad de información, puede codificarla manualmente en el mensaje del sistema. Si tiene una gran cantidad de datos que el modelo debe tener en cuenta, puede usar inserciones o un producto como Azure AI Search para recuperar la información más relevante en el momento de la consulta.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI Serivce. Only answer questions using the context below and if you're not sure of an answer, you can say 'I don't know'.

Context:
- Azure OpenAI Service provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI Service gives customers advanced language AI with OpenAI GPT-3, Codex, and DALL-E models with the security and enterprise promise of Azure. Azure OpenAI co-develops the APIs with OpenAI, ensuring compatibility and a smooth transition from one to the other.
- At Microsoft, we're committed to the advancement of AI driven by principles that put people first. Microsoft has made significant investments to help guard against abuse and unintended harm, which includes requiring applicants to show well-defined use cases, incorporating Microsoft’s principles for responsible AI use."
},
{"role": "user", "content": "What is Azure OpenAI Service?"}

Aprendizaje de pocas etapas con finalización del chat

También puede dar algunos ejemplos de etapas al modelo. El enfoque para el aprendizaje de pocas etapas ha cambiado ligeramente debido al nuevo formato de solicitud. Ahora puede incluir una serie de mensajes entre el usuario y el asistente en la solicitud como algunos ejemplos de etapa. Con estos ejemplos, puede inicializar respuestas a preguntas comunes para preparar el modelo o enseñar comportamientos concretos al modelo.

En este ejemplo se muestra cómo puede usar GPT-35-Turbo y GPT-4 con pocos pasos. Puede experimentar con diferentes enfoques para ver el más adecuado para su caso de uso.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer their tax related questions. "},
{"role": "user", "content": "When do I need to file my taxes by?"},
{"role": "assistant", "content": "In 2023, you will need to file your taxes by April 18th. The date falls after the usual April 15th deadline because April 15th falls on a Saturday in 2023. For more details, see https://www.irs.gov/filing/individuals/when-to-file."},
{"role": "user", "content": "How can I check the status of my tax refund?"},
{"role": "assistant", "content": "You can check the status of your tax refund by visiting https://www.irs.gov/refunds"}

Usar la finalización del chat para escenarios que no son de chat

La API de finalización de chat está diseñada para trabajar con conversaciones multiturno, pero también funciona bien para escenarios que no son de chat.

Por ejemplo, para un escenario de extracción de entidad, puede usar la solicitud del sistema:

{"role": "system", "content": "You are an assistant designed to extract entities from text. Users will paste in a string of text and you will respond with entities you've extracted from the text as a JSON object. Here's an example of your output format:
{
   "name": "",
   "company": "",
   "phone_number": ""
}"},
{"role": "user", "content": "Hello. My name is Robert Smith. I'm calling from Contoso Insurance, Delaware. My colleague mentioned that you are interested in learning about our comprehensive benefits policy. Could you give me a call back at (555) 346-9322 when you get a chance so we can go over the benefits?"}

Crear un bucle de conversación básico

Los ejemplos hasta ahora muestran la mecánica básica de interactuar con la API de finalización de chat. En este ejemplo se muestra cómo crear un bucle de conversación que realice las siguientes acciones:

  • Recibe continuamente la entrada de la consola y le da formato de forma adecuada como parte de la lista de mensajes como contenido del rol de usuario.
  • Respuestas de salida que se imprimen en la consola, tienen formato y se agregan a la lista de mensajes como contenido del rol de asistente.

Cada vez que se formula una nueva pregunta, se envía una transcripción de la conversación hasta el momento junto con la última pregunta. Dado que el modelo no tiene memoria, debe enviar una transcripción actualizada con cada nueva pregunta o el modelo perderá el contexto de las preguntas y respuestas anteriores.

import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")  # Your Azure OpenAI resource's endpoint value.
)

conversation=[{"role": "system", "content": "You are a helpful assistant."}]

while True:
    user_input = input("Q:")      
    conversation.append({"role": "user", "content": user_input})

    response = client.chat.completions.create(
        model="gpt-35-turbo", # model = "deployment_name".
        messages=conversation
    )

    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

Al ejecutar el código anterior, obtendrá una ventana de consola en blanco. Escriba la primera pregunta en la ventana y, a continuación, seleccione la clave Enter. Una vez que se devuelve la respuesta, puede repetir el proceso y realizar preguntas.

Administrar conversaciones

El ejemplo anterior se ejecuta hasta alcanzar el límite de tokens del modelo. Con cada pregunta y respuesta recibida, la lista messages aumenta de tamaño. El límite de tokens para gpt-35-turbo es de 4,096 tokens. Los límites de token para gpt-4 y gpt-4-32k son 8192 y 32 768, respectivamente. Estos límites incluyen el número de tokens de la lista de mensajes enviada y la respuesta del modelo. El número de tokens en la lista de mensajes combinado con el valor del parámetro max_tokens debe permanecer por debajo de estos límites o recibirá un error.

Es su responsabilidad asegurarse de que la solicitud y la finalización se encuentran dentro del límite de tokens. Para conversaciones más largas, debe realizar un seguimiento del recuento de tokens y enviar solo al modelo una solicitud que se encuentre dentro del límite.

Nota:

Se recomienda que se mantenga dentro del límite de tokens de entrada documentado para todos los modelos, incluso si detecta que puede superar ese límite.

En el ejemplo de código siguiente se muestra un ejemplo de bucle de chat simple con una técnica para controlar un número de tokens de 4,096 mediante la biblioteca tiktoken de OpenAI.

El código usa tiktoken 0.5.1. Si tiene una versión anterior, ejecute pip install tiktoken --upgrade.

import tiktoken
import os
from openai import AzureOpenAI

client = AzureOpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  api_version = "2024-02-01",
  azure_endpoint = os.getenv("AZURE_OPENAI_ENDPOINT")  # Your Azure OpenAI resource's endpoint value.
)

system_message = {"role": "system", "content": "You are a helpful assistant."}
max_response_tokens = 250
token_limit = 4096
conversation = []
conversation.append(system_message)

def num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613"):
    """Return the number of tokens used by a list of messages."""
    try:
        encoding = tiktoken.encoding_for_model(model)
    except KeyError:
        print("Warning: model not found. Using cl100k_base encoding.")
        encoding = tiktoken.get_encoding("cl100k_base")
    if model in {
        "gpt-3.5-turbo-0613",
        "gpt-3.5-turbo-16k-0613",
        "gpt-4-0314",
        "gpt-4-32k-0314",
        "gpt-4-0613",
        "gpt-4-32k-0613",
        }:
        tokens_per_message = 3
        tokens_per_name = 1
    elif model == "gpt-3.5-turbo-0301":
        tokens_per_message = 4  # every message follows <|start|>{role/name}\n{content}<|end|>\n
        tokens_per_name = -1  # if there's a name, the role is omitted
    elif "gpt-3.5-turbo" in model:
        print("Warning: gpt-3.5-turbo may update over time. Returning num tokens assuming gpt-3.5-turbo-0613.")
        return num_tokens_from_messages(messages, model="gpt-3.5-turbo-0613")
    elif "gpt-4" in model:
        print("Warning: gpt-4 may update over time. Returning num tokens assuming gpt-4-0613.")
        return num_tokens_from_messages(messages, model="gpt-4-0613")
    else:
        raise NotImplementedError(
            f"""num_tokens_from_messages() is not implemented for model {model}."""
        )
    num_tokens = 0
    for message in messages:
        num_tokens += tokens_per_message
        for key, value in message.items():
            num_tokens += len(encoding.encode(value))
            if key == "name":
                num_tokens += tokens_per_name
    num_tokens += 3  # every reply is primed with <|start|>assistant<|message|>
    return num_tokens
while True:
    user_input = input("Q:")      
    conversation.append({"role": "user", "content": user_input})
    conv_history_tokens = num_tokens_from_messages(conversation)

    while conv_history_tokens + max_response_tokens >= token_limit:
        del conversation[1] 
        conv_history_tokens = num_tokens_from_messages(conversation)

    response = client.chat.completions.create(
        model="gpt-35-turbo", # model = "deployment_name".
        messages=conversation,
        temperature=0.7,
        max_tokens=max_response_tokens
    )


    conversation.append({"role": "assistant", "content": response.choices[0].message.content})
    print("\n" + response.choices[0].message.content + "\n")

En este ejemplo, una vez que se alcanza el número de tokens, se quitan los mensajes más antiguos de la transcripción de conversación. Para mejorar la eficacia, del se usa en lugar de pop(). Empezamos por el índice 1 para conservar siempre el mensaje del sistema y eliminar únicamente los mensajes del usuario o del asistente. Con el tiempo, este método de administración de la conversación puede hacer que la calidad de la conversación se degrade, ya que el modelo pierde gradualmente el contexto de las partes anteriores de la conversación.

Un enfoque alternativo consiste en limitar la duración de la conversación a la longitud máxima del token o a un número específico de turnos. Una vez alcanzado el límite máximo de tokens, el modelo perdería el contexto si permitiera que la conversación continuara. Puede solicitar al usuario que inicie una nueva conversación y borre la lista de mensajes para iniciar una nueva conversación con el límite de tokens completo disponible.

La parte del código de recuento de tokens que se mostró anteriormente es una versión simplificada de uno de los ejemplos de la guía paso a paso de OpenAI.

Solución de problemas

Esta es una sugerencia de solución de problemas.

No use la sintaxis de ChatML ni tokens especiales con el punto de conexión de finalización del chat

Algunos clientes intentan usar la sintaxis heredada de ChatML con los puntos de conexión de finalización de chat y los modelos más recientes. ChatML era una funcionalidad de versión preliminar que solo funcionaba con el punto de conexión de finalizaciones heredado con el modelo de la versión 0301 de gpt-35-turbo. Este modelo está programado para la retirada. Si intenta usar la sintaxis ChatML con modelos más recientes y el punto de conexión de finalización del chat, puede producir errores y un comportamiento inesperado de respuesta del modelo. No se recomienda este uso. Este mismo problema puede producirse al usar tokens especiales comunes.

Código de error Mensaje de error Solución
400 400: "no se pudo generar la salida debido a tokens especiales en la entrada". El mensaje contiene tokens especiales o tokens de ChatML heredados no reconocidos o admitidos por el modelo o punto de conexión. Asegúrese de que la matriz de mensajes o mensajes no contenga tokens de ChatML heredados ni tokens especiales. Si va a actualizar desde un modelo heredado, excluya todos los tokens especiales antes de enviar una solicitud de API al modelo.

No se pudo crear la finalización porque el modelo generó una salida Unicode no válida

Código de error Mensaje de error Solución alternativa
500 500 - InternalServerError: Código de error: 500 - {'error': {'message': 'No se pudo crear la finalización como salida Unicode no válida generada por el modelo}}}. Para minimizar la aparición de estos errores, reduzca la temperatura de los mensajes a menos de 1 y asegúrese de que usa un cliente con lógica de reintento. Volver a adjuntar la solicitud suele dar lugar a una respuesta correcta.

Pasos siguientes