Skip to content

Latest commit

 

History

History
472 lines (340 loc) · 23.3 KB

File metadata and controls

472 lines (340 loc) · 23.3 KB

Fonksiyon Çağrımı ile Entegrasyon

Fonksiyon Çağrımı ile Entegrasyon

Önceki derslerde oldukça fazla şey öğrendiniz. Ancak daha da geliştirebiliriz. Ele alabileceğimiz bazı konular, yanıt formatını daha tutarlı hale getirerek yanıtı daha kolay işlenebilir hale getirmek ve uygulamamızı daha da zenginleştirmek için diğer kaynaklardan veri eklemek olabilir.

Bu bölümde yukarıda belirtilen sorunları ele alacağız.

Giriş

Bu derste şunlar ele alınacak:

  • Fonksiyon çağrımının ne olduğunu ve kullanım alanlarını açıklamak.
  • Azure OpenAI kullanarak bir fonksiyon çağrımı oluşturmak.
  • Bir uygulamaya fonksiyon çağrımını entegre etmek.

Öğrenme Hedefleri

Bu dersin sonunda şunları yapabileceksiniz:

  • Fonksiyon çağrımı kullanmanın amacını açıklamak.
  • Azure OpenAI Hizmeti kullanarak Fonksiyon Çağrımı kurmak.
  • Uygulamanızın kullanım senaryosu için etkili fonksiyon çağrımları tasarlamak.

Senaryo: Sohbet botumuzu fonksiyonlarla geliştirmek

Bu derste, kullanıcıların teknik kurslar bulmasına olanak tanıyan bir sohbet botu özelliği oluşturmak istiyoruz. Kullanıcıların beceri seviyelerine, mevcut rollerine ve ilgilendikleri teknolojiye uygun kurslar önereceğiz.

Bu senaryoyu tamamlamak için aşağıdaki kombinasyonu kullanacağız:

  • Kullanıcı için bir sohbet deneyimi oluşturmak için Azure OpenAI.
  • Kullanıcıların isteklerine göre kurs bulmalarına yardımcı olmak için Microsoft Learn Catalog API.
  • Kullanıcının sorgusunu alıp bir API isteği yapmak için bir fonksiyona göndermek için Fonksiyon Çağrımı.

Başlamak için, neden ilk etapta fonksiyon çağrımı kullanmak isteyebileceğimize bakalım:

Neden Fonksiyon Çağrımı

Fonksiyon çağrımından önce, bir LLM'den gelen yanıtlar yapılandırılmamış ve tutarsızdı. Geliştiriciler, her yanıt varyasyonunu işleyebildiklerinden emin olmak için karmaşık doğrulama kodları yazmak zorundaydı. Kullanıcılar "Stockholm'deki hava durumu nedir?" gibi sorulara yanıt alamıyordu. Bunun nedeni, modellerin yalnızca eğitildikleri zamandaki verilere sınırlı olmasıydı.

Fonksiyon Çağrımı, Azure OpenAI Hizmeti'nin aşağıdaki sınırlamaları aşmak için sunduğu bir özelliktir:

  • Tutarlı yanıt formatı. Yanıt formatını daha iyi kontrol edebilirsek, yanıtı diğer sistemlere entegre etmek daha kolay olur.
  • Harici veri. Bir uygulamanın diğer kaynaklarından gelen verileri bir sohbet bağlamında kullanma yeteneği.

Sorunu bir senaryo ile açıklamak

Aşağıdaki senaryoyu çalıştırmak istiyorsanız, dahil edilen notebook'u kullanmanızı öneririz. Ayrıca sadece okuyarak da devam edebilirsiniz, çünkü burada fonksiyonların sorunu nasıl çözebileceğini açıklamaya çalışıyoruz.

Yanıt formatı sorununu açıklayan bir örneğe bakalım:

Diyelim ki öğrenci verilerinden oluşan bir veritabanı oluşturmak istiyoruz, böylece onlara doğru kursu önerebiliriz. Aşağıda, içerdiği veriler açısından çok benzer olan iki öğrenci tanımı var.

  1. Azure OpenAI kaynağımıza bir bağlantı oluşturun:

    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']

    Aşağıda, api_type, api_base, api_version ve api_key ayarlarını yaptığımız Azure OpenAI bağlantımızı yapılandırmak için bazı Python kodları bulunmaktadır.

  2. student_1_description ve student_2_description değişkenlerini kullanarak iki öğrenci tanımı oluşturma.

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

    Yukarıdaki öğrenci tanımlarını bir LLM'e gönderip verileri ayrıştırmasını istiyoruz. Bu veriler daha sonra uygulamamızda kullanılabilir ve bir API'ye gönderilebilir veya bir veritabanında saklanabilir.

  3. LLM'e hangi bilgileri istediğimizi belirttiğimiz iki özdeş istem oluşturun:

    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}
    '''

    Yukarıdaki istemler, LLM'e bilgileri çıkarmasını ve yanıtı JSON formatında döndürmesini talimat verir.

  4. İstemleri ve Azure OpenAI bağlantısını ayarladıktan sonra, istemleri openai.ChatCompletion kullanarak LLM'e göndereceğiz. İstemi messages değişkeninde saklayıp role user atayacağız. Bu, bir kullanıcının bir sohbet botuna yazdığı bir mesajı taklit etmek içindir.

    # 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

Şimdi her iki isteği LLM'e gönderebilir ve aldığımız yanıtı openai_response1['choices'][0]['message']['content'] gibi bulabiliriz.

  1. Son olarak, yanıtı JSON formatına dönüştürmek için json.loads çağırabiliriz:

    # Loading the response as a JSON object
    json_response1 = json.loads(openai_response1.choices[0].message.content)
    json_response1

    Yanıt 1:

    {
      "name": "Emily Johnson",
      "major": "computer science",
      "school": "Duke University",
      "grades": "3.7",
      "club": "Chess Club"
    }

    Yanıt 2:

    {
      "name": "Michael Lee",
      "major": "computer science",
      "school": "Stanford University",
      "grades": "3.8 GPA",
      "club": "Robotics Club"
    }

    İstemler aynı ve tanımlar benzer olmasına rağmen, Grades özelliğinin değerlerinin farklı formatlarda olduğunu görüyoruz; bazen 3.7 veya 3.7 GPA formatında olabiliyor.

    Bu sonuç, LLM'in yazılı istem şeklindeki yapılandırılmamış verileri alması ve yapılandırılmamış veriler döndürmesi nedeniyle oluşur. Bu verileri saklarken veya kullanırken ne bekleyeceğimizi bilmek için yapılandırılmış bir formata sahip olmamız gerekir.

Peki formatlama sorununu nasıl çözeriz? Fonksiyonel çağrımı kullanarak yapılandırılmış veriler alacağımızdan emin olabiliriz. Fonksiyon çağrımı kullanıldığında, LLM aslında herhangi bir fonksiyonu çağırmaz veya çalıştırmaz. Bunun yerine, LLM'in yanıtları için takip edeceği bir yapı oluştururuz. Daha sonra bu yapılandırılmış yanıtları kullanarak uygulamalarımızda hangi fonksiyonun çalıştırılacağını biliriz.

fonksiyon akışı

Fonksiyondan dönen verileri alıp bunu LLM'e geri gönderebiliriz. LLM daha sonra kullanıcının sorgusuna yanıt vermek için doğal dil kullanarak yanıt verir.

Fonksiyon çağrımı kullanımı için senaryolar

Fonksiyon çağrımının uygulamanızı geliştirebileceği birçok farklı kullanım alanı vardır, örneğin:

  • Harici Araçları Çağırma. Sohbet botları, kullanıcılardan gelen sorulara yanıt vermede harikadır. Fonksiyon çağrımı kullanarak, sohbet botları kullanıcıların mesajlarını belirli görevleri tamamlamak için kullanabilir. Örneğin, bir öğrenci sohbet botuna "Bu konuda daha fazla yardıma ihtiyacım olduğunu söyleyen bir e-posta gönder" diyebilir. Bu, send_email(to: string, body: string) adlı bir fonksiyon çağrısı yapabilir.

  • API veya Veritabanı Sorguları Oluşturma. Kullanıcılar, doğal dili kullanarak biçimlendirilmiş bir sorguya veya API isteğine dönüştürülen bilgileri bulabilir. Örneğin, bir öğretmen "Son ödevi tamamlayan öğrenciler kimler?" diye sorabilir ve bu get_completed(student_name: string, assignment: int, current_status: string) adlı bir fonksiyonu çağırabilir.

  • Yapılandırılmış Veri Oluşturma. Kullanıcılar bir metin bloğunu veya CSV'yi alabilir ve LLM'i kullanarak önemli bilgileri çıkarabilir. Örneğin, bir öğrenci bir Wikipedia makalesini barış anlaşmaları hakkında AI flash kartları oluşturmak için dönüştürebilir. Bu, get_important_facts(agreement_name: string, date_signed: string, parties_involved: list) adlı bir fonksiyon kullanılarak yapılabilir.

İlk Fonksiyon Çağrınızı Oluşturma

Bir fonksiyon çağrısı oluşturma süreci 3 ana adımdan oluşur:

  1. Çağırma: Fonksiyonlarınızın bir listesini ve bir kullanıcı mesajını içeren Chat Completions API'sini çağırma.
  2. Okuma: Modelin yanıtını bir işlem gerçekleştirmek için okuma, yani bir fonksiyon veya API çağrısı yürütme.
  3. Yapma: Fonksiyondan gelen yanıtla Chat Completions API'sine başka bir çağrı yaparak bu bilgiyi kullanıcının sorgusuna yanıt oluşturmak için kullanma.

LLM Akışı

Adım 1 - mesajlar oluşturma

İlk adım bir kullanıcı mesajı oluşturmaktır. Bu, bir metin girişinin değerini dinamik olarak alarak atanabilir veya buraya bir değer atanabilir. Chat Completions API'si ile ilk kez çalışıyorsanız, mesajın role ve content değerlerini tanımlamanız gerekir.

role ya system (kurallar oluşturma), assistant (model) ya da user (son kullanıcı) olabilir. Fonksiyon çağrımı için bunu user olarak atayacağız ve örnek bir soru ekleyeceğiz.

messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]

Farklı roller atayarak, LLM'e sistemin mi yoksa kullanıcının mı bir şey söylediği açıkça belirtilir, bu da LLM'in üzerine inşa edebileceği bir konuşma geçmişi oluşturmasına yardımcı olur.

Adım 2 - fonksiyonlar oluşturma

Sonraki adımda bir fonksiyon ve bu fonksiyonun parametrelerini tanımlayacağız. Burada sadece search_courses adlı bir fonksiyon kullanacağız, ancak birden fazla fonksiyon oluşturabilirsiniz.

Önemli: Fonksiyonlar, LLM'e gönderilen sistem mesajına dahil edilir ve kullanılabilir token miktarınıza dahil edilir.

Aşağıda, fonksiyonları bir öğe dizisi olarak oluşturuyoruz. Her öğe bir fonksiyondur ve name, description ve parameters özelliklerine sahiptir:

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

Her bir fonksiyon örneğini daha ayrıntılı olarak açıklayalım:

  • name - Çağrılmasını istediğimiz fonksiyonun adı.
  • description - Fonksiyonun nasıl çalıştığını açıklayan açıklama. Burada spesifik ve net olmak önemlidir.
  • parameters - Modelin yanıtında üretmesini istediğiniz değerlerin ve formatın bir listesi. Parametreler dizisi, öğelerin aşağıdaki özelliklere sahip olduğu öğelerden oluşur:
    1. type - Özelliklerin saklanacağı veri türü.
    2. properties - Modelin yanıtı için kullanacağı belirli değerlerin listesi.
      1. name - Modelin biçimlendirilmiş yanıtında kullanacağı özelliğin adı, örneğin product.
      2. type - Bu özelliğin veri türü, örneğin string.
      3. description - Belirli özelliğin açıklaması.

Ayrıca isteğe bağlı bir özellik olan required - fonksiyon çağrımının tamamlanması için gerekli olan özellik.

Adım 3 - Fonksiyon çağrımı yapma

Bir fonksiyon tanımladıktan sonra, bunu Chat Completion API çağrısına dahil etmemiz gerekiyor. Bunu isteğe functions ekleyerek yapıyoruz. Bu durumda functions=functions.

Ayrıca function_call seçeneğini auto olarak ayarlama seçeneği vardır. Bu, kullanıcı mesajına göre hangi fonksiyonun çağrılması gerektiğine LLM'in karar vermesine izin verir, kendimiz atamak yerine.

Aşağıda ChatCompletion.create çağrısında functions=functions ve function_call="auto" ayarladığımız ve böylece LLM'e sağladığımız fonksiyonları ne zaman çağıracağına karar verme yetkisi verdiğimiz bir kod bulunmaktadır:

response = client.chat.completions.create(model=deployment,
                                        messages=messages,
                                        functions=functions,
                                        function_call="auto")

print(response.choices[0].message)

Gelen yanıt şu şekilde görünüyor:

{
  "role": "assistant",
  "function_call": {
    "name": "search_courses",
    "arguments": "{\n  \"role\": \"student\",\n  \"product\": \"Azure\",\n  \"level\": \"beginner\"\n}"
  }
}

Burada search_courses fonksiyonunun çağrıldığını ve JSON yanıtındaki arguments özelliğinde listelenen argümanlarla çağrıldığını görebiliyoruz.

Sonuç olarak, LLM, messages parametresine sağlanan değerden verileri çıkararak fonksiyonun argümanlarına uygun verileri bulabildi. Aşağıda messages değerinin bir hatırlatması bulunmaktadır:

messages= [ {"role": "user", "content": "Find me a good course for a beginner student to learn Azure."} ]

Gördüğünüz gibi, student, Azure ve beginner messages'dan çıkarıldı ve fonksiyona giriş olarak ayarlandı. Fonksiyonları bu şekilde kullanmak, bir istemden bilgi çıkarmanın harika bir yoludur, aynı zamanda LLM'e yapı sağlamak ve yeniden kullanılabilir işlevsellik sunmak için harika bir yöntemdir.

Şimdi bunu uygulamamızda nasıl kullanabileceğimizi görmemiz gerekiyor.

Fonksiyon Çağrılarını Bir Uygulamaya Entegre Etme

LLM'den gelen biçimlendirilmiş yanıtı test ettikten sonra, bunu artık bir uygulamaya entegre edebiliriz.

Akışı Yönetme

Bunu uygulamamıza entegre etmek için şu adımları izleyelim:

  1. İlk olarak, OpenAI hizmetlerine çağrı yapalım ve mesajı response_message adlı bir değişkende saklayalım.

    response_message = response.choices[0].message
  2. Şimdi Microsoft Learn API'yi çağırarak bir kurs listesi almak için bir fonksiyon tanımlayacağız:

    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)

    Şimdi functions değişkenlerinde tanıtılan fonksiyon adlarına eşleşen gerçek bir Python fonksiyonu oluşturduğumuza dikkat edin. Ayrıca ihtiyaç duyduğumuz verileri almak için gerçek harici API çağrıları yapıyoruz. Bu durumda, eğitim modüllerini aramak için Microsoft Learn API'ye gidiyoruz.

Tamam, functions değişkenlerini ve karşılık gelen bir Python fonksiyonunu oluşturduk, peki Python fonksiyonumuzun çağrılmasını LLM'e nasıl söyleyeceğiz?

  1. Bir Python fonksiyonunu çağırmamız gerekip gerekmediğini görmek için LLM yanıtını inceleyip function_call'ın bir parçası olup olmadığını kontrol etmemiz ve belirtilen fonksiyonu çağırmamız gerekiyor. Aşağıda bu kontrolü nasıl yapabileceğinizi görebilirsiniz:

    # 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,
         }
     )

    Bu üç satır, fonksiyon adını, argümanları çıkarır ve çağrıyı yapar:

    function_to_call = available_functions[function_name]
    
    function_args = json.loads(response_message.function_call.arguments)
    function_response = function_to_call(**function_args)

    Aşağıda kodumuzu çalıştırdıktan sonra çıkan sonuç bulunmaktadır:

    Çıktı

    {
      "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'>
    
  2. Şimdi güncellenmiş mesajı, messages'ı LLM'e göndererek bir API JSON formatında yanıt yerine doğal dilde bir yanıt alabiliriz.

    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)

    Çıktı

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

Ödev

Azure OpenAI Fonksiyon Çağrımı öğreniminizi devam ettirmek için şunları yapabilirsiniz:

  • Öğrencilerin daha fazla kurs bulmasına yardımcı olabilecek fonksiyonun daha fazla parametresini ekleyin.
  • Öğrenciden ana dili gibi daha fazla bilgi alan başka bir fonksiyon çağrısı oluşturun.
  • Fonksiyon çağrısı ve/veya API çağrısı uygun kurslar döndürmediğinde hata işleme oluşturun.

İpucu: Bu verilerin nasıl ve nerede mevcut olduğunu görmek için Learn API referans dokümantasyonu sayfasını takip edin.

Harika İş! Yolculuğa Devam Edin

Bu dersi tamamladıktan sonra, Generative AI Öğrenme koleksiyonumuza göz atarak Generative AI bilginizi geliştirmeye devam edin!

  1. Derse geçin, burada AI uygulamaları için UX tasarımını inceleyeceğiz!

Feragatname:
Bu belge, AI çeviri hizmeti Co-op Translator kullanılarak çevrilmiştir. Doğruluk için çaba göstersek de, otomatik çeviriler hata veya yanlışlıklar içerebilir. Belgenin orijinal dili, yetkili kaynak olarak kabul edilmelidir. Kritik bilgiler için profesyonel insan çevirisi önerilir. Bu çevirinin kullanımından kaynaklanan herhangi bir yanlış anlama veya yanlış yorumlama durumunda sorumluluk kabul edilmez.