Eddig már sok mindent megtanultál az előző leckék során. Azonban tovább javíthatunk. Néhány dolog, amivel foglalkozhatunk, az a válaszformátum egységesítése, hogy könnyebben lehessen dolgozni a válasszal később. Emellett szeretnénk más forrásokból származó adatokat is hozzáadni, hogy még gazdagabbá tegyük az alkalmazásunkat.
A fent említett problémák azok, amelyeket ez a fejezet kíván megoldani.
Ebben a leckében a következőkről lesz szó:
- Mi az a function calling és milyen esetekben használjuk.
- Hogyan hozzunk létre function call-t az Azure OpenAI segítségével.
- Hogyan integráljuk a function call-t egy alkalmazásba.
A lecke végére képes leszel:
- Elmagyarázni a function calling használatának célját.
- Beállítani a Function Call-t az Azure OpenAI szolgáltatásban.
- Hatékony function call-okat tervezni az alkalmazásod igényeihez.
Ebben a leckében egy olyan funkciót szeretnénk létrehozni az oktatási startupunk számára, amely lehetővé teszi a felhasználók számára, hogy chatbot segítségével technikai kurzusokat találjanak. Ajánlani fogunk olyan kurzusokat, amelyek megfelelnek a felhasználó képzettségi szintjének, jelenlegi szerepének és érdeklődési technológiájának.
A forgatókönyv megvalósításához a következőket használjuk:
Azure OpenAIa felhasználói chat élmény létrehozásához.Microsoft Learn Catalog APIa kurzusok kereséséhez a felhasználó kérésének megfelelően.Function Callinga felhasználói lekérdezés feldolgozásához és az API kérés elküldéséhez.
Kezdésként nézzük meg, miért is szeretnénk egyáltalán function calling-et használni:
A function calling előtt az LLM válaszai rendezetlenek és következetlenek voltak. A fejlesztőknek bonyolult érvényesítő kódot kellett írniuk, hogy kezelni tudják a válaszok különböző változatait. A felhasználók nem kaphattak olyan válaszokat, mint például: „Milyen az aktuális időjárás Stockholmban?”. Ez azért volt, mert a modellek csak a tanítási adatok idejéig voltak korlátozva.
A Function Calling az Azure OpenAI szolgáltatás egy olyan funkciója, amely a következő korlátokat segít leküzdeni:
- Következetes válaszformátum. Ha jobban tudjuk szabályozni a válasz formátumát, könnyebben integrálhatjuk azt más rendszerekbe.
- Külső adatok. Lehetőség arra, hogy az alkalmazás más forrásaiból származó adatokat is használjunk a chat kontextusában.
Ajánljuk, hogy a mellékelt notebookot használd, ha szeretnéd lefuttatni az alábbi forgatókönyvet. De akár csak olvashatod is, mert egy olyan problémát mutatunk be, amelynél a funkciók segíthetnek a megoldásban.
Nézzük meg a példát, amely a válaszformátum problémáját illusztrálja:
Tegyük fel, hogy létre akarunk hozni egy adatbázist diákadatokkal, hogy a megfelelő kurzust tudjuk ajánlani nekik. Lent két diák leírását látjuk, amelyek nagyon hasonló adatokat tartalmaznak.
-
Hozzunk létre kapcsolatot az Azure OpenAI erőforrásunkhoz:
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']
Lent egy Python kódot látsz az Azure OpenAI kapcsolat beállításához, ahol megadjuk az
api_type,api_base,api_versionésapi_keyértékeket. -
Két diák leírásának létrehozása a
student_1_descriptionésstudent_2_descriptionváltozókkal.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."
Ezeket a diák leírásokat szeretnénk elküldeni az LLM-nek, hogy feldolgozza az adatokat. Ezek az adatok később felhasználhatók lesznek az alkalmazásban, API-nak küldhetők vagy adatbázisban tárolhatók.
-
Készítsünk két azonos promptot, amelyekben megmondjuk az LLM-nek, milyen információkat szeretnénk kinyerni:
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} '''
A fenti promptok arra utasítják az LLM-et, hogy vonja ki az információkat és JSON formátumban adja vissza a választ.
-
Miután beállítottuk a promptokat és a kapcsolatot az Azure OpenAI-hoz, elküldjük a promptokat az LLM-nek az
openai.ChatCompletionsegítségével. A promptot amessagesváltozóban tároljuk, és a szerepetuser-re állítjuk. Ez azt szimulálja, mintha egy felhasználó írna egy üzenetet a chatbotnak.# 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
Most elküldhetjük mindkét kérést az LLM-nek, és megvizsgálhatjuk a választ úgy, hogy lekérjük openai_response1['choices'][0]['message']['content'].
-
Végül a választ JSON formátumra alakíthatjuk a
json.loadshívásával:# Loading the response as a JSON object json_response1 = json.loads(openai_response1.choices[0].message.content) json_response1
Válasz 1:
{ "name": "Emily Johnson", "major": "computer science", "school": "Duke University", "grades": "3.7", "club": "Chess Club" }Válasz 2:
{ "name": "Michael Lee", "major": "computer science", "school": "Stanford University", "grades": "3.8 GPA", "club": "Robotics Club" }Bár a promptok ugyanazok és a leírások hasonlóak, a
Gradestulajdonság értékei eltérő formátumban jelennek meg, például néha3.7, máskor3.7 GPA.Ez azért van, mert az LLM a promptban lévő rendezetlen adatokat is rendezetlen formában adja vissza. Szükségünk van egy strukturált formátumra, hogy tudjuk, mire számíthatunk az adatok tárolásakor vagy használatakor.
Tehát hogyan oldjuk meg a formázási problémát? A function calling segítségével biztosíthatjuk, hogy strukturált adatot kapjunk vissza. A function calling használatakor az LLM valójában nem hív meg vagy futtat funkciókat. Ehelyett létrehozunk egy struktúrát, amelyet az LLM követ a válaszai során. Ezeket a strukturált válaszokat használjuk arra, hogy tudjuk, melyik funkciót kell meghívni az alkalmazásunkban.
A funkcióból visszakapott adatokat visszaküldhetjük az LLM-nek, amely természetes nyelven válaszol a felhasználó kérdésére.
Számos olyan eset van, amikor a function call javíthatja az alkalmazásodat, például:
-
Külső eszközök hívása. A chatbotok remekül válaszolnak a felhasználók kérdéseire. A function calling segítségével a chatbotok képesek bizonyos feladatokat elvégezni a felhasználói üzenetek alapján. Például egy diák megkérheti a chatbotot, hogy „Küldj egy e-mailt az oktatómnak, hogy több segítségre van szükségem ebben a témában”. Ez egy
send_email(to: string, body: string)nevű funkcióhívást eredményezhet. -
API vagy adatbázis lekérdezések létrehozása. A felhasználók természetes nyelven kereshetnek információkat, amelyeket lekérdezéssé vagy API kérésé alakítunk. Például egy tanár megkérdezheti: „Kik azok a diákok, akik befejezték az utolsó feladatot?”, ami meghívhat egy
get_completed(student_name: string, assignment: int, current_status: string)nevű funkciót. -
Strukturált adatok létrehozása. A felhasználók egy szövegrészt vagy CSV-t használhatnak arra, hogy az LLM segítségével fontos információkat vonjanak ki. Például egy diák egy Wikipedia cikket alakíthat át AI flashcardokká a békeegyezményekről. Ehhez használható egy
get_important_facts(agreement_name: string, date_signed: string, parties_involved: list)nevű funkció.
A function call létrehozásának folyamata három fő lépésből áll:
- Meghívjuk a Chat Completions API-t a funkciók listájával és egy felhasználói üzenettel.
- Kiolvassuk a modell válaszát, hogy végrehajtsunk egy műveletet, például egy funkció vagy API hívást.
- Egy újabb hívást teszünk a Chat Completions API-hoz a funkció válaszával, hogy ezt az információt felhasználva válaszoljunk a felhasználónak.
Az első lépés egy felhasználói üzenet létrehozása. Ezt dinamikusan is megadhatjuk egy szövegbeviteli mező értékéből, vagy itt is beállíthatunk egy értéket. Ha először dolgozol a Chat Completions API-val, meg kell határoznunk az üzenet role és content értékét.
A role lehet system (szabályok létrehozása), assistant (a modell) vagy user (a végfelhasználó). A function calling esetén ezt user-re állítjuk, és megadunk egy példakérdést.
messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]A különböző szerepek hozzárendelésével az LLM számára egyértelművé válik, hogy a rendszer vagy a felhasználó mond valamit, ami segít a beszélgetés előzményeinek felépítésében.
Ezután definiálunk egy funkciót és annak paramétereit. Itt csak egy search_courses nevű funkciót használunk, de több funkciót is létrehozhatsz.
Fontos: A funkciók a rendszerüzenet részeként kerülnek az LLM-hez, és beleszámítanak a rendelkezésre álló tokenek számába.
Lent a funkciókat egy tömbként hozzuk létre. Minden elem egy funkció, amelynek vannak name, description és parameters tulajdonságai:
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"
]
}
}
]Nézzük meg részletesebben a funkcióelemeket:
name– A funkció neve, amelyet hívni szeretnénk.description– A funkció működésének leírása. Fontos, hogy itt pontos és világos legyen.parameters– Az értékek és formátumok listája, amelyeket a modellnek a válaszában elő kell állítania. A paraméterek tömbje elemekből áll, amelyek a következő tulajdonságokkal rendelkeznek:type– Az adattípus, amelyben az értékek tárolódnak.properties– A konkrét értékek listája, amelyeket a modell a válaszában használ.name– A kulcs, amely a válaszban szereplő tulajdonság neve, példáulproduct.type– A tulajdonság adattípusa, példáulstring.description– A tulajdonság leírása.
Van egy opcionális required tulajdonság is, amely megadja, hogy mely paraméterek kötelezőek a funkcióhívás sikeréhez.
A funkció definiálása után be kell illesztenünk azt a Chat Completion API hívásába. Ezt úgy tesszük, hogy a kéréshez hozzáadjuk a functions paramétert. Ebben az esetben functions=functions.
Van lehetőség a function_call paramétert auto értékre állítani, ami azt jelenti, hogy az LLM döntheti el, melyik funkciót hívja meg a felhasználói üzenet alapján, nem nekünk kell ezt megadni.
Lent egy kódot látsz, ahol meghívjuk a ChatCompletion.create-t, és beállítjuk functions=functions és function_call="auto" értékeket, így az LLM választhat, mikor hívja meg a megadott funkciókat:
response = client.chat.completions.create(model=deployment,
messages=messages,
functions=functions,
function_call="auto")
print(response.choices[0].message)A visszakapott válasz így néz ki:
{
"role": "assistant",
"function_call": {
"name": "search_courses",
"arguments": "{\n \"role\": \"student\",\n \"product\": \"Azure\",\n \"level\": \"beginner\"\n}"
}
}Itt látható, hogy a search_courses funkciót hívtuk meg, és milyen argumentumokkal, amelyek az arguments tulajdonságban szerepelnek a JSON válaszban.
Az LLM képes volt kinyerni az adatokat a messages paraméterben megadott értékből, és ezek alapján illeszteni az argumentumokat a funkcióhoz. Lent emlékeztetőül a messages értéke:
messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]Ahogy láthatod, a student, Azure és beginner értékeket kinyerte a messages-ből, és bemenetként adta át a funkciónak. A funkciók ilyen használata nagyszerű módja az információk kinyerésének egy promptból, ugyanakkor struktúrát ad az LLM-nek és újrahasznosítható funkciókat biztosít.
Most nézzük meg, hogyan használhatjuk ezt az alkalmazásunkban.
Miután teszteltük az LLM által visszaadott formázott választ, most integrálhatjuk azt egy alkalmazásba.
Az alkalmazásba való integráláshoz tegyük meg a következő lépéseket:
-
Először hívjuk meg az OpenAI szolgáltatást, és tároljuk el a választ egy
response_messagenevű változóban.response_message = response.choices[0].message
-
Most definiáljuk azt a funkciót, amely meghívja a Microsoft Learn API-t, hogy lekérje a kurzusok listáját:
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)
Figyeld meg, hogy most egy valódi Python függvényt hozunk létre, amely megfelel a
functionsváltozóban megadott funkcióneveknek. Valódi külső API hívásokat végzünk, hogy lekérjük a szükséges adatokat. Ebben az esetben a Microsoft Learn API-t használjuk képzési modulok keresésére.
Rendben, létrehoztuk a functions változót és a hozzá tartozó Python függvényt, hogyan mondjuk meg az LLM-nek, hogy hogyan kapcsolja össze ezt a kettőt, hogy a Python függvényünk hívódjon meg?
-
Ahhoz, hogy megtudjuk, szükséges-e Python függvényt hívni, meg kell néznünk az LLM válaszát, és ellenőrizni, hogy tartalmazza-e a
function_callrészt, majd meghívni a megjelölt funkciót. Íme, hogyan végezheted el ezt az ellenőrzést:# 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, } )
Ezek a három sor biztosítja, hogy kinyerjük a funkció nevét, az argumentumokat, és meghívjuk a funkciót:
function_to_call = available_functions[function_name] function_args = json.loads(response_message.function_call.arguments) function_response = function_to_call(**function_args)
Lent látható a kód futtatásának eredménye:
Kimenet
{ "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'> -
Most elküldjük az frissített
messagesváltozót az LLM-nek, hogy természetes nyelvű választ kapjunk az API JSON formátumú válasza helyett.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)
Kimenet
{ "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." }
Az Azure OpenAI Function Calling további tanulásához építhetsz:
- Több paramétert a funkcióhoz, amelyek segíthetnek a tanulóknak több kurzus megtalálásában.
- Egy másik function call-t, amely több információt kér a tanulótól, például az anyanyelvét.
A lecke befejezése után nézd meg a Generatív AI tanulási gyűjteményünket, hogy tovább fejleszthesd generatív AI ismereteidet!
Lépj tovább a 12. leckébe, ahol megnézzük, hogyan lehet AI alkalmazások UX-ét tervezni!
Jogi nyilatkozat:
Ez a dokumentum az AI fordító szolgáltatás, a Co-op Translator segítségével készült. Bár a pontosságra törekszünk, kérjük, vegye figyelembe, hogy az automatikus fordítások hibákat vagy pontatlanságokat tartalmazhatnak. Az eredeti dokumentum az anyanyelvén tekintendő hiteles forrásnak. Fontos információk esetén szakmai, emberi fordítást javaslunk. Nem vállalunk felelősséget a fordítás használatából eredő félreértésekért vagy téves értelmezésekért.


