Sytuacja: dobra firma, słaba ekonomia ofertowania
Firma — średniej wielkości generalny wykonawca działający w segmencie budownictwa kubaturowego i infrastrukturalnego — chciała rozszerzyć działalność o większy udział w rynku zamówień publicznych. Strategia trafna: zamówienia publiczne to przewidywalny przepływ projektów, klarowne procedury płatności, mniejsza zmienność niż prywatny rynek deweloperski.
Problem: matematyka ofertowania w przetargach publicznych jest bezlitosna dla małych i średnich firm.
- Średnio 8-20 godzin pracy specjalisty ds. zamówień + estymatora + osoby z kierownictwa na jedną dokładnie przygotowaną ofertę
- SIWZ-y mają regularnie 100-300 stron z załącznikami
- Wymagania formalne (referencje, kadra, sytuacja finansowa) muszą być precyzyjnie dopasowane do ogłoszenia
- Pominięcie jednego załącznika lub niewłaściwa forma podpisu = odrzucenie oferty
- Win rate w przetargach otwartych: ~10-20% dla średnich graczy
Wniosek finansowy: żeby wygrać 1 kontrakt, trzeba zainwestować 80-200 godzin pracy w 5-10 ofert. Jeśli kontrakt jest wart 500k-2M zł, to się opłaca. Jeśli mniejszy — biznes zaczyna zjadać własny ogon. A firmy, które chcą rosnąć, muszą startować w wielu przetargach jednocześnie, co rozciąga zespół do granic.
To nie problem motywacji zespołu, to problem skali
Klient miał świetny dział ofertowania. Po prostu fizycznie nie da się wycisnąć więcej godzin z trzyosobowej ekipy. Bez automatyzacji albo rezygnujesz z części przetargów (= ucieczka okazji), albo skalujesz zespół (= drogie i powolne).
Wizja systemu
Zaprojektowaliśmy system w trzech warstwach, z których każda przejmuje konkretną część pracy zespołu:
Każda z tych warstw to oddzielne wyzwanie techniczne. Pójdziemy po kolei.
Warstwa 1: Filtrowanie ogłoszeń
Na platformach ezamowienia.gov.pl i Biuletynie Zamówień Publicznych ukazuje się dziennie kilkaset nowych ogłoszeń. W skali tygodnia to kilka tysięcy postępowań, z których dla konkretnej firmy interesujące jest może 10-30. Manualne przeglądanie wszystkich nie ma sensu.
Co zbudowaliśmy
Crawler napisany w PHP (zgodny ze stackiem klienta), który codziennie o 6:00 rano:
- Pobiera nowe ogłoszenia z głównych platform przetargowych (ezamowienia.gov.pl, BZP, platforma e-Zamówienia, regionalne BIP-y)
- Pobiera załączniki (SIWZ, OPZ, formularze) — często w PDF, czasem ZIP
- Przepuszcza ogłoszenie przez Claude'a z konkretnym promptem profilującym (CPV firmy, typowe wartości, geografia działania)
- Każdemu ogłoszeniu przypisuje score 0-100 i krótkie uzasadnienie
- Top 20 ogłoszeń trafia do dashboardu zespołu ofertowego rano
Klucz tu nie leży w technologii (crawlowanie i klasyfikacja to dziś standard), tylko w profilu firmy podawanym Claude'owi. Spędziliśmy 2 dni z zarządem klienta na precyzyjnym opisaniu:
- Jakie typy obiektów firma faktycznie umie wybudować (a w czym nie ma doświadczenia)
- W jakich kategoriach CPV się specjalizuje (główne i poboczne)
- Jaka jest typowa wartość projektu, w której firma jest konkurencyjna
- Geografia działania (do ilu km od bazy logistycznej)
- Kadra dostępna do projektów (jakich uprawnień nie mają — co automatycznie eliminuje przetargi)
- Sytuacja finansowa (obrót minimalny, ubezpieczenie OC, zabezpieczenie należytego wykonania)
Wszystko to trafia do profilu, którym Claude porównuje każde ogłoszenie. System eliminuje ~98% ogłoszeń automatycznie, zostawiając zespołowi do oceny ludzkiej już tylko realnie interesujące postępowania.
Pierwsze zaskoczenie klienta
System zaczął wskazywać też przetargi, których wcześniej zespół nie zauważał — bo były publikowane na regionalnych BIP-ach, nie na głównej platformie. Z każdego z nich powstała szansa biznesowa, której wcześniej fizycznie nie dało się wyłapać manualnie.
Warstwa 2: Analiza SIWZ — ekstrakcja wymagań
SIWZ to dokument, który ma swoją strukturę logiczną, ale niekoniecznie konsekwentnie stosowaną. Zamawiający różnie układają informacje, używają różnych nomenklatur, czasem kluczowe wymagania ukryte są w pkt 9.3.4.b.II załącznika nr 4. Ręczne wyłuskanie tego trwa godziny.
Dlaczego nie wystarczy "wrzuć PDF do ChatGPT"
To pierwsza rzecz, którą próbowaliśmy. Wynik: średnio sensowny. Claude (i GPT-4) świetnie streszcza dokumenty, ale gdy zadasz mu szczegółowe pytanie typu "jakie są wymagania dot. doświadczenia kierownika budowy" — czasami trafia, czasami pomija ważne niuanse zakopane w odległym fragmencie dokumentu, czasami "halucynuje" wymagania, których faktycznie tam nie ma.
W przetargu publicznym "prawie dobra odpowiedź" oznacza odrzucenie oferty. Musieliśmy zbudować coś dokładniejszego.
Rozwiązanie: hybryda Claude + własny fine-tuned model
Stack warstwy analizy SIWZ
- Claude Code (orkiestracja)
- Llama 3.1 8B fine-tuned na PL przetargach
- vLLM (serwowanie modelu)
- Custom OCR pipeline (PDF z tabelami)
- Structured extraction (JSON schema)
- PostgreSQL + pgvector
Zebraliśmy dataset 4000+ historycznych SIWZ-ów z polskich przetargów budowlanych (publicznie dostępne na archiwach platform). Każdy z nich zaanotowaliśmy semi-automatycznie:
- Co jest sekcją "wymagania dotyczące zamawiającego"
- Co jest opisem przedmiotu zamówienia
- Co jest wymaganiem formalnym (kadra, referencje, sytuacja finansowa)
- Co jest opisem kryteriów oceny ofert
- Co jest harmonogramem realizacji
- Co jest klauzulą szczególną (gwarancje, kary umowne)
Na tym datasecie zrobiliśmy fine-tuning Llamy 3.1 8B (LoRA, 3 epoki, treningowo na własnej infrastrukturze — RTX 5090 wystarcza w zupełności). Powstał model wyspecjalizowany w jednym konkretnym zadaniu: ekstrakcja strukturalnych informacji z polskich dokumentów przetargowych.
Jak to działa razem
Claude Code orkiestruje cały proces — wie kiedy użyć którego narzędzia:
Workflow analizy SIWZ:
1. OCR + parsing PDF-a (zachowanie tabel)
2. Podział na sekcje logiczne
3. Każdy fragment → fine-tuned model
→ ekstrakcja strukturalnych pól
(JSON: wymagania, terminy, kryteria, ...)
4. Konsolidacja pól → walidacja spójności
5. Claude robi finalną kontrolę jakości
→ sprawdza czy nic nie zostało pominięte
→ flaguje wątpliwe interpretacje do weryfikacji
6. Wynik: ustrukturyzowany "profil przetargu"
gotowy do porównania z profilem firmy
Dlaczego nie sam Claude, dlaczego nie sam własny model:
- Sam Claude ma problem ze 100% pokryciem 200-stronicowego dokumentu, niekiedy halucynuje wymagania
- Sam fine-tuned model jest dokładny w ekstrakcji, ale słaby w "rozumieniu kontekstu" — nie widzi co jest dziwne, co warto sprawdzić
- Hybryda łączy precyzję jednego z inteligencją drugiego
Warstwa 3: Wstępne wypełnianie ofert
Trzecia warstwa to ta, która faktycznie oszczędza najwięcej czasu: system na podstawie wyekstrahowanych wymagań i istniejącej bazy danych firmy wstępnie wypełnia ofertę.
Co znajduje się w bazie danych firmy
- Lista wszystkich zrealizowanych projektów (z opisami, wartościami, datami, lokalizacjami, branżami)
- Skany podpisanych referencji (PDF z OCR)
- Kadra firmy z uprawnieniami (kierownicy budowy, kosztorysanci, projektanci) wraz z numerami uprawnień i datami ich uzyskania
- Dokumenty finansowe (sprawozdania, polisy OC, zaświadczenia o niezaleganiu)
- Wzory ofert i pisanych dotychczas opisów technicznych
Jak działa wypełnianie
Dla każdego przetargu zakwalifikowanego do dalszej obróbki system robi:
- Mapowanie wymagań → zasoby firmy. Wymaganie: "kierownik budowy z uprawnieniami konstrukcyjno-budowlanymi bez ograniczeń, doświadczenie min. 5 lat, w tym 1 projekt o wartości min. 1 mln zł". System sprawdza w bazie: który kierownik to spełnia? Czy mamy referencje na taki projekt? Generuje konkretną propozycję wraz z numerem uprawnień i numerem referencji.
- Identyfikacja luk. Czasem wymagania są takie, że firma ich nie spełnia. System to flaguje wcześnie — "nie startujemy, bo brak doświadczenia z X" lub "musimy zorganizować konsorcjum z firmą posiadającą uprawnienia Y".
- Generowanie tekstów ofertowych. Opis sposobu realizacji, opis doświadczenia, deklaracje formalne — wszystko wstępnie napisane na podstawie wzorów z poprzednich ofert i konkretnych danych z bazy firmy.
- Lista dokumentów do podpisu/skanowania. System wskazuje dokładnie które oryginalne dokumenty z bazy firmy (referencje, uprawnienia, zaświadczenia) trzeba załączyć — z linkiem do skanu.
Co zostaje człowiekowi
Specjalista ds. zamówień otwiera "wstępną ofertę" wygenerowaną przez system i:
- Czyta podsumowanie wymagań (Claude pokazuje top 10 najważniejszych do potwierdzenia)
- Weryfikuje proponowane dopasowanie kadry i referencji
- Decyduje o stawce — to nadal człowiek (estymacja kosztów wymaga znajomości lokalnych warunków, sytuacji rynkowej, ryzyk)
- Modyfikuje teksty opisowe tam, gdzie warto pokazać konkretną przewagę firmy
- Klika "wygeneruj finalne pakiety dokumentów" — system składa wszystko zgodnie z wymaganiami SIWZ (z numeracją załączników, podpisami w odpowiednich miejscach)
Z 8-20 godzin pracy → 1-3 godzin weryfikacji i decyzji wartościowych. Reszta to było zbieranie informacji i przepisywanie — czyli dokładnie to, co AI robi szybko i niezawodnie.
Najważniejszy efekt: firma startuje w więcej przetargów
Nie chodzi tylko o oszczędność czasu na jednej ofercie. Chodzi o to, że firma może startować w 30-50 przetargach miesięcznie zamiast w 5-10. To 5x większa powierzchnia ekspozycji rynkowej — przy tym samym zespole. Wzrost przychodów wynika z większej liczby wygranych w absolutnych liczbach, mimo tego samego win rate.
Architektura całego systemu
Pełen stack wdrożenia
- Frontend: PHP + jQuery
- Backend: PHP + Node.js (MCP)
- Claude Code (orkiestracja)
- Llama 3.1 8B fine-tuned
- vLLM (model serving)
- PostgreSQL + pgvector
- Redis (cache)
- Cron jobs (crawler nocny)
- Własna infrastruktura GPU (RTX 5090)
Model jest trenowany i hostowany lokalnie. Żaden fragment SIWZ ani dokumentu firmy nie wychodzi poza serwer klienta. Claude Code jako warstwa orkiestracji jest jedynym komponentem zewnętrznym — i jemu też podawane są tylko ustrukturyzowane podsumowania, nie surowe dokumenty.
Czego się nauczyliśmy
Lekcja 1: Polskie dokumenty wymagają polskich modeli
Ogólne LLM-y (Claude, GPT) świetnie rozumieją polski w warstwie konwersacji. Ale gdy mówimy o wyciąganiu strukturalnych danych z dokumentów prawno-technicznych, terminologia branżowa (budowlana, zamówień publicznych) sprawia, że model wyspecjalizowany w polskich SIWZ-ach jest znacząco dokładniejszy niż ogólny model. Fine-tuning na własnych danych branżowych to nie luksus, to konieczność dla niektórych zastosowań.
Lekcja 2: Hybryda > monolit
Najlepsze wyniki dostajemy łącząc różne komponenty AI dla różnych zadań. Claude jako "mózg" orkiestrujący proces. Własny model jako precyzyjny ekstraktor. RAG dla wyszukiwania w bazie firmy. Klasyczna logika biznesowa (PHP) dla deterministycznych reguł (np. "jeśli wymaga się ubezpieczenia 5M zł, a my mamy 3M zł, nie startujemy"). Nie próbuj zrobić wszystkiego jednym modelem.
Lekcja 3: Procesy zewnętrzne (przetargi) zmieniają się rzadko — to ogromny plus
Struktura polskich SIWZ-ów, wymagań KSC dotyczących informatyzacji, kategorii CPV — to wszystko zmienia się raz na lata. Model trenowany dziś będzie działał świetnie za 3 lata. To bardzo komfortowy biznesowo obszar do automatyzacji AI — w przeciwieństwie np. do reagowania na trendy konsumenckie, gdzie model się starzeje w miesiącach.
Lekcja 4: Pierwszy przetarg wygrany dzięki systemowi to moment "wow"
Klient pamięta dokładnie pierwszą wygraną, w której system zidentyfikował ogłoszenie z regionalnego BIP-u, wstępnie wypełnił ofertę, a specjalista po godzinie weryfikacji złożył. Wygrali. To był moment, w którym wszyscy w firmie zrozumieli co właśnie się stało.
Co dalej
Najbliższe rozwinięcia, nad którymi pracujemy z klientem:
- Predykcja konkurencji — analiza historycznych wyników przetargów żeby przewidzieć, którzy oferenci wystartują w danym postępowaniu i jakie zaproponują ceny
- Auto-monitoring zmian SIWZ — zamawiający czasami publikują wyjaśnienia i modyfikacje już po ogłoszeniu. System sam wykrywa zmiany i aktualizuje analizę
- Asystent na rozprawie odwoławczej — gdy oferta zostaje odrzucona, AI pomaga przygotować odwołanie do KIO na podstawie znajomości precedensów
Startujesz w przetargach publicznych?
Jeśli Twoja firma uczestniczy w postępowaniach przetargowych — w budownictwie, IT, usługach, dostawach — możemy zbudować podobny system. Pierwsza konsultacja 60 minut, bezpłatna, bez zobowiązań.
Umów konsultację →