Repozytorium zawiera przykłady z lekcji kursu AI_devs 3. Więcej informacji znajdziesz na aidevs.pl.
Wszystkie przykłady zostały napisane w JavaScript / TypeScript i większość z nich zawiera kod backendowy do którego uruchomienia potrzebny jest Node.js oraz Bun.
Upewnij się, że posiadasz najnowsze wersje Node.js oraz Bun zainstalowane na swoim komputerze.
-
Pobierz repozytorium:
git clone git@github.com:i-am-alice/3rd-devs.git cd 3rd-devs
-
Zainstaluj zależności:
bun install
-
Skopiuj plik
.env.example
do.env
i wypełnij go kluczami API (na początek wystarczy klucz OpenAI). -
Uruchom dostępne przykłady z pliku
package.json
, według poniższej instrukcji.
Przykład przedstawia konwersację między użytkownikiem i asystentem, w której działa mechanizm podsumowania konwersacji.
- Uruchomienie serwera:
bun run thread
- Interakcja demo:
curl -X POST http://localhost:3000/api/demo
- Interakcja chat:
curl -X POST http://localhost:3000/api/chat -H "Content-Type: application/json" -d '{"message": { "role": "user", "content": "Hi"}}'
Wywołanie powyższego endpointu uruchomi trzy niezależne zapytania do OpenAI, jednak w wiadomości systemowej zostanie przekazane podsumowanie poprzedniej interakcji, dzięki czemu model będzie miał możliwość odwołać się do ich treści.
W przykładzie uwzględniony jest także endpoint /api/chat
na który można przesłać obiekt { "message": "..." } zawierający treść wiadomości do modelu. Wątek zostanie zresetowany dopiero po ponownym uruchomieniu serwera (wciśnij CMD + C / Control + C i ponownie bun run thread
).
UWAGA: przykład wymaga zainstalowania promptfoo
w przypadku którego prawdopodobnie musisz to zrobić poleceniem npm install promptfoo
ponieważ bun install promptfoo
nie działa poprawnie w każdej sytuacji.
- Uruchomienie skryptu:
bun use_search
Rezultatem działania skryptu jest tablica zawierająca kilkanaście przykładowych testów dla promptu decydującego o tym, czy skorzystanie z wyszukiwarki jest potrzebne.
- Uruchomienie skryptu:
bun pick_domains
Rezultatem działania skryptu jest tablica zawierająca kilkanaście przykładowych testów dla promptu generującego zapytania do wyszukiwarki Internetowej, wskazując także odpowiednie domeny.
- Uruchomienie skryptu:
bun rate
Rezultatem działania skryptu jest tablica zawierająca kilkanaście przykładowych testów dla promptu oceniającego, czy odpowiedź modelu zawiera odpowiednie informacje.
Przykład ten korzysta z Firecrawl do przeszukiwania Internetu oraz pobierania treści stron www. Konieczne jest więc uzupełnienie pliku .env
wartości FIRECRAWL_API_KEY ustawionej na klucz API.
(Firecrawl oferuje bezpłatny plan).
- Uruchomienie serwera:
bun websearch
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Search wiki for 'John Wick'"}]}'
Ważne: w pliku websearch/app.ts
można zmienić listę domen, które są dopuszczalne do przeszukiwania i pobierania treści.
Uruchomienie tego przykładu wymaga uzupełnienia pliku .env
i wartości LINEAR_API_KEY
oraz LINEAR_WEBHOOK_SECRET
.
Obie wartości można znaleźć w ustawieniach API. Dodatkowo Twój localhost musi być dostępny z poza Twojej sieci lokalnej, np. za pomocą ngrok. Publiczny adres URL należy także wskazać w panelu Linear w sekcji Webhooks, np.: https://<ngrok-url>/api/linear/watch-issue
(pamiętaj o dodaniu właściwego endpointu do adresu).
WAŻNE: w pliku linear/prompts.ts
znajduje się prompt w którym zostały opisane moje projekty w Linear.
Aby skrypt działał poprawnie, musisz zmodyfikować ten prompt, tak aby zawierał identyfikatory oraz opisy Twoich projektów.
Listę projektów i ich identyfikatory możesz pobrać korzystając z endpointu /api/linear/projects
.
- Uruchomienie serwera:
bun linear
- Pobranie listy projektów:
curl http://localhost:3000/api/linear/projects
- Po dodaniu nowego wpisu w Twoim linearze, zostanie on automatycznie przypisany do projektu zgodnie z zasadami w promptach, o ile nie został przypisany przez Ciebie ręcznie.
- Uruchomienie serwera:
bun files
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hey there, what\'s up?"}], "conversation_id": "d7582176-bc52-4ef3-980a-047b868f9f49"}'
Przykład ten pokazuje mechanizm podejmowania decyzji o zapamiętywaniu informacji na podstawie kontekstu rozmowy.
Dodatkowo w przypadku podania conversation_id
w obiekcie żądania, do rozmowy zostaną wczytane wszystkie wiadomości dotyczące konkretnej rozmowy.
Wszystkie pliki zapisywane są w folderze files/context
, a sam katalog można otworzyć w aplikacji Obsidian aby zobaczyć powiązania pomiędzy wspomnieniami.
Ten przykład wymaga uzupełnienia pliku .env
o wartości LANGFUSE_PUBLIC_KEY
, LANGFUSE_SECRET_KEY
oraz LANGFUSE_HOST
. Można je uzyskać zakładając bezpłatne konto na Langfuse.
UWAGA: Aby uruchomić ten przykład, musisz w panelu Langfuse utworzyć nowy prompt o nazwie Answer
, którego wartość możesz ustawić na np. 'Odpowiadaj pisząc wyłącznie wielkimi literami'.
- Uruchomienie serwera:
bun langfuse
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hey there, what\'s up?"}]}'
Po wykonaniu zapytania, zostanie ono automatycznie zalogowane do Langfuse, a wynik wyświetlony w panelu.
- Uruchomienie serwera:
bun tiktokenizer
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hey there, what\'s up?"}], "model": "gpt-4o"}'
Przykład ten pokazuje mechanizm liczenia tokenów w zapytaniach do modeli OpenAI (np. gpt-4o).
Przykład ten pokazuje jeden mechanizm pozwalający na kontynuowanie wypowiedzi modelu, pomimo osiągnięcia maksymalnej liczby tokenów wyjściowych (output tokens).
- Uruchomienie serwera:
bun max_tokens
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Write ten sentences about apples and put them in order."}]}'
Przykład ten przedstawia mechanizm blokowania zapytań, które nie spełniają warunków określonych w prompcie /constitution/prompts.ts
.
- Uruchomienie serwera:
bun constitution
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Ten przykład po uruchomieniu tworzy katalog memories w którym zapisywane są pliki markdown, pełniące rolę pamięci modelu. Nie jest to przykład nadający się na produkcję, lecz przedstawia ogólne mechaniki pamięci długoterminowej, które będziemy rozwijać w dalszych lekcjach.
- Uruchomienie serwera:
bun memory
- Interakcja:
curl -X POST http://localhost:3000/api/chat \
-H "Content-Type: application/json" \
-d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Ten przykład zawiera standardową logikę interakcji z modelem, ale wymaga podania klucza API w nagłówku Authorization
w formacie Bearer <klucz>
. Wartość klucza zostaje wczytana z pliku .env
jako PERSONAL_API_KEY
. Dodatkowo zostały dodane mechanizmy ograniczania liczby zapytań, więc po kilku próbach ponowne wywołanie zapytania zwróci błąd 429.
- Uruchomienie serwera:
bun external
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
UWAGA: Aby uruchomić ten przykład konieczne jest nawiązanie połączenie z Langfuse poprzez uzupełnienie pliku .env
o wartości LANGFUSE_PUBLIC_KEY
, LANGFUSE_SECRET_KEY
oraz LANGFUSE_HOST
. Dodatkowo na Twoim koncie musisz utworzyć nowy prompt o nazwie Answer
, którego wartość możesz ustawić na np. 'Odpowiadaj pisząc wyłącznie wielkimi literami', aby tylko sprawdzić działanie mechanizmu. Dodatkowo prompt "Answer" należy dodać w ustawieniu "Chat", a nie "Text" (tryb można zmienić z pomocą zakładek w Langfuse)
- Uruchomienie serwera:
bun prompts
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Ten przykład nie dotyczy bezpośrednio działania LLM, lecz przedstawia sposób organizacji informacji w bazie danych, takich jak konwersacje czy historia wiadomości.
- Uruchomienie serwera:
bun database
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
Przykład ten przedstawia absolutnie podstawowe połączenie z bazą wektorową Qdrant. Jego zadaniem jest zapisywanie historii wiadomości, a następnie wyszukiwanie i wczytywanie do kontekstu rozmowy najbardziej podobnych wiadomości. Przykład ten będziemy rozbudowywać w dalszych lekcjach, łącząc się z Qdrant w bardziej złożonych konfiguracjach.
UWAGA: Aby uruchomić ten przykład, musisz w panelu Langfuse utworzyć nowy prompt o nazwie Answer
, którego wartość możesz ustawić na np. 'Odpowiadaj pisząc wyłącznie wielkimi literami'. Powodem jest fakt, że w ten przykład został powiązany z przykładem langfuse
.
- Uruchomienie serwera:
bun qdrant
- Interakcja:
curl -X POST http://localhost:3000/api/chat \ -H "Content-Type: application/json" \ -d '{"messages": [{"role": "user", "content": "Hello!"}]}'
UWAGA: Ten przykład wymaga uruchomienia frontendu w folderze audio-frontend
oraz backendu w folderze audio-backend
. W związku z tym przykład trzeba uruchomić na własnym komputerze.
- Uruchomienie frontendu:
bun audio:dev
- Uruchomienie backendu:
bun audio
- Interakcja: Otwórz w przeglądarce stronę http://localhost:5173
WAŻNE: Jakość działania tego przykładu zależy głównie od jakości mikrofonu oraz dźwięków otoczenia. Upewnij się więc, że jakość nagrania jest dobra i że nie ma zakłóceń uniemożliwiających wykrywanie końca wypowiedzi.
- Uruchomienie kodu:
bun vision
- Uruchomienie kodu:
bun recognize
Do uruchomienia tego przykładu należy uzupełnić plik .env
o wartość MISTRAL_API_KEY
. Można go pobrać tutaj na Mistral.ai
- Uruchomienie kodu:
bun recognize_pixtral
- Uruchomienie kodu:
bun vision
- Interakcja: przykład wykonuje się automatycznie na pliku
vision/lessons.png
- Uruchomienie kodu:
bun recognize
- Interakcja: przykład wykonuje się automatycznie na plikach z katalogu
recognize/avatars
- Uruchomienie kodu:
bun recognize_pixtral
- Interakcja: przykład wykonuje się automatycznie na plikach z katalogu
recognize_pixtral/avatars
--- brak przykładów ---
- Uruchomienie kodu:
bun captions
- Interakcja: przykład wykonuje się automatycznie na pliku
captions/article.md
- Uruchomienie kodu:
bun summary
- Interakcja: skrypt wykonuje się automatycznie na pliku
summary/article.md
Do uruchomienia tego przykładu należy uzupełnić plik .env
o wartość GOOGLE_AI_STUDIO_API_KEY
, który można pobrać z Google AI Studio.
- Uruchomienie kodu:
bun video
- Interakcja: przykład wykonuje się automatycznie na pliku
video/test.mp3
UWAGA: Ten przykład może zużywać duże ilości kredytów na ElevenLabs, więc jeśli chcesz zobaczyć rezultat jego działania, to w katalogu narration
znajdują się dwa przykładowe pliki audio, które możesz odtworzyć bez uruchamiania kodu.
Do uruchomienia tego przykładu należy uzupełnić plik .env
o wartość GOOGLE_AI_STUDIO_API_KEY
, który można pobrać z Google AI Studio oraz ELEVEN_LABS_API_KEY
, który można pobrać z ElevenLabs.
- Uruchomienie kodu:
bun narration
- Interakcja: przykład wykonuje się automatycznie na treści wiadomości użytkownika przekazanej w funkcji
generateNarration
w plikunarration/app.ts
- Uruchomienie kodu:
bun read
- Interakcja: przykład wykonuje się automatycznie na pliku
read/article.md
i generuje plik audio w folderze read/summary.wav
Ten przykład wymaga uruchomienia frontendu w folderze audio-map-frontend
oraz backendu w folderze audio-map
. W związku z tym przykład trzeba uruchomić na własnym komputerze.
- Uruchomienie frontendu:
bun map:dev
- Uruchomienie backendu:
bun audio-map
- Interakcja: Otwórz w przeglądarce stronę http://localhost:5173
- Uruchomienie kodu:
bun notes
- Interakcja: przykład wykonuje się automatycznie na wiadomości wpisanej w treść pliku
notes/app.ts
(jest tam kilka przykładów innych wiadomości, które można podmienić).
- Uruchomienie kodu:
bun text-splitter
- Interakcja: przykład wykonuje się automatycznie na plikach markdown z katalogu "text-splitter"
- Uruchomienie kodu:
bun unstructured
- Interakcja: przykład wykonuje się automatycznie na pliku source.md z katalogu "unstructured"
Uruchomienie tego przykładu wymaga uzupełnienia pliku .env
o wartości "QDRANT_URL" oraz "QDRANT_API_KEY".
Wartości te można znaleźć w panelu Qdrant po zalogowaniu na bezpłatne konto na stronie Qdrant Cloud.
Natomiast klucz API można pobrać w zakładce "Data Access Control".
- Uruchomienie kodu:
bun embedding
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku embedding/app.ts
- Uruchomienie kodu:
bun rerank
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku rerank/app.ts
- Uruchomienie kodu:
bun naive-rag
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku naive-rag/app.ts
- Uruchomienie kodu:
bun better-rag
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku better-rag/app.ts
- Uruchomienie kodu:
bun semantic
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku semantic/app.ts
Do uruchomienia tego przykładu konieczne jest uzupełnienie ALGOLIA_APP_ID
oraz ALGOLIA_API_KEY
w pliku .env
.
UWAGA: przy pierwszym uruchomieniu przykładu pojawi się błąd ale spowoduje to utworzenie indeksu w Algolia. Wówczas należy przejść do panelu Algolia i w zakładce "Facets" dodać nowy facet o nazwie author
.
- Uruchomienie kodu:
bun algolia
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku algolia/app.ts
UWAGA: Do uruchomienia tego przykładu konieczne jest uzupełnienie ALGOLIA_APP_ID
oraz ALGOLIA_API_KEY
w pliku .env
.
Wymagane jest bezpłatne konto na Algolia.
Dodatkowo jeśli wyniki wyszukiwania nie są poprawnie zwracane, należy sprawdzić czy pole text
zostało poprawnie ustawione w panelu Algolia jako searchableAttributes
.
- Uruchomienie kodu:
bun sync
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku sync/app.ts
UWAGA: Do uruchomienia tego przykładu konieczne jest uzupełnienie QDRANT_URL
oraz QDRANT_API_KEY
w pliku .env
.
Konieczne jest także połączenie z Algolia podobnie jak w przypadku przykładu sync
.
- Uruchomienie kodu:
bun hybrid
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku hybrid/app.ts
Do uruchomienia tego przykładu konieczne jest połączenie z bazą Neo4j. Można ją zainstalować lokalnie, a następnie uzupełnić plik .env
o wartości NEO4J_URI
, NEO4J_USER
oraz NEO4J_PASSWORD
.
- Uruchomienie kodu:
bun neo4j-101
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku neo4j-101/app.ts
- Uruchomienie kodu:
bun neo4j
- Interakcja: przykład wykonuje się automatycznie na danych osadzonych w pliku neo4j/app.ts