P R O J E K T YK O N T A K T

[06]

LEX AI — WTYCZKA DO WORDA DLA PRAWNIKÓW

TIER A · ROK 2026 · STATUS: W BUDOWIE · JĘZYKI: TYPESCRIPT

Dodatek do Worda łączący twardy szablon z polami generowanymi przez model

[FIG. 1] MISJA

Buduję dodatki do aplikacji biurowych (Office.js), czyli interfejs w miejscu, w którym odbiorca już pracuje — tu w samym Wordzie. Mój klient, prawnik z kancelarii, automatyzował szablony w ClauseBase, ale twarda automatyzacja nie radzi sobie z klauzulami negocjowanymi indywidualnie, a czyste narzędzia AI generują cały dokument i robią z prawnika pełnoetatowego recenzenta. Łączę więc dwa paradygmaty w jednym dokumencie: twarde placeholdery (string/data/kwota) wypełniane formularzem bez żadnej weryfikacji oraz placeholdery AI z instrukcją, których treść Claude streamuje na żywo do podglądu w task pane. Teza produktu: 90% dokumentu to deterministyczny szablon, AI wypełnia ~10% „unknown unknowns” — prawnik weryfikuje 8–10 klauzul zamiast 20 stron, co czyni jego odpowiedzialność zawodową (wytyczne izby radców) fizycznie wykonalną. Rozróżnienie twarde-vs-AI zakodowałem wprost w systemie typów; skaner przechodzi dokument przez Office.js, a builder promptów składa kontekst dokumentu z instrukcją placeholdera, przycinając go świadomie: około 12 tysięcy znaków całości albo sama końcówka sekcji, zależnie od pola. Odpowiedź modelu strumieniuję przez SSE, żeby prawnik widział tekst w trakcie powstawania. Pracuję tu z klientem z branży regulowanej i projektuję pod jego proces, nie pod demonstrację technologii — stąd analiza konkurencji (ClauseBase/Spellbook/Libra) i wycena etapowa, MVP 100–180 tys. PLN netto.

[FIG. 2] ARCHITEKTURA

najedź na blok, by zobaczyć opis

[FIG. 3] WYZWANIA

[+][CH-01]

Dwa paradygmaty w jednym dokumencie to nie problem UI, tylko problem odpowiedzialności: jeśli prawnik nie odróżni na pierwszy rzut oka treści deterministycznej od wygenerowanej, musi weryfikować wszystko — i cała wartość produktu znika. Rozdzieliłem więc paradygmaty na poziomie systemu typów (types/placeholder.ts) i zbudowałem skaner, który klasyfikuje każdy placeholder w dokumencie; twarde pola wypełnia formularz, AI-owe dostają kartę z instrukcją i podglądem. Dzięki temu weryfikacji podlega tylko ~10% treści — i dokładnie widać, które.

[+][CH-02]

Kancelaria używała już ClauseBody — zamkniętego narzędzia do szablonów, z którym wtyczka musiała współistnieć w tych samych dokumentach, a które nie wystawia żadnego API. Jedynym „interfejsem” okazał się wygląd dokumentu: pola ClauseBody to tekst we wzorcu {{NAZWA}} podświetlony na turkusowo. Napisałem więc detektor, który szuka wildcardem {{*}}, filtruje trafienia po highlightColor === 'Cyan' i waliduje nazwę regexem — a cały skan działa warstwowo „najpewniejsze źródło najpierw”: natywne ContentControls wtyczki, potem regex-fallback na markery tekstowe, na końcu detektor obcych pól, z deduplikacją po nazwie. Z tego samego świata przyszło drugie ograniczenie: identyfikatory pól nie mogą mieć polskich znaków, więc zamiast odrzucać „Nazwa firmy” zbudowałem transliterator (Ą→A … Ż→Z) i rozdzieliłem model na techniczny name i ludzki displayName — prawnik pisze po polsku, dokument dostaje bezpieczne ASCII.

[+][CH-03]

Office.js to zamknięte, kapryśne środowisko: każda mutacja dokumentu idzie przez asynchroniczny cykl load → sync → zapis, a samo ustawienie koloru podświetlenia wymaga dwóch osobnych sync() — najpierw załadowania fontu, potem zapisu. Szablon musiał przy tym żyć w samym pliku .docx, bez zewnętrznej bazy — a CustomXmlParts nie mają operacji „zastąp”: jest tylko dodawanie i kasowanie. Zbudowałem więc ręczny upsert: załaduj wszystkie części XML, odfiltruj po namespace jako kluczu tożsamości, skasuj stare, dodaj nową — cztery sync() po kolei — a JSON szablonu opakowałem w CDATA, żeby nie walczyć z XML-escapowaniem; odczyt ma dwie ścieżki fallbacku, zanim podda się z czytelnym błędem domenowym. Do tego bramka gotowości: Office.onReady bywa niewywołane poza Wordem, więc hook po 3 sekundach i tak renderuje panel, rozróżniając platformy Word/Browser/Standalone/Timeout — UI nie zawisa na spinnerze niezależnie od humoru hosta.

[+][CH-04]

Prawnik nie zaufa czarnej skrzynce, która po 20 sekundach wypluwa gotową klauzulę — musi widzieć, jak treść powstaje. Zbudowałem streaming Claude prosto do task pane (useClaudeStream, StreamingPreview): klauzula pisze się na ekranie na żywo, a builder promptów skleja kontekst całego dokumentu z instrukcją konkretnego placeholdera, żeby wygenerowany fragment pasował do reszty tonem i terminologią. Podgląd na żywo zmienia psychologię weryfikacji — prawnik czyta w trakcie, nie po fakcie.

[FIG. 4] WARSTWA AI

Model generuje strumieniowo tylko treść placeholderów AI — tych ~10% dokumentu, których nie da się przewidzieć szablonem; builder promptów składa instrukcję pola z przyciętym kontekstem dokumentu (~12 tysięcy znaków dla całości albo końcówka sekcji, per pole do wyboru). Warstwę produktową odseparowałem od dostawcy bramką OpenRouter w formacie OpenAI-compatible: domyślnie pracuje Claude Sonnet, ale zmiana na GPT to zmiana pola w ustawieniach, nie kodu. Granica jest twarda i zakodowana w typach: AI nigdy nie dotyka części deterministycznej, bo każdy jej dotyk oznaczałby dodatkową weryfikację prawnika — czyli śmierć tezy produktu.

[FIG. 4A] PRESALE — WYCENA ETAPOWA

ETAP 1 · ANALIZA RYNKU + SPECYFIKACJAwymagania.md ✓
ETAP 2 · WYCENAMVP 100–180 TYS. PLN NETTO
ETAP 3 · MVP + PILOTAŻ W KANCELARIIW TOKU
ETAP 4 · ROLLOUTPO PILOTAŻU

REALNY KLIENT · KANCELARIA · ANALIZA KONKURENCJI: CLAUSEBASE / SPELLBOOK / LIBRA

[FIG. 2A] TEZA 90/10

20 STRON DO PRZECZYTANIA8 KLAUZUL DO WERYFIKACJI

czyste AI: prawnik czyta wszystko od zera

[FIG. 6] STACK & LINKI

OFFICE.JSREACT 18TYPESCRIPTFLUENT UIVITE 6TAILWINDOPENROUTER (CLAUDE/GPT, STREAMING SSE)ZUSTAND