OpenAI, jeden z liderów w dziedzinie sztucznej inteligencji, zapewnia dostęp do zaawansowanych narzędzi, takich jak chociażby znany już wszystkim ChatGPT. Platforma ta nie tylko umożliwia korzystanie z gotowych rozwiązań, ale udostępnia także interfejs programistyczny API. Dzięki temu istnieje możliwość integracji naszych aplikacji z zaawansowanymi modelami sztucznej inteligencji.

W niniejszym artykule przedstawimy opis podłączenia OpenAI API  w Ferryt Enterprise Platform 2.0 na wersji 2.13. Integracja ta umożliwi skorzystanie z modeli sztucznej inteligencji w rozwiązaniach biznesowych. To na czym skupimy się w tym artykule to podłączenie do procesu modelu GPT, a konkretnie modelu konwersacyjnego LLM, na którym pracuje wspomniany już ChatGPT (https://chat.openai.com/).

OpenAI API – parę słów wstępu

Czy korzystanie z OpenAI API wymaga założenia konta?

Tak. Aby móc korzystać z OpenAI API należy założyć konto na platformie https://platform.openai.com. Konto wymagane  jest przede wszystkim do wygenerowania klucza  dostępowego, który należy dołączać do każdego wywołania API w nagłówku http. Klucze można generować pod adresem https://platform.openai.com/account/api-keys.

Czy korzystanie z OpenAI API jest bezpłatne?

Nie. Korzystanie z OpenAI API wiąże się z kosztami. OpenAI oferuje różne pakiety cenowe, w zależności od liczby żądań API i rodzaju dostępu. Opłaty obejmują aspekty takie jak ilość żądań API na minutę, pojemność modelu, a także rodzaj dostępu (np. użytkownik indywidualny, przedsiębiorstwo itp.). Więcej o opłatach jest dostępnych na stronie https://openai.com/pricing.

Na koncie należy zarejestrować metodę płatności np. kartę płatniczą.   Po zalogowaniu można monitorować „koszty”, które ponieśliśmy w związku z używaniem OpenAI.„Używanie” API jest rozliczane w tokenach. Token jest to część tekstu wysyłanego do API i odebranego z API. Może być to pojedyncza litera lub słowo. Aby zagłębić się w tą tematykę polecamy lekturę https://platform.openai.com/docs/guides/text-generation/managing-tokens.

Aktualne limity i utylizacja są zawsze dostępne na naszym https://platform.openai.com/account/limits:

Rys. Przykład informacji o aktualnych płatnościach dla konta.

Rys. Wykorzystanie limitów

OpenAI API z punktu widzenia technicznego

OpenAI udostępnia parę modeli dostępnych przez API, o których można poczytać na stronie https://platform.openai.com/docs/models.

My skupimy się na wywołaniu konwersacyjnego API https://api.openai.com/v1/chat/completions, umożliwiając tym samym wysyłanie zapytań tekstowych z Ferryt i otrzymywanie odpowiedzi.

W dokumentacji OpenAI https://platform.openai.com/docs/api-reference/chat/object jest dostępny opis interfejsu wraz z przykładami. Z github OpenAI  https://github.com/openai/openai-openapi można pobrać plik yaml z pełną specyfikacją OpenAI API.

Z technicznego punktu widzenia API Open AI jest API RESTowym opartym o komunikację w formacie JSON. W każdym żądaniu do API należy w nagłówku http Authorisation dodać klucz dostępowy, w postaci „Bearer OPENAI_API_KEY”, gdzie OPENAI_API_KEY to klucz dostępowy wspomniany wyżej.

Zapoznając się z pełną specyfikacją opisu API widzimy, że zarówno żądanie, jak i odpowiedz z API posiada wiele parametrów. W niniejszym artykule nie będziemy jednak skupiać się na znaczeniu każdego parametru. Omówimy te główne, kluczowe dla nawiązania komunikacji z OpenAI API.

Praca w samym Ferryt

Jak będzie wyglądał proces

Zbudujemy prosty proces z jedną formatką, na której wprowadzimy klucz dostępowy API, treść zapytania oraz przycisk do wysłania formularza. Odpowiedź zaprezentujemy na tym samym ekranie w etykiecie.

Poniżej przedstawiono 4 kroki zbudowania prostego procesu wywołującego API OpenAI na platformie Ferryt 2.0 wersja 2.13. Kroki te to:

  • KROK1. Rejestracja typów danych dla żądania i odpowiedzi serwisu OpenAI API
  • KROK2. Rejestracja serwisu OpenAI API
  • KROK3. Utworzenie ekranów, zdefiniowanie BPMN
  • KROK4. Uruchomienie formularza

KROK1. Rejestracja typów danych dla żądania i odpowiedzi serwisu

W pierwszym kroku utworzymy typy danych o symbolach chatCompletionRequest i chatCompletionResponse, które będą odpowiadały formatom żądania i odpowiedzi z API Open AI.

W Ferryt 2.0 rejestrację typu można zrobić ręcznie, budując struktury na podstawie specyfikacji https://platform.openai.com/docs/guides/text-generation/chat-completions-api, https://platform.openai.com/docs/api-reference/chat/object.

Jednak my skorzystamy z mechanizmu Ferryt 2.0 automatycznego tworzenia typów na podstawie przykładowych żądań i odpowiedzi.

Z github OpenAI  https://github.com/openai/openai-openapi pobieramy plik yaml z pełną specyfikacją OpenAI API.

Uprzedzając pytania 🙂 – w roadmap Ferryt 2.0 jest zaplanowany mechanizm rejestracji serwisu na podstawie definicji yaml, jednak na chwilę obecną posłużymy się przykładowymi żądaniami i odpowiedziami, które generuje nam swagger.

Za pomocą edytora swagger (np. na stronie https://editor.swagger.io/  ) odczytujemy JSON-y dla żądania i odpowiedzi dla endpoint chatCompletions, który obsługuje interesujące nas API.

Rys. Widok przykładu żądania metody chat/completions w Swagger.

Kopiujemy zawartość z pola ExampleValue i zapisujemy do pliku np. CreateChatCompletionRequest.json

Poniżej zawartość pliku CreateChatCompletionRequest.json

{
  "messages": [
    {
      "content": "string",
      "role": "system",
      "name": "string"
    },
    {
      "content": "string",
      "role": "user",
      "name": "string"
    },
    {
      "content": "string",
      "role": "assistant",
      "name": "string",
      "tool_calls": [
        {
          "id": "string",
          "type": "function",
          "function": {
            "name": "string",
            "arguments": "string"
          }
        }
      ]
    },
    {
      "role": "tool",
      "content": "string",
      "tool_call_id": "string"
    },
    {
      "role": "function",
      "arguments": "string",
      "name": "string"
    }
  ],
  "model": "gpt-3.5-turbo",
  "frequency_penalty": 0,
  "logit_bias": null,
  "max_tokens": "inf",
  "n": 1,
  "presence_penalty": 0,
  "response_format": {
    "type": "json_object"
  },
  "seed": 9223372036854776000,
  "stop": null,
  "stream": false,
  "temperature": 1,
  "top_p": 1,
  "tools": [
    {
      "type": "function",
      "function": {
        "description": "string",
        "name": "string",
        "parameters": {
          "additionalProp1": {}
        }
      }
    }
  ],
  "tool_choice": "none",
  "user": "user-1234"
}

Analogicznie tworzymy plik ChatCompletionResponse.json z przykładem odpowiedzi

Rys. Widok przykładu żądania metody chat/completions w Swagger.

Poniżej zawartość pliku CreateChatCompletionResponse.json

{
  "id": "string",
  "choices": [
    {
      "finish_reason": "stop",
      "index": 0,
      "message": {
        "content": "string",
        "tool_calls": [
          {
            "id": "string",
            "type": "function",
            "function": {
              "name": "string",
              "arguments": "string"
            }
          }
        ],
        "role": "assistant"
      }
    }
  ],
  "created": 0,
  "model": "string",
  "system_fingerprint": "string",
  "object": "chat.completion",
  "usage": {
    "completion_tokens": 0,
    "prompt_tokens": 0,
    "total_tokens": 0
  }
}

Przechodzimy do aplikacji  Ferryt Architect,  do modułu Projektowanie>model danych>typy danych i rejestrujemy nowy typ. Podajemy symbol typu np. chatCompletionRequest, wskazujemy Rodzaj – struktura, Typ struktury wybieramy json/avro i w polu Wybierz plik wskazujemy utworzony plik chatCompletionRequest.json:

Rys. Definiowanie typu dla żądania

Wracając na listę typów danych możemy obejrzeć strukturę chatCompletionRequest:

Rys. Widok struktury typu w module Typy danych

Przygotowanie typu danych dla odpowiedzi – analogicznie postępujemy dla pliku chatCompletionResponse.json i tworzymy typ chatCompletionResponse dla odpowiedzi:

Rys. Definicja typu odpowiedzi

Wracając na listę typów możemy obejrzeć strukturę chatChatCompletionResponse:

Rys Widok struktury typu odpowiedzi w module Typy danych

Po rejestracji tych serwisów warto jeszcze zrobić mały check, zwracając uwagę na poprawność typów dla pól int, decimal. Ferryt automatycznie rozpoznaje typ pola na podstawie przekazanej wartości z pliku json. Jeżeli w tym pliku dla pola typu decimal zostanie przykładowo podana wartość 5, to Ferryt założy dla pola typ Int, a nie decimal. Swagger generując przykładowe wartości nie zawsze do pola zmiennoprzecinkowego wygeneruje wartość zmiennoprzecinkową.

Po przejrzeniu założonych typów danych i porównując do oryginalnej definicji yaml, skorygowaliśmy typ danych na Decimal dla parametrów Frequency_penality, Persense_penality, temperature.

Mając dokładniejsze pliki json z poprawniejszymi wartościami, Ferryt utworzyłby pola z poprawnymi typami.

KROK2. Rejestracja serwisu

Przechodzimy do modułu Integracje>serwisy zewnętrzne i dodajemy serwis REST  o nazwie np. openAIAPI.

W polu adresURL wpisujemy adres: https://api.openai.com/:

Rys. Widok ekranu dodania serwisu zewnętrznego

Przechodzimy do zakładki Metody i definiujemy endpoint dla konwersacyjnego API v1/chat/completions. Endpoint ten możemy nazwać chatCompletion.

W polu Adres URL wpisujemy:  v1/chat/completions , Rodzaj żądania POST. Jako format wejściowy wskazujemy JSON i w polu Typy danych wejście wskazujemy typ chatCompletionRequest. Jako Format wyjściowy wskazujemy JSON i w Typy danych wyjście wskazujemy chatCompletionResponse.

Rys. Widok metody serwisu

Ostatnim krokiem rejestracji metody będzie dodanie informacji o tym, że w żądaniu wysyłany będzie custom-owy nagłówek. W tym celu na liście metod serwisu wskazujemy właśnie dodaną metodę chatCompletion i w dolnej sekcji, w zakładce Wejście zaznaczamy InputHeaders[].Key i klikamy Ustawienia. Dodajemy jeden klucz o symbolu Authorization, ale bez treści. Wartość dla nagłówka dodamy w procesie.

KROK3. Utworzenie prostego procesu

Na potrzeby testów utworzymy prosty proces o symbolu openAIConversation i dodamy parę pól charakterystycznych:

  • chAnswer – pole do zapisania odpowiedzi API
  • chAPIKey – pole do wprowadzenia klucza API
  • chQuestion – pole do wprowadzenia zapytania użytkownika
Rys. Lista pól charakterystycznych procesu

Proces będzie miał jeden ekran. Na formularzu będzie dostępne pole do wprowadzenia API Key i treści zapytania. Będzie dostępne również pole typu Etykieta, gdzie pokażemy użytkownikowi odpowiedź  OpenAI API:

Rys. Wygląd formularza w designerze

W modelu BPMN dodamy jedną akcję, która zostanie wywołana na kliknięcie przez użytkownika przycisku ‘Ask Chat GPT’. Akcja ta wywoła serwis zewnętrzny openAIAPI, wyśle żądanie, odbierze odpowiedz i pokaże ją na ekranie użytkownika.

Poniżej przestawiamy jak wygląda definicja akcji w designerze BPMN:

Rys. Definicja BPMN akcji podpiętej pod przycisk ‘Ask Chat GPT’
Rys. Definicja BPMN akcji podpiętej pod przycisk ‘Ask Chat GPT’

W akcji kładziemy bloczek Serwis Zewnętrzny o nazwie np. Call OpenAI chat completions API, wskazujemy zarejestrowany serwis openAIAPI i metodę chatCompletions. Ustawiamy parametry wejściowe oraz wyjściowe:

1. Parametry wejściowe:

  • Frequency_penality, Persense_penality – tu nie będziemy się zagłębiać w znaczenie tych parametrów. Możemy ich nie ustawiać. My eksperymentalnie ustawiliśmy je na  np. 0.52 i 0.5
  • Pierwszy element tablicy messages[0] – przekazujemy wartość zapytania wprowadzonego przez użytkownika (pole PF.chQuestion)
  • Role = user
  • Model – ustawimy tu najnowszy (na moment tworzenia artykułu) model GPT 3.5 – gpt-3.5-turbo-1106.  
  • Max_tokens – parametrem tym wskazujemy maksymalną oczekiwaną długość dla odpowiedzi- zostawiamy pustą
  • Temparature – 1. Jest to parametr żądania, który określa na ile „kreatywnych odpowiedzi” oczekujemy od API. Dopuszczalne wartości dla tego parametru to liczba rzeczywista z zakresu <0;2>. Im parametr ten jest bliższy 0, to odpowiedz API jest bardziej formalna.

Nagłówki żądania:

W polu InputHeaders należy ustawić nagłówek Authorization do przekazania klucza autoryzacyjnego.

2. Parametry wyjściowe:

  • Z tablic choices odczytujemy rekord z indeksem 0 i z niego czytamy zawartość message.content, którą przypisujemy do pola PF.chAnswers
  • Resztę parametrów odpowiedzi nie sczytujemy na razie do procesu

KROR 4. Uruchomienie wniosku

Aby dokończyć w 100% przygotowanie procesu wymagane jest wykonanie standardowych czynności związanych z włączeniem edytowalności pól. Wymagane jest także  nadanie uprawnień do statusów i akcji.

Jeżeli mamy taką potrzebę, można przygotować osobnego FerrytLinka  do uruchomienia naszego procesu.

Składamy wniosek w przeglądarce. Po podaniu do formularza klucza, treści zapytania i kliknięciu [Ask chat GPT] dostajemy odpowiedz ????

Klikając jeszcze raz przycisk Ask Chat GPT otrzymujemy inną odpowiedź

Podsumowując

W niniejszym artykule przedstawiliśmy możliwość podłączenia low-code’owo OpenAI API na platformie Ferryt.

Należy pamiętać o zasadach budowania rozwiązań opartych na AI i regulacjach prawnych, i AI Act (https://artificialintelligenceact.eu/the-act/). Dokument został ratyfikowany 09.12.2023 przez Parlament Europejski https://www.consilium.europa.eu/pl/press/press-releases/2023/12/09/artificial-intelligence-act-council-and-parliament-strike-a-deal-on-the-first-worldwide-rules-for-ai/ . Niewątpliwie ważne są też zasady „godnej zaufania sztucznej inteligencji” (https://digital-strategy.ec.europa.eu/en/library/ethics-guidelines-trustworthy-ai), gdzie zebrane są wytyczne dotyczące wytworzenia, wdrożenia i używania rozwiązań opartych na AI.

Należy pamiętać również, że używając rozwiązań AI w sektorze bankowym trzeba szczególnie zadbać o ochronę danych osobowych i tajemnicę bankową.

Autorka:

Dorota Wichowska – Senior Ferryt Manager, Team Leader