Dela via


Arbeta med modeller för chattavslut

Chattmodeller är språkmodeller som är optimerade för konversationsgränssnitt. Modellerna beter sig annorlunda än de äldre GPT-3-modellerna. Tidigare modeller var text-in och text-ut, vilket innebär att de accepterade en textsträng som prompt och returnerade en genererad text att lägga till i prompten. De senaste modellerna är dock designade för att ta in konversationer och ge ut meddelanden. Modellerna förväntar sig att indata formateras i ett specifikt chattliknande avskriftsformat. De returnerar ett slutförande som representerar ett modellskrivet meddelande i chatten. Det här formatet har utformats specifikt för konversationer med flera omgångar, men det kan också fungera bra för ickechatt-scenarier.

Den här artikeln beskriver hur du kommer igång med modeller för chattavslut. Använd de tekniker som beskrivs här för att få bästa resultat. Försök inte interagera med modellerna på samma sätt som du gjorde med den äldre modellserien eftersom modellerna ofta är utförliga och ger mindre användbara svar.

Arbeta med modeller för chattens slutförande

Följande kodfragment visar det mest grundläggande sättet att interagera med modeller som använder API:et för chattens slutförande. Om det här är första gången du använder dessa modeller programmatiskt rekommenderar vi att du börjar med snabbstartsguiden för chattslutföranden.

import os
from openai import OpenAI

client = OpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
)

response = client.chat.completions.create(
    model="gpt-4o", # 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-4o",
  "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.

Varje svar innehåller finish_reason. Möjliga värden finish_reason är:

  • stop: API returnerade fullständiga modellutdata.
  • längd: Ofullständiga modellutdata på grund av parametern max_tokens eller tokengränsen.
  • content_filter: Utelämnat innehåll på grund av en flagga från våra innehållsfilter.
  • null: API-svaret pågår fortfarande eller är ofullständigt.

Överväg att ange max_tokens ett något högre värde än normalt. Ett högre värde säkerställer att modellen inte slutar generera text innan den når slutet av meddelandet.

Arbeta med API:et för chattens slutförande

OpenAI tränade chattmodeller för att acceptera inmatning som är formaterad som en konversation. Parametern meddelanden tar en matris av meddelandeobjekt som innehåller en konversation organiserad efter roll. När du använder Python-API:et används en lista med ordlistor.

Formatet för en grundläggande chattkomplettering är:

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

En konversation med ett exempelsvar följt av en fråga skulle se ut så här:

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

Systemroll

Systemrollen, även kallat systemmeddelandet, ingår i början av matrisen. Det här meddelandet innehåller de första instruktionerna för modellen. Du kan ange olika uppgifter i systemrollen, till exempel:

  • En kort beskrivning av assistenten.
  • Assistentens personlighetsdrag.
  • Instruktioner eller regler som du vill att assistenten ska följa.
  • Data eller information som behövs för modellen, till exempel relevanta frågor från vanliga frågor och svar.

Du kan anpassa systemrollen för ditt användningsfall eller inkludera grundläggande instruktioner. Systemrollen/meddelandet är valfritt, men vi rekommenderar att du åtminstone inkluderar en grundläggande för att få bästa resultat.

Meddelanden

Efter systemrollen kan du inkludera en serie meddelanden mellan user och assistant.

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

Om du vill utlösa ett svar från modellen slutar du med ett användarmeddelande som anger att det är assistentens tur att svara. Du kan också inkludera en serie exempelmeddelanden mellan användaren och assistenten som ett sätt att använda few-shot-lärande.

Exempel på meddelandeprompt

I följande avsnitt visas exempel på olika typer av frågor som du kan använda med modeller för chattavslut. De här exemplen är bara en startpunkt. Du kan experimentera med olika uppmaningar för att anpassa beteendet för dina egna användningsfall.

Grundläggande exempel

Om du vill att modellen för chattavslut ska fungera på samma sätt som chatgpt.com kan du använda ett grundläggande systemmeddelande som 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?"}

Exempel med instruktioner

I vissa scenarier kanske du vill ge fler instruktioner till modellen för att definiera skyddsräcken för vad modellen kan göra.

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

Använda data för jordning

Du kan också inkludera relevanta data eller information i systemmeddelandet för att ge modellen extra kontext för konversationen. Om du bara behöver inkludera en liten mängd information kan du hårdkoda den i systemmeddelandet. Om du har en stor mängd data som modellen bör känna till kan du använda inbäddningar eller en produkt som Azure AI Search för att hämta den mest relevanta informationen vid frågetillfället.

{"role": "system", "content": "Assistant is an intelligent chatbot designed to help users answer technical questions about Azure OpenAI in Azure AI Foundry Models. 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 provides REST API access to OpenAI's powerful language models including the GPT-3, Codex and Embeddings model series.
- Azure OpenAI 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?"}

Få-exemplesinlärning med chattkomplettering

Du kan också ge exempel på några bilder till modellen. Metoden för inlärning med få skott har ändrats något på grund av det nya promptformatet. Nu kan du inkludera en serie meddelanden mellan användaren och assistenten i prompten som exempel med få bilder. Med hjälp av de här exemplen kan du få svar på vanliga frågor för att skapa en modell eller lära ut specifika beteenden till modellen.

Det här exemplet visar hur du kan använda inlärning med få skott med GPT-35-Turbo och GPT-4. Du kan experimentera med olika metoder för att se vad som fungerar bäst för ditt användningsfall.

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

Använd chattavslutning för icke-chattscenarier

API:et för chattslutsättning är utformat för att fungera med konversationer med flera turer, men det fungerar också bra för icke-chattscenarier.

För ett scenario med entitetsextrahering kan du till exempel använda följande fråga:

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

Skapa en grundläggande konversationsloop

Exemplen hittills visar den grundläggande mekaniken för att interagera med API:et för chattens slutförande. Det här exemplet visar hur du skapar en konversationsloop som utför följande åtgärder:

  • Tar kontinuerligt emot indata från konsolen och formaterar den korrekt som en del av meddelandelistan som innehåll i användarrollen.
  • Matar ut svar som skrivs ut till konsolen och formateras och läggs till i meddelandelistan som assistentrollinnehåll.

Varje gång en ny fråga ställs skickas en löpande utskrift av konversationen hittills tillsammans med den senaste frågan. Eftersom modellen inte har något minne måste du skicka en uppdaterad avskrift med varje ny fråga, annars förlorar modellen kontexten för de tidigare frågorna och svaren.

import os
from openai import OpenAI

client = OpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
)

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-4o", # model = "deployment_name".
        messages=conversation
    )

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

När du kör föregående kod får du ett tomt konsolfönster. Ange din första fråga i fönstret och välj sedan Enter. När svaret har returnerats kan du upprepa processen och fortsätta att ställa frågor.

Hantera konversationer

Föregående exempel körs tills du når modellens tokengräns. Med varje fråga som ställs och svar tas emot messages växer listan i storlek. Tokengränsen för chattavslutsmodeller varierar mellan modeller och versioner Tokengränserna för gpt-4 och gpt-4-32k är 8 192 respektive 32 768. Dessa gränser omfattar antalet token från både meddelandelistan som skickats och modellsvaret. Antalet token i meddelandelistan i kombination med värdet för parametern max_tokens måste ligga under dessa gränser eller så får du ett fel. Se modellsidan för varje modelltokensgränser/kontextfönster.

Det är ditt ansvar att se till att prompten och slutförandet ligger inom tokengränsen. För längre konversationer måste du hålla reda på antalet token och bara skicka en uppmaning till modellen som ligger inom gränsen. Alternativt kan du med svars-API:et låta API:et hantera avkortning och hantering av konversationshistoriken åt dig.

Anmärkning

Vi rekommenderar starkt att du håller dig inom den dokumenterade gränsen för indatatoken för alla modeller, även om du upptäcker att du kan överskrida den gränsen.

Följande kodexempel visar ett enkelt chattloopexempel med en teknik för att hantera ett antal 4 096 token med hjälp av OpenAI:s tiktoken-bibliotek.

Koden använder tiktoken 0.5.1. Om du har en äldre version kör du pip install tiktoken --upgrade.

import tiktoken
import os
from openai import OpenAI

client = OpenAI(
  api_key = os.getenv("AZURE_OPENAI_API_KEY"),  
  base_url="https://YOUR-RESOURCE-NAME.openai.azure.com/openai/v1/"
)

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")

I det här exemplet tas de äldsta meddelandena i konversationsavskriften bort när antalet token har nåtts. För effektivitet del används i stället för pop(). Vi börjar vid index 1 för att alltid bevara systemmeddelandet och bara ta bort användar- eller assistentmeddelanden. Med tiden kan den här metoden för att hantera konversationen göra att konversationskvaliteten försämras eftersom modellen gradvis förlorar kontexten för de tidigare delarna av konversationen.

En alternativ metod är att begränsa konversationens varaktighet till den maximala tokenlängden eller ett visst antal svängar. När den maximala tokengränsen har nåtts förlorar modellen kontexten om du tillåter att konversationen fortsätter. Du kan uppmana användaren att starta en ny konversation och rensa meddelandelistan för att starta en ny konversation med den fullständiga tillgängliga tokengränsen.

Den tokenräkningsdel av koden som visades tidigare är en förenklad version av ett av OpenAI:s kokboksexempel.

Felsökning

Det gick inte att skapa slutförande eftersom modellen genererade ogiltiga Unicode-utdata

Felkod Felmeddelande Övergångslösning
500 500 – InternalServerError: Felkod: 500 – {'error': {'message': 'Det gick inte att skapa slutförande eftersom modellen genererade ogiltig Unicode-utdata}}. Du kan minimera förekomsten av dessa fel genom att sänka temperaturen på dina promptar till mindre än 1 och se till att du använder en klient med omstartningslogik. Om du försöker igen resulterar det ofta i ett lyckat svar.

Nästa steg