Nowy standard. Twoje centrum tworzenia inteligentnego, szybkiego i zrównoważonego oprogramowania AI

Zobacz teraz
Abstrakcyjna grafika przedstawiająca niestandardowy szkielet aplikacji Flutter utworzony na podstawie promptu dla LLM.

Jak promptować LLM-y, by tworzyły niestandardowy szkielet aplikacji we Flutterze

Marcin Wróblewski
|   Updated Aug 10, 2026

Najpewniejszy sposób, by uzyskać z LLM-a użyteczny szkielet aplikacji we Flutterze, to nie prosić go o całość. Niech flutter create zbuduje szkielet projektu — tam poprawność jest gwarantowana, a halucynacje niemożliwe — a modelowi wyspecjalizowanemu w kodzie powierz jedno zadanie, w którym naprawdę jest dobry: opisanie i wypełnienie plików implementujących nawigację w twojej aplikacji.

Ten artykuł pokazuje taki podział na przykładzie modeli Mistral i przedstawia prompty, dzięki którym to zadziałało.

Duże modele językowe zmieniają sposób, w jaki deweloperzy tworzą aplikacje, ale wydobycie z nich realnej wartości wymaga czegoś więcej niż ogólnych instrukcji. Gdy chodzi o generowanie kodu — szczególnie dla frameworków takich jak Flutter — precyzja promptu decyduje o tym, czy otrzymasz działający prototyp, czy splątany kod, którego nie da się skalować.

LLM-y potrafią czasem halucynować, co sprawia, że prompty oparte na faktach tracą sens, ale świetnie radzą sobie z wychwytywaniem zależności między słowami, nawet w różnych językach. Model Codestral od Mistral, trenowany na przykładach kodu, pozwala użytkownikom tłumaczyć między dość nieoczywistymi językami, na przykład z angielskiego na język programowania.

Poniżej pokazujemy, jak użyć Codestral do generowania szkieletów aplikacji we Flutterze, które odpowiadają opisanemu po angielsku pomysłowi użytkownika, bez konieczności natychmiastowej refaktoryzacji, zanim deweloper będzie mógł rozwijać ich funkcjonalność.

Podsumowanie dla kadry zarządzającej

Traktowanie LLM-a jak generatora kodu ogólnego przeznaczenia daje wynik w postaci pojedynczego pliku, który zadziała raz, a potem opiera się każdej zmianie. Lepsze efekty daje inny podział pracy: deterministyczne narzędzia CLI tworzą fundament projektu, a model wyspecjalizowany w kodzie zajmuje się częścią wymagającą oceny twojego konkretnego pomysłu.

Po przejściu przez trzystopniowy proces — dopracowanie pomysłu, nadanie nazwy projektowi, zaplanowanie i zapisanie implementacji — wynikiem jest wieloplikowa baza kodu Fluttera, którą deweloper może od razu rozwijać, zamiast przepisywać od nowa.

Jak się okazuje, mierzalną dźwignią jest słownictwo: w testach użycie właściwego dla frameworka terminu „routes” zamiast intuicyjnego „pages” podniosło skuteczność generowania z zera na dziesięć prób do około dziewięciu na dziesięć.

To tańsza i bardziej przewidywalna droga od pomysłu na aplikację do działającego szkieletu niż promptowanie modelu frontier i liczenie na szczęście.

Struktura projektu Flutter z Codestral: generowanie kodu wspierane przez LLM

LLM-y ogólnego przeznaczenia, takie jak Mistral Large 2 czy seria GPT od OpenAI, generują rozwiązania kodowe w pojedynczym pliku. Choć takie podejście znacząco zwiększa szansę, że wynikowy kod będzie działał, jednocześnie sprawia, że staje się on słabą bazą do dalszego rozwoju przed rozbudową funkcjonalności.

Codestral to wyspecjalizowany model trenowany konkretnie na przykładach kodu. Dzięki temu zaskakująco dobrze dzieli implementację na logiczną strukturę plików, a następnie importuje je do głównego pliku projektu. Zaraz pokażemy to wszystko oczywiście na odpowiednich promptach.

Codestral potrafi przedstawić poprawną strukturę projektu Flutter, co możesz łatwo sprawdzić promptem w rodzaju „Present a default Flutter project structure in a text tree view.” Jest jednak dobry powód, by wesprzeć ten proces „klasycznym” podejściem i wywołać polecenie flutter create … Dzięki temu masz pewność, że struktura jest faktycznie poprawna, więc na przykład plik pubspec.yaml zawiera odpowiednie importy pakietów. Codestral przydaje się natomiast do opisania plików potrzebnych do zaimplementowania podstawowej nawigacji aplikacji oraz ich początkowej implementacji.

Taki model przekazywania pracy między LLM-ami i narzędziami to główna idea tego tekstu. Po co ryzykować halucynacje na poziomie fundamentów, skoro mamy inne narzędzia gwarantujące poprawność? Są kroki, których tradycyjne narzędzia nie potrafią wykonać — i właśnie wtedy promptujemy Codestral (albo Ministral czy Large 2), by pomógł. To jednocześnie tańszy i łatwiejszy do kontrolowania sposób zarządzania procesem tworzenia.

Od promptów po angielsku do kodu źródłowego aplikacji Flutter

Przekształcenie prostego pomysłu w działającą aplikację Flutter zaczyna się od dobrze przygotowanego promptu. Gdy rozbijemy cel aplikacji i jej kluczowe funkcje na zwięzłe, uporządkowane opisy, tworzymy podstawę do wygenerowania wykonywalnego kodu Dart.

Nasz plan jest następujący:

  • Pozyskać prompt od użytkownika

  • Wygenerować i uruchomić pasującą aplikację Flutter

Aby proces promptowania dało się sensownie przeprowadzić, zakładamy, że prompt będzie luźno trzymał się następującej struktury: jednozdaniowe wyjaśnienie celu aplikacji, a następnie funkcje kluczowe z perspektywy użytkownika.

Przykładowe prompty:

  • „Aplikacja do streamingu wideo. Funkcje: rekomendowane filmy, feed obserwowanych, strona przesyłania wideo, ustawienia konta.”

  • „Aplikacja do czatu. Funkcje: lista kontaktów, przeglądarka stories użytkowników, ustawienia konta.”

Uwaga! Sprowadzenie pomysłu na aplikację do tak zwięzłego opisu może być najtrudniejszym krokiem w całym procesie. Chętnie pomożemy.

Aby zamienić pomysł na aplikację w wykonywalny kod Dart, użyjemy następującego procesu:

  1. Dopracować i ujednolicić strukturę pomysłu na aplikację

  2. Znaleźć nazwę aplikacji dla projektowanego rozwiązania

  3. Zaplanuj i opisz implementację

Każdym etapem będzie zarządzał osobny model. Może to być dowolny model dostępny na rynku o odpowiednich możliwościach, ale skupimy się na modelach Mistral, a konkretnie Large 2, Ministral, i Codestral.

Od promptów po angielsku do kodu źródłowego aplikacji Flutter

Przekształcenie prostego pomysłu w działającą aplikację Flutter zaczyna się od dobrze przygotowanego promptu. Gdy rozbijemy cel aplikacji i jej kluczowe funkcje na zwięzłe, uporządkowane opisy, tworzymy podstawę do wygenerowania wykonywalnego kodu Dart.

Nasz plan zakłada:

  • Uzyskać prompt od użytkownika

  • Wygenerować i uruchomić odpowiadającą mu aplikację Flutter

Żeby ułatwić pracę z promptami, zakładamy, że prompt będzie luźno trzymał się tej struktury: jednozdaniowe wyjaśnienie celu aplikacji, a następnie funkcje kluczowe dla użytkownika.

Przykładowe prompty:

  • „Aplikacja do streamingu wideo. Funkcje: polecane filmy, kanał obserwowanych, strona przesyłania wideo, ustawienia konta.”

  • „Aplikacja do czatu. Funkcje: lista kontaktów, przegląd relacji użytkowników, ustawienia konta.”

Uwaga! Sprowadzenie pomysłu na aplikację do tak zwięzłego opisu może być najtrudniejszym etapem całego procesu; być może warto skontaktować się ze specjalistami żeby ci w tym pomogli

Aby przekształcić pomysł na aplikację w wykonywalny kod Dart, użyjemy następującego procesu:

  1. Dopracować i ujednolicić strukturę pomysłu na aplikację

  2. Znaleźć nazwę aplikacji dla opracowywanego projektu

  3. Zaplanuj i opisz implementację

Każdym etapem będzie zarządzał osobny model. Może to być dowolny model dostępny na rynku o odpowiednich możliwościach, ale skupimy się na modelach Mistral, a konkretnie Large 2, Ministral, i Codestral.

Które modele Mistral wybrać w 2026 roku

Uwaga dodana w sierpniu 2026 roku. Ten eksperyment pierwotnie przeprowadzono w 2025 roku, a wszystkie trzy wymienione wyżej modele zostały od tego czasu wycofane z API Mistral: mistral-large-2407 został wycofany w marcu 2025 roku, codestral-2501 w listopadzie 2025 roku, a ministral-8b-2410 pod koniec grudnia 2025 roku. Wszystkie wyniki opisane w tym artykule zmierzono na tych pierwotnych modelach.

Sam pipeline pozostaje bez zmian, a obecny zestaw modeli nadal odpowiada tym samym trzem rolom:

  • Doprecyzowanie pomysłu — Mistral Large 3 (mistral-large-3-2512), wydany 2 grudnia 2025 roku na licencji Apache 2.0, zastępuje Large 2 jako ogólnego przeznaczenia etap wnioskowania.

  • Nadawanie nazwy projektowi — Ministral 3 8B (ministral-3-8b-2512) zastępuje Ministral 8B jako mały, tani model do zadania wymagającego odpowiedzi jednym słowem.

  • Pisanie implementacji — Codestral 25.08 (codestral-2508) to obecny model wyspecjalizowany w kodzie, nadal oparty na uzupełnianiu fill-in-the-middle i generowaniu z niskimi opóźnieniami.

Zanim zaczniesz budować rozwiązanie pod konkretny identyfikator, sprawdź dokumentację modeli Mistral — harmonogram wycofywania zmienia się szybciej niż większość pipeline’ów.

Jak rozbijać pomysły na aplikacje, by uzyskiwać lepsze wyniki z LLM-ów

Im więcej informacji podamy w początkowym promcie, tym precyzyjniejszy może być wynik LLM-u. Ustaliliśmy już, że prompt użytkownika jest krótki, żeby skupiał się na celu, ale teraz trzeba go rozwinąć, aby uzyskać lepsze rezultaty. Z funkcji takiej jak na przykład „following feed” można wyczytać naprawdę dużo. Dla osób obeznanych z technologią ukryte znaczenie jest jasne, więc wykorzystajmy jedną z nich, żeby nam to wyjaśniła: Large 2 idealnie nadaje się do tego zadania.

Prompt, który przekazujemy modelowi, jest prosty:

„Jesteś architektem oprogramowania planującym aplikację Flutter opartą na trasach. Podsumuj poniższy pomysł na aplikację, używając języka technicznego. Opis i cel każdej funkcji mają być oddzielone przecinkami. Podsumuj wyłącznie funkcje; nie podawaj żadnych wskazówek. Pisz zwięźle.”

Aby pokazać oczekiwany wynik, rozbudowany pomysł na aplikację do streamingu wideo daje w efekcie:

„Nazwa aplikacji: FlutterFlow Video Streaming App

Funkcje:

-Ekran polecanych filmów, implementuje spersonalizowany algorytm rekomendacji wideo, cel: zwiększenie zaangażowania użytkowników, odkrywanie nowych treści,

-Ekran Following Feed, wyświetla treści z subskrybowanych kanałów, cel: tworzenie spersonalizowanego feedu, utrzymywanie użytkowników na bieżąco z obserwowanymi twórcami,

-Strona przesyłania wideo, umożliwia publikowanie treści tworzonych przez użytkowników, cel: zachęcanie do zaangażowania użytkowników, budowanie biblioteki treści,


-Strona ustawień konta, zarządza profilami użytkowników, preferencjami oraz ma na celu: dostosowanie doświadczenia użytkownika i obsługę prywatności oraz powiadomień.”

Daje nam to optymalną ilość kontekstu dla każdej funkcji i wyraźnie je rozdziela.

Jak wygenerować idealną nazwę aplikacji z pomocą LLM-ów

Żeby zapisać kod do plików, najpierw musimy utworzyć projekt Flutter. Aby wywołać flutter create, musimy jednak podać nazwę projektu, a tej nie mamy. Generyczna nazwa by zadziałała, ale zostałaby też zaszyta w implementacji, przez co projekt od początku byłby bezużyteczny. Na szczęście także do tego celu możemy użyć LLM-u! Do tego zadania wybrałem Ministral 8B.

Z promptem:

„Zaproponuj nazwę aplikacji. Odpowiedz wyłącznie nazwą, bez wyjaśnienia.”

Model jest w stanie zaproponować sensowną nazwę aplikacji. Polecenie Flutter CLI wymaga jednak nazwy w formacie snake_case, co zapewniamy po prostu za pomocą pakietu Dart change_case , żeby nie wydłużać promptu i nie narzucać mu zbyt wielu ograniczeń.

Planowanie i realizacja implementacji aplikacji z użyciem LLM-ów

Teraz przejdźmy do najciekawszej części: implementacji. Naszym celem jest uzyskanie dobrze uporządkowanej bazy kodu, na której można od razu rozpocząć proces tworzenia bez ręcznej ingerencji. Celem — przynajmniej na razie — nie jest pełne zaimplementowanie aplikacji; chodzi raczej o to, by była ona o krok bliżej naszej konkretnej wizji niż podstawowy projekt startowy Fluttera. Historia tworzenia promptu do tego kroku jest długa, zawiła, a jednocześnie na tyle specyficzna, że nie widzę sensu opisywać jej krok po kroku. Oto jednak najważniejsze założenia, które za nim stoją:

  • W sieci jest mnóstwo kodu Fluttera, a część z niego jest już przestarzała. Musieliśmy dodać kilka instrukcji dotyczących niektórych widgetów żeby LLM nie sięgał po nieaktualny kod.

  • Ma strukturę przypominającą XML, dzięki czemu odwołania wewnętrzne są możliwe i ujednolicone.

  • Prompt zawiera przykład implementacji funkcji, dzięki czemu wyniki są bardziej ukierunkowane. Zobacz few-shot prompting (w tym przypadku jeden przykład daje dobre rezultaty).

  • Nieoczekiwanym i interesującym elementem całego promptu jest to, jak wiele daje poprawne nazewnictwo. W prompcie odwołujemy się do „routes” w odniesieniu do funkcji, co jest standardowym sposobem definiowania pełnoekranowych części aplikacji we Flutterze. Na pewnym etapie eksperymentu spróbowałem zamienić odniesienia do „routes” na „pages” — pojęcia, które pozornie znaczą to samo. Jednak przy „routes” generowanie kończyło się sukcesem w 90% przypadków, a przy „pages” żadna z 10 prób nie dała działającej ani nawet poprawnie zbudowanej aplikacji. Wychodzi więc na to, że do tworzenia oprogramowania przez LLM-y nadal potrzebny jest programista.

Prompt implementacyjny wygląda tak:

<objective>

Jesteś ekspertem od Fluttera. Twoim zadaniem jest zaplanowanie i zaimplementowanie aplikacji opisanej poniżej. Zaplanuj implementację w następującej kolejności:

1. Konfiguracja nawigacji — zaplanuj nazwy tras i przypisz do nich nazwy widgetów. Do nawigacji w aplikacji użyj BottomNavigationBar;

2. Struktura plików — implementację strony dla każdej trasy umieść w osobnym pliku w podkatalogu „routes”;

3. Implementacja widgetów stron — wypełnij widget każdej trasy Scaffold i AppBar;

</objective>

<assignment>

Poczekaj na specyfikację aplikacji od użytkownika i zaplanuj dla niej implementację zgodnie z <rules/>, pamiętając o <objective/>

</assignment>

<rules>

- Odpowiadaj wyłącznie kodem i odpowiednimi pełnymi ścieżkami plików w pierwszej linii komentarza.

- Unikaj słowa kluczowego const.

- Koniecznie użyj label zamiast title we widżecie BottomNavigationBarItem.

- Nie ustawiaj własnego selectedItemColor dla BottomNavigationBarItem.

- Koniecznie ustaw pole type na BottomNavigationBarType.fixed w BottomNavigationBar.

- Jako zawartość każdej trasy użyj widgetów Placeholder().

- Używaj importów względnych.

- main.dart powinien zawierać BottomNavigationBar, który prowadzi do innych podtras.

</rules>

<example>

```dart

// feature.dart

import 'package:flutter/material.dart';

class Feature extends StatelessWidget {

  @override

  Widget build(BuildContext context) {

    return Scaffold(

      appBar: AppBar(

        title: Text('Feature name'),

      ),

      body: Placeholder(),

    );

  }

}

```

</example>

Wynik zawiera osobne bloki kodu z komentarzem opisującym docelową ścieżkę pliku w katalogu lib/ projektu.

Co zmieniło się we Flutterze od czasu napisania tego promptu

Powyższe reguły dotyczące widgetów istnieją dlatego, że publiczne API Fluttera się zmienia, a dane treningowe nie nadążają za tymi zmianami. Ten efekt tylko się nasilił, co najlepiej pokazuje, że w prompcie warto na sztywno wskazać wybór widgetów, zamiast ufać domyślnym wyborom modelu.

Jeśli dostosowujesz ten prompt do Fluttera 3.44 (wydanego 18 maja 2026 roku razem z Dartem 3.12), warto wiedzieć o trzech rzeczach:

  • BottomNavigationBar nadal działa i nie jest oznaczony jako przestarzały, ale dokumentacja Fluttera kieruje teraz raczej nowe aplikacje i aplikacje w Material 3 do NavigationBar zamiast niego, z destinations/NavigationDestination zamiast items, onDestinationSelected zamiast onTap, a także selectedIndex zamiast currentIndex. Ponieważ flutter create domyślnie tworzy szkielet aplikacji w Material 3, więc prompt proszący o BottomNavigationBar da ci komponent Material 2 wewnątrz projektu w Material 3.

  • Reguła labelzamiasttitle przestała być aktualna: BottomNavigationBarItem nie ma już w ogóle właściwości title właściwości. Pozostawienie tej reguły nic nie kosztuje, a nadal pomaga ukierunkować modele trenowane na starszym kodzie.

  • W Flutterze 3.44 biblioteki Material i Cupertino zostały zamrożone w głównym frameworku. Są rozdzielane na niezależnie wersjonowane pakiety material_ui i cupertino_ui — a wersje wbudowane w framework mają zostać uznane za przestarzałe w jednym z kolejnych stabilnych wydań. Każdy prompt, który na sztywno wpisuje importy package:flutter/material.dart będzie trzeba przejrzeć, gdy ta migracja wejdzie w życie.

Jak wygląda pipeline od początku do końca

Opisany wyżej proces krok po kroku można łatwo zautomatyzować, dlatego stworzyliśmy wewnętrzne narzędzie CLI, które robi dokładnie to. Zobacz je w praktyce poniżej:

Planowanie i realizacja implementacji aplikacji z użyciem LLM-ów

Na demo widać, jak prompt użytkownika trafia do opisanego wyżej pipeline i jak uruchamiany jest wygenerowany kod.

Najważniejsze wnioski

  • Niech deterministyczne narzędzia odpowiadają za fundamenty. flutter create gwarantuje poprawną strukturę projektu i prawidłowo uzupełniony plik pubspec.yaml— więc nie ma sensu marnować na to wywołań modelu ani ryzykować halucynacji.

  • Do pracy obejmującej wiele plików użyj modelu wyspecjalizowanego w kodzie. Podczas gdy modele ogólnego przeznaczenia zwykle zwracają jeden duży plik, Codestral dzieli implementację na logiczne pliki i włącza je do głównego pliku projektu.

  • Podziel pipeline między modele dopasowane rozmiarem do konkretnego zadania. Rozwinięcie pomysłu wymaga dobrego modelu ogólnego, ale nazwanie projektu już nie — mały model poradzi sobie z tym za ułamek kosztu.

  • Słownictwo frameworka ma krytyczne znaczenie. Zamiana „routes” na „pages” w prompcie implementacyjnym obniżyła skuteczność generowania z 90% do zera w dziesięciu próbach, mimo że oba terminy wydają się zamienne.

  • Nie marnuj budżetu promptu na styl. Formatowanie i dobre praktyki można zastosować po wygenerowaniu kodu za pomocą lintera i formattera, dzięki czemu prompt pozostaje skupiony na wartości biznesowej.

Jak dzięki kodowi tworzonemu przez LLM-y przekuć precyzyjne prompty w skalowalne aplikacje

Pipeline od angielskiego do kodu mają duży potencjał, ale chodzi w nich o przekład technicznych promptów po angielsku na poprawny kod. W takich scenariuszach jedno nieprecyzyjne słowo w oryginalnym prompcie może zepsuć cały proces generowania. Dobór właściwych słów nadal wygląda na zadanie dla programisty, ale programista nie musi tracić czasu na szczegóły implementacyjne.

„Klasyczne” narzędzia CLI sterowane wynikami z LLM-ów dobrze ze sobą współpracują, bo kod wygenerowany przez LLM musi być poprawny. Nie musi jednak być idealny: po zakończeniu generowania towarzyszące im linter i formatter kodu mogą automatycznie zastosować dobre praktyki, dzięki czemu prompty mogą skupiać się na wartości biznesowej zamiast grzęznąć w semantyce czy optymalizacjach.

Ten podział pracy stał się od tego czasu oficjalnym podejściem platformy. Flutter i Dart dostarczają teraz Agent Skills— katalogi instrukcji ograniczonych do konkretnych zadań, które zapewniają agentom kodującym zweryfikowane workflowy dla takich obszarów jak nawigacja i testy integracyjne, a także serwer Dart MCP, który pozwala agentowi wykonywać hot reload i analizować działającą aplikację. Inna infrastruktura, ta sama zasada: daj modelowi wyselekcjonowane instrukcje specyficzne dla frameworka i realne narzędzia, zamiast oczekiwać, że odtworzy framework z pamięci.

Jeśli zastanawiasz się, gdzie to pasuje do szerszej strategii mobilnej, nasz przewodnik po tworzeniu aplikacji we Flutterze oraz nasze spojrzenie na trendy w rozwoju Fluttera omawiają decyzje, które trzeba podjąć wokół tego tematu. A jeśli chcesz przekształcić pomysł na aplikację w coś, nad czym zespół będzie mógł dalej pracować, chętnie porozmawiamy.

FAQ

Marcin Wróblewski  avatar
Marcin Wróblewski
Senior Mobile Developer
Linkedin
Open-source enthusiast, focusing on Dart and Flutter due to their technical excellence. Codeusse’s creator.