Trabalhar com os modelos GPT-3.5-Turbo e GPT-4

Os modelos GPT-3.5-Turbo e GPT-4 são modelos de linguagem otimizados para interfaces de conversação. Os modelos se comportam de maneira diferente dos modelos GPT-3 mais antigos. Os modelos anteriores eram de entrada e saída de texto, o que significa que aceitavam uma cadeia de caracteres de prompt e retornavam um preenchimento para anexar ao prompt. No entanto, o GPT-3.5-Turbo e GPT-4 são modelos entrada de conversas e saída de mensagens. Os modelos esperam uma entrada formatada em um formato de transcrição específico semelhante ao de um chat e retornam um preenchimento que representa uma mensagem escrita pelo modelo no chat. Esse formato foi projetado especificamente para conversas de várias rodadas, mas também pode funcionar bem para cenários que não sejam de chat.

Este artigo explica como começar a usar os modelos GPT-3.5-Turbo e GPT-4. Para obter os melhores resultados, use as técnicas descritas aqui. Não tente interagir com os modelos da mesma maneira como você interagia com a série de modelos mais antiga, porque os modelos costumam ser prolixos e fornecerão respostas menos úteis.

Trabalhar com os modelos GPT-3.5-Turbo e GPT-4

O snippet de código a seguir mostra a maneira mais básica de usar os modelos GPT-3.5-Turbo e GPT-4 com a API de Conclusão de Chat. Se essa for sua primeira vez usando esses modelos programaticamente, recomendamos que você comece com o início rápido do GPT-3.5-Turbo e GPT-4.

Observação

Na documentação do OpenAI do Azure, nos referimos ao GPT-3.5-Turbo e ao GPT-35-Turbo de forma intercambiável. O nome oficial do modelo no OpenAI é gpt-3.5-turbo. Para o OpenAI do Azure, devido a restrições de caractere específicas do Azure, o nome do modelo subjacente é 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.

Observação

Os parâmetros a seguir não estão disponíveis com os novos modelos GPT-35-Turbo e GPT-4: logprobs, best_of e echo. Se você definir qualquer um desses parâmetros, você receberá um erro.

Todas as respostas incluem uma finish_reason. Os possíveis valores para finish_reason são:

  • parada: a API retornou a saída completa do modelo.
  • comprimento: saída de modelo incompleta devido ao parâmetro max_tokens ou ao limite de tokens.
  • content_filter: conteúdo omitido devido a um sinalizador dos nossos filtros de conteúdo.
  • nulo: resposta da API ainda em andamento ou incompleta.

Pense em definir max_tokens como um valor ligeiramente mais alto do que o normal, como, por exemplo, 300 ou 500. Um valor mais alto garante que o modelo não pare de gerar o texto antes de chegar ao final da mensagem.

Controle de versão de modelo

Observação

A versão gpt-35-turbo é equivalente ao modelo gpt-3.5-turbo da OpenAI.

Ao contrário dos modelos GPT-3 e GPT-3.5 anteriores, o modelo gpt-35-turbo e os modelos gpt-4 e gpt-4-32k continuarão a ser atualizados. Ao criar uma implantação desses modelos, você também precisará especificar uma versão do modelo.

Você pode encontrar as datas de desativação desses modelos na página de modelos.

Trabalhar com a API de Preenchimento de Chat

A OpenAI treinou os modelos GPT-35-Turbo e GPT-4 para aceitar entradas formatadas como uma conversa. O parâmetro mensagens utiliza uma matriz de objetos de mensagem com uma conversa organizada por função. Quando você usa a API do Python, uma lista de dicionários é usada.

O formato de um preenchimento de chat básico é o seguinte:

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

Uma conversa com um exemplo de resposta seguida por uma pergunta seria semelhante a:

{"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."}

Função do sistema

A função do sistema, também conhecida como mensagem do sistema, é incluída no início da matriz. Esta mensagem fornece as instruções iniciais para o modelo. Você pode fornecer várias informações na função do sistema, como, por exemplo:

  • Uma breve descrição do assistente.
  • Traços de personalidade do assistente.
  • Instruções ou regras que você quer que o assistente siga.
  • Dados ou informações necessários para o modelo, tais como dúvidas relevantes provenientes de um conjunto de Perguntas Frequentes.

Você pode personalizar a função do sistema para o seu caso de uso ou incluir instruções básicas. A função/mensagem do sistema é opcional, mas recomendamos que você inclua pelo menos uma mensagem básica para obter os melhores resultados.

Mensagens

Após a função do sistema, você poderá incluir uma série de mensagens entre o user e o assistant.

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

Para disparar uma resposta do modelo, termine com uma mensagem do usuário indicando que é a vez do assistente responder. Você também pode incluir uma série de exemplos de mensagens entre o usuário e o assistente como uma forma de realizar o few-shot learning.

Exemplos de prompt de mensagens

A seção a seguir mostra exemplos de diferentes estilos de prompts que você pode usar com os modelos GPT-35-Turbo e GPT-4. Esses exemplos são apenas um ponto de partida. Você pode experimentar diferentes prompts para personalizar o comportamento para seus próprios casos de uso.

Exemplo básico

Se você quiser que o modelo GPT-35-Turbo se comporte de forma semelhante ao chat.openai.com, você pode usar uma mensagem básica do 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?"}

Exemplo com instruções

Para alguns cenários, você talvez queira dar mais instruções ao modelo para definir proteções quanto ao que o modelo pode fazer.

{"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 dados para fins de fundamentação

Você também pode incluir dados ou informações relevantes na mensagem do sistema para dar ao modelo um contexto adicional para a conversa. Se precisar incluir somente uma pequena quantidade de informações, você poderá incluí-las no código da mensagem do sistema. Se você tiver uma grande quantidade de dados dos quais o modelo deve estar ciente, poderá usar inserções ou um produto como a Pesquisa de IA do Azure para recuperar as informações mais relevantes no momento da 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?"}

Few-shot learning com preenchimento de chat

Você também pode dar alguns exemplos de few-shot para o modelo. A abordagem do few-shot learning mudou ligeiramente por causa do novo formato do prompt. Agora, você pode incluir uma série de mensagens entre o usuário e o assistente no prompt como exemplos de few-shot. Ao usar esses exemplos, você pode semear respostas para as perguntas mais comuns de modo a preparar o modelo ou ensinar a ele comportamentos específicos.

Esse exemplo mostra como você pode usar o few-shot learning com o GPT-35-Turbo e o GPT-4. Você pode experimentar diferentes abordagens para ver o que funciona melhor no seu 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 o preenchimento de chat para cenários que não sejam de chat

A API de Preenchimento de Chat foi projetada para trabalhar com conversas de várias rodadas, mas também funciona bem para cenários que não sejam de chat.

Por exemplo, para um cenário de extração de entidades, você pode usar o seguinte prompt:

{"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?"}

Criar um loop de conversa básico

Os exemplos até agora mostraram a mecânica básica de interação com a API de Preenchimento de Chat. Este exemplo mostra como criar um loop de conversação que executa as seguintes ações:

  • Aceita continuamente as entradas do console e as formata de forma adequada como parte da lista de mensagens como conteúdo da função de usuário.
  • Respostas de saída que são impressas no console, formatadas e adicionadas à lista de mensagens como conteúdo da função de assistente.

Isso significa que, toda vez que uma nova pergunta é feita, uma transcrição contínua da conversa até aquele momento é enviada junto com a pergunta mais recente. Como o modelo não tem memória, você precisa enviar uma transcrição atualizada a cada nova pergunta, ou o modelo perderá o contexto das perguntas e respostas 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")

Ao executar o código anterior, você obterá uma janela de console em branco. Insira sua primeira pergunta na janela e selecione a chave Enter. Quando a resposta for retornada, você poderá repetir o processo e continuar fazendo perguntas.

Gerenciar conversas

O exemplo anterior será executado até você atingir o limite de tokens do modelo. Com cada pergunta feita e resposta recebida, a lista messages aumenta de tamanho. O limite de tokens para o gpt-35-turbo é de 4.096 tokens. Os limites de tokens para gpt-4 e gpt-4-32k são 8.192 e 32.768, respectivamente. Esses limites incluem a contagem de tokens da lista de mensagens enviada e da resposta do modelo. O número de tokens na lista de mensagens combinado com o valor do parâmetro max_tokens deve permanecer abaixo desses limites, ou você receberá um erro.

É sua responsabilidade garantir que o prompt e o preenchimento estejam dentro do limite de tokens. Isso significa que, para conversas mais longas, você precisará acompanhar o número de tokens e somente enviar ao modelo um prompt que esteja dentro do limite.

Observação

Recomendamos fortemente que você se mantenha dentro do limite de tokens de entrada documentado para todos os modelos, mesmo se descobrir que pode exceder esse limite.

A amostra de código a seguir mostra um exemplo simples de loop de chat com uma técnica para lidar com um número de 4.096 tokens usando a biblioteca tiktoken da OpenAI.

O código usa tiktoken 0.5.1. Se tiver uma versão mais antiga, execute 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")

Nesse exemplo, assim que o número máximo de tokens é atingido, as mensagens mais antigas na transcrição da conversa são removidas. Para maior eficiência, del é usado em vez de pop(). Começamos no índice 1 para sempre preservar a mensagem do sistema e remover apenas mensagens do usuário ou do assistente. Com o tempo, esse método de gerenciamento da conversa pode fazer com que a qualidade fique degradada, já que o modelo perde gradualmente o contexto das partes iniciais da conversa.

Uma abordagem alternativa é limitar a duração da conversa ao comprimento máximo de tokens ou a um número de rodadas específico. Após o limite máximo de tokens ser atingido, o modelo perderá o contexto se você permitir que a conversa continue. Você pode solicitar que o usuário inicie uma nova conversa e limpar a lista de mensagens para iniciar uma nova conversa com o limite total de tokens disponível.

A parte do código de contagem de tokens demonstrada anteriormente é uma versão simplificada de um dos exemplos do livro de receitas da OpenAI.

Solução de problemas

Aqui está uma dica de solução de problemas.

Não use a sintaxe chatml ou tokens especiais com o ponto de extremidade de conclusão do chat

Alguns clientes tentam usar a sintaxe de ChatML herdada com os pontos de extremidade de preenchimento de chat e modelos mais recentes. ChatML era uma funcionalidade de visualização que funcionava somente com o ponto de extremidade de preenchimento herdado com a versão 0301 do modelo gpt-35-turbo. Esse modelo está programado para ser desativado. Se você tentar usar a sintaxe ChatML com modelos mais recentes e o ponto de extremidade de preenchimento do chat, isso poderá resultar em erros e comportamento inesperado da resposta do modelo. Não recomendamos esse uso. Este mesmo problema pode ocorrer ao usar tokens especiais comuns.

Código de erro Mensagem de erro Solução
400 400 — "Falha ao gerar a saída devido à presença de tokens especiais na entrada." Seu prompt contém tokens especiais ou tokens ChatML herdados não reconhecidos ou compatíveis com o modelo/ponto de extremidade. Certifique-se de que a matriz de solicitação/mensagens não contenha tokens ChatML herdados/tokens especiais. Se você estiver fazendo o upgrade de um modelo herdado, exclua todos os tokens especiais antes de enviar uma solicitação de API para o modelo.

Falha ao criar a conclusão, pois o modelo gerou uma saída Unicode inválida

Código de erro Mensagem de erro Solução alternativa
500 500 – InternalServerError: código de erro: 500 – {'error': {'message': 'Failed to create completion as the model generated invalid Unicode output}}. Você pode minimizar a ocorrência desses erros reduzindo a temperatura dos prompts para menos de 1 e garantindo que você esteja usando um cliente com lógica de repetição. Tentar realizar a solicitação novamente geralmente resulta em uma resposta bem-sucedida.

Próximas etapas