Wróć do katalogu
Season 51 14 Odcinki 55 min 2026

LlamaIndex: Context-Augmented LLM Applications

v0.14 — Edycja 2026. Kompleksowy przewodnik po LlamaIndex, obejmujący Context Augmentation, RAG pipelines, autonomiczne agenty i multi-agent workflows. Dowiedz się, jak budować gotowe na produkcję aplikacje LLM przy użyciu wersji 0.14.

Orkiestracja LLM RAG Frameworki AI/ML
LlamaIndex: Context-Augmented LLM Applications
Teraz odtwarzane
Click play to start
0:00
0:00
1
Imperatyw Context Augmentation
Odkryj podstawowe koncepcje LlamaIndex i dowiedz się, dlaczego modele LLM potrzebują zewnętrznego kontekstu, aby być naprawdę użyteczne. Ten odcinek omawia filozofię stojącą za Retrieval-Augmented Generation, workflows oraz aplikacjami opartymi na agentach.
4m 08s
2
Ingestia danych: Documents i Nodes
Poznaj pierwszą połowę RAG pipeline. Dowiesz się o Connectors, Documents, Nodes oraz o kluczowym procesie indeksowania nieustrukturyzowanych danych do postaci wektorowych embeddings.
4m 24s
3
Query Pipeline: Retrievers i Routers
Zanurz się w drugiej połowie cyklu życia RAG. Dowiedz się, jak Retrievers znajdują odpowiednie fragmenty, jak Routers wybierają najlepsze podejście i jak Postprocessors udoskonalają kontekst dla modelu LLM.
4m 03s
4
Interfejsy dla LLM i wejścia Multi-Modal
Opanuj klasę LLM w LlamaIndex do generowania języka naturalnego. Ten odcinek szczegółowo omawia interfejsy czatu, strumieniowanie odpowiedzi oraz przekazywanie obrazów do modeli wielomodalnych (multi-modal).
3m 43s
5
Ekstrakcja ustrukturyzowanych danych z Pydantic
Dowiedz się, jak zmusić nieprzewidywalne modele LLM do zwracania ścisłych, typowanych danych w formacie JSON. Odkryj, jak Pydantic BaseModels działają jako schematy do ekstrakcji wiarygodnych, ustrukturyzowanych informacji z surowego tekstu.
3m 37s
6
Budowanie autonomicznych Function Agents
Zrób krok naprzód od statycznego kodu do autonomicznych agentów. Dowiesz się, jak opakować funkcje języka Python w narzędzia (tools) i wdrożyć FunctionAgent do dynamicznego wykonywania zadań.
3m 34s
7
Rozszerzanie agentów za pomocą narzędzi LlamaHub
Wzmocnij swoich agentów dzięki gotowym integracjom. Ten odcinek pokazuje, jak przeglądać LlamaHub, instalować specyfikacje narzędzi (tool specs) i błyskawicznie nadawać agentom rzeczywiste możliwości.
4m 20s
8
Roje Multi-Agent z AgentWorkflow
Wyjdź poza konfiguracje z jednym agentem. Dowiedz się, jak skonfigurować liniowy rój wyspecjalizowanych agentów, którzy autonomicznie przekazują sobie zadania za pomocą AgentWorkflow.
3m 54s
9
Wzorzec Orchestrator Agent
Przejmij szczegółową kontrolę nad swoimi agentic workflows. Odkryj, jak zbudować głównego agenta orkiestrującego (orchestrator agent), który zarządza podrzędnymi agentami jako wywoływalnymi narzędziami (callable tools).
4m 05s
10
Niestandardowe Multi-Agent Planners
Osiągnij najwyższą elastyczność w środowisku multi-agent. Dowiedz się, jak stworzyć własną pętlę orkiestracji (orchestration loop), używając niestandardowego XML prompting, Pydantic i imperatywnego wykonywania.
3m 57s
11
Workflows typu Human-in-the-Loop
Zapobiegaj autonomicznym katastrofom, zatrzymując człowieka w pętli decyzyjnej. Dowiesz się, jak wstrzymywać workflows za pomocą zdarzeń, aby poczekać na potwierdzenie od człowieka przed wykonaniem niebezpiecznych zadań.
3m 24s
12
Observability i Tracing
Przestań debugować AI za pomocą instrukcji print. Ten odcinek omawia callbacks w LlamaIndex oraz observability za jednym kliknięciem, aby śledzić wejścia, czas trwania i wyjścia w złożonych pipelines.
4m 10s
13
Metryki ewaluacji RAG
Zmierz prawdziwą skuteczność swoich aplikacji. Dowiedz się, jak używać FaithfulnessEvaluator i RetrieverEvaluator do obiektywnego oceniania jakości wyszukiwania i odpowiedzi.
4m 15s
14
Scaffolding na produkcję
Błyskawicznie przekształcaj prototypy w pełnoprawne aplikacje. Odkryj, jak używać create-llama i RAG CLI do generowania (scaffold) pełnostosowych aplikacji webowych i czatów w terminalu bez pisania powtarzalnego kodu.
4m 14s

Odcinki

1

Imperatyw Context Augmentation

4m 08s

Odkryj podstawowe koncepcje LlamaIndex i dowiedz się, dlaczego modele LLM potrzebują zewnętrznego kontekstu, aby być naprawdę użyteczne. Ten odcinek omawia filozofię stojącą za Retrieval-Augmented Generation, workflows oraz aplikacjami opartymi na agentach.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z context augmentation, odcinek 1 z 14. Modele pre-trained są genialne, ale nie wiedzą absolutnie nic o prywatnych dokumentach, które stworzyłeś dziś rano. Prosisz LLM o podsumowanie twojej nowej prezentacji finansowej za Q3, a on albo zgaduje na ślepo, albo mówi, że nie może ci pomóc. Imperatyw context augmentation to sposób na rozwiązanie tego problemu. Duże modele językowe, czyli LLM-y, posiadają niesamowite możliwości rozumowania, ale ich wiedza jest zamrożona w czasie i ograniczona do publicznych danych. Nie mają dostępu do twoich wewnętrznych wiki, ticketów z supportu ani prywatnych raportów finansowych. LlamaIndex istnieje po to, aby wypełnić dokładnie tę lukę. Służy jako tkanka łączna między modelami fundamentalnymi a twoimi prywatnymi, lokalnymi danymi. Kiedy prosisz model o podsumowanie tej prezentacji za Q3, nie możesz po prostu wysłać pytania. Potrzebujesz systemu, który znajdzie odpowiednie slajdy, wyciągnie tekst i przekaże te konkretne informacje do modelu razem z twoim promptem. Ten proces to context augmentation. Dajesz modelowi dokładny kontekst, którego potrzebuje, aby zastosować swoje umiejętności wnioskowania na twoich prywatnych danych. LlamaIndex zapewnia infrastrukturę do ingestowania, organizowania i wyszukiwania twoich danych, dzięki czemu context augmentation działa niezawodnie. Pobieranie tekstu i odpowiadanie na pojedyncze pytanie to tylko podstawa. Nowoczesne aplikacje wymagają większej autonomii. To prowadzi nas do aplikacji agentowych. Aplikacja agentowa nie idzie po prostu po linii prostej od pytania, przez bazę danych, aż do odpowiedzi. Po drodze podejmuje decyzje, żeby obsłużyć złożone intencje użytkownika. Pierwszym elementem jest routing. Kiedy użytkownik zadaje pytanie, system musi zdecydować, które źródło danych lub narzędzie będzie odpowiednie. Jeśli użytkownik prosi o ogólne podsumowanie firmy, router kieruje zapytanie do indeksu prezentacji za Q3. Jeśli użytkownik prosi o dokładne rozbicie liczbowe sprzedaży regionalnej, router może zamiast tego wysłać zapytanie do ustrukturyzowanej bazy danych SQL. Routing zapewnia, że model użyje odpowiedniego narzędzia do danego zadania na podstawie inputu. Drugim elementem jest prompt chaining. Złożone zadania często kończą się błędem, gdy prosisz model o obsłużenie ich w jednym, ogromnym prompcie. Prompt chaining dzieli złożony cel na mniejsze, sekwencyjne zadania. System może uruchomić jeden prompt, żeby wyciągnąć dane o przychodach z prezentacji, przekazać te liczby do drugiego promptu, który porówna je z danymi historycznymi, i wysłać ten output do trzeciego promptu, który przygotuje podsumowanie. Output z jednego kroku staje się dokładnym kontekstem dla następnego kroku. I tu robi się ciekawie. Nawet przy odpowiednich danych i ustrukturyzowanym chainie, modele popełniają błędy. Tutaj wkracza reflection. Reflection to zautomatyzowany etap kontroli jakości. Przed dostarczeniem użytkownikowi ostatecznego podsumowania prezentacji za Q3, aplikacja agentowa używa oddzielnego promptu do oceny własnego draftu. Sprawdza, czy wygenerowany tekst ma pełne poparcie w pobranych slajdach. Jeśli krok reflection wykryje halucynację albo pominiętą kluczową metrykę, odrzuca draft i uruchamia korektę. Prawdziwa moc aplikacji z context augmentation to nie tylko danie LLM-owi dokumentu do przeczytania, ale zapewnienie mu ustrukturyzowanego, samokorygującego się workflow, żeby mógł bezpiecznie wnioskować na twoich prywatnych danych. Jeśli chcesz pomóc nam tworzyć ten podcast, wyszukaj DevStoriesEU na Patreonie i wesprzyj nas tam. To wszystko w tym odcinku. Dzięki za wysłuchanie i kodujcie dalej!
2

Ingestia danych: Documents i Nodes

4m 24s

Poznaj pierwszą połowę RAG pipeline. Dowiesz się o Connectors, Documents, Nodes oraz o kluczowym procesie indeksowania nieustrukturyzowanych danych do postaci wektorowych embeddings.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 2 z 14. Nie możesz po prostu wcisnąć 500-stronicowego PDF-a w context window LLM-a i oczekiwać precyzyjnej odpowiedzi. Model straci wątek, zacznie halucynować albo po prostu odrzuci payload za przekroczenie limitów. Żeby ogromne pliki stały się użyteczne, musisz je rozbić na drobne kawałki i przetłumaczyć na format matematyczny, który maszyna potrafi przeszukać. I właśnie ten proces omawiamy dzisiaj w odcinku Data Ingestion: Documents and Nodes. Wyobraź sobie przetwarzanie wielkiego podręcznika dla pracowników HR. Tekst siedzi w gigantycznym PDF-ie, który ciągnie się przez dziesiątki złożonych rozdziałów. Pierwszym krokiem w pipeline Retrieval-Augmented Generation jest etap ładowania. To właśnie tutaj do gry wkraczają Data Connectors, często nazywane Readers. Taki connector bierze twoje surowe źródło danych — niezależnie od tego, czy jest to lokalny PDF, zdalna tabela w bazie danych, czy odpowiedź z zewnętrznego API — i opakowuje je w strukturę danych zwaną Document. Ludzie często mylą się przy tym pojęciu. W tym frameworku Document nie oznacza pliku Worda ani PDF-a. Document to po prostu generyczny kontener na dowolne wczytane źródło danych. Przechowuje surowy tekst wraz z kilkoma podstawowymi właściwościami. Jednak pojedynczy Document reprezentujący 500-stronicowy podręcznik jest całkowicie bezużyteczny do precyzyjnego i szybkiego wyszukiwania. Musisz go rozbić na mniejsze części. I tak dochodzimy do Nodes. Node to tak naprawdę atomowa jednostka danych w LlamaIndex. To mniejszy, łatwiejszy w zarządzaniu chunk nadrzędnego Documentu — na przykład pojedynczy akapit szczegółowo opisujący zasady urlopów rodzicielskich. Kiedy przetwarzasz podręcznik HR, framework bierze ten ogromny Document i tnie go na tysiące Nodes. I tu pojawia się kluczowa kwestia. Nodes nie przechowują tylko wyizolowanego tekstu. Niosą ze sobą bogate metadane i relacje strukturalne. Node dokładnie wie, z jakiego nadrzędnego Documentu pochodzi. Wie również, który Node logicznie go poprzedza, a który po nim następuje. Ta powiązana struktura to coś, co pozwala systemowi na późniejszą syntezę szerszego kontekstu, jeśli pojedynczy chunk nie zawiera całej odpowiedzi. Kiedy już posiekasz swoje dane na precyzyjne Nodes, przechodzisz do etapu indeksowania. Potrzebujesz solidnego sposobu na znalezienie właściwego Node'a, gdy użytkownik zada później pytanie. To wymaga przetłumaczenia ludzkiego języka na format numeryczny zwany embeddingiem. Embedding to tablica liczb zmiennoprzecinkowych reprezentująca semantyczne znaczenie tekstu wewnątrz Node'a. Przepuszczasz każdego Node'a przez model embeddingowy. Model odczytuje taki chunk i zwraca wielowymiarowy wektor. Jeśli dwa Nodes omawiają koncepcyjnie podobne tematy — jak zwolnienie lekarskie i płatny urlop — ich wektory numeryczne będą znajdować się matematycznie blisko siebie w przestrzeni. Mając wygenerowane te wektory, konstruujesz Index. Index to główny komponent strukturalny, który organizuje twoje Nodes, aby można było je odpytywać. W większości aplikacji ten Index jest oparty na Vector Store. Vector Store działa jak wyspecjalizowana baza danych, zaprojektowana specjalnie do przechowywania tych matematycznych reprezentacji i wykonywania na nich wysoce wydajnych obliczeń podobieństwa. Logiczny flow jest bardzo przewidywalny. Najpierw konfigurujesz data connector, żeby wskazywał na twój podręcznik HR. Connector odczytuje plik i zwraca pojedynczy obiekt Document. Następnie parser bierze ten Document i dzieli go na tablicę niezależnych obiektów Node. Na koniec przekazujesz tę tablicę Nodes do Indexu, który koordynuje tworzenie wektorowych embeddingów i zapisuje je w Vector Store. Cały ten ingestion pipeline istnieje po to, aby rozwiązać jedno fundamentalne ograniczenie. Duże modele językowe nie potrafią niezawodnie czytać całych książek naraz, ale potrafią błyskawicznie obliczyć matematyczną odległość między dwiema tablicami liczb. Tłumaczenie twoich surowych plików na Documents, cięcie ich na powiązane Nodes i kodowanie w wektorowych Indexach to coś, co wypełnia tę lukę. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórzcie dalej!
3

Query Pipeline: Retrievers i Routers

4m 03s

Zanurz się w drugiej połowie cyklu życia RAG. Dowiedz się, jak Retrievers znajdują odpowiednie fragmenty, jak Routers wybierają najlepsze podejście i jak Postprocessors udoskonalają kontekst dla modelu LLM.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Context-Augmented LLM Applications, odcinek 3 z 14. Pobierasz odpowiedni chunk dokumentu, wysyłasz go do modelu językowego i nadal dostajesz złą odpowiedź, bo była przykryta dziesięcioma nieistotnymi chunkami. Znalezienie tekstu to dopiero połowa sukcesu. Filtrowanie, ranking i decydowanie o tym, jak w ogóle go pobrać, to moment, w którym system tak naprawdę odnosi sukces albo ponosi porażkę. Dzisiaj przyjrzymy się fazie egzekucji RAG, a konkretnie The Query Pipeline: Retrievers and Routers. Na tym etapie twoje dane są już załadowane i zindeksowane. Użytkownik wysyła query. Pierwszym komponentem, który przechwytuje to query, jest często router. Router to silnik decyzyjny. Analizuje przychodzące pytanie i określa, który tool lub index pod spodem najlepiej nadaje się do udzielenia na nie odpowiedzi. Załóżmy, że użytkownik zadaje złożone pytanie o konkretne wydarzenie historyczne, które zawiera też bardzo specyficzne akronimy. Standardowy vector search może uchwycić semantyczne znaczenie wydarzenia, ale pominąć akronimy. Keyword search idealnie trafi w akronimy, ale pominie szerszy kontekst. Router ewaluuje query i decyduje się wysłać je dwiema ścieżkami jednocześnie. Routuje request zarówno do vector searcha, jak i keyword searcha. To prowadzi nas do retrieverów. Retriever odpowiada za dokładne zdefiniowanie, jak pobrać odpowiedni kontekst z indexu. Nie generuje odpowiedzi. Pobiera tylko dane. Wracając do naszego scenariusza, vector retriever konwertuje query użytkownika na embedding i wyciąga najbardziej matematycznie podobne node'y, które są po prostu chunkami twoich dokumentów źródłowych. W tym samym czasie keyword retriever wyciąga node'y, które zawierają dokładne dopasowania tekstowe dla tych akronimów. Masz teraz dwa oddzielne stosy node'ów. Nie możesz po prostu w ciemno dokleić ich wszystkich do promptu twojego modelu językowego. Context windows są ograniczone, a modele łatwo rozpraszają się nieistotnymi danymi. I tutaj do akcji wkraczają node postprocessory. Oto kluczowa kwestia. Node postprocessory działają jak strażnik między retrieverami a modelem językowym. Aplikują transformacje, filtrowanie lub logikę re-rankingu do pobranych node'ów. Na przykład, postprocessor może wymusić similarity cutoff, odrzucając wszystkie node'y, które uzyskały wynik poniżej określonego progu. Może zdeduplikować node'y, jeśli vector search i keyword search przypadkiem pobrały dokładnie ten sam akapit. Może też zrobić re-ranking pozostałych node'ów, tak aby absolutnie najbardziej trafny chunk znalazł się na samej górze context window. Kiedy postprocessor oczyści i uporządkuje dane, system przekazuje je do response synthesizera. Synthesizer ma jedno zadanie. Bierze dopracowaną listę node'ów i oryginalne query użytkownika, łączy je w ustrukturyzowany prompt i wysyła do modelu językowego. Następnie model językowy generuje ostateczną, czytelną dla człowieka odpowiedź, opierając się wyłącznie na dostarczonym kontekście. Faza egzekucji query to stricte pipeline. Routujesz query, pobierasz surowe node'y, filtrujesz i rankujesz te node'y za pomocą postprocessora, a na koniec syntetyzujesz tekst. Jeśli kontrolujesz to, co widzi model językowy, kontrolujesz jakość outputu. Dzięki za spędzenie ze mną tych kilku minut. Do usłyszenia następnym razem, trzymaj się.
4

Interfejsy dla LLM i wejścia Multi-Modal

3m 43s

Opanuj klasę LLM w LlamaIndex do generowania języka naturalnego. Ten odcinek szczegółowo omawia interfejsy czatu, strumieniowanie odpowiedzi oraz przekazywanie obrazów do modeli wielomodalnych (multi-modal).

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 4 z 14. Tworzysz agenta, który obsługuje tickety IT, ale połowa zgłoszeń to po prostu zdjęcia ze smartfona pokazujące migające kontrolki błędów. Przetwarzanie tylko tekstu zmusza cię do budowania oddzielnych pipeline'ów wizyjnych albo całkowitego porzucenia kontekstu wizualnego. Dzisiaj omówimy komunikację z LLM-ami i multimodalne inputy, co rozwiązuje ten problem bezpośrednio w warstwie modelu. W LlamaIndex interakcja z modelem językowym przechodzi przez bazową klasę LLM. Działa ona jako ujednolicony interfejs. Niezależnie od tego, czy wywołujesz model OpenAI, model od Anthropic, czy innego providera, podstawowe metody, których używasz, są identyczne. Ta abstrakcja chroni logikę twojej aplikacji przed zmianami w API specyficznymi dla danego providera. Kiedy chcesz uzyskać odpowiedź od modelu, wybierasz między dwiema głównymi metodami. Pierwsza z nich to metoda complete. Przekazujesz do niej pojedynczy string zawierający twój prompt, a ona zwraca pojedynczą odpowiedź tekstową. Jest to stworzone do prostych zadań typu single-shot, takich jak podsumowanie dokumentu czy wyciągnięcie konkretnego faktu. Drugą metodą jest metoda chat. Jest ona zaprojektowana do konwersacji lub ustrukturyzowanych interakcji. Zamiast pojedynczego stringa, przekazujesz listę obiektów chat message. Każda wiadomość ma przypisaną konkretną rolę, zazwyczaj system, user lub assistant. Przekazując listę, metoda chat daje modelowi pełny kontekst wymiany wiadomości przed wygenerowaniem kolejnej odpowiedzi. Zarówno complete, jak i chat czekają, aż model zakończy całe generowanie, zanim zwrócą output. Jeśli model generuje długą odpowiedź, twoja aplikacja pozostaje bezczynna. Aby to naprawić, używasz streamingu. Zamiast tego wywołujesz stream complete lub stream chat. Te metody zwracają generator. Kiedy model produkuje tokeny, twój kod otrzymuje je w małych chunkach. Iterujesz po tym generatorze, aby wyświetlać odpowiedź w UI w czasie rzeczywistym, eliminując poczucie opóźnienia. Druga kwestia to obsługa danych nietekstowych. Tu robi się ciekawie. Nowoczesne LLM-y analizują informacje wizualne, a LlamaIndex wspiera to za pomocą content blocków. Zamiast przekazywać zwykły string wewnątrz user chat message, możesz przekazać listę blocków. Wróćmy do ticketa IT z zepsutą szafą serwerową. Potrzebujesz, żeby model spojrzał na zdjęcie i przeczytał twoje instrukcje diagnostyczne. Najpierw tworzysz ImageBlock. Przekazujesz do tego blocka dane obrazu. LlamaIndex pozwala ci przekazać lokalną ścieżkę do pliku, bezpośredni URL lub surowe bajty zakodowane w base64. Następnie tworzysz TextBlock. Przekazujesz mu swój tekstowy prompt, prosząc model o zidentyfikowanie usterki sprzętowej pokazanej na zdjęciu. Umieszczasz zarówno ImageBlock, jak i TextBlock w jednej liście, a następnie dołączasz tę listę do nowego user chat message. Kiedy przekażesz tę wiadomość do metody chat modelu z obsługą vision, LLM przetworzy wizualny układ szafy serwerowej wraz z twoimi instrukcjami tekstowymi. Zwróci diagnozę na podstawie obu połączonych inputów. Oto kluczowy wniosek. Prawdziwą siłą tej architektury jest jej spójność. Niezależnie od tego, czy wysyłasz jednolinijkowego stringa, streamujesz odpowiedź w czasie rzeczywistym, czy przekazujesz złożoną tablicę text i image blocków, wzorzec interakcji z klasą LLM pozostaje całkowicie ustandaryzowany w całym twoim codebase'ie. To tyle w tym odcinku. Do usłyszenia następnym razem!
5

Ekstrakcja ustrukturyzowanych danych z Pydantic

3m 37s

Dowiedz się, jak zmusić nieprzewidywalne modele LLM do zwracania ścisłych, typowanych danych w formacie JSON. Odkryj, jak Pydantic BaseModels działają jako schematy do ekstrakcji wiarygodnych, ustrukturyzowanych informacji z surowego tekstu.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 5 z 14. Nic nie wywala produkcyjnego pipeline'u szybciej niż LLM, który postanowi dodać „Jasne, oto twój JSON” tuż przed właściwym payloadem danych. Prosisz o machine-readable output, dostajesz conversational filler, a twój parser natychmiast się wywala. Połączenie nieustrukturyzowanego języka naturalnego z niezawodnymi typami programistycznymi to dokładnie to, co rozwiązuje Structured Data Extraction przy użyciu biblioteki Pydantic. Weźmy scenariusz parsowania zabałaganionej skrzynki mailowej, pełnej wiadomości od dostawców, przypomnień o płatnościach i nieustrukturyzowanych paragonów. Twój system musi wyciągnąć z tego tekstu ustrukturyzowane dane faktur. Jeśli polegasz na standardowym text generation, dostajesz nieprzewidywalne rezultaty. Jedna odpowiedź może użyć camel case dla kluczy, inna inaczej sformatuje daty, a ceny często wracają jako stringi z doklejonymi symbolami walut. W efekcie piszesz w nieskończoność logikę do manipulacji na stringach, tylko po to, żeby wyciągnąć z odpowiedzi użyteczną liczbę. Zamiast prosić model o JSON i mieć nadzieję, że się posłucha, definiujesz swoje dokładne wymagania za pomocą base modelu Pydantic. Tworzysz klasę w Pythonie o nazwie Invoice. Wewnątrz tej klasy deklarujesz dokładne typy danych, jakich oczekuje twoja aplikacja. Definiujesz datę jako string, zakupione produkty jako listę stringów, a cenę całkowitą ściśle jako float. I tu pojawia się kluczowa kwestia. LlamaIndex bierze twoją klasę Pydantic i automatycznie serializuje ją do ścisłego JSON schema. Kiedy wysyłasz tekst maila do modelu, LlamaIndex dołącza ten schemat i odpala structured output lub function-calling API bazowego modelu. Schemat działa jak sztywna granica. LLM nie generuje już tekstu typu freeform. Jest zmuszony do wypełnienia pól w JSON schema dokładnie takimi typami, jakich zażądałeś. Możesz również sterować rozumowaniem modelu bezpośrednio w swoich strukturach danych. Dodając field description do atrybutu, dajesz LLM-owi precyzyjne instrukcje. Dla atrybutu price możesz dodać field description mówiący, żeby wyciągnąć ostateczny koszt całkowity, ignorując koszty wysyłki. LLM czyta ten opis jako część schema definition i stosuje tę logikę podczas fazy ekstrakcji. Kiedy wraca odpowiedź, LlamaIndex nie daje ci raw stringa ani generycznego dictionary. Przetwarza odpowiedź przez Pydantic i zwraca w pełni zinstancjonowany obiekt Invoice. Dane są już zwalidowane. Ponieważ framework wykorzystuje natywne funkcje structured output, model z góry wie, że musi dostarczyć prawdziwego floata dla ceny, a nie jego reprezentację w postaci stringa. Możesz natychmiast odwołać się do atrybutu invoice dot price w swoim kodzie i wykonywać na nim operacje matematyczne. Nie ma potrzeby wycinania conversational filler, usuwania znaków dolara ani castowania stringów na liczby. Przejście z języka naturalnego do logiki aplikacji odbywa się płynnie w warstwie ekstrakcji. Wpychając swoje data schema bezpośrednio w proces ekstrakcji, zmuszasz LLM do dostosowania się do twojego kodu aplikacji, zamiast pisać kruchy kod, który ma tolerować nieprzewidywalne zachowanie LLM-a. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
6

Budowanie autonomicznych Function Agents

3m 34s

Zrób krok naprzód od statycznego kodu do autonomicznych agentów. Dowiesz się, jak opakować funkcje języka Python w narzędzia (tools) i wdrożyć FunctionAgent do dynamicznego wykonywania zadań.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 6 z 14. Co by było, gdyby twoja aplikacja mogła decydować, które funkcje uruchomić na podstawie intencji użytkownika, a nie sztywnego zestawu instrukcji warunkowych? To główna idea stojąca za budowaniem autonomicznych agentów funkcji. Tworząc standardowy query pipeline, dyktujesz ścieżkę wykonania. Agent odwraca ten paradygmat. Dostarczasz zestaw toolsów, a zautomatyzowany silnik wnioskowania wykorzystuje duży model językowy, aby zdecydować, które toolsy wywołać i w jakiej kolejności, aby rozwiązać problem. Zanim przejdziemy dalej, musimy wyjaśnić pewne powszechne nieporozumienie. Sam LLM nie wykonuje twojego kodu w Pythonie. Generuje jedynie ustrukturyzowane żądanie tekstowe, informując, że chce wywołać konkretną funkcję z konkretnymi argumentami. Framework agenta LlamaIndex przechwytuje to żądanie, wykonuje twój lokalny kod w Pythonie, a następnie przekazuje wynik z powrotem do LLM-a. Aby ten autonomiczny routing zadziałał, potrzebujesz toolsów. Tool to w zasadzie standardowa funkcja w Pythonie opakowana w klasę LlamaIndex o nazwie FunctionTool. Ale ponieważ LLM musi wiedzieć, kiedy i jak użyć twojej funkcji, metadane twojego kodu stają się kluczową częścią systemu. Framework wyodrębnia nazwę funkcji, type hinty oraz docstring i przekazuje je do LLM-a jako instrukcje. Przyjrzyjmy się konkretnemu scenariuszowi. Chcesz, aby twój agent rozwiązywał matematyczne zadania tekstowe. Piszesz dwie funkcje w Pythonie, jedną o nazwie add, a drugą o nazwie multiply. Dla funkcji multiply, twoje type hinty określają, że przyjmuje ona dwie liczby całkowite i zwraca liczbę całkowitą. Co kluczowe, piszesz docstring, który jasno mówi, że ta funkcja mnoży przez siebie dwie liczby. Opakowujesz obie funkcje w toolsy i przekazujesz je w liście, razem z wybranym LLM-em, aby zainicjować agenta. Tutaj robi się ciekawie. Pytasz agenta, ile to jest dwa plus dwa, pomnożone przez trzy. Agent wchodzi w pętlę wnioskowania. Najpierw LLM analizuje prompt i sprawdza dostępne toolsy. Czyta twoje docstringi i decyduje, że najpierw musi wykonać dodawanie. Zwraca żądanie wywołania toola add z argumentami dwa i dwa. Framework uruchamia twoją funkcję w Pythonie lokalnie i zwraca wynik, cztery, z powrotem do agenta. Agent jeszcze nie skończył. Patrzy na wynik pośredni i swój pierwotny cel. Decyduje, że teraz musi wykonać mnożenie. Żąda toola multiply, przekazując czwórkę, którą właśnie otrzymał, oraz trójkę z twojego oryginalnego promptu. Framework wykonuje mnożenie i zwraca dwanaście. Na koniec LLM rozpoznaje, że problem został rozwiązany i generuje konwersacyjną odpowiedź dla użytkownika. Nie ma tu żadnych hardcodowanych reguł ani jawnej logiki routingu. Agent samodzielnie rozpracował zależności i kolejność operacji, bazując wyłącznie na dostępnych toolsach. Oznacza to, że sposób, w jaki piszesz swoje definicje w Pythonie, bezpośrednio dyktuje to, jak mądry jest twój agent. Twoje type hinty i docstringi nie są już tylko dla innych programistów, są dosłownym promptem, który napędza autonomiczną logikę agenta. Jeśli te odcinki są dla ciebie wartościowe i chcesz wesprzeć podcast, możesz wyszukać DevStoriesEU na Patreonie. To wszystko w tym odcinku. Dzięki za wysłuchanie i twórz dalej!
7

Rozszerzanie agentów za pomocą narzędzi LlamaHub

4m 20s

Wzmocnij swoich agentów dzięki gotowym integracjom. Ten odcinek pokazuje, jak przeglądać LlamaHub, instalować specyfikacje narzędzi (tool specs) i błyskawicznie nadawać agentom rzeczywiste możliwości.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Context-Augmented LLM Applications, odcinek 7 z 14. Budujesz agenta, który musi sprawdzać ceny akcji, pobierać wiadomości ze Slacka lub odpytywać bazę danych. Możesz spędzić dni na czytaniu dokumentacji API, obsłudze schematów autentykacji i pisaniu boilerplate'owego kodu integracyjnego. Albo możesz po prostu wziąć gotowe rozwiązanie, które inny deweloper ze społeczności już napisał i zweryfikował. W tym odcinku omówimy rozszerzanie agentów za pomocą LlamaHub Tools. Agenci wykorzystują toolsy do interakcji ze światem zewnętrznym. Choć każdą integrację możesz napisać ręcznie, LlamaHub istnieje właśnie po to, by wyeliminować tę powtarzalną pracę. Działa jako ogromny, open-source'owy rejestr gotowych tool specs. Tool specification, czyli tool spec, to w zasadzie klasa w Pythonie, która grupuje wiele powiązanych wywołań API w jeden package. Zaciągając je bezpośrednio do swojego projektu, omijasz cały proces pisania logiki pod spodem dla zewnętrznych serwisów. Aby użyć jednej z tych integracji, instalujesz jej konkretny package. Jeśli chcesz, żeby twój agent odpowiadał na pytania o ceny akcji firmy, nie piszesz customowego requestu HTTP do API Yahoo. Zamiast tego używasz swojego standardowego package managera, żeby zainstalować package LlamaIndex Yahoo Finance. Po instalacji, importujesz klasę Yahoo Finance Tool Spec do swojego skryptu. I tu jest kluczowa sprawa. Nie przekazujesz klasy tool spec bezpośrednio do agenta. Ponieważ tool spec to zbiór wielu możliwości, musisz go najpierw rozpakować. Robisz to, tworząc instancję Yahoo Finance Tool Spec, a następnie wywołując na niej konkretną metodę o nazwie to_tool_list. Ta metoda rozbija ten zbiór i zwraca standardową, płaską tablicę pojedynczych toolsów, które agent może odczytać i wykonać. Taki modułowy design oznacza, że nie ograniczasz się do używania tylko zewnętrznych lub tylko wewnętrznych toolsów. Możesz je płynnie łączyć. Załóżmy, że masz już lokalny, customowy function tool, który formatuje kwoty walut specjalnie pod wewnętrzny dashboard twojej firmy. Po prostu tworzysz standardową listę w Pythonie. Wewnątrz tej listy umieszczasz swój customowy tool do formatowania walut, a także dorzucasz rozpakowane toolsy z listy toolsów Yahoo Finance. Następnie bierzesz tę połączoną tablicę i przekazujesz ją bezpośrednio do agenta podczas inicjalizacji, przypisując ją do parametru tools. Kiedy wysyłasz do agenta prompt z pytaniem o aktualną cenę akcji, agent ocenia request użytkownika na podstawie opisów wszystkich toolsów z tej połączonej listy. Rozpoznaje, że tool Yahoo Finance to właściwy wybór do pobrania danych rynkowych. Wyciąga ticker firmy z promptu użytkownika, wykonuje tool Yahoo Finance, pobiera cenę w czasie rzeczywistym, a następnie opcjonalnie może zchainować ten surowy wynik do twojego lokalnego toola formatującego, zanim zwróci ostateczną odpowiedź użytkownikowi. Właśnie dodałeś do swojej aplikacji zaawansowane możliwości wyszukiwania danych finansowych, instalując package, tworząc instancję klasy i wywołując jedną metodę rozpakowującą. Ten wzorzec architektoniczny ma zastosowanie do setek integracji na LlamaHub, od czytania dokumentów z Google Drive po odpytywanie Wikipedii. Prawdziwa siła autonomicznego agenta nie tkwi wyłącznie w możliwościach wnioskowania modelu językowego pod spodem, ale w ogromnej liczbie zewnętrznych systemów, do których może on natychmiast uzyskać dostęp poprzez gotowe tool specs. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
8

Roje Multi-Agent z AgentWorkflow

3m 54s

Wyjdź poza konfiguracje z jednym agentem. Dowiedz się, jak skonfigurować liniowy rój wyspecjalizowanych agentów, którzy autonomicznie przekazują sobie zadania za pomocą AgentWorkflow.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 8 z 14. Wrzucasz do modelu językowego jeden ogromny prompt, prosząc go o zbadanie tematu, napisanie raportu i krytyczną ocenę własnej pracy. To nie działa. Context window się sypie, tools są źle używane, a output to płytki kompromis. Rozwiązaniem jest rozbicie tego ogromnego promptu na rój specjalistów, używając Multi-Agent Swarms z AgentWorkflow. Pojedynczy, przeładowany agent sobie nie radzi, ponieważ ma zbyt wiele tools i sprzeczne instrukcje. Musi decydować, kiedy szukać, kiedy pisać draft, a kiedy edytować, i to wszystko zarządzając ogromnym wewnętrznym kontekstem. AgentWorkflow rozwiązuje ten problem, pozwalając ci zdefiniować sieć wysoce wyspecjalizowanych agentów. Każdy agent działa z wąskim system promptem, ograniczonym zestawem tools i jednym, konkretnym celem. Weźmy pod uwagę pipeline do generowania treści. Zamiast jednego mega-agenta, tworzymy trzech oddzielnych FunctionAgents. Po pierwsze, Researcher. Wyposażamy tego agenta w web search tool i dajemy mu ścisłe instrukcje, żeby tylko zbierał fakty. On nie pisze gotowego tekstu. Następnie definiujemy Writera. Całkowicie zabieramy mu search tools, żeby go nie rozpraszać. Jego jedynym zadaniem jest wzięcie surowych faktów i przygotowanie draftu czystych akapitów. Na koniec definiujemy Reviewera. Dajemy mu wytyczne dotyczące tonu i poprawności faktów, instruując go, aby ocenił tekst. I tu jest kluczowa sprawa. Posiadanie wielu agentów jest bezużyteczne, jeśli nie potrafią się skoordynować, ale danie im wolnej ręki na rozmowę z kimkolwiek tworzy chaos. Musisz ich ze sobą jawnie połączyć. W AgentWorkflow robisz to, definiując handoff permissions. Konfigurując swoich agentów, określasz właściwość o nazwie can handoff to. Przyjmuje ona listę innych agentów. W naszym pipeline dajemy Researcherowi uprawnienie do zrobienia handoffu do Writera. Writerowi dajemy uprawnienie do handoffu do Reviewera. Dajemy też Reviewerowi uprawnienie do handoffu z powrotem do Writera, jeśli tekst wymaga poprawek. To tworzy ścisły, skierowany graf agentów. Framework wymusza te granice. Researcher nie może pominąć Writera i wysłać surowych notatek prosto do Reviewera. Po prostu nie ma do tego autoryzacji. Aby to wykonać, przekazujesz swoją listę agentów do instancji AgentWorkflow. Zaczynasz proces, uruchamiając workflow z początkowym user query, kierując je do Researchera, żeby wystartować. Framework workflow automatycznie zarządza shared state i routingiem. Researcher uruchamia swoje search tools, kompiluje dane i wewnętrznie decyduje, że jego praca jest skończona. Następnie używa swojego handoff tool, aby przekazać kontrolę, wraz z zebranymi danymi, do Writera. Writer bierze ten kontekst, pisze draft raportu i robi handoff do Reviewera. Jeśli Reviewer zauważy błąd, triggeruje handoff z powrotem do Writera z feedbackiem. Ta pętla trwa, dopóki agent nie uzna, że praca jest skończona i nie zwróci finalnej odpowiedzi do usera, zamiast triggerować kolejny handoff. Ograniczenie agenta do jednej roli i jawne zdefiniowanie jego ścieżek komunikacji to najbardziej niezawodny sposób na wymuszenie złożonego, wieloetapowego rozumowania z modeli językowych. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
9

Wzorzec Orchestrator Agent

4m 05s

Przejmij szczegółową kontrolę nad swoimi agentic workflows. Odkryj, jak zbudować głównego agenta orkiestrującego (orchestrator agent), który zarządza podrzędnymi agentami jako wywoływalnymi narzędziami (callable tools).

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 9 z 14. Jeśli pozwolisz autonomicznym agentom przekazywać kontrolę peer-to-peer, łatwo doprowadzisz do nieskończonych pętli lub utraty kontekstu. Czasami nie możesz polegać na tym, że agenci będą przekazywać sobie kontrolę. Potrzebujesz centralnego menedżera zarządzającego całą operacją. To właśnie jest wzorzec Orchestrator Agent. W systemie multi-agentowym, pozwolenie agentom na bezpośrednią komunikację ze sobą brzmi potężnie, ale szybko staje się koszmarem przy debugowaniu. Tracisz orientację, kto ma kontrolę, a zarządzanie global statem aplikacji staje się niezwykle skomplikowane. Wzorzec Orchestratora rozwiązuje ten problem, ściśle wymuszając model hub-and-spoke. Istnieje jeden top-levelowy agent orchestrator, a wszyscy pozostali agenci są traktowani ściśle jako toolsy do wykorzystania przez tego orchestratora. Przeanalizujmy scenariusz, w którym twój system musi wygenerować dobrze zresearchowany briefing techniczny. Konfigurujesz agenta orchestratora, żeby działał jako surowy menedżer. Ten menedżer trzyma global state. Pamięta oryginalny prompt użytkownika, trzyma główny kontekst i śledzi to, co udało się do tej pory osiągnąć. Sam nie wykonuje czarnej roboty. Zamiast tego, dostarczasz mu toolsy. Te toolsy to nie są proste wrappery na API czy zwykłe kalkulatory. To całkowicie oddzielne, w pełni funkcjonalne sub-agenty. Możesz zbudować jednego sub-agenta dedykowanego do researchu, wyposażonego w vector search i web scraping. Możesz zbudować drugiego sub-agenta dedykowanego do pisania, wyposażonego w wytyczne stylistyczne i logikę formatowania. W LlamaIndex bierzesz te sub-agenty i wystawiasz ich metody run jako toolsy. Robiąc to, opakowujesz całe ich wewnętrzne pętle wnioskowania w standardowy tool interface z nazwą i opisem. Dla orchestratora te sub-agenty wyglądają dokładnie tak samo jak standardowe funkcje w Pythonie. Kiedy użytkownik prosi o briefing, orchestrator ocenia ogólny cel na podstawie opisów toolsów, które mu dostarczyłeś. Decyduje się najpierw wywołać tool do researchu i przekazuje niezbędne parametry. Kontrola tymczasowo przechodzi na sub-agenta do researchu. Ten sub-agent uruchamia swoją własną, autonomiczną pętlę. Może wykonać trzy lub cztery wewnętrzne tool calls, żeby zebrać dane, zsyntetyzować fakty i sformułować odpowiedź. Kiedy agent do researchu skończy, zwija całą tę pracę w końcowy string tekstowy i go zwraca. I tu jest kluczowa sprawa. Orchestrator tak naprawdę nigdy nie oddaje kontroli nad głównym procesem. Po prostu czeka, aż tool zwróci wartość. Orchestrator otrzymuje podsumowanie researchu, dodaje je do swojego własnego kontekstu i ocenia kolejny krok. Orientuje się, że informacje muszą zostać spisane w dokumencie, więc wywołuje tool do pisania, przekazując świeży research jako parametr wejściowy. Piszący sub-agent przejmuje kontrolę, robi swoje własne wewnętrzne przetwarzanie i oddaje gotowy tekst. Orchestrator widzi, że ostateczny cel został osiągnięty i dostarcza odpowiedź użytkownikowi. To ścisłe separation of concerns sprawia, że twój system jest wysoce przewidywalny. Agent do researchu nie musi wiedzieć, że agent do pisania w ogóle istnieje. Żaden z sub-agentów nie musi się martwić o przekazywanie kontekstu, formatowanie końcowej odpowiedzi dla użytkownika, ani o decydowanie, kiedy cała robota jest skończona. Orchestrator centralizuje całą high-levelową logikę decyzyjną. Zmuszając sub-agenty do działania wyłącznie jako odizolowane toolsy w pętli centralnego menedżera, możesz budować potężne systemy multi-agentowe, które pozostają całkowicie przewidywalne i łatwe do debugowania. To wszystko na dzisiaj. Do usłyszenia następnym razem!
10

Niestandardowe Multi-Agent Planners

3m 57s

Osiągnij najwyższą elastyczność w środowisku multi-agent. Dowiedz się, jak stworzyć własną pętlę orkiestracji (orchestration loop), używając niestandardowego XML prompting, Pydantic i imperatywnego wykonywania.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM rozszerzone o kontekst, odcinek 10 z 14. Wbudowana orkiestracja agentów sprawdza się świetnie, dopóki twoja logika biznesowa nie zacznie wyglądać jak spaghetti. Kiedy standardowe hand-offy nie są w stanie obsłużyć twoich bardzo specyficznych reguł schedulingu, abstrakcje stają się blokerem. Właśnie wtedy potrzebujesz Custom Multi-Agent Planners. Customowy planner to twoja furtka awaryjna dla power-userów. Pozwala ci zbudować własną pętlę orkiestracji od zera, używając standardowego Workflow z LlamaIndex. Zamiast polegać na gotowym supervisorze, który dyktuje, który agent działa jako następny, kontrolujesz cały proces schedulingu imperatywnie w Pythonie. To ty dyktujesz kolejność wykonywania, routing danych i state management. Proces zazwyczaj zaczyna się w customowej klasie, często nazywanej PlannerWorkflow. Pierwsza faza to planowanie. Kiedy użytkownik wysyła request, twój workflow wysyła prompt do dużego modelu językowego. Ten prompt zawiera query użytkownika i ścisły opis toolsów lub agentów, które masz do dyspozycji. Jawnie instruujesz model językowy, żeby wygenerował plan krok po kroku w mocno ustrukturyzowanym formacie. Na przykład, możesz kazać modelowi opakować każdą akcję w blok XML używając tagów step, albo sformatować ją jako tablicę JSON. Kiedy model odpowie, parsujesz ten ustrukturyzowany output. Używasz biblioteki takiej jak Pydantic, żeby zwalidować XML lub JSON i przekonwertować go na konkretną listę tasków, po której twój kod może iterować. Teraz wchodzisz w fazę egzekucji. Ta część zależy już całkowicie od twojej customowej logiki. Twój workflow iteruje po sparsowanej liście kroków jeden po drugim. Dla każdego kroku sprawdza żądaną akcję. Używasz standardowej logiki warunkowej, żeby zdecydować, co zrobić dalej. Jeśli sparsowany krok określa task typu research, twój kod jawnie wywołuje twojego research agenta. Jeśli kolejny krok wymaga obliczeń, triggerujesz swojego math agenta. I tu jest kluczowa sprawa. Ponieważ sam piszesz pętlę, zachowujesz pełną kontrolę nad statem. Zazwyczaj tworzysz współdzielony słownik kontekstu, który żyje przez cały czas trwania runu twojego workflow. Kiedy twój research agent skończy swój task, twój workflow bierze wynik i zapisuje go bezpośrednio do tego słownika. Kiedy kolejny krok triggeruje math agenta, twoja customowa logika może przekazać mu dokładnie te dane, których potrzebuje, z tego współdzielonego słownika. Nie masz tylko nadziei, że black-boxowy orkiestrator przekaże odpowiednie zmienne. Jawnie mapujesz outputy jednego agenta na inputy następnego. Kiedy pętla zakończy wszystkie kroki w twoim zwalidowanym planie, twój workflow wykonuje końcowe formatowanie i zwraca odpowiedź. Budowanie customowego plannera oznacza, że wymieniasz wygodę rozwiązań out-of-the-box na całkowitą kontrolę. Jeśli agent sfailuje, możesz napisać customową logikę retry dla tego konkretnego kroku. Jeśli krok wymaga zewnętrznej walidacji API, możesz zapauzować pętlę. Piszesz standardowy, imperatywny kod, który tak się składa, że używa modeli językowych jako funkcji. Największą wartością customowego plannera jest przewidywalność. Zmuszając model językowy do wygenerowania sztywnego planu w XML i egzekwując go za pomocą standardowych pętli i słowników w Pythonie, całkowicie eliminujesz zgadywanki związane z black-boxową orkiestracją. To wszystko w tym odcinku. Dzięki za wysłuchanie i keep building!
11

Workflows typu Human-in-the-Loop

3m 24s

Zapobiegaj autonomicznym katastrofom, zatrzymując człowieka w pętli decyzyjnej. Dowiesz się, jak wstrzymywać workflows za pomocą zdarzeń, aby poczekać na potwierdzenie od człowieka przed wykonaniem niebezpiecznych zadań.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 11 z 14. Tworzysz agenta do zarządzania infrastrukturą, a on decyduje, że najlepszym sposobem na rozwiązanie błędu jest usunięcie produkcyjnej bazy danych. Nigdy nie pozwalaj autonomicznemu agentowi na podjęcie destrukcyjnej akcji bez wyraźnego zapytania człowieka o zgodę. Aby temu zapobiec, potrzebujesz workflowów typu Human-in-the-Loop. Human-in-the-loop to mechanizm event-driven, który pauzuje agenta, prosi o zewnętrzny input i wznawia działanie na podstawie odpowiedzi. Zamiast pozwalać agentowi na nieprzerwane działanie w jego cyklu myślenia i akcji, przechwytujesz operacje wysokiego ryzyka. Osiągasz to w LlamaIndex Workflows za pomocą trzech konkretnych komponentów: InputRequiredEvent, metody wait_for_event oraz HumanResponseEvent. Wyobraź sobie niebezpieczny tool zaprojektowany do usuwania zasobów w chmurze. Agent decyduje, że musi użyć tego toola i triggeruje odpowiedni krok workflow. Jeśli tool wykona się natychmiast, zasób zniknie. Zamiast tego, krok workflow przechwytuje wykonanie. Przed usunięciem czegokolwiek, krok tworzy zdarzenie InputRequiredEvent. To zdarzenie niesie ze sobą payload zawierający szczegóły akcji, takie jak nazwa docelowego zasobu oraz prompt z prośbą o potwierdzenie usunięcia. Krok emituje to zdarzenie na zewnątrz, do głównej aplikacji. I tu jest kluczowa sprawa. Krok workflow nie może po prostu tkwić w aktywnej pętli, czekając na odpowiedź. Musisz zawiesić jego stan. Robisz to wywołując wait_for_event w kontekście workflow, określając, że krok nasłuchuje teraz zdarzenia HumanResponseEvent. Ta akcja oddaje kontrolę z powrotem do środowiska. Silnik workflow całkowicie pauzuje krok, zamrażając agenta w jego obecnym stanie, bez zużywania zasobów obliczeniowych podczas oczekiwania. Poza workflow, twoja warstwa aplikacji przechwytuje InputRequiredEvent. Odczytujesz payload i wyświetlasz użytkownikowi prompt z potwierdzeniem w jego interfejsie wiersza poleceń. Człowiek czyta ostrzeżenie i wpisuje tak lub nie. Teraz musisz odpauzować agenta. Twoja aplikacja bierze input od użytkownika i opakowuje go w HumanResponseEvent. Wysyłasz to nowe zdarzenie bezpośrednio z powrotem do działającego silnika workflow. Silnik rozpoznaje typ zdarzenia i kieruje je dokładnie do tego kroku, który został zawieszony. Metoda wait_for_event kończy działanie, zwracając string z odpowiedzią człowieka z powrotem do logiki toola. Tool analizuje odpowiedź. Jeśli człowiek wpisał tak, tool kontynuuje wywołanie API, aby usunąć zasób w chmurze. Jeśli człowiek wpisał nie, tool przerywa usuwanie. W obu przypadkach tool zwraca końcowy komunikat o statusie z powrotem do agenta. Agent przetwarza ten wynik, rozumie, czy akcja zakończyła się sukcesem, czy została zablokowana przez użytkownika, i decyduje o swoim kolejnym ruchu. Używając zdarzeń do pauzowania i wznawiania wykonania, twój agent zachowuje cały swój kontekst rozumowania i pamięć, czekając godzinami, a nawet dniami, aż człowiek podejmie decyzję. To wszystko w tym odcinku. Dzięki za wysłuchanie i koduj dalej!
12

Observability i Tracing

4m 10s

Przestań debugować AI za pomocą instrukcji print. Ten odcinek omawia callbacks w LlamaIndex oraz observability za jednym kliknięciem, aby śledzić wejścia, czas trwania i wyjścia w złożonych pipelines.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 12 z 14. Kiedy autonomiczny agent popełnia błąd, przekopywanie się przez standardowe printy w Pythonie, żeby znaleźć problem, to prawdziwy koszmar. Zadajesz proste pytanie, dostajesz wyhalucynowaną odpowiedź, a standardowy stack trace nie mówi ci absolutnie nic o tym, dlaczego model skłamał. Żeby to naprawić, potrzebujesz sposobu na zajrzenie do tej czarnej skrzynki. W tym odcinku omówimy observability i tracing. Tradycyjne narzędzia do debugowania nie sprawdzają się przy dużych modelach językowych. Stack trace mówi ci, gdzie kod się wysypał, ale błędy LLM-ów są zazwyczaj logiczne. Kod działa idealnie, ale system pobiera zły dokument albo źle interpretuje prompt. Standardowy logging w Pythonie to twoja pierwsza linia obrony. Ustawiając poziom logowania na debug, LlamaIndex wypisuje surowy strumień wszystkiego, co robi. Zobaczysz dokładne prompty wysyłane do modelu językowego i surowe odpowiedzi HTTP. To przydatne, żeby sprawdzić, czy request sieciowy się nie powiódł, ale przy wieloetapowym workflow agenta, czytanie ściany nieustrukturyzowanego tekstu jest strasznie żmudne. I tu pojawia się kluczowa kwestia. Nie potrzebujesz tylko logu zdarzeń; musisz zobaczyć call graph. Potrzebujesz ustrukturyzowanego widoku tego, jak dane przepływają od początkowego query, przez retrievery, do modelu językowego i z powrotem. LlamaIndex ogarnia to za pomocą systemu callbacków. Callbacki to hooki, które odpalają się w określonych momentach cyklu wykonania. Framework dostarcza wbudowane narzędzie o nazwie Llama debug handler. Inicjalizujesz ten handler i podpinasz go do swoich globalnych ustawień. Od tego momentu po cichu nagrywa każdą operację. Powiedzmy, że odpalasz query engine, a on zwraca całkowicie zmyślony fakt. Bez tracingu nie masz pojęcia, czy model wyhalucynował, czy to twoja baza danych podała mu złe informacje. Z podpiętym debug handlerem możesz kazać mu wypisać trace po zakończeniu query. Trace pokazuje dokładną sekwencję zdarzeń. Widzisz początkowe query. Widzisz krok retrievalu. Co najważniejsze, widzisz dokładne text nodes, które retriever wyciągnął z twojego indeksu. Analizujesz te node'y w trace i odkrywasz, że pobrany został nieaktualny dokument. Model językowy nie wyhalucynował; po prostu przeczytał złe dane. Naprawiasz indeks i bug jest rozwiązany. Trace'y w terminalu są świetne do lokalnego developmentu, ale słabo się skalują, gdy masz złożonych agentów wykonujących dziesiątki kroków wnioskowania. Na produkcji LlamaIndex oferuje coś, co nazywa one-click observability. Ustawiając konkretną zmienną środowiskową albo dodając jedną linijkę konfiguracji, możesz przekierować wszystkie te dane z callbacków do dedykowanej platformy observability. Te platformy zasysają dane z trace'ów i generują wizualne dashboardy. Możesz przeklikać się przez wizualne drzewo workflow twojego agenta, sprawdzając dokładne latency, zużycie tokenów i payload dla każdego pojedynczego kroku. Nie musisz ręcznie instrumentować każdej funkcji; natywne callbacki frameworka odwalają całą czarną robotę. Różnica między kruchym prototypem a niezawodną aplikacją na produkcji polega na tym, czy potrafisz dokładnie wyjaśnić, dlaczego system wygenerował konkretną odpowiedź. Jeśli uznałeś to za przydatne i chcesz wesprzeć podcast, poszukaj DevStoriesEU na Patreon. To wszystko w tym odcinku. Dzięki za wysłuchanie i buduj dalej!
13

Metryki ewaluacji RAG

4m 15s

Zmierz prawdziwą skuteczność swoich aplikacji. Dowiedz się, jak używać FaithfulnessEvaluator i RetrieverEvaluator do obiektywnego oceniania jakości wyszukiwania i odpowiedzi.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 13 z 14. Zmieniasz swój embedding model i nagle twoje odpowiedzi wydają się trochę dziwne, ale nie potrafisz dokładnie określić dlaczego. Jeśli tylko oceniasz wyniki na oko, żeby sprawdzić ich jakość, twój pipeline zgaduje w ciemno. Żeby przestać polegać na przeczuciach i zapobiec regresjom na produkcji, potrzebujesz metryk ewaluacji RAG. Zbudowanie aplikacji RAG jest proste, ale sprawienie, żeby była niezawodna, jest trudne. Będziesz ciągle dostrajać rozmiary chunków, prompty i strategie retrievalu. Jeśli przy testowaniu każdej zmiany będziesz polegać na manualnej weryfikacji, to albo spowolnisz development, albo zrobisz deploy z regresjami. Potrzebujesz zautomatyzowanych, obiektywnych pomiarów. Ponieważ RAG składa się z dwóch odrębnych kroków: znalezienia właściwych informacji i wygenerowania na ich podstawie odpowiedzi, musisz ewaluować oba te etapy oddzielnie. Przyjrzyjmy się najpierw generowaniu. To tak zwane Response Evaluation. Główną metryką jest tutaj faithfulness. Celem jest wychwycenie halucynacji. Wierna odpowiedź to taka, w której model językowy opiera się wyłącznie na pobranym kontekście, zamiast wymyślać fakty ze swoich własnych danych z pre-trainingu. W LlamaIndex robisz to za pomocą FaithfulnessEvaluator. To narzędzie pod spodem wykorzystuje model językowy, który pełni rolę sędziego. Inicjalizujesz ewaluator, a następnie przekazujesz mu oryginalne query, tablicę pobranych node'ów kontekstu i ostatecznie wygenerowany tekst. Ewaluator zwraca obiekt ewaluacji zawierający boolean typu pass lub fail, który mówi ci, czy odpowiedź ma ścisłe poparcie w dostarczonym kontekście. Zwraca również string z uzasadnieniem, wyjaśniający, dlaczego sędzia podjął taką decyzję. Jeśli twój wynik faithfulness spadnie po aktualizacji, twój prompt lub model językowy mogą być zbyt kreatywne. A teraz druga część tej układanki. Nawet najlepszy model językowy nie wygeneruje wiernej odpowiedzi, jeśli przekażesz mu niewłaściwe dokumenty. Tutaj do gry wchodzi Retrieval Evaluation. Oto kluczowa kwestia. Ewaluujesz retrieval, sprawdzając, czy system pobrał dokładnie te źródłowe node'y, których oczekiwałeś dla danego query, całkowicie ignorując ostatecznie wygenerowany tekst. Obsługujesz to za pomocą RetrieverEvaluator. Wyobraź sobie scenariusz, w którym chcesz przetestować nowy embedding model. Zamiast robić jego deploy i zgadywać, czy jest lepszy, budujesz ewaluacyjny dataset. Ten dataset zawiera listę query sparowanych z konkretnymi identyfikatorami dokumentów, które zawierają poprawne odpowiedzi. Przepuszczasz całą partię query przez RetrieverEvaluator. Ewaluator oblicza dwie kluczowe metryki: Hit Rate i MRR. Hit Rate jest prosty. Sprawdza, czy oczekiwany dokument pojawił się gdziekolwiek w twoich topowych zwróconych wynikach. Jeśli pobierzesz pięć dokumentów i jest wśród nich ten poprawny, to masz hit. Mierzy to czysty recall. Ale pozycja ma znaczenie. Jeśli poprawny dokument jest zawsze piąty, twój model językowy może go zignorować z powodu limitów kontekstu lub attention decay. W tym miejscu do gry wchodzi Mean Reciprocal Rank, czyli MRR. MRR analizuje pozycję pierwszego istotnego dokumentu. Jeśli poprawny dokument znajduje się na samej górze, wynik wynosi jeden. Jeśli jest drugi, wynik wynosi jedną drugą. Jeśli jest trzeci, jedną trzecią. Ewaluator uśrednia te ułamki dla całego twojego datasetu. Wyższy MRR oznacza, że twój retriever konsekwentnie wypycha najbardziej istotne informacje na samą górę okna kontekstowego. Porównując Hit Rate i MRR twojego starego embedding modelu z nowym, zyskujesz matematyczny dowód na to, który model radzi sobie lepiej. Możesz śledzić te liczby w czasie i automatycznie uruchamiać ten pipeline przy każdym pull requeście. Najcenniejszą rzeczą, jaką możesz zrobić dla swojego pipeline'u RAG, jest oddzielenie ewaluacji tego, co pobierasz, od tego, jak generujesz ostateczną odpowiedź. Dzięki za spędzenie ze mną tych kilku minut. Do usłyszenia następnym razem, trzymaj się.
14

Scaffolding na produkcję

4m 14s

Błyskawicznie przekształcaj prototypy w pełnoprawne aplikacje. Odkryj, jak używać create-llama i RAG CLI do generowania (scaffold) pełnostosowych aplikacji webowych i czatów w terminalu bez pisania powtarzalnego kodu.

Pobierz
Cześć, tu Alex z DEV STORIES DOT EU. LlamaIndex: Aplikacje LLM z rozszerzonym kontekstem, odcinek 14 z 14. Przestań kopiować i wklejać ten sam boilerplate API i Reacta za każdym razem, gdy chcesz przetestować nowy pomysł na Retrieval-Augmented Generation. Rozumiesz już mechanikę frameworka, ale postawienie czystego interfejsu, żeby faktycznie używać twoich modeli, wciąż zajmuje godziny powtarzalnej pracy. Dzisiaj omówimy narzędzia startowe, które pozwolą ci wygenerować produkcyjny scaffold w kilka sekund. Zbudowanie działającej aplikacji wymaga znacznie więcej niż tylko indeksu i query engine'u. Potrzebujesz serwera backendowego, żeby bezpiecznie obsługiwać przychodzące requesty. Potrzebujesz endpointów API, żeby przesyłać wiadomości w obie strony. Potrzebujesz klienta frontendowego, żeby wyświetlać historię czatu, renderować loading state'y i parsować odpowiedzi. Pisanie tej infrastruktury od zera dla każdego nowego datasetu czy prototypu po prostu pożera twój czas. Żeby to rozwiązać, LlamaIndex udostępnia narzędzie CLI o nazwie create-llama. To narzędzie generuje kompletną aplikację webową full-stack, wstępnie skonfigurowaną zgodnie z best practices LlamaIndex. Otwierasz terminal i odpalasz komendę create-llama. Narzędzie przeprowadzi cię potem przez serię wyborów. Zapyta, czy chcesz backend w Pythonie na FastAPI, czy backend w Node na Expressie. Zapyta, czy chcesz frontend w Next JS, żeby dać użytkownikom dopracowany interfejs webowy. Następnie zapyta o twoje źródło danych. Możesz nakierować to narzędzie bezpośrednio na lokalny folder z twoimi plikami PDF. Kiedy przejdziesz przez te prompty, create-llama przejmuje kontrolę. Instaluje wszystkie wymagane zależności. Robi scaffold struktury katalogów. Pisze skrypt do ingestii, żeby sparsować twoje PDF-y. Podpina endpointy API, żeby twój frontend mógł gadać z twoim retrieval engine. Na koniec ustawia zmienne środowiskowe. Odpalasz jedną komendę start i od razu masz ostylowany interfejs czatu śmigający w twojej przeglądarce. Możesz wpisać pytanie, a interfejs uderzy do wygenerowanego backendu, pobierze kontekst z twoich PDF-ów i przestreamuje odpowiedź z powrotem na twój ekran. Przechodzisz od pustego folderu do działającego prototypu full-stack w około trzydzieści sekund. To załatwia sprawę aplikacji webowych. Ale czasami serwer webowy i interfejs graficzny to po prostu overkill. Jeśli właśnie pobrałeś długą specyfikację techniczną i musisz ją od razu odpytać bez wychodzenia z linii komend, używasz RAG CLI. RAG CLI to narzędzie stworzone wyłącznie do interakcji z dokumentami z poziomu terminala. Instalujesz je, a potem odpalasz komendę, żeby wskazać mu twój lokalny katalog z dokumentami. CLI automatycznie odpala proces ingestii. Robi chunking tekstu, generuje embeddingi i zapisuje je w lokalnej wektorowej bazie danych, prosto na twojej maszynie. Kiedy ingestia się skończy, odpalasz komendę chat. Twój standardowy prompt w terminalu zamienia się w sesję czatu. Zadajesz pytanie, CLI pobiera odpowiednie dane, odpytuje model językowy i wypisuje wygenerowaną odpowiedź bezpośrednio w twojej konsoli. Nie ma tu żadnych wizualnych komponentów ani routingu webowego do konfigurowania. To absolutnie najszybszy sposób, żeby pogadać ze swoimi danymi lokalnie. Oto kluczowy wniosek. Rozumiesz już głęboką mechanikę aplikacji z rozszerzonym kontekstem, od chunkingu dokumentów po budowanie złożonych routerów dla agentów. Te narzędzia do scaffoldingu istnieją po to, żebyś mógł przestać użerać się z podstawową infrastrukturą i spędził czas na tuningu tych kluczowych strategii retrievalu. Ponieważ to ostatni odcinek naszej serii o LlamaIndex, najlepszym kolejnym krokiem będzie zajrzenie do oficjalnej dokumentacji i spróbowanie zbudowania tych pipeline'ów własnoręcznie. Jeśli masz pomysł na zupełnie inny stack technologiczny, który chciałbyś, żebyśmy omówili, odwiedź DEV STORIES DOT EU, żeby zaproponować temat. To wszystko w tym odcinku. Dzięki za słuchanie i buduj dalej!