Strona główna / Artykuły / „Practical notes: Building Autonomous AI Agents Locally: A Step-by-Step Guide” – praktyczny przewodnik.

„Practical notes: Building Autonomous AI Agents Locally: A Step-by-Step Guide” – praktyczny przewodnik.

Praktyczny przewodnik po „Practical notes: Building Autonomous AI Agents Locally: A Step-by-Step Guide”: umowy, sprawdzenia oraz miejsca na kod do wstawienia dla zespołów wdrażających ten wzorzec.

4685 słów

Poniższe notatki przedstawiają praktyczny plan działania oparty na książce „Building Autonomous AI Agents Locally: A Step-by-Step Guide for 16GB RAM Systems”. Nacisk kładziony jest na umowy, sprawdzania oraz miejsca zastępcze dla kodu, a nie na motywacyjne aspekty.

Poobietnice i trudności

Gdy przechodzisz przez etap „Poobietnice i trudności”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Utrzymuj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Twórz punkty kontrolne po kosztownych krokach. System powinien unikać ponownego uruchamiania tej samej operacji LLM, gdy operator próbuje ponownie wykonać późniejszy element procesu.

Część 1: Wybór broni — Dylemat wyboru modelu — Ocena lokalnych modeli pod kątem generowania tokenów i efektywności agencji

Gdy przechodzisz przez etap Wyboru broni z Części 1, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę naprawczą. Próby ponowne, kontrola przez człowieka oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dopiero późniejszej optymalizacji. Zachowuj w pamięci podręcznej stabilne instrukcje systemu oraz schematy narzędzi. Ponowne wysyłanie identycznego wstępu to częsty powód marnotrawstwa zasobów.

Konkurenci: Porównanie head-to-head

Gdy pracujesz nad etapem The Contenders A Head-to-Head, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustaw punkty kontrolne po kosztownych krokach. System powrotu nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

Qwen3.5:4b — Demon Prędkości

Gdy pracujesz nad etapem Qwen3 5 4b The stage, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Ustaw punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą próbę wywołania LLM, gdy operator ponawia działanie późniejszego węzła.

Llama3.1:latest (8B) — Niezawodny uniwersalista

Gdy pracujesz z najnowszą wersją Llama3 1 o pojemności 8B, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czas wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Jasna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od środowiska demonstracyjnego do współdzielonych środowisk. Utwórz punkt kontrolny po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą próbę wywołania LLM, gdy operator ponawia działanie późniejszego węzła. Gdy pracujesz z najnowszą wersją Llama3 1 o pojemności 8B, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodatkowej optymalizacji.

Gemma4:12b-it-q4_K_M — Potężne narzędzie do rozumowania

Faza rozumowania w Gemma4 12b-it-q4KM działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden udany wynik, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Wolij małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Określ budżet tokenów na jeden ruch i na jedną sesję. Narzędzia typu agentic intensywnie rozszerzają kontekst; sztywne limity zapobiegają temu, by demonstracje przerodziły się w niespodziewane rachunki.

Qwen3.5:9b-q4_K_M — Opcja złotego środka

Qwen3 5 9b-q4KM – ten etap funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia. Zapisz jeden udany przypadek, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po przerwach.

Analiza modeli porównawczych

Etap analizy modelu porównawczego działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przepis, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się z środowiska demonstracyjnego do współdzielonych środowisk. Przydziel budżet tokenów na jeden ruch i na jedną sesję. Narzędzia agentowe intensywnie rozszerzają kontekst; sztywne limity zapobiegają temu, by demonstracje przerodziły się w nieoczekiwane rachunki.

Wynik

Faza The Verdict działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przypadek, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Utrzymuj stan struktury w formie prostych, typizowanych elementów. Wplecione bloki danych ukrywają informację o tym, który węzeł zapisał dane w danym polu, i powodują przerwanie kontynuacji po przerwach.

Część 2: Przygotowanie sprzętu i konfiguracja lokalnych inferencji

Etap przygotowań sprzętowych w Części 2 działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia działań, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę przywracania do stanu poprzedniego. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji działania po przerwach.

Krok 1: Zainstaluj Ollama — Twój lokalny silnik inferencji

Etap 1 – instalacja Ollamy – działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden udany przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustal stałe wartości interpretera oraz pliku lockfile z zależnościami przed wprowadzaniem pętli. Różnice między laptopem a środowiskiem CI są najczęstszą przyczyną ukrytych awarii w demonstracjach API.

Instalacja na Linuxie

Faza instalacji Linux działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po przerwach.

curl -fsSL https://ollama.com/install.sh | sh

Instalacja macOS

Faza instalacji macOS funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zapisuj czasy wykonywania operacji oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy przechodzi się od wersji demonstracyjnej do środowisk współdzielonych. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach. Faza instalacji macOS funkcjonuje najlepiej, gdy traktowana jest jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno prawidłowy przebieg działania, jak i ścieżkę odzyskiwania. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później.

curl -fsSL https://ollama.com/install.sh | sh

Instalacja Windows

W fazie instalacji w systemie Windows należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić dany krok na podstawie znanej punktacji kontrolnej, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy dany krok zawiedzie, powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Zatwierdzenie przez człowieka powinno być wymagane w przypadkach, gdy dochodzi do wydawania pieniędzy lub modyfikacji danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się kompletności rozwiązania biznesowego.

irm https://ollama.com/install.ps1 | iex

Weryfikacja instalacji

W fazie weryfikacji instalacji należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany krok oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten krok na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nazwij poszczególne elementy, zdefiniuj kryteria sukcesu i odrzuć ciche, częściowe ukończenie zadania. Konieczna jest ludzka akceptacja w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego.

ollama --version
ollama version is 0.5.x

Krok 2: Pobierz swój model

Dla etapu 2 „Pull Your stage” należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisuj czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. W przypadku, gdy następnym krokiem jest kod lub wywołanie narzędzia, lepiej używać ustrukturyzowanych wyników z walidacją schematu niż swobodnego tekstu. Dla etapu 2 „Pull Your stage” należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Dokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

# For the winner
ollama pull qwen3.5:9b-q4_K_M

# For speed
ollama pull qwen3.5:4b

# For reasoning
ollama pull gemma4:e4b-q4_K_M

Krok 3: Uruchomienie serwera Ollama

Podczas pracy nad krokiem 3, zacznij od sporządzenia listy wymagań: niezbędnych danych wejściowych, sygnału o pomyślności oraz tego, co dzieje się w przypadku częściowego niepowodzenia. Taka lista zapewnia przejrzystość przy późniejszych zmianach w kodzie. Wolno preferować małe, łatwe do przetestowania jednostki nad rozbudowanymi skryptami. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną sekwencję operacji. Zapisuj identyfikator żądania, identyfikator modelu oraz czas reakcji przy każdym wywołaniu. Bez tych informacji przerywane błędy dostawcy mogą wyglądać jak błędy aplikacji.

ollama serve

Krok 4: Testowanie modelu

Gdy przechodzisz przez etap 4 „Testuj”, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć możliwość cichego, częściowego ukończenia zadania. Zachowuj w pamięci tymczasowej stabilne instrukcje systemu oraz schematy narzędzi. Ponowne wysyłanie identycznego nagłówka jest częstą przyczyną marnotrawstwa zasobów.

ollama run qwen3.5:9b-q4_K_M "Hello, introduce yourself briefly."

Część 3: Konfiguracja CrewAI — Framework orkiestracji

Podczas przechodzenia przez etap Konfiguracji z Części 3, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zapisz czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Ustal punkty kontrolne po kosztownych krokach. Narzędzie do kontynuacji pracy nie powinno ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł. Podczas przechodzenia przez etap Konfiguracji z Części 3, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Zdokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych wywołań, mechanizmy ludzkiej kontroli oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

Wymagania systemowe

Etap wymagań systemowych funkcjonuje najlepiej, gdy traktowany jest jako mierzalna powierzchnia do analizy. Zapisz jeden idealny przepis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wtórne struktury ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwanie kontynuacji po przerwach.

Krok 1: Zainstaluj uv (nowoczesny instalator pakietów Pythona)

Krok 1 – instalacja środowiska uv działa najlepiej, gdy traktuje się je jako powierzchnię mierzalną. Zapisz jeden przykład udanego działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzuć przypadki częściowego ukończenia bez informacji. Ustal stałe wartości interpretera oraz pliku blokującego zależności przed nauczeniem pętli. Rozbieżności pomiędzy laptopem a środowiskiem CI są najczęstszą przyczyną niewidzialnych awarii w demonstracjach API.

curl -LsSf https://astral.sh/uv/install.sh | sh
powershell -c "irm https://astral.sh/uv/install.ps1 | iex"

Krok 2: Instalacja CrewAI CLI

Etap instalacji CrewAI w kroku 2 działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zarejestruj czasy wykonywania zadań oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega nieoczekiwanym rachunkom, gdy przechodzi się od wersji demonstracyjnej do środowisk współdzielonych. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji pracy po przerwach.

uv tool install crewai

Krok 3: Stwórz swój projekt Crew

Krok 3 „Stwórz swoją scenę” działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę o cofnięciu zmian, zanim rozszerzysz zakres pracy. Trzymaj konfigurację poza kodem aplikacji. Pliki środowiskowe, magazyny tajnych danych oraz flagi funkcjonalne powinny znajdować się w jednym miejscu, które operatorzy mogą sprawdzić bez konieczności czytania całej struktury. Utrzymuj stan struktury w prostym formacie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane w danym polu, co powoduje przerwę w kontynuacji pracy po zakłóceniach.

crewai create crew my_agent_team
cd my_agent_team
my_agent_team/
├── src/
│   └── my_agent_team/
│       ├── __init__.py
│       ├── crew.py
│       ├── agents.py
│       ├── tasks.py
│       └── main.py
├── .env
└── pyproject.toml

Krok 4: Zainstaluj zależności

Etap 4 – instalacja zależności – działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przypadek działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Zdokumentuj zarówno prawidłowy przebieg operacji, jak i ścieżkę przywracania do stanu poprzedniego. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później w celu udoskonalenia. Utrzymuj strukturę grafu w prostym formacie i z określonym typem danych. Wkładki nawiasowe ukrywają informację o tym, który węzeł zapisał dane w danym polu, co utrudnia kontynuację pracy po przerwach.

uv pip install -e .

Krok 5: Instalacja dodatkowych narzędzi

Etap 5, polegający na instalacji dodatkowych komponentów, działa najlepiej, gdy traktuje się go jako mierzalną powierzchnię do analizy. Zapisz jeden idealny przykład działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś etap zawiedzie, awaria powinna wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Używaj narzędzi o wąskich schematach i wyraźnych oznaczeniach efektów ubocznych. Hostowie muszą wiedzieć, które wywołania zmieniają stan systemu, zanim automatycznie je zatwierdzą.

uv pip install crewai-tools langchain-ollama python-pptx

Część 4: Budowanie zespołu agentów

Część 4 „Budowanie Twojej platformy” działa najlepiej, gdy traktuje się ją jako mierzalną powierzchnię. Zapisz jeden idealny przykład działania, jeden przypadek niepowodzenia oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres pracy. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i odrzucaj ciche, częściowe ukończenie zadań. Utrzymuj stan grafu w prostej formie i określonej typowości. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, co powoduje przerwanie kontynuacji po zakłóceniach.

Architektura

Faza Architektury funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Zapisuj czasy wykonywania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy proces przechodzi z wersji demonstracyjnej do środowisk współdzielonych. Utrzymuj stan grafu w prostej formie i z określonym typem danych. Wplecione elementy ukrywają informację o tym, który węzeł zapisał dane do którego pola, i powodują przerwę w kontynuacji działania po zakłóceniach. Faza Architektury funkcjonuje najlepiej, gdy jest traktowana jako mierzalna powierzchnia. Zapisz jeden idealny zapis działania, jeden przypadek awarii oraz notatkę dotyczącą cofnięcia zmian, zanim rozszerzysz zakres. Dokumentuj zarówno optymalną ścieżkę działania, jak i ścieżkę przywracania do normalnego stanu. Próby ponownych działań, kontrolne punkty ludzkie oraz obsługa wiadomości nieodebranych stanowią część produktu, a nie elementy dodawane później.

Krok 1: Konfiguracja LLM

W kroku 1 – Konfiguracja etapu – należy zdefiniować dane wejściowe, osobę odpowiedzialną za dany etap oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić etap na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Należy preferować małe, testowalne jednostki nad rozbudowanymi skryptami. Gdy etap zawiedzie, powód awarii powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowaną strukturę procesu. W przypadku, gdy następnym krokiem jest kod lub wywołanie narzędzia, lepsze są ustrukturyzowane wyniki z walidacją schematu niż tekst w formie swobodnej.

from langchain_ollama import OllamaLLM

def get_llm():
    """ Initialize the local LLM for CrewAI."""
    return OllamaLLM(
        model="qwen3.5:9b-q4_K_M",
        base_url="http://localhost:11434",
        temperature=0.3,  # Lower = more deterministic
        top_p=0.9,
    )

Krok 2: Zdefiniuj swoich agentów

W drugim kroku, „Określ swój etap”, należy zdefiniować dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia przed modyfikacją kodu. Operatorzy powinni móc ponownie uruchomić ten etap na podstawie znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Traktuj ten etap jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy artefaktom, zdefiniuj sprawdzenia sukcesu i odrzuć ciche, częściowe ukończenie zadań. Wymagaj ludzkiej aprobaty w przypadkach, gdy dochodzi do wydawania pieniędzy lub zmiany danych produkcyjnych. Połączenia realizowane w czasie kompilacji nie równają się pełnej kompletności procesu biznesowego.

from crewai import Agent
from crewai_tools import SerperDevTool, FileReadTool
from .llm_config import get_llm

# Initialize tools
search_tool = SerperDevTool()  # Requires Serper API key (free tier available)
file_tool = FileReadTool()
def create_coding_agent():
    """Agent specialized in writing and reviewing code."""
    return Agent(
        role="Senior Software Engineer",
        goal="Write clean, efficient, and well-documented code that solves the given problem",
        backstory="""You are a senior software engineer with 15 years of experience
        across multiple programming languages. You specialize in Python, JavaScript,
        and system architecture. You write code that is not only functional but
        also maintainable and follows best practices.""",
        tools=[file_tool],  # Can read existing files
        llm=get_llm(),
        verbose=True,
        allow_delegation=False,
    )
def create_research_agent():
    """Agent specialized in deep research and report writing."""
    return Agent(
        role="Lead Research Analyst",
        goal="Conduct thorough research and synthesize findings into comprehensive reports",
        backstory="""You are a seasoned research analyst with a PhD in Computer Science.
        You have expertise in finding, verifying, and synthesizing information from
        multiple sources. Your reports are known for their depth, clarity, and
        actionable insights.""",
        tools=[search_tool],  # Can search the web
        llm=get_llm(),
        verbose=True,
        allow_delegation=False,
    )
def create_presentation_agent():
    """Agent specialized in creating PowerPoint presentations."""
    return Agent(
        role="Senior Presentation Designer",
        goal="Transform research findings into compelling, visually-appealing PowerPoint presentations",
        backstory="""You are a presentation designer with 10 years of experience
        creating executive-level decks for Fortune 500 companies. You know how to
        structure information for maximum impact and create slides that tell a
        compelling story.""",
        tools=[],  # We'll handle PPT generation separately
        llm=get_llm(),
        verbose=True,
        allow_delegation=False,
    )

Krok 3: Określ swoje zadania

W etapie 3 „Zdefiniuj swój etap” należy określić dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Zapisuj czas trwania oraz koszt tokenów lub zapytań obok wyników funkcjonalnych. Wczesna widoczność kosztów zapobiega niespodziewanym rachunkom, gdy ścieżka przechodzi z środowiska demonstracyjnego do współdzielonych środowisk. Wprowadź ludzką aprobatę dla operacji, które generują wydatki lub zmieniają dane produkcyjne. Połączenia skompilowane w czasie kompilacji nie równają się pełnej kompletności rozwiązania biznesowego. W etapie 3 „Zdefiniuj swój etap” należy określić dane wejściowe, osobę odpowiedzialną za ten etap oraz kryteria zakończenia przed zmianą kodu. Operatorzy powinni móc ponownie uruchomić ten etap od znanego punktu kontrolnego, bez konieczności zgadywania ukrytego stanu. Dokumentuj zarówno ścieżkę prawidłowego działania, jak i ścieżkę naprawczą. Próby ponownych działań, ludzkie kontrolne punkty oraz obsługa wiadomości błędowych stanowią część produktu, a nie elementy dodawane później.

from crewai import Task

def create_coding_task(topic, requirements):
    """Task for the coding agent."""
    return Task(
        description=f"""
        Write a Python solution for the following problem:

        Topic: {topic}
        Requirements: {requirements}

        Your response should include:
        1. Complete, working Python code
        2. Explanation of the approach
        3. Time and space complexity analysis
        4. Example usage

        Make sure the code is production-ready and includes error handling.
        """,
        expected_output="A complete Python solution with documentation and analysis.",
        agent=None,  # Will be assigned later
    )
def create_research_task(query):
    """Task for the research agent."""
    return Task(
        description=f"""
        Conduct in-depth research on the following topic:

        Query: {query}

        Your research should cover:
        1. Current state of the art
        2. Key players and technologies
        3. Challenges and limitations
        4. Future trends and predictions
        5. Actionable recommendations

        Cite your sources and provide a well-structured report.
        """,
        expected_output="A comprehensive research report with citations.",
        agent=None,  # Will be assigned later
    )
def create_presentation_task(research_findings):
    """Task for the presentation agent."""
    return Task(
        description=f"""
        Create a PowerPoint presentation based on the following research:

        {research_findings}

        The presentation should include:
        1. Title slide with a compelling title
        2. Executive summary
        3. Key findings (3-5 slides)
        4. Visual data representation
        5. Recommendations
        6. Conclusion and next steps

        Provide a detailed outline and slide content.
        """,
        expected_output="A detailed PowerPoint presentation outline with slide content.",
        agent=None,  # Will be assigned later
    )

Krok 4: Koordynacja zespołu

Podczas pracy nad krokiem 4, czyli koordynacją procesu, najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co się dzieje w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Wolno preferować małe, testowalne jednostki zamiast rozbudowanych skryptów. Gdy jakiś krok się nie powiedzie, błąd powinien wskazywać na konkretną odpowiedzialność, a nie na skomplikowany łańcuch operacji. Ustalaj punkty kontrolne po kosztownych krokach. Program nie powinien ponownie naliczać opłat za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

from crewai import Crew, Process
from .agents import (
    create_coding_agent,
    create_research_agent,
    create_presentation_agent
)
from .tasks import (
    create_coding_task,
    create_research_task,
    create_presentation_task
)

def create_crew(topic, query, requirements):
    """Create and configure the multi-agent crew."""

    # Initialize agents
    coding_agent = create_coding_agent()
    research_agent = create_research_agent()
    presentation_agent = create_presentation_agent()

    # Create tasks
    coding_task = create_coding_task(topic, requirements)
    research_task = create_research_task(query)

    # Assign agents to tasks
    coding_task.agent = coding_agent
    research_task.agent = research_agent

    # The presentation task depends on research findings
    # We'll create it dynamically after research is complete

    return Crew(
        agents=[coding_agent, research_agent, presentation_agent],
        tasks=[coding_task, research_task],
        process=Process.sequential,  # Tasks run in order
        verbose=True,
    )
def run_crew(topic, query, requirements):
    """Run the multi-agent crew and return results."""
    crew = create_crew(topic, query, requirements)
    result = crew.kickoff()
    return result

Krok 5: Główny punkt wejścia

Gdy przechodzisz przez etap 5 – „Główna faza” – najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie. Traktuj tę fazę jako umowę pomiędzy danymi wejściowymi a zweryfikowanymi wynikami. Nadaj nazwy poszczególnym elementom, zdefiniuj kryteria sukcesu i unikaj cichego ukończenia zadania w częściowym stopniu. Zrób kontrolę po kosztownych krokach. Program nie powinien ponownie naliczać opłaty za tę samą wywołanie LLM, gdy operator próbuje ponownie uruchomić późniejszy węzeł.

import os
from .crew import run_crew

def main():
    """Main entry point for the multi-agent system."""

    # Define your project
    topic = "Building a REST API with FastAPI"
    query = "Best practices for FastAPI REST API development in 2026"
    requirements = """
    - Python 3.11+
    - FastAPI framework
    - PostgreSQL database
    - JWT authentication
    - Docker deployment
    """

    print("🚀 Starting multi-agent workflow...")
    print("=" * 50)

    # Run the crew
    result = run_crew(topic, query, requirements)

    print("\n✅ Workflow complete!")
    print("=" * 50)
    print("\n📊 Results:")
    print(result)

    return result
if __name__ == "__main__":
    main()

Część 5: Automatyczna generacja prezentacji PowerPoint

Gdy przechodzisz przez etap 5 – „Automatyczna generacja prezentacji PowerPoint” – najpierw zapisz umowę: wymagane dane wejściowe, sygnał sukcesu oraz to, co dzieje się w przypadku częściowego niepowodzenia. Taka lista kontrolna zapewnia uczciwość późniejszych zmian w kodzie.

Krok 1: Stworzenie generatora PPT

from pptx import Presentation
from pptx.util import Inches, Pt
from pptx.enum.text import PP_ALIGN
from pptx.dml.color import RGBColor
import os

def create_presentation_from_content(content, filename="presentation.pptx"):
    """
    Generate a PowerPoint presentation from structured content.

    Args:
        content: Dictionary with slide titles and content
        filename: Output filename
    """
    prs = Presentation()

    # Set slide dimensions (16:9)
    prs.slide_width = Inches(13.333)
    prs.slide_height = Inches(7.5)

    # Title Slide
    title_slide_layout = prs.slide_layouts[0]
    slide = prs.slides.add_slide(title_slide_layout)
    slide.shapes.title.text = content.get("title", "AI-Generated Presentation")
    slide.placeholders[1].text = content.get("subtitle", "Powered by CrewAI + Ollama")

    # Content Slides
    for slide_data in content.get("slides", []):
        bullet_slide_layout = prs.slide_layouts[1]
        slide = prs.slides.add_slide(bullet_slide_layout)

        # Title
        slide.shapes.title.text = slide_data.get("title", "Untitled")

        # Content
        content_text = slide.placeholders[1]
        content_frame = content_text.text_frame
        content_frame.clear()

        for point in slide_data.get("points", []):
            p = content_frame.add_paragraph()
            p.text = point
            p.level = 0
            p.font.size = Pt(18)

    # Save
    prs.save(filename)
    print(f"✅ Presentation saved as: {filename}")
    return filename
def generate_ppt_from_research(research_text, topic):
    """
    Generate a PPT from research findings using the presentation agent.
    """
    from .agents import create_presentation_agent
    from .llm_config import get_llm

    # Have the presentation agent structure the content
    agent = create_presentation_agent()

    prompt = f"""
    Based on the following research about "{topic}", create a structured
    presentation outline with 6-8 slides.

    Research:
    {research_text[:2000]}  # Limit to avoid context overflow

    Return a JSON object with the following structure:
    {{
        "title": "Presentation title",
        "subtitle": "Subtitle or tagline",
        "slides": [
            {{
                "title": "Slide title",
                "points": ["Point 1", "Point 2", "Point 3"]
            }}
        ]
    }}
    """

    # Get structured output from the agent
    response = agent.llm.invoke(prompt)

    # Parse the response (simplified - in production, use proper JSON parsing)
    import json
    try:
        # Extract JSON from response
        content = json.loads(response)
    except:
        # Fallback: create a simple structure
        content = {
            "title": f"Research on {topic}",
            "subtitle": "AI-Generated Presentation",
            "slides": [
                {"title": "Introduction", "points": ["Overview of research"]},
                {"title": "Key Findings", "points": ["Finding 1", "Finding 2"]},
                {"title": "Recommendations", "points": ["Recommendation 1"]}
            ]
        }

    # Generate the PPT
    filename = f"{topic.replace(' ', '_')}_presentation.pptx"
    return create_presentation_from_content(content, filename)

Krok 2: Integracja generowania PPT z systemem Crew

from .ppt_generator import generate_ppt_from_research

def run_full_workflow(topic, query, requirements):
    """Run the complete workflow including PPT generation."""

    # Step 1: Run the crew (coding + research)
    crew_result = run_crew(topic, query, requirements)

    # Step 2: Extract research findings (simplified - in production, parse properly)
    research_findings = crew_result  # This would be the research agent's output

    # Step 3: Generate PowerPoint
    ppt_file = generate_ppt_from_research(research_findings, topic)

    return {
        "crew_result": crew_result,
        "presentation_file": ppt_file
    }

Część 6: Powszechne pułapki i sposoby ich rozwiązania

Problem 1: „Connection refused” gdy CrewAI próbuje połączyć się z Ollamą

litellm.APIConnectionError: OllamaException - [Errno 111] Connection refused
llm = OllamaLLM(
    model="qwen3.5:9b-q4_K_M",
    base_url="http://localhost:11434",  # Ensure this is correct
)

Problem 2: Model nie potrafi przestrzegać schematów wywoływania narzędzi

Problem 3: Błędy braku pamięci (OOM)

Problem 4: Agent utyka w pętlach rekurencyjnych

Problem 5: Powolna generacja tokenów

Część 7: Uruchamianie pierwszego workflow z wieloma agentami

Pełna konfiguracja

#!/usr/bin/env python3
"""
Complete Multi-Agent System with Ollama and CrewAI
"""

import os
import sys
from src.my_agent_team.crew import run_full_workflow
def main():
    print("""
    ╔═══════════════════════════════════════════════════════╗
    ║     🤖 Multi-Agent AI System - Local Edition         ║
    ║     Powered by Ollama + CrewAI + Qwen3.5:9b         ║
    ╚═══════════════════════════════════════════════════════╝
    """)

    # Check if Ollama is running
    import requests
    try:
        response = requests.get("http://localhost:11434")
        print("✅ Ollama is running!")
    except:
        print("❌ Ollama is not running. Please start it with: ollama serve")
        sys.exit(1)

    # Define your project
    topic = input("Enter your project topic (e.g., 'Building a REST API with FastAPI'): ")
    query = input("Enter your research query (e.g., 'Best practices for FastAPI'): ")
    requirements = input("Enter your requirements (e.g., 'Python, PostgreSQL, JWT'): ")

    print("\n🚀 Starting multi-agent workflow...")
    print("=" * 60)

    try:
        result = run_full_workflow(topic, query, requirements)

        print("\n✅ Workflow complete!")
        print("=" * 60)
        print(f"\n📄 Presentation saved as: {result['presentation_file']}")
        print("\n📊 Crew Results:")
        print(result['crew_result'])

    except Exception as e:
        print(f"\n❌ Error: {e}")
        print("\n💡 Troubleshooting tips:")
        print("1. Make sure Ollama is running: ollama serve")
        print("2. Check if the model is downloaded: ollama list")
        print("3. Ensure you have enough memory (close other apps)")
        print("4. Check the error message above for specific issues")
if __name__ == "__main__":
    main()

Zainstaluj i uruchom!

python run.py

Część 8: Lista kontrolna optymalizacji wydajności

Optymalizacja pamięci

Optymalizacja szybkości

Optymalizacja niezawodności

Wniosek: Udało ci się!

Ostatnie uwagi

Lista kontrolna operacyjna