Połącz możliwości GPT-3 i automatyzacji
2 godz. 3 min · OpenAI · Biznes i Automatyzacje
Adam GospodarczykWykorzystanie API OpenAI nie różni się w żaden sposób od innych. Przesyłając dane i parametry na wskazany endpoint, otrzymujemy odpowiedź wygenerowaną przez model (np. text-da-vinci-003). Na tym jednak możliwości tego API się nie kończą. Przykładem z którego skorzystamy będzie zamiana danych na tzw. embedding (listę wektorów). Dane zapisane w takiej formie będą wstępem do "pamięci" bota i tym samym pierwszym punktem procesu nauki.
Prompt Engineering to rozwijająca się dziedzina skupiona na projektowaniu systemów zdolnych do skutecznego reagowania na dane wprowadzone przez użytkownika. W przypadku tworzonego przez nas bota, wykorzystamy pewne elementy tego procesu aby zmodyfikować jego domyślne zachowanie oraz przygotowywanie odpowiedzi na podstawie wyłącznie wcześniejszych danych. W przypadku braku wiedzy na jakiś temat, bot będzie nas o tym informował w sarkastyczny sposób lub nawet zwracał informacje w podanym przez nas formacie.
Wysyłając zapytanie do API OpenAI, jesteśmy ograniczeni liczbą znaków. Tworząc bota chcemy uwzględniać nie tylko to aby odpowiadał na nasze pytania ale także uwzględniał przekazany przez nas kontekst, składający się z informacji jakie zapamiętał bot. Problemem jest tutaj wybór, które dane ma brać pod uwagę. Rozwiązanie po które sięgamy w tym warsztacie polega na wykorzystaniu bazy wektorowej (Pinecone), która pełni rolę pamięci oraz bazy lokalnej w której przechowujemy faktyczne informacje. Ich połączenie pozwala na wybranie najbardziej istotnych danych i uwzględnienie ich w kontekście, który pozwoli GPT-3 przygotować odpowiedź.
Temat wykorzystania AI w codziennym życiu nie jest nowy ale nabrał szczególnego znaczenia po pojawieniu się ChatGPT. Wiele osób zaczęło wykorzystywać AI do rozwiązywania bieżących problemów i ułatwiania sobie różnych zadań. W tym warsztacie znajdziesz kilka inspiracji, które nakierują Cię na to jak możesz rozwijać swojego własnego, inteligentnego i uczącego się bota.
Warsztat został stworzony z myślą o osobach znających JavaScript i Node.js, chcących postawić pierwsze kroki w praktycznym wykorzystaniu GPT-3 oraz API OpenAI. Poza znajomością JavaScript, konieczne będzie minimum doświadczenia w pracy z API oraz bazami danych (SQL). Po ukończeniu tego warsztatu zyskasz ogólne zrozumienie możliwości GPT-3 oraz umiejętności umożliwiające wpływ na jego zachowanie i generowane odpowiedzi.
W tej lekcji zajmiemy się utworzeniem
nowej tabeli, wewnątrz której będziemy przechowywać historię naszych konwersacji.
Jak zwykle usunę tylko niepotrzebne
kolumny i od razu przejdziemy do ustawienia pierwszej kolumny jako formuła,
wewnątrz której zapiszemy identyfikator tego recordu.
Jeżeli chodzi o kolumny będziemy mieć
tutaj pytanie, czyli Long text oraz odpowiedź.
Następnie zapiszemy sobie tutaj także bieżące podsumowanie, a także potrzebujemy
pola created_at, aby wiedzieć kiedy dany wpis został utworzony.
Teoretycznie powinno nam to wystarczyć, w praktyce jednak potrzebuję jeszcze jednej
kolumny o nazwie diff, której typ ustawię na formula.
Wewnątrz niej skorzystamy z funkcji datetime diff.
Która liczy różnicę pomiędzy przekazanymi
datami i zwraca wynik w podanej tutaj jednostce.
Mnie konkretnie interesuje czas, jaki
upłynął od utworzenia recordu do bieżącego momentu.
Po utworzeniu tego pola mamy tutaj wartość, na podstawie której możemy
utworzyć nowy widok, wewnątrz którego będą zawarte wyłącznie te
konwersacje, które odbyły się w ciągu ostatnich 10 minut.
Wybieramy więc filtr dla pola diff i
sprawdzamy, czy jego wartość jest większa bądź równa minus 10.
Inaczej mówiąc, do tej tabeli będą
trafiały te recordy, które zostaną utworzone w ciągu ostatnich 10 minut.
W sytuacji, gdy czas zostanie
przekroczony, zostaną tutaj tylko te najnowsze recordy.
Zatem możemy teraz usunąć te wszystkie
wpisy, a następnie przejść do naszego scenariusza.
Dokładnie w tym miejscu pobierzemy sobie
wszystkie recordy, które będą pasowały nam do określonych warunków.
Mianowicie po wybraniu odpowiedniej bazy,
oraz tabeli i w tym przypadku będzie to tabela
konwersacja.
Ustawiamy filtr sortujący recordy według
kolumny Created_at i konkretnie najnowszych recordów.
Następnie wybieramy tylko z najnowszej
konwersacji i ograniczamy liczbę zwróconych recordów do jednego.
Inaczej mówiąc w tym miejscu zostanie zwrócona ostatnia konwersacja, której
podsumowanie możemy dołączyć do naszego kontekstu.
Konkretnie zapiszemy tutaj dodatkową
sekcję o nazwie Podsumowanie i przekażemy do niej wartość pola Summary.
Oczywiście musimy tutaj uwzględnić
sytuację, w której podsumowania nie będzie.
Wówczas zapiszemy tutaj brak.
No i teraz musimy zmodyfikować nasz
prompt, aby odpowiadał również uwzględniając podsumowanie naszej rozmowy.
Wykorzystując magię kina zmodyfikowałem prompt w taki sposób, aby avatar uwzględniał
tutaj dwie zmienne, jaką jest kontekst oraz podsumowanie i nawiasami klamrowymi.
Wyraźnie podkreśliłem te dwa słowa oraz zaznaczyłem, że avatar potrafi wyraźnie
oddzielić te dwa zestawy informacji od siebie.
Zanim będziemy to testować, to zwróć uwagę jak szybko rośnie nasz prompt.
Jest to szczególnie istotne, aby
uwzględniać tutaj wyłącznie najważniejsze informacje.
Ze względu na to, że jesteśmy ograniczeni długością do czterech tysięcy tokenów.
Dodatkowo im dłuższy prompt, tym dłużej
trwa generowanie odpowiedzi i tym większe koszty ponosisz.
Zatem uwzględnia tutaj wyłącznie te informacje, które są absolutnie niezbędne.
Teraz zapisuję tutaj zmiany.
No i przechodzimy dalej.
Po pierwsze chciałbym, aby odpowiedź, która zostaje tutaj zwracana została
zwracana w formacie JSON i w przeciwieństwie do tego, co robiliśmy
tutaj do tej pory, ustawię tylko tutaj zmienną response, która będzie tekstem
wymaganym oraz ta właściwość będzie mogła zawierać tekst zapisany w wielu liniach.
Jeżeli teraz uzupełnimy sobie naszą odpowiedź, no to będziemy mogli wykorzystać to, co tutaj
utworzymy do przesłania odpowiedzi zwrotnej.
Oczywiście tutaj przekazujemy obiekt JSON,
który przed sekundą utworzyliśmy, a następnie ustawiamy jeszcze
nagłówek o wartości Content type ustawionej na application/json.
Ostatnim krokiem który musimy tutaj zrobić jest zapisanie konwersacji.
W związku z tym otworzę teraz nowy record Airtable,
dodając do tabeli Conversation nowy wpis, wewnątrz którego zapiszę zarówno moje
pytanie, jak i odpowiedź zwróconą przez avatara.
Ostatnim polem, które odgrywa tutaj szczególną rolę, jest pole podsumowania.
Wewnątrz którego zapiszemy wynik
pochodzący z dodatkowego wywołania modułu GPT3.
Wewnątrz tego modułu zapiszemy sobie następujący prompt. Jako Avatar AI
podsumuję dla siebie mój dialog z usera no i tutaj jeżeli istnieje podsumowanie,
dodamy fragment łącząc z nim podsumowanie poprzedniej rozmowy.
Efekt będzie taki, że jeżeli jest to początek rozmowy, avatar podsumuje
wyłącznie dialog, a w przeciwnym razie uwzględni także podsumowanie.
I tutaj poniżej znajduje się najnowszy
dialog uwzględniający to, co powiedział użytkownik oraz to, co mówi Avatar.
Samo podsumowanie uwzględniamy tutaj.
Zapisuję więc zmiany i upewniam się, że
wynik, który tutaj mamy został zapisany w Airtabeli, a dodatkowo jeszcze tylko testując
zachowanie avatara zmieniłem ten główny prompt i dodałem
do niego również zmienne w postaci wiadomości, kontekstu oraz podsumowania.
I zmodyfikowałem ten prompt, aby
wykorzystywał wyłącznie podane niżej fragmenty kontekstu, zaznaczając, że są to
informacje, o których on wie oraz podsumowanie wcześniejszej konwersacji.
Dodatkowo w rozmowie potrafi wyraźnie
oddzielić to, co wie, czyli kontekst od naszej rozmowy, czyli podsumowania.
Jest to tak bardzo wyraźnie podkreślone ze względu na to, że nieustannie mylił to, o
czym rozmawialiśmy z kontekstem bieżącej rozmowy.
W każdym razie tutaj jeszcze mamy ten
fragment o odpowiadaniu nie wiem, i zadawaniu kolejnych pytań.
Jeżeli teraz wrócimy do aplikacji Postman będziemy mogli tutaj zadać pytanie np.
Cześć, jak się masz?
Powinniśmy otrzymać informację, że nasz
avatar ma się dobrze i zapytać nas o to samo.
No i dokładnie tak się stało.
Dodatkowo w Airtable została zapisana konwersacja, wewnątrz której mamy moje
pytanie, odpowiedź avatara oraz krótkie podsumowanie.
No to teraz napiszmy kolejną wiadomość.
Powiem, że mam się dobrze i zapytam czy wie jak ma na imię.
No i zobacz na jaki problem tutaj trafiliśmy.
Mianowicie nasz avatar pomylił informacje.
Oczywiście sam wie, że jest avatarem AI i to jest w porządku.
Wie także, że mój pies ma na imię Alexa, ale
nie wie jak ja mam na imię i czy mógłbym mu to powiedzieć.
Jeżeli zajrzymy sobie w wykonanie
scenariusza, to zobaczymy, że teoretycznie w kontekście znajduje się informacja, że
mam na imię Adam, ale GPT3 w tej chwili nie wie, że rozmawia z Adamem.
W związku z tym coś takiego możemy załatwić na kilka sposobów.
Mianowicie w pierwszej kolejności możemy przywitać się z Adamem.
Dodatkowo możemy zaznaczyć, że wierzę
kontekst to notatki Adama, którymi kiedyś się ze mną podzielił.
Następnie zaznaczymy jeszcze, że wiadomość, którą tutaj mamy napisał Adam.
No to teraz mogę zapisać zmiany oraz
scenariusz i upewnić się, że mamy tutaj tylko tą ostatnią wiadomość.
Wysyłam zapytanie i zobaczymy jak teraz będzie wyglądała odpowiedź.
Wygląda na to, że teraz nasz avatar dokładnie wie z kim rozmawia.
Natomiast można tutaj jeszcze popracować np.
nad tym, aby nie witał się za każdym razem
oraz także, aby nie zadawał za każdym razem jakiegoś pytania.
Spróbujemy to ponownie zrobić.
Ponownie zmodyfikujemy prompt i zrobimy to tak.
Fragment o zadawaniu pytań znajduje się
dokładnie w tym miejscu, ale szczerze mówiąc nie mam pomysłu jak to naprawić.
W związku z tym proponuję, abyśmy przeszli
do Chat GPT i tutaj możemy rozpocząć konwersację od powiedzenia, że jest
światowej klasy prompt designerem i teraz możemy zadawać pytania.
Napisałem tutaj prośbę informującą o tym,
że mam prompt dla avatara AI i potrzebuję go zmodyfikować, aby avatar nie witał się za
każdym razem oraz aby nie zadawał mi pytań w sytuacji, gdy udzielił odpowiedzi.
Dodatkowo zaznaczam także, aby nie zmieniał mi pozostałej części promptu i
przekazuję sam prompt, oznaczając także jego zakończenie.
No i otrzymałem teraz nowy prompt.
W związku z tym wykorzystam teraz go bezpośrednio w Make.
Zanim przejdziemy do testów, zatrzymałem
jeszcze nagrywanie na chwilę, aby zmodyfikować prompt jeszcze bardziej.
Po pierwsze zaznaczyłem, że avatar jest kobietą.
Podkreśliłem jeszcze bardziej różnice pomiędzy kontekstem oraz podsumowaniem.
Uwzględniłem, że zwroty
zawarte w kontekście wskazują na rozmówcę, czyli na Adama oraz zaznaczyłem wyraźną
różnicę pomiędzy początkiem oraz końcem kontekstu i podsumowania rozmowy.
No i teraz upewniam się, że w Airtable
nie ma żadnych konwersacji i zadajemy pytanie. Jak się masz?
Cześć Adamie, Dziękuję za pytanie. Mam się dobrze.
Dziękuję. A jak się masz Ty?
W porządku. W tym momencie mógł zadać to pytanie.
Nie mam z tym najmniejszego problemu.
Teraz nie będę zadawał kolejnych pytań, tylko po prostu odpowiem na jego pytanie.
No i wygląda na to, że odpowiedział na
moją wiadomość i nie zadawał kolejnych pytań.
Wszystko się zgadza.
Na pytanie, czy podsumuje naszą aktualną
rozmowę, powiedział, że była przyjemna i że cieszy się, że mam się dobrze.
Wygląda więc na to, że wszystko działa
tutaj poprawnie, aczkolwiek w tle przeprowadzę jeszcze kilka testów.
No i faktycznie zadałem tutaj kilka kolejnych pytań.
Mianowicie zacząłem od pytania kim jesteś?
Odpowiedziała Jestem Avatarką AI, wszystko się zgadza.
Czy wiesz, kim ja jestem?
Tak wiem, że jesteś Adamem.
Również wszystko się zgadza.
Czy wiesz coś o moim pokoju?
Oczywiście nic takiego nie mówiłem.
W związku z tym poprosiła mnie o więcej danych.
No i w momencie, gdy poprosiłem o podsumowanie naszej rozmowy, mówiła, że
nasza rozmowa dotyczyła twojego pokoju, ale nie udało mi się uzyskać więcej
wystarczających informacji, aby odpowiedzieć na pytania.
Wygląda więc na to, że wszystko się tutaj zgadza.
Jednocześnie cieszę się, że udało mi się
doprowadzić do wystąpienia różnego rodzaju błędów ze względu na to, że pokazałem Ci,
z czym tak naprawdę się mierzysz projektując prompt własnego avatara.
Im bardziej skomplikowany będzie avatar oraz im bardziej będzie rosła baza wiedzy
którą będzie posiadał.
Tym trudniej będzie odnaleźć właściwe informacje.
i tym trudniej będzie ich nie mieszać.
W związku z tym warto poza systemem tagów
wprowadzić jakiś nieco bardziej złożony system wybierania treści.
Tym bardziej, że mamy do dyspozycji tutaj przynajmniej kilka narzędzi.
Pierwszym jest filtrowanie recordów w Airtable,
drugim pobieranie informacji z różnych baz danych na podstawie np.
zadanego pytania.
Jeszcze kolejnym jest budowanie zapytania do Pinecone w taki sposób, aby np.
uwzględniać filtrowanie informacji.
Coś takiego także jest możliwe.
Poza tym wszystkim myślę, że dało się
zauważyć, że największą rolę odgrywa sposób w jaki zdefiniujemy prompt, no i
oczywiście jakość naszych danych przechowywanych w Airtable.
Ostatecznie udało nam się doprowadzić do
sytuacji, w której avatar spełnia minimum swoich funkcji i potrafi zapamiętywać,
zapominać oraz odpowiadać na pytania na podstawie posiadanych informacji.
W tym momencie zachęcam Cię do tego, aby
odzwierciedlić cały scenariusz, który tutaj mamy oraz pobawić się nim próbując
nadać jakieś dodatkowe cechy osobowości dla naszego avatara i np.
rozbudować go o jakieś dodatkowe funkcje.
A tymczasem ja dziękuję Ci za uwagę i zapraszam do kolejnych materiałów.