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 przechodzimy już do drugiej,
najważniejszej funkcji naszego avatara, jaką jest odpisywanie na nasze wiadomości.
Zatem w pierwszej kolejności ustawię tutaj
jeszcze jeden filtr weryfikujący to, czy typ ustawiony jest na answer.
Jeżeli tak, to zostanie zrealizowana logika odpowiadająca na naszą wiadomość.
Proponuję jednak, abyśmy wrócili do
naszego schematu, gdzie dokładnie mamy rozpisane co tutaj musimy zrobić.
Mianowicie tak jak już wspominałem, w momencie gdy użytkownik wyśle wiadomość do
naszego avatara, wiadomość ta zostanie zamieniona na Embedding.
Następnie na jego podstawie, odszukamy zbliżone informacje znajdujące się w Pinecone
i w związku z tym, że dołączone są do nich identyfikatory Airtable, pobierzemy
tekstowe treści tych wpisów, a następnie wygenerujemy odpowiedź.
No i oczywiście ją zwrócimy.
Zabierajmy się więc do pracy.
Pierwszym krokiem będzie tak naprawdę skopiowanie modułów, które mamy tutaj.
Ze względu na to, że musimy zrobić praktycznie to samo.
Rzecz w tym, że na Embedding nie będziemy tutaj zamieniać wartości
pochodzącej z Airtable, tylko bezpośrednio wartość przekazaną przez użytkownika.
W moim przypadku będzie to zmienna content.
Następnie, skoro już mamy Embedding, muszę utworzyć teraz nowy obiekt JSON,
który opisze strukturę niezbędną do tego, aby wykonać zapytanie do Pinecone.
Jak zwykle do materiałów dodatkowych dołączam obiekt JSON, który właśnie
wklejam, na podstawie którego możesz wygenerować strukturę dla siebie.
Parametr topK ustawiamy na wymagany i domyślnie będzie wskazywał 5.
TopK oznacza liczbę recordów, które zostaną zwrócone z Pinecone.
Oznaczamy jako wymagane, a następnie ustawiamy domyślną wartość na 10.
Ten parametr określa to, ile recordów
zostanie zwróconych na podstawie przekazanego Embeddingu.
Potem mamy tutaj naszą kolekcję z
możliwością filtrowania, aczkolwiek tam nie będziemy się w tym momencie zajmować.
A poniżej mamy listę wektorów oraz możliwość zwrócenia dodatkowych
metadanych, w przypadku których chcemy ustawić tą opcję na True.
Dzięki temu uzyskamy następującą
strukturę, do której przekażemy Embedding wygenerowany w poprzednim kroku.
Rzecz w tym, że w tym momencie nie mamy jasnej struktury tych informacji.
W związku z tym odłączam ten moduł, a
następnie przełączam scenariusz w tryb nasłuchiwania.
Wewnątrz aplikacji Postman utworzymy sobie jeszcze jedno połączenie i tutaj również
będziemy przesyłać obiekt JSON, ale z ustawionym typem na answer.
Jeżeli jako content wpiszę pytanie jak mam na imię to scenariusz zostanie wywołany, a
następnie zostanie jak widać zrealizowana ta dolna ścieżka.
Na tym etapie, jeżeli połączymy nasze
moduły powinniśmy mieć już tutaj dostęp do Embeddingu.
Usunę jednak ten wpis i przełączę tutaj mapowanie, a następnie umieszczę tutaj
dokładnie tablicę, którą w tym miejscu otrzymaliśmy
i teraz mogę zapisać zmiany, a następnie wykonać zapytanie bezpośrednio do Pinecone.
Jak widzisz skopiowałem tylko moduł
odpowiedzialny za aktualizowanie recordów i zamienie tylko jego adres na ten
kierujący do naszej bazy na Endpoint Query.
Muszę tylko jeszcze upewnić się, że
przekazany tutaj JSON będzie pochodził dokładnie z wcześniejszego modułu.
No i możemy już zapisać zmiany.
Jeżeli teraz, raz jeszcze przetestujemy sobie nasz scenariusz, powinniśmy na tym etapie
otrzymać wygenerowany Embedding, a na tym zbliżone do niego recordy.
Konkretnie mamy tutaj tablicę matches, a
wewnątrz niej pojedynczy record z dodatkową wartością score, która określa
to, jak bardzo zbliżona jest ta informacja do tej, którą właśnie przekazaliśmy.
Jeżeli skopiujemy sobie ten record i wrócimy do Airtable, to zobaczymy, że odpowiada on
dokładnie recordowi, które mamy w tym miejscu.
Oznacza to mniej więcej tyle, że możemy
wykorzystać tutaj iterator po to, aby przejść po tablicę matches,
a następnie wykorzystać tutaj opcję Get record i dzięki temu będziemy mogli
wykorzystać znajdujące się w niej identyfikatory.
Do pobrania szczegółów poszczególnych recordów.
Jak zwykle wybieram tutaj odpowiednią bazę
danych oraz tabelę no i przekazuję identyfikator.
Teraz ostatnim krokiem będzie wykorzystanie text agregator, z pomocą
którego zgromadzimy wszystkie właściwości content zapisane w naszym Airtable.
Tutaj w opcjach dodatkowych wykorzystamy jako separator nowy wiersz oraz umieścimy
tutaj dodatkowe znaki sygnalizujące nowy fragment.
Upewnij się teraz tylko, że nazwy tych modułów są poprawne.
No i możemy raz jeszcze przetestować nasz scenariusz.
W tym momencie mamy tutaj jasne potwierdzenie, że przechodzimy przez
wszystkie podobne recordy w Airtable i pobieramy ich zawartość.
No to teraz ostatnim krokiem będzie
wykorzystanie GPT3 po to, aby wygenerować odpowiedź na tą wiadomość.
Mam tutaj taki bardzo prosty i przykładowy
prompt, który od razu nadaje ton wypowiedzi.
Następnie
sugeruje, że odpowiada na nasze wiadomości tak szczerze, jak to możliwe,
wykorzystując wyłącznie podane niżej fragmenty kontekstu.
W przeciwnym razie mówi nie wiem i zadaję
pytanie, które pozwala dowiedzieć się więcej.
Bez wątpienia jest to takie minimum, które możemy tutaj wykorzystać.
Jeżeli chodzi o sam kontekst, podajemy
tutaj zmienną, którą przed chwilą utworzyliśmy.
Podajemy tutaj zgromadzony tekst z Airtable a następnie wpisujemy wiadomość, której
wartość ustawiamy na wartość, którą przesłaliśmy bezpośrednio na Webhook i
zapisujemy odpowiedź, którą ma uzupełnić nasz avatar.
Jeżeli chodzi o ustawienia, na początek ustawimy tutaj 250 tokenów i ostatni
wskaźnik na 0,4, czyli taką umiarkowaną kreatywność.
Jeżeli uruchomimy ten scenariusz, a następnie zadamy pytanie jak mam na imię,
to powinniśmy otrzymać informację, że mam na imię Adam.
Wszystko się zgadza.
Jeżeli jednak zapytamy, jak ma na imię mój
pies, to sytuacja powinna wyglądać nieco inaczej.
Ze względu na to, że nasz avatar powinien powiedzieć, że nie wie i powinien zadać
pytanie, które pozwoli mu się tego dowiedzieć.
No i rzeczywiście odpowiedział, że nie wie i zapytał jak ma na imię mój pies.
No to teraz przeprowadzimy pewien
eksperyment, mianowicie napiszemy, że mój pies ma na imię Alexa.
Jeżeli teraz zapiszę te zmiany, to oczywiście one pojawią się w moim
Airtable, a chwilę potem pojawią się tutaj także tagi.
Oznacza to, że ten wpis zostanie zaindeksowanych w Pinecone, co będzie
równoznaczne z tym, że nasz avatar będzie mieć dostęp do tych informacji.
No to wykonujemy sobie scenariusz ponownie i pytamy ponownie o imię mojego psa.
W generowanej odpowiedzi otrzymujemy tutaj
rezultat mówiący o tym, że Twój pies ma na imię Alexa.
Wygląda więc na to, że nasz avatar jest w
stanie zapamiętywać informacje, zapominać je oraz odpowiadać na nie.
W związku z tym zapisuję teraz scenariusz i powoli możemy kończyć tą lekcję.
Aczkolwiek muszę Ci powiedzieć o czymś ważnym.
To jak skutecznie będzie działał Twój
avatar w dużym stopniu będzie zależało od jakości przechowywanych informacji w Airtable.
Dodatkowo są pewne wyjątki, na które również ja nie znalazłem na ten moment
sensownej odpowiedzi, które dotyczą nawet prostej sytuacji, takie jak fakt, że teraz
mój avatar może mylić asystenta głosowego Alexa z moim psem.
Oczywiście są tutaj proste rozwiązania, których moglibyśmy się trzymać.
Przykładem może być zawsze zaznaczanie
tego, kiedy mówimy o asystencie głosowym, a kiedy o psie.
To rozwiązanie jednak słabo sprawdza się w
momencie, gdy nasz avatar uczy się jakichś rzeczy pochodzących np.
ze stron internetowych.
Wówczas zapamiętywanie odbywa się automatycznie no i nie mamy już takiej pełnej
kontroli nad tym, w jaki sposób te informacje zostaną zaindeksowane.
Warto więc o tym pamiętać.
I dodatkowo też warto podkreślić, że problem, o którym teraz powiedziałem, nie
jest problemem charakterystycznym wyłącznie dla naszego avatara.
Jest to powszechny problem, z którym spotykają się osoby zaangażowane w rozwój
AI, zanim jeszcze całkowicie zakończymy tą lekcję.
Chciałbym jeszcze tutaj w tym miejscu uwzględnić fakt, że możemy wykorzystać
wartość Score i powiedzieć, że musi być ona wyższa bądź równa np.
0.75.
W ten sposób, jeżeli znajdziemy wyłącznie bardzo odległe recordy, nasz avatar nie
będzie próbował wykorzystać ich do udzielenia odpowiedzi.
Oczywiście w takiej sytuacji dobrze jest
jeszcze tutaj dołożyć jakiś warunek sprawdzający, czy w kontekście jest
cokolwiek ustawione i w przeciwnym razie poinformować naszego bota, że sam kontekst
może się w ogóle nie pojawić i wówczas również można dostosować jego zachowanie.
Tymczasem ponownie zapisuję scenariusz.
Dziękuję Ci za uwagę i zapraszam Cię do kolejnej lekcji.