05.2026 — present
Fullstack Developer / AI Engineer
Nodeic — own company (B2B contract) · client: AI recruitment platform (NDA)
Building a recruitment platform with an AI-powered candidate search engine. I built the front end from scratch; the backend, the vector database and the infrastructure were already running, so I work inside existing code — the search engine, the data model, migrations and re-processing the whole base after changes. The same client also got an internal contact-sourcing tool.
- Built a production web application from scratch (Nuxt 4 / Vue 3, SSR, BFF): Vertical Slice Architecture on Nuxt Layers, a design system of my own, PL/EN i18n, consent-gated analytics.
- Developing a semantic candidate search engine (Google Gemini, e5-large embeddings, Qdrant) over a corpus of a few thousand CVs: strategy-pattern rebuild, hard filters, pipeline versioning and a full re-extraction run in production. I wrote the second version of the engine test-first — the scoring engine is fully covered, and edge-case model responses are exercised through a fake LLM, because writing a test is easier than forcing a model into a specific wrong answer.
- Improved the data the search runs on: a canonical profession category derived during CV extraction, skill entries reduced to a shared form, and a rebuild of the matching logic with Polish inflection handling. see the case study ↓
- Established a search evaluation methodology (LLM-as-judge, ranking correlations, a 50-posting benchmark built from real-traffic logs) and based decisions on it: data fixes raised ranking agreement with the independent evaluation from 2% to 52%, my cross-encoder reranking R&D ended in a documented decision not to ship with the conclusion that the next leap needed LLM reranking, and a second engine version built in isolation from production — with a light LLM reranker built on that conclusion — wins the benchmark 22:2 (ordering agreement 70% vs 35%) and serves production traffic — the post-deployment balance, computed on 1,214 rows of real search logs, showed four classes of defect gone from the list the client sees, among them a filter cutting more than half the pool in 9% of queries and 6% of positions scoring below the quality threshold. see the case study ↓
- GDPR in the AI layer: fail-closed anonymization of surnames in LLM-generated text (handling Polish declension). Found and fixed a stored XSS in the CV preview myself: the file came back with the MIME type stored at upload and opened as a blob inheriting the panel's origin — the server now forces the content type, adds nosniff and rejects anything that is not a PDF.
- For the same client I built the second version of a B2B lead-sourcing tool (Python, Pydantic AI / Gemini, FastAPI, PostgreSQL, Docker), rewritten from scratch: a pipeline from job postings, through employer profiles and model enrichment with grounding, to three independent sources verifying the phone number — the company's website, the GUS state register, Google Places — in “free before paid” order. Every fact carries its origin and status, the model runs in a single typed call forbidden to guess, and its output feeds a deterministic target filter. About 1.3k companies in the base, 83% of in-target companies with a confirmed phone. see the case study ↓