Du har allerede lært en del i de tidligere lektioner. Men vi kan stadig forbedre os. Nogle ting, vi kan tage fat på, er hvordan vi kan få et mere konsistent svarformat, så det bliver lettere at arbejde med svaret senere. Derudover kunne vi ønske at tilføje data fra andre kilder for at berige vores applikation yderligere.
De ovennævnte problemer er, hvad dette kapitel sigter mod at løse.
Denne lektion vil dække:
- Forklaring af, hvad funktionskald er, og dets anvendelsesmuligheder.
- Oprettelse af et funktionskald ved hjælp af Azure OpenAI.
- Hvordan man integrerer et funktionskald i en applikation.
Ved afslutningen af denne lektion vil du kunne:
- Forklare formålet med at bruge funktionskald.
- Opsætte Funktionskald ved hjælp af Azure OpenAI Service.
- Designe effektive funktionskald til din applikations brugsscenarie.
I denne lektion ønsker vi at bygge en funktion til vores uddannelses-startup, der giver brugerne mulighed for at bruge en chatbot til at finde tekniske kurser. Vi vil anbefale kurser, der passer til deres færdighedsniveau, nuværende rolle og interesse for teknologi.
For at fuldføre dette scenarie vil vi bruge en kombination af:
Azure OpenAItil at skabe en chatoplevelse for brugeren.Microsoft Learn Catalog APItil at hjælpe brugerne med at finde kurser baseret på deres forespørgsel.Funktionskaldtil at tage brugerens forespørgsel og sende den til en funktion for at lave API-anmodningen.
Lad os starte med at se på, hvorfor vi overhovedet vil bruge funktionskald:
Før funktionskald var svar fra en LLM ustrukturerede og inkonsistente. Udviklere var nødt til at skrive kompleks valideringskode for at sikre, at de kunne håndtere hver variation af et svar. Brugere kunne ikke få svar som "Hvad er vejret i Stockholm lige nu?". Dette skyldes, at modellerne var begrænset til den tid, dataene blev trænet på.
Funktionskald er en funktion i Azure OpenAI Service, der overvinder følgende begrænsninger:
- Konsistent svarformat. Hvis vi kan kontrollere svarformatet bedre, kan vi lettere integrere svaret i andre systemer.
- Eksterne data. Mulighed for at bruge data fra andre kilder i en applikation i en chatkontekst.
Vi anbefaler, at du bruger den inkluderede notebook, hvis du vil køre nedenstående scenarie. Du kan også blot læse med, da vi forsøger at illustrere et problem, hvor funktioner kan hjælpe med at løse det.
Lad os se på et eksempel, der illustrerer problemet med svarformat:
Lad os sige, at vi vil oprette en database med studentdata, så vi kan foreslå det rigtige kursus til dem. Nedenfor har vi to beskrivelser af studerende, der er meget ens i de data, de indeholder.
-
Opret en forbindelse til vores Azure OpenAI-ressource:
import os import json from openai import AzureOpenAI from dotenv import load_dotenv load_dotenv() client = AzureOpenAI( api_key=os.environ['AZURE_OPENAI_API_KEY'], # this is also the default, it can be omitted api_version = "2023-07-01-preview" ) deployment=os.environ['AZURE_OPENAI_DEPLOYMENT']
Nedenfor er noget Python-kode til at konfigurere vores forbindelse til Azure OpenAI, hvor vi sætter
api_type,api_base,api_versionogapi_key. -
Opret to studenterbeskrivelser ved hjælp af variablerne
student_1_descriptionogstudent_2_description.student_1_description="Emily Johnson is a sophomore majoring in computer science at Duke University. She has a 3.7 GPA. Emily is an active member of the university's Chess Club and Debate Team. She hopes to pursue a career in software engineering after graduating." student_2_description = "Michael Lee is a sophomore majoring in computer science at Stanford University. He has a 3.8 GPA. Michael is known for his programming skills and is an active member of the university's Robotics Club. He hopes to pursue a career in artificial intelligence after finishing his studies."
Vi ønsker at sende ovenstående studenterbeskrivelser til en LLM for at analysere dataene. Disse data kan senere bruges i vores applikation og sendes til en API eller gemmes i en database.
-
Lad os oprette to identiske prompts, hvor vi instruerer LLM om, hvilke oplysninger vi er interesserede i:
prompt1 = f''' Please extract the following information from the given text and return it as a JSON object: name major school grades club This is the body of text to extract the information from: {student_1_description} ''' prompt2 = f''' Please extract the following information from the given text and return it as a JSON object: name major school grades club This is the body of text to extract the information from: {student_2_description} '''
Ovenstående prompts instruerer LLM om at udtrække oplysninger og returnere svaret i JSON-format.
-
Efter at have opsat prompts og forbindelsen til Azure OpenAI, sender vi nu prompts til LLM ved hjælp af
openai.ChatCompletion. Vi gemmer prompten i variablenmessagesog tildeler rollenuser. Dette er for at efterligne en besked fra en bruger, der skriver til en chatbot.# response from prompt one openai_response1 = client.chat.completions.create( model=deployment, messages = [{'role': 'user', 'content': prompt1}] ) openai_response1.choices[0].message.content # response from prompt two openai_response2 = client.chat.completions.create( model=deployment, messages = [{'role': 'user', 'content': prompt2}] ) openai_response2.choices[0].message.content
Nu kan vi sende begge anmodninger til LLM og undersøge det svar, vi modtager, ved at finde det som openai_response1['choices'][0]['message']['content'].
-
Til sidst kan vi konvertere svaret til JSON-format ved at kalde
json.loads:# Loading the response as a JSON object json_response1 = json.loads(openai_response1.choices[0].message.content) json_response1
Svar 1:
{ "name": "Emily Johnson", "major": "computer science", "school": "Duke University", "grades": "3.7", "club": "Chess Club" }Svar 2:
{ "name": "Michael Lee", "major": "computer science", "school": "Stanford University", "grades": "3.8 GPA", "club": "Robotics Club" }Selvom prompts er de samme, og beskrivelserne er ens, ser vi værdierne for egenskaben
Gradesformateret forskelligt, da vi nogle gange får formatet3.7eller3.7 GPAfor eksempel.Dette resultat skyldes, at LLM tager ustrukturerede data i form af den skrevne prompt og også returnerer ustrukturerede data. Vi har brug for et struktureret format, så vi ved, hvad vi kan forvente, når vi gemmer eller bruger disse data.
Så hvordan løser vi problemet med formatering? Ved at bruge funktionskald kan vi sikre, at vi modtager strukturerede data tilbage. Når vi bruger funktionskald, kalder eller kører LLM faktisk ikke nogen funktioner. I stedet opretter vi en struktur, som LLM skal følge for sine svar. Vi bruger derefter disse strukturerede svar til at vide, hvilken funktion der skal køres i vores applikationer.
Vi kan derefter tage det, der returneres fra funktionen, og sende det tilbage til LLM. LLM vil derefter svare ved hjælp af naturligt sprog for at besvare brugerens forespørgsel.
Der er mange forskellige anvendelsesmuligheder, hvor funktionskald kan forbedre din app, såsom:
-
Kalder eksterne værktøjer. Chatbots er gode til at give svar på spørgsmål fra brugere. Ved at bruge funktionskald kan chatbots bruge beskeder fra brugere til at udføre visse opgaver. For eksempel kan en studerende bede chatbotten om "Send en e-mail til min underviser, hvor jeg siger, at jeg har brug for mere hjælp med dette emne". Dette kan lave et funktionskald til
send_email(to: string, body: string). -
Opret API- eller databaseforespørgsler. Brugere kan finde information ved hjælp af naturligt sprog, der konverteres til en formateret forespørgsel eller API-anmodning. Et eksempel på dette kunne være en lærer, der spørger "Hvem er de studerende, der har fuldført den sidste opgave", hvilket kunne kalde en funktion ved navn
get_completed(student_name: string, assignment: int, current_status: string). -
Oprettelse af strukturerede data. Brugere kan tage en tekstblok eller CSV og bruge LLM til at udtrække vigtige oplysninger fra den. For eksempel kan en studerende konvertere en Wikipedia-artikel om fredsaftaler til at skabe AI-flashkort. Dette kan gøres ved hjælp af en funktion kaldet
get_important_facts(agreement_name: string, date_signed: string, parties_involved: list).
Processen med at oprette et funktionskald inkluderer 3 hovedtrin:
- Kalder Chat Completions API med en liste over dine funktioner og en brugermeddelelse.
- Læser modellens svar for at udføre en handling, dvs. udføre en funktion eller API-anmodning.
- Laver endnu et kald til Chat Completions API med svaret fra din funktion for at bruge disse oplysninger til at skabe et svar til brugeren.
Det første trin er at oprette en brugermeddelelse. Dette kan dynamisk tildeles ved at tage værdien af en tekstinput, eller du kan tildele en værdi her. Hvis det er første gang, du arbejder med Chat Completions API, skal vi definere role og content for beskeden.
Role kan enten være system (opretter regler), assistant (modellen) eller user (slutbrugeren). For funktionskald vil vi tildele dette som user og et eksempelspørgsmål.
messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]Ved at tildele forskellige roller bliver det klart for LLM, om det er systemet, der siger noget, eller brugeren, hvilket hjælper med at opbygge en samtalehistorik, som LLM kan bygge videre på.
Dernæst vil vi definere en funktion og parametrene for den funktion. Vi vil kun bruge én funktion her kaldet search_courses, men du kan oprette flere funktioner.
Vigtigt: Funktioner inkluderes i systembeskeden til LLM og vil blive inkluderet i antallet af tilgængelige tokens, du har til rådighed.
Nedenfor opretter vi funktionerne som en array af elementer. Hvert element er en funktion og har egenskaberne name, description og parameters:
functions = [
{
"name":"search_courses",
"description":"Retrieves courses from the search index based on the parameters provided",
"parameters":{
"type":"object",
"properties":{
"role":{
"type":"string",
"description":"The role of the learner (i.e. developer, data scientist, student, etc.)"
},
"product":{
"type":"string",
"description":"The product that the lesson is covering (i.e. Azure, Power BI, etc.)"
},
"level":{
"type":"string",
"description":"The level of experience the learner has prior to taking the course (i.e. beginner, intermediate, advanced)"
}
},
"required":[
"role"
]
}
}
]Lad os beskrive hver funktion mere detaljeret nedenfor:
name- Navnet på den funktion, vi ønsker at få kaldt.description- Dette er beskrivelsen af, hvordan funktionen fungerer. Her er det vigtigt at være specifik og klar.parameters- En liste over værdier og format, som du ønsker, at modellen skal producere i sit svar. Parameters-arrayet består af elementer, hvor elementerne har følgende egenskaber:type- Datatypen, som egenskaberne vil blive gemt i.properties- Liste over de specifikke værdier, som modellen vil bruge til sit svar.name- Nøglen er navnet på egenskaben, som modellen vil bruge i sit formaterede svar, for eksempelproduct.type- Datatypen for denne egenskab, for eksempelstring.description- Beskrivelse af den specifikke egenskab.
Der er også en valgfri egenskab required - påkrævet egenskab for at funktionskaldet kan fuldføres.
Efter at have defineret en funktion, skal vi nu inkludere den i kaldet til Chat Completion API. Dette gør vi ved at tilføje functions til anmodningen. I dette tilfælde functions=functions.
Der er også en mulighed for at sætte function_call til auto. Dette betyder, at vi lader LLM beslutte, hvilken funktion der skal kaldes baseret på brugermeddelelsen i stedet for selv at tildele den.
Her er noget kode nedenfor, hvor vi kalder ChatCompletion.create, bemærk hvordan vi sætter functions=functions og function_call="auto" og dermed giver LLM valget om, hvornår funktionerne, vi giver den, skal kaldes:
response = client.chat.completions.create(model=deployment,
messages=messages,
functions=functions,
function_call="auto")
print(response.choices[0].message)Svaret, der kommer tilbage, ser nu sådan ud:
{
"role": "assistant",
"function_call": {
"name": "search_courses",
"arguments": "{\n \"role\": \"student\",\n \"product\": \"Azure\",\n \"level\": \"beginner\"\n}"
}
}Her kan vi se, hvordan funktionen search_courses blev kaldt og med hvilke argumenter, som angivet i egenskaben arguments i JSON-svaret.
Konklusionen er, at LLM var i stand til at finde dataene, der passer til funktionens argumenter, da den udtrak dem fra værdien, der blev givet til parameteren messages i chat completion-kaldet. Nedenfor er en påmindelse om værdien af messages:
messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]Som du kan se, blev student, Azure og beginner udtrukket fra messages og sat som input til funktionen. At bruge funktioner på denne måde er en fantastisk måde at udtrække information fra en prompt, men også at give struktur til LLM og have genanvendelig funktionalitet.
Næste skridt er at se, hvordan vi kan bruge dette i vores app.
Efter at vi har testet det formaterede svar fra LLM, kan vi nu integrere dette i en applikation.
For at integrere dette i vores applikation, lad os tage følgende trin:
-
Først lad os lave kaldet til OpenAI-tjenesterne og gemme beskeden i en variabel kaldet
response_message.response_message = response.choices[0].message
-
Nu vil vi definere funktionen, der vil kalde Microsoft Learn API for at få en liste over kurser:
import requests def search_courses(role, product, level): url = "https://learn.microsoft.com/api/catalog/" params = { "role": role, "product": product, "level": level } response = requests.get(url, params=params) modules = response.json()["modules"] results = [] for module in modules[:5]: title = module["title"] url = module["url"] results.append({"title": title, "url": url}) return str(results)
Bemærk, hvordan vi nu opretter en faktisk Python-funktion, der matcher funktionsnavnene introduceret i variablen
functions. Vi laver også reelle eksterne API-kald for at hente de data, vi har brug for. I dette tilfælde går vi mod Microsoft Learn API for at søge efter træningsmoduler.
Okay, så vi oprettede functions-variabler og en tilsvarende Python-funktion, hvordan fortæller vi LLM, hvordan man matcher disse to sammen, så vores Python-funktion bliver kaldt?
-
For at se, om vi skal kalde en Python-funktion, skal vi kigge i LLM-svaret og se, om
function_caller en del af det og kalde den angivne funktion. Her er, hvordan du kan lave den nævnte kontrol nedenfor:# Check if the model wants to call a function if response_message.function_call.name: print("Recommended Function call:") print(response_message.function_call.name) print() # Call the function. function_name = response_message.function_call.name available_functions = { "search_courses": search_courses, } function_to_call = available_functions[function_name] function_args = json.loads(response_message.function_call.arguments) function_response = function_to_call(**function_args) print("Output of function call:") print(function_response) print(type(function_response)) # Add the assistant response and function response to the messages messages.append( # adding assistant response to messages { "role": response_message.role, "function_call": { "name": function_name, "arguments": response_message.function_call.arguments, }, "content": None } ) messages.append( # adding function response to messages { "role": "function", "name": function_name, "content":function_response, } )
Disse tre linjer sikrer, at vi udtrækker funktionsnavnet, argumenterne og foretager kaldet:
function_to_call = available_functions[function_name] function_args = json.loads(response_message.function_call.arguments) function_response = function_to_call(**function_args)
Nedenfor er output fra at køre vores kode:
Output
{ "name": "search_courses", "arguments": "{\n \"role\": \"student\",\n \"product\": \"Azure\",\n \"level\": \"beginner\"\n}" } Output of function call: [{'title': 'Describe concepts of cryptography', 'url': 'https://learn.microsoft.com/training/modules/describe-concepts-of-cryptography/? WT.mc_id=api_CatalogApi'}, {'title': 'Introduction to audio classification with TensorFlow', 'url': 'https://learn.microsoft.com/en- us/training/modules/intro-audio-classification-tensorflow/?WT.mc_id=api_CatalogApi'}, {'title': 'Design a Performant Data Model in Azure SQL Database with Azure Data Studio', 'url': 'https://learn.microsoft.com/training/modules/design-a-data-model-with-ads/? WT.mc_id=api_CatalogApi'}, {'title': 'Getting started with the Microsoft Cloud Adoption Framework for Azure', 'url': 'https://learn.microsoft.com/training/modules/cloud-adoption-framework-getting-started/?WT.mc_id=api_CatalogApi'}, {'title': 'Set up the Rust development environment', 'url': 'https://learn.microsoft.com/training/modules/rust-set-up-environment/?WT.mc_id=api_CatalogApi'}] <class 'str'> -
Nu vil vi sende den opdaterede besked,
messages, til LLM, så vi kan modtage et naturligt sprog-svar i stedet for et API JSON-formateret svar.print("Messages in next request:") print(messages) print() second_response = client.chat.completions.create( messages=messages, model=deployment, function_call="auto", functions=functions, temperature=0 ) # get a new response from GPT where it can see the function response print(second_response.choices[0].message)
Output
{ "role": "assistant", "content": "I found some good courses for beginner students to learn Azure:\n\n1. [Describe concepts of cryptography] (https://learn.microsoft.com/training/modules/describe-concepts-of-cryptography/?WT.mc_id=api_CatalogApi)\n2. [Introduction to audio classification with TensorFlow](https://learn.microsoft.com/training/modules/intro-audio-classification-tensorflow/?WT.mc_id=api_CatalogApi)\n3. [Design a Performant Data Model in Azure SQL Database with Azure Data Studio](https://learn.microsoft.com/training/modules/design-a-data-model-with-ads/?WT.mc_id=api_CatalogApi)\n4. [Getting started with the Microsoft Cloud Adoption Framework for Azure](https://learn.microsoft.com/training/modules/cloud-adoption-framework-getting-started/?WT.mc_id=api_CatalogApi)\n5. [Set up the Rust development environment](https://learn.microsoft.com/training/modules/rust-set-up-environment/?WT.mc_id=api_CatalogApi)\n\nYou can click on the links to access the courses." }
For at fortsætte din læring om Azure OpenAI Funktionskald kan du bygge:
- Flere parametre for funktionen, der kan hjælpe elever med at finde flere kurser.
- Oprette et andet funktionskald, der tager mere information fra eleven, som deres modersmål.
- Opret fejlhåndtering, når funktionskaldet og/eller API-kaldet ikke returnerer nogen passende kurser
Tip: Følg siden Learn API reference documentation for at se, hvordan og hvor disse data er tilgængelige.
Efter at have afsluttet denne lektion, kan du tjekke vores Generative AI Learning collection for at fortsætte med at opbygge din viden om Generativ AI!
Gå videre til Lektion 12, hvor vi vil se på, hvordan man designer UX til AI-applikationer!
Ansvarsfraskrivelse:
Dette dokument er blevet oversat ved hjælp af AI-oversættelsestjenesten Co-op Translator. Selvom vi bestræber os på nøjagtighed, skal du være opmærksom på, at automatiserede oversættelser kan indeholde fejl eller unøjagtigheder. Det originale dokument på dets oprindelige sprog bør betragtes som den autoritative kilde. For kritisk information anbefales professionel menneskelig oversættelse. Vi er ikke ansvarlige for eventuelle misforståelser eller fejltolkninger, der opstår som følge af brugen af denne oversættelse.


