Zaka Tabish
Selected work

Projects

Each one starts with the short version. Open Engineering details when you want the problem, the decisions and what went wrong.

Innovation Challenge 2026 · Use Case 13 · Python, FastAPI, Qdrant, BGE-M3, BM25, Docling, Ollama / vLLM, Go

Private RAG Assistant: a compliance document reader for banks

Ask about GwG, KWG, MaRisk or DORA in English or German and get an answer where every statement points to a file, section and page. Fully self-hosted: documents, model and answers never leave the bank. Built in a 24-hour sprint in Specific-Group's Landshut office after the event's kick-off in Landau, and covered in the regional press.

50 PDFsDocling, §-aware chunks
QdrantBGE-M3 dense + BM25
Question + German rewrite4 ranked lists
RRF fusiontop 8, max 4 per doc
Open-source LLMMistral Small 3.1, in-tenant
Verified answercitations, confidence, audit
  • 12,186chunks from 3,387 pages
  • 5 → 20of 31 questions found, after the German rewrite
  • 113tests on the failure paths
Engineering details

Built for Specific-Group at the Innovation Challenge & Fair 2026 of Ecosystem Smart Niederbayern (8–10 October 2026). The event ran in two phases: it opened in Landau an der Isar with all teams together, then each team moved to its host company for the 24-hour build. Ours worked from Specific-Group's Landshut office, which is the part the regional press covered. This is Variant B of the brief: the fully self-hosted, open-source pipeline, from PDF ingestion to the chat UI and a one-click installer.

The problem

Compliance, risk and audit teams at German banks spend hours searching and quoting BaFin circulars, MaRisk, EBA guidelines and laws like the GwG and KWG. ChatGPT is off the table: the questions and documents fall under banking secrecy. They need answers they can verify, from a model that never leaves the bank's own infrastructure.

What I built

A citation-backed assistant over 50 regulatory PDFs (3,387 pages, 12,186 chunks). A natural-language question in English or German returns an answer in which every statement carries a [n] pointing to a file, section and page, plus a confidence score, a status and an audit-trail entry.

Key decisions
  • Hybrid search, because the questions are English and the law is German. Plain dense + keyword search found an expected document for 5 of 31 questions. Adding a German query (an LLM rewrite plus an EN→DE compliance glossary) to both sides raised that to 20 of 31 with the local stand-in models.
  • Chunks never cross a legal boundary. A chunker that knows § 10, Artikel 19 and AT 4.4.2 means every citation reads like 01_GwG.pdf | § 10 | p. 17-18.
  • Distrust the model's citations. Markers pointing to sources that were never shown are removed, fewer than 2 citations triggers one retry, and NOT_IN_SOURCES produces an honest refusal.
  • No Docker, no admin rights. Two shell scripts and a Go launcher for Windows install everything in user space and restore a prebuilt vector database.
Challenges
  • Parsing PDFs the way lawyers cite them: a non-breaking space in § 10, cross-references that look like headings, table-of-contents pages and EU recitals all broke section detection.
  • A stale checkpoint bug kept old chunks after a chunker change. The checkpoint fingerprint now includes a hash of the ingestion code itself.
  • Small models sometimes loop on citation markers or refuse and then answer anyway. Both are detected and cleaned up.
  • 113 tests cover corrupt or encrypted PDFs, the embedding endpoint or LLM going down mid-request, a database failing during an audit write, and 16 concurrent requests.
Result

50 of 50 PDFs ingested with no failures, 12,186 chunks embedded with BGE-M3 on a single RTX 2080 SUPER, and Mistral Small 3.1 24B answering through Ollama on hardware the bank controls. The Playground demo runs that same index in your browser; on the 30 in-scope evaluation questions it retrieves an expected source document for 26. The LLM step there is simulated, and the demo says so.

Personal hardware project · Arduino Nano, IR proximity sensors, relays, 12 V DC + 220 V AC motors, C++

An automatic cone crimping machine, built in my garage

I took a manual machine that crimps lids onto ice-cream cones and made it run itself: drop in a cone, and it turns, crimps and throws the finished cone into a bin. The video shows the result first, then the mechanism, the electronics, a live demo and a full code review.

Cone dropped inIR sensor A sees it
Disc turns12 V DC motor
Under the pressIR sensor B stops it
Crimp220 V winch, reed switch
Ejectseesaw lever to a bin
Engineering details
The problem

The base machine, from Maru Machinery, crimps the lid onto a filled ice-cream cone so nothing falls out. Run by hand, every cone has to be positioned, pressed and removed one at a time, which is slow and tiring.

The mechanism

A slotted disc carries the cones. A motor-driven winch pulls the crimping piston down onto the cone, and on the way round a seesaw lever with a leaf-spring "spatula" knocks the finished cone out of its holder into a container. Slots for small and large cones are calibrated separately.

The electronics
  • An Arduino Nano reads two IR proximity sensors and a reed switch that signals when the crimp has reached full tension.
  • Three relays: one drives the 12 V disc motor, and the 220 V crimping motor is switched through a 30 A secondary relay, because the 10 A relay module isn't rated for a motor with that much torque.
  • A flyback diode on the DC motor absorbs the back-EMF so it stops the instant power is cut. A fan cools the relays.
  • The USB port is brought outside the box, so a laptop can watch every state change live in the serial monitor.
The code
  • A small state machine. Cone at sensor A and nothing at B: turn the disc. Cone arrives at B: stop the disc, wait 100 ms to settle, run the crimp motor until the reed switch closes, wait 200 ms for the piston to retract, then wait for the next cone.
  • Safe on power-up. Inputs use INPUT_PULLUP and the relay logic is inverted, so every motor is guaranteed off when the machine is switched on.
  • Observable. Every change in sensor and motor state is printed over serial, for example Sensor A: ACTIVE | Sensor B: INACTIVE | Motor: ON.
Result

A fully automatic cycle: drop in a cone and it is indexed, crimped and ejected with no hands on the machine, and the lid is held firmly by the cone's edges. The demo uses empty cones, because ice cream melts faster than a calibration run.

Nokia Nuremberg · Python, HTTP streaming, MCP, Jira API

An MCP server for hardware diagnostics

An engineer asks "board B3 failed overnight, why?" in Cursor, and the model runs the real test pipeline on the real board, checks Jira for related tickets and answers with both.

Engineerasks in Cursor
MCP serverlab gateway machine
Diagnostics suiteruns on real hardware
Jira APIticket history
Grounded answerback in the conversation
Engineering details
The problem

Engineers investigating a failing board had to run the right test pipeline by hand, then dig through Jira for related history separately. Two disconnected tools, no shortcut from a symptom to its context.

What I built

A streamable HTTP MCP server on a lab gateway machine that exposes the diagnostics suite and Jira as tools an AI model can call, so a plain-language question returns real results from physical hardware.

Key decisions
  • Streamable HTTP over stdio, so engineers reach the server from their own machines.
  • Tools scoped narrowly to specific tests and ticket lookups, not open shell access, so a wrong guess from the model can't harm the hardware.
Challenges
  • Test pipelines run for minutes, so long calls must not block the conversation.
  • Results need enough structure for the model to reason over, not raw logs.

Internal work. Code stays with Nokia, but I can talk through the architecture in detail.

Nokia Nuremberg · Python, anomaly detection, SMTP alerting

Lab network monitoring & anomaly alerting

A degrading link used to show up hours later as a mysterious test failure. Now it is caught against its own normal behaviour and reported by email the moment it drifts.

Lab network linksperiodic health checks
Anomaly detectiondeviation from baseline
Within rangelogged, silent
AnomalySMTP alert sent
Engineering details
Key decisions
  • Lightweight polling instead of new monitoring infrastructure; the lab had enough moving parts.
  • Tuned for fewer, trustworthy alerts: too strict pages someone for every blip, too loose misses what it exists to catch.
Challenges
  • Lab traffic is bursty (test runs, firmware flashes, hardware plugged in and out), so "normal" isn't a fixed number.
  • A baseline that adapts to that without drowning in false positives was most of the work.

Internal work. Architecture and approach available on request.

Bachelor thesis · NodeMCU ESP8266, NEO-6M GPS, WebSockets, MERN, React Leaflet, OpenStreetMap

City Waste Management System Using Van Tracking

Vans, complaints and routes were three systems that never spoke. A GPS box in each van, a WebSocket backend and three web portals put them in one data model, and complaint handling got 17% faster.

NodeMCU + NEO-6Min the van
WebSocketpersistent, not polled
Node / Expresssocket.io broadcast
MongoDBpositions, routes, complaints
Adminlive fleet map
Driverroute & queue
Citizenfile & track
  • 17%faster complaint handling
  • 25%better route efficiency
  • 3portals, one data model

Live simulation City Waste Collection: Fleet View

simulated data, updating now

A front-end rebuild of the real dashboard, driven by simulated GPS and sensor data. The real system also needs Node/Express, MongoDB and GPS hardware.

4Vans active
…Bins over 80% full
25%Route efficiency gain
17%Complaint time saved
    Engineering details

    Final year project at Marathwada Institute of Technology, Chh. Sambhajinagar, under Dr. Babasaheb Ambedkar Technological University. Submitted May 2024 under the guidance of Ms. Ankita Shewale, built by a team of four; my share was the hardware-to-backend link and the live tracking side of the web application.

    The three portals

    Citizen

    Drops a pin on the map to mark exactly where the problem is, files a complaint against those coordinates, and watches its status and the assigned van live.

    Van driver

    Sees the assigned route and the complaints along it, and resolves each one from the same screen, so a complaint closes when the work is done.

    Municipal corporation

    Registers vans, watches the whole fleet on one map, assigns complaints to routes and reads collection efficiency per zone.

    Key decisions
    • WebSockets over HTTP polling. One persistent socket per van, broadcast through socket.io, keeps the map live without thousands of near-empty requests an hour. WebSocketClient.h and TinyGPS++ on the ESP8266.
    • OpenStreetMap and Leaflet over a paid maps API, so it stays viable on a municipal budget.
    • Coordinates as the primary key of a complaint, which is what lets complaints be assigned to routes automatically.
    • Built to run on simulated GPS during development, the same approach the dashboard above uses.
    Challenges
    • A GPS fix is not a position. Raw fixes jitter by tens of metres while a van sits still, so points are filtered before they are trusted.
    • A moving fleet without melting the browser: updates batched, markers grouped by zoom level.
    • Defining "route efficiency" as distance covered against bins actually served, and time in the zone against time getting there.
    The hardware

    A self-contained box: NodeMCU ESP8266, NEO-6M GPS and antenna, a LiPo battery with micro-USB charging, and a toggle switch. Nothing needs attention during a round, because a tracker that needs attention gets switched off.

    Security

    bcrypt-hashed passwords, explicit CORS, and each role reaching only its own endpoints. The system holds phone numbers next to home coordinates; treating that casually was not an option.

    University project · Clickable prototype · HTML, CSS, vanilla JavaScript

    Großry: a student collective purchasing app

    Wholesale prices without wholesale quantities. Students pool their monthly groceries to unlock bulk price tiers, Großry buys once, and a student crew brings it to campus for QR pickup.

    Student demandmonthly basket
    Aggregationprice tiers unlock
    Bulk procurementone supplier order
    Runner + Distributoreach with a backup
    Slot + QR pickup12 people / 15 min
    Engineering details
    Key decisions
    • Savings defined, not asserted. Saving = reference retail basket − actual landed cost. Großry takes 20% of that verified saving, and the cart shows every line of it.
    • No single point of failure. Every crew job has a paid backup who takes over automatically.
    • Aggregated insights, not data selling. Partners see totals only; products bought by fewer than 10 students are suppressed.
    Constraints taken seriously
    • GDPR data minimisation, with export and deletion in the profile.
    • Food hygiene: everything handed out sealed as supplied; chilled and frozen goods stay out of student-run distribution.
    • Terms and Privacy ship as clearly marked drafts.
    Try it

    Use the demo account, then press Advance to move the month from shopping to distribution day. All people, prices and suppliers are fictional.

    More code on GitHub