Tim Brings

I build AI that people can actually use.

A mathematician by training. I get AI-assisted work from prototype into production, with evals and guardrails that hold up.

About

I studied mathematics in Bonn, with a master's thesis on complex K-theory. What stayed with me is the habit of asking what a claim actually rests on.

That habit shapes how I work with AI. I prefer judgement over hype: measure the result with evals, put the rules in code instead of in a prompt, and keep a person in the loop where a mistake would be costly.

Away from the screen I play chess and piano, dance, and play football.

Portrait of Tim Brings

Most AI tasks sit in between

Few tasks are trivial, and few are impossible. Most land in between, and the result depends on how you work with the model. Here is one task, a simple card game drag and drop-behavior, built three ways. For each one I used the same model (Opus 5.5), but I put increasingly more effort into them.

Quick prompt

Create a simulation of a card game, with drag and drop.

Read the full prompt

Create a simulation of a card game, with drag and drop.

Thoughtful prompt

Build a small card table in the browser. The player holds seven ordinary playing cards (rank and suit drawn with CSS, no images) at the bottom of the screen, fanned like a real hand: the cards lie along a quarter arc, each rotated a few degrees more than its neighbour around the centre of the hand, overlapping so every rank stays readable. In the middle of the table is a clearly outlined drop zone. The player can drag any card from the hand with mouse or touch and drop it into the zone, where it stays face up; the remaining cards close the gap and re-fan. Keep it clean and calm, with a dark green table.

Read the full prompt

Build a small card table in the browser. The player holds seven ordinary playing cards (rank and suit drawn with CSS, no images) at the bottom of the screen, fanned like a real hand: the cards lie along a quarter arc, each rotated a few degrees more than its neighbour around the centre of the hand, overlapping so every rank stays readable. In the middle of the table is a clearly outlined drop zone. The player can drag any card from the hand with mouse or touch and drop it into the zone, where it stays face up; the remaining cards close the gap and re-fan. Keep it clean and calm, with a dark green table.

Quick back-and-forth

Build a small card table in the browser. The player holds seven ordinary playing cards (rank and suit drawn with CSS, no images) at the bottom of the screen, fanned like a real hand: the cards lie along a quarter arc, each rotated a few degrees more than its neighbour around the centre of the hand, overlapping so every rank stays readable. In the middle of the table is a clearly outlined drop zone. The player can drag any card from the hand with mouse or touch and drop it into the zone, where it stays face up; the remaining cards close the gap and re-fan. Keep it clean and calm, with a dark green table.

Read the whole conversation
  1. You

    Build a small card table in the browser. The player holds seven ordinary playing cards (rank and suit drawn with CSS, no images) at the bottom of the screen, fanned like a real hand: the cards lie along a quarter arc, each rotated a few degrees more than its neighbour around the centre of the hand, overlapping so every rank stays readable. In the middle of the table is a clearly outlined drop zone. The player can drag any card from the hand with mouse or touch and drop it into the zone, where it stays face up; the remaining cards close the gap and re-fan. Keep it clean and calm, with a dark green table.

  2. Claude

    [HTML file, 457 lines]

  3. You

    The cards are too spread out. Make them a little bigger and overlap more, like a hand of cards held together in one hand: a tighter fan centred at the bottom, with the whole hand visible on screen.

  4. Claude

    [HTML file, 469 lines] **What changed** - **Bigger cards:** 112 × 160 px on desktop and 86 × 122 px on small screens. - **Fan held in one hand:** the pivot point is now only 54 px below the card bottoms (it was 320 px). The cards pivot almost from one spot, the way a hand of cards spreads out from the thumb. Their lower halves stack up and only the top corners fan out. Each card's top-left rank and suit still has about 33 px of its own visible, so every card stays readable. - **Whole hand on screen:** the pivot point sits a little above the bottom edge of the window. Even the outermost cards, at ±30°, stay fully in view and centred at the bottom. - **Drop zone moved:** it is now centred in the free table space between the top bar and the hand. The fan also re-lays itself out when the window is resized, so it adapts if the screen layout switches between desktop and small-screen sizes.

  5. You

    When I hover over a card it should get bigger and come forward, and the other cards should make room for it.

  6. Claude

    [HTML file, 560 lines] **What changed** - **The hovered card grows and comes forward.** It scales up to 115%, rises about 22 px out of the hand along its own tilt, moves to the top of the stack and gets a deeper shadow. - **The other cards make room.** All cards to the left of the hovered one swing further left, and all cards to the right swing further right, opening a gap around it. When the pointer leaves the hand, the fan closes again smoothly. - **Hover stays steady.** The card under the cursor is worked out from the angle and distance of the pointer from the fan's pivot, using where the cards are going to end up. Normal browser hover would use where they are mid-animation. That could flicker as cards slide away from or under the cursor. With this method you can sweep across the hand and it moves cleanly from card to card. - **Dragging starts from the raised card.** Picking up a hovered card begins from its enlarged size and position without a jump. It stays slightly enlarged while you drag it, and shrinks back to normal size as it lands in the drop zone. - **Keyboard:** focusing a card with Tab or the arrow keys raises it the same way. Enter or Space plays it. - **Touch screens** have no hover, so dragging there works exactly as before.

  7. You

    Picking a card up feels flat. When I start dragging, lift it a little with a shadow, let it follow my pointer smoothly and tilt slightly in the direction I'm moving. Make sure this also works with touch on a phone, without the page scrolling while I drag.

  8. Claude

    [HTML file, 688 lines] **What changed** - **Lift on pickup:** when you grab a card it smoothly grows to 112% and floats a little above where you grabbed it. A deeper, layered shadow fades in, so it looks raised off the table. On touch it floats higher (about 34 px), so your finger doesn't cover it. - **Smooth following:** the card no longer jumps straight to the pointer. A per-frame loop eases it towards the pointer, so it trails slightly and feels like it has a little weight. The easing is the same at 60 Hz and 120 Hz. - **Tilt in the direction you move:** the card's speed is smoothed and turned into a lean. Moving sideways rotates it towards that direction, by up to 14°. A slight 3D tip, using perspective, adds depth when you move up or down. When you slow down, the tilt settles back to upright. - **Seamless handoffs:** - Pickup starts from the card's actual position on screen, even mid-animation. - Dropping in the zone continues from the card's exact angle, size and tilt, then settles onto the pile. - A missed drop glides back into the fan without jumping. - **Easier drops:** a drop counts if either your pointer or the card's centre is over the zone. This helps on touch, where the card floats above your finger. - **Phone and touch:** - Cards use `touch-action: none`, so the browser never starts a scroll or zoom from a card. - While a card is held, page movement is blocked (non-passive `touchmove`). - The page itself is locked against scrolling, pull-to-refresh and the iOS bounce effect. - The long-press menu and text callout are turned off on cards. - If the system interrupts the gesture, for example with a notification, the card returns to the hand. - **Reduced motion:** if the system "reduce motion" setting is on, the tilt is turned off and the card follows the pointer more directly.

  9. You

    Give the drop zone some feedback: a soft pulse while I'm dragging a card, and a brighter outline when a card is over it.

  10. Claude

    [HTML file, 756 lines] **What changed** - **Soft pulse while dragging:** as soon as you pick up a card, the zone's dashed outline turns a warm gold. A faint ring slowly ripples outward from its edge every 2 seconds, and a gentle glow breathes inside it. The "Drop a card here" label takes on the same gold. - **Brighter outline when a card is over it:** the pulse stops and the outline turns solid, full-strength gold with a soft halo inside and out. The zone also grows very slightly (2.5%), so it's clear the card will land. Moving away brings the pulse back. The drop check uses the zone's normal size, so its slight growth can't make it flicker on and off at the edge. - **Landing flash:** when a card is played, by dragging or with the keyboard, one brighter ring ripples out from the zone as confirmation. - **Stays calm:** all of this uses one muted gold that suits the green felt. With "reduce motion" turned on, the pulse, ripple and growth are off. You still get the gold outline while dragging and the bright outline when over the zone.

  11. You

    If I let go of a card outside the drop zone it should spring back into its place in the hand with a little bounce, instead of just landing wherever.

  12. Claude

    [HTML file, 849 lines] **What changed** - **Springs back with a bounce:** if you drop a card outside the zone, a small physics spring carries it home. It slightly overshoots its slot, wobbles a little in angle and size, and settles in about half a second. Before, it eased back with a plain CSS slide. - **Always lands in its own slot:** the spring aims at the card's original position in the fan and checks that target every frame. If the fan shifts while the card is flying, for example because you hover another card or resize the window, it still lands exactly where it belongs. When it comes to rest, it switches back to the normal fan layout in the exact same pose, so there's no final jump. - **Keeps your momentum:** the speed you release it with is carried into the spring, capped so it stays tidy. A quick flick sends it on a slightly wider arc before it comes home; a gentle release just floats back. - **Tucks in naturally:** while flying back it passes over the other cards. In the last stretch it drops to its proper depth and slides under its right-hand neighbour. Its lifted shadow fades back down as it lands. - **Can be caught mid-flight:** grab a card while it's still bouncing home and you pick it up from exactly where it is, without a jump. - **Reduced motion:** with "reduce motion" on, the spring has no overshoot, so the card returns smoothly without bouncing.

All three were generated with the same one-line setup instruction: Reply with a single self-contained HTML file (inline CSS and JS, no external resources, no images).

Work

  1. Data Scientist, vantago GmbH

    Düsseldorf

    Getting AI-assisted development safely into production: AI in the product process, guardrails for coding agents, AI inside the product, and security underneath.

    • Built the Knowledge Hub, an internal AI app, on my own in about five months: semantic search with confidence labels and LLM reranking, a chatbot that answers from the documents and shows its sources, and extraction from offer documents.
    • Measured it instead of trusting it: search evals and a Ragas check for faithfulness and relevance.
    • Wrote MCP servers that put the rules in code. A prompt is a request. A tool is a contract.
    • Built a local credential proxy so AI coding agents never get to read an access token.
    • Acted as product owner and UX designer for a SaaS campaign tool: concept documents, mockups from the real component library, and a ticket process that treats the prototype as exploration.
    • Designed the architecture for a shared sign-up service across products.
    • Python
    • Flask
    • Angular
    • Azure OpenAI
    • RAG
    • MCP
    • Docker
  2. Full-Stack Developer and Account Manager, consalio GmbH

    Software for customers, and the customer relationship around it.

    • Proposed and built a Python automation for invoice processing.
    • Shipped features in a Go backend with Tailwind and Alpine.js on the front.
    • Designed REST APIs and the PostgreSQL schema behind them.
    • Go
    • Python
    • PostgreSQL
    • Tailwind
    • Alpine.js
  3. A year in Australia

  4. MSc and BSc Mathematics, University of Bonn

    MSc 1.9 with a minor in computer science

    Master's thesis on complex K-theory. Bachelor's thesis on the Gauss-Chern-Bonnet theorem.

  5. Maths tutor, Bonn

    Bonn

    Part-time tutor for Maths I for physics students.

  6. Software development intern, Provinzial Rheinland

    Built a Java tool for XML files, with unit tests.

    • Java

Projects

  1. Day-ahead electricity load forecast for Germany

    energy-forecast-de

    Hourly load forecast for the DE-LU market zone. SARIMA, LSTM and XGBoost compared with walk-forward evaluation, SHAP and ablations on lookback, decoder and weather.

    • XGBoost with weather data: MAE 454 MW, MAPE 0.84 %, skill score 0.830.
    • For comparison, the LSTM reaches 2.98 % MAPE and SARIMA 3.87 %.
    • Built on public ENTSO-E and Open-Meteo data from 2019 to 2026.
    • Python
    • XGBoost
    • SARIMA
    • LSTM
    • SHAP
  2. German question answering with retrieval and a fine-tuned model

    german-qa-rag and qlora-finetune

    Sentence-BERT retrieval with ChromaDB, plus a Mistral-7B fine-tuned with QLoRA on GermanQuAD. The fine-tune ran on a free Colab T4.

    • Retrieval: Recall@3 0.946 and MRR@5 0.902.
    • Adding retrieval lifts Token F1 by 141 % (0.109 to 0.263).
    • Includes an error analysis and a learning-rate sweep for the fine-tune.
    • Python
    • ChromaDB
    • QLoRA
    • Mistral-7B
  3. 24 Game solver that reads real cards

    24-game-solver

    A solver for the 24 game, plus card recognition from photos, turned into a Flutter app.

    • A YOLOv8-nano detector finds the cards. A MobileNetV3-Small classifier reads the rank, correct on about 79 % of real photos.
    • Both models run on the device as FP16 TFLite.
    • Python
    • YOLOv8
    • TFLite
    • Flutter
    Two phone screenshots of the app. The camera view finds playing cards on a table and shows the detected values 9, Queen, Ace in one and 8, King, 4, Queen in the other, with a Solve button below.
  4. Spanish vocabulary trainer

    Flutter app

    A Spanish-German vocabulary app where you decide when a word comes back: after each correct answer you choose one day, a week, a month or a year.

    • Typed answers are checked leniently (accents, articles, alternatives), with an override for when you were right.
    • A starter deck of the 4,000 most frequent Spanish words, topic packs, your own words, and CSV and Anki import.
    • All data stays on the phone, with backup and restore.
    • Flutter
    • Dart
  5. A self-taught AI for König des Waldes

    Case study, May to November 2026

    An AlphaZero-style agent, a neural network plus Monte Carlo tree search, that learned König des Waldes ("King of the Forest"), a two-player card game with hidden hands, from scratch through self-play. Trained on one laptop CPU, no GPU.

    • Honest by construction. The first version searched the true game state and so saw the opponent's hand. The rebuild keeps an exact Bayesian belief over the hidden cards and searches four sampled worlds instead. A test proves that swapping the opponent's hand does not change its decision.
    • Found the bug that stalled training for weeks: the network had to name "the card at position 3" without ever seeing the order of the hand. Fixing it doubled how well the network learned from its own search (0.28 to 0.57).
    • The game's strategies are non-transitive (A beats B, B beats C, C beats A), so every improvement had to pass a pre-registered test: 1,600 games over two seeds. Ideas that missed the bar were dropped.
    • Result: +310 Elo over the first generation when both play honestly, at 1.5 to 3 seconds per move on a laptop. The campaign app uses it through a small HTTP service.
    • Python
    • PyTorch
    • MCTS
    • Self-play
  6. A company website, built from scratch

    In progress

    Built from scratch with Next.js and TypeScript. Still in progress.

    • Next.js
    • TypeScript
  7. Website redesign

    In progress

    Details coming soon.

  8. Website for a friend

    In progress

    Details coming soon.

Contact

Or write to me here

Your message reaches my inbox by email. I use your details only to reply.