AI vytěžování dokumentů s OpenAI GPT [Vzdělávací okénko, 12.6.2025]

Záznam ze Vzdělávacího okénka HAVIT z 12. června 2025.
Ukázka implementace (POC) vytěžování dokumentů pomocí moderních AI technik. Kombinace Azure Document Intelligence (s výstupem do Markdown) a LLM (OpenAI GPT-4o) pro efektivní vytěžování netriviálních dokumentů (zde přijatých faktur i s energetickými přílohami).

O čem přednáška je

Potřebujete z naskenovaných nebo PDF dokumentů dostat strukturovaná data? Tradiční OCR systémy (Kofax, EFlow, starší Azure Forms Recognizer) vyžadují trénování na konkrétních layoutech a ruční definici cílových polí. V této přednášce ukazuji modernější přístup – kombinaci dvou AI služeb, která zvládne i netriviální dokumenty bez předchozího trénování.

Azure Document Intelligence – konverze do Markdown

Prvním krokem je převod vstupního dokumentu (PDF, sken, fotografie) do strojově čitelné podoby. Azure Document Intelligence analyzuje layout dokumentu a výstupem je Markdown – čistý text se zachovanou strukturou tabulek, nadpisů a odstavců. Oproti klasickému OCR výstupu je Markdown ideálním vstupem pro LLM, protože zachovává kontext a vztahy mezi údaji.

OpenAI GPT-4o – extrakce strukturovaných dat

Markdown výstup z Document Intelligence předáváme OpenAI GPT-4o s promptem, který definuje cílovou strukturu JSON výstupu. Model díky function calling vrací přesně typovaný JSON se všemi požadovanými poli – číslo faktury, datum, dodavatel, položky, částky, měrné jednotky a další technické údaje.

Energetické faktury jako netriviální use case

Ukázka pracuje s reálným scénářem zákazníka – vytěžování přijatých energetických faktur. Tyto dokumenty obsahují desítky položek s různými měrnými jednotkami (kWh, MW, Kč/MWh), technické údaje jako činná a jalová složka, distribuční poplatky, rezervované kapacity a smluvní hodnoty. Výstupní JSON se zapisuje přes REST API do cílového systému, kde se jednotlivé řádky mapují na specifická pole včetně netypických zápisů (např. nulová jednotková cena pro technické údaje).

Implementace v .NET

Celý POC je implementován v C# / .NET s využitím Azure SDK pro Document Intelligence a OpenAI SDK pro komunikaci s GPT-4o. Přednáška zahrnuje praktické ukázky kódu, prompt engineering pro strukturovaný výstup a tipy pro nasazení v produkčním prostředí.

Blazor performance – záznam a slides [TechEd Praha 2025]

Záznam z přednášky pro konferenci TechEd Praha 2025, kde jsem ukazoval některé zajímavé aspekty výkonnosti Blazor (WebAssembly) aplikací.

  • Specifika výkonu Blazor WebAssembly vs. Server — kde jsou skutečná výkonová úzká hrdla
  • JavaScript interop overhead — proč ho chápat jako inter-process komunikaci
  • Optimalizace download size — Map Static Assets a fingerprintování v .NET 9
  • Component lifecycle a change detection — kdy a proč Blazor přerenderuje
  • Jak zastavit lavinu přerenderování — @key direktiva a správná struktura komponent
  • Výkonový overhead při velkém počtu komponent (měření Blazor týmu)
  • Server prerendering pro lepší UX i SEO
  • WebAssembly profiling v .NET 10 — nativní Browser DevTools profiling (preview)

Slides

Novinky v C# 12, 13 a 14 (.NET 8, 9 a 10) – záznam [TechEd Praha 2025]

Přehled novinek C# 12 (.NET 8), C# 13 (.NET 9) a preview C# 14 (.NET 10) – praktické ukázky ve Visual Studiu.

  • C# 12: primary constructors – DI pattern, capture, naming konvence
  • C# 12: collection expressions, inline arrays, spread operátor
  • C# 12: type aliases, default lambda parametry, [Experimental] atribut, interceptory
  • C# 13: nová třída Lock – modernizované zamykání vláken s using
  • C# 13: params collections (Span, IEnumerable) a výkonové výhody
  • C# 13: partial properties, indexery a ref struct vylepšení
  • C# 14: extension members – extension bloky, properties, statické metody
  • C# 14: klíčové slovo field, null conditional assignment (?=), dictionary expressions

Přednáška zazněla na konferenci TechEd Praha 2025.

FluentValidations vs Today [Robert Haken, Vzdělávací okénko, 5.6.2025]

Po půlnoci hlásil validátor: datum vystavení faktury nesmí být v budoucnosti – ale porovnával se včerejším datem. Proč?

  • Záhadný bug v Blazor WebAssembly: fakturační validátor po půlnoci odmítá dnešní datum
  • FluentValidation validátory jsou scoped-service – v Blazor WASM to prakticky znamená singleton
  • Pravidla jako LessThanOrEqualTo(datum) se vyhodnotí jednou v konstruktoru a hodnotu zmrazí
  • Řešení: Must(x => x <= timeProvider.GetLocalNow()) – lambda se vyhodnocuje při každé validaci
  • Přidej custom error message – Must generuje pouze generické hlášení

Vzdělávací okénko prezentoval Robert Haken.

WASM: AggregateException_ctor_DefaultMessage (Could not resolve type with token …)

Narazili jsme po instalaci .NET 9 SDK 9.0.204 (a nepomohl ani 9.0.300) na zajímavou chybu published Blazor WebAssembly front-endů (browser console výstup, front-end nenabíhá):

ManagedError: AggregateException_ctor_DefaultMessage (Could not resolve type with token 01000024 from typeref (expected class 'System.Reflection.Assembly' in assembly 'netstandard, Version=2.1.0.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51'))
    at an (dotnet.runtime.5nhp1wfg9b.js:3:26894)
    at Kt.resolve_or_reject (dotnet.runtime.5nhp1wfg9b.js:3:26449)
    at dotnet.runtime.5nhp1wfg9b.js:3:172714
    at dotnet.runtime.5nhp1wfg9b.js:3:172778
    at fr (dotnet.runtime.5nhp1wfg9b.js:3:35046)
    at Fc (dotnet.runtime.5nhp1wfg9b.js:3:172361)
    at dotnet.native.swgexbmoy7.wasm:0x1f1a4
    at dotnet.native.swgexbmoy7.wasm:0x1c8ae
    at dotnet.native.swgexbmoy7.wasm:0xea19
    at dotnet.native.swgexbmoy7.wasm:0x1ec88

První podezření bylo na trimming, nicméně když to zkrátím, tak se ukázalo, že se jedná o klasický problém buildů po instalaci nového SDK – je potřeba vymazat pracovní složky build-agentů, pokud každý váš build neběží na úplně čistém prostředí, ale používáte nějakou formu inkrementálního uspořádání. Když to převedu do roviny lokálního vývoje s Visual Studiem, je potřeba udělat Clean solution a vymazat složky bin a obj.

Proč to vůbec píšu? Kdyby někoho potkala stejná chyba, při troše štěstí vygooglí tento post a ušetří si čas s diagnostikou. U nás už jsme si poměrně zvykli, že když po instalaci nové verze SDK padá build, je potřeba před dalším bádáním vymazat pracovní složky build-agentů. Poprvé v historii se nám však stalo, že build úspěšně prošel (nepadal), ale výsledek build byl „vadný“ způsobem, který se projevil až při spuštění Blazor WASM front-endu v browseru.

OpenAPI + Scalar UI [Alexandr Hájek, Vzdělávací okénko, 22.5.2025]

Swagger UI v .NET 9 na odchodu? Scalar UI – moderní alternativa s dark mode, vyhledáváním a výměnou za jeden řádek kódu.

  • Proč Microsoft v .NET 9 opouští Swagger generátor a co ho nahrazuje
  • Scalar UI: dark/light mode, integrované vyhledávání a classic layout jako Swagger
  • Jak přidat Scalar UI do projektu – výměna jednoho řádku kódu
  • Konfigurace OIDC autentizace s Microsoft OpenAPI generátorem (access token, scopes)
  • Kompatibilita Scalar UI se staršími verzemi .NET a jinými OpenAPI generátory
  • MIT licence – open source s aktivní komunitou a rychlými opravami

Vzdělávací okénko prezentoval Alexandr Hájek.

Web Accessibility a EAA [Michal Melena, Vzdělávací okénko, 15.5.2025]

Záznam Vzdělávacího okénka HAVIT z 15. května 2025, kdy nám Michal Melena povídal o Accessibility a aktuálních povinnostech webových aplikací v této oblasti.

Seedy, UoW a Created v HAVIT stacku [Robert Haken, Vzdělávací okénko, 15.5.2025]

Technická změna v seedech, kde se nyní používá Unit of Work. Není potřeba explicitně nastavovat Created atribut, protože se o to postará systém. Taktéž je vhodné použít ExcludeUpdate, aby se Created hodnota nepřepisovala.

Tipy a triky pro mobilní vývoj na webu [Dominik Crha, Vzdělávací okénko, 10.4.2025]

Znáte v CSS funkci clamp()? To a další triky z vývoje webů pro mobilní zařízení nám ukázal Dominik.

  • CSS funkce clamp() pro fluid typography a spacing bez media queries
  • Accessibility a clamp(): proč záleží na 200% zoomu (WCAG SC 1.4.4) a jak ji neporusit
  • Touch targets: detekce dotikových zařízení pomocí pointer: coarse místo hardcoded breakpointů
  • Responzivní tabulky: negantivní margin + flexbox trik pro full-width scroll na mobilu
  • CSS funkce attr() – čtení HTML atributů přímo v CSS (užitelné v Blazoru)
  • CSS funkce light-dark() – automatická podpora dark/light mode bez Bootstrap boilerplate

Vzdělávací okénko prezentoval Dominik Crha.

Blazor – past cyklu for s RenderFragment [Vzdělávací okénko, 24.4.2025]

Představení problému s cyklem for v Blazoru, kde se při použití s RenderFragment může objevit poslední hodnota řídící proměnné. Je potřeba řídící proměnnou vykopírovat do lokální proměnné nebo se jí vyhnout cyklem foreach.