Projects

Chatbot AI

My first AI assistant, trained, not wrapped.

An Italian-language assistant built on a fine-tuned DistilBERT: weather, news, stocks and crypto, a TODO list and a few jokes, with the intent classifier trained by me, not borrowed from an API.

DateAugust 2025
StatusLive on Hugging Face
Tech stack
  • Python
  • DistilBERT
  • PyTorch
  • Flask
  • SQLite
  • Docker

The starting point

In 2025 the easy move was obvious: wrap someone else's LLM API in a chat window and call it a project. I wanted the opposite. I wanted to understand what happens inside, tokenization, fine-tuning, class imbalance, the moment a validation loss finally stops improving. So I built an assistant whose brain I trained myself.

The constraint that made it interesting: Italian. Most tutorials, datasets and pre-trained intent models assume English. Building a chatbot that natively understands “che tempo fa a Catania?” meant building the training set, the augmentation and the message-handling logic around my own language.

What it can do

The assistant routes every message through twelve intents: real-time weather for 100+ cities, US news headlines, stock and crypto prices across 50+ symbols, a full TODO list with priorities, plus time, small talk and jokes. Each external service (OpenWeatherMap, NewsAPI, Alpha Vantage, CoinGecko) sits behind a rate-limiting layer with simulated fallbacks, so the bot degrades gracefully instead of dying when a free-tier quota runs out.

It all lives inside a deliberately familiar chat interface. Dark and light mode are the same product, not two separate skins: the hierarchy, feedback and conversation remain readable whichever side of the toggle you prefer.

The simple surface hides the router underneath. The skills menu makes its vocabulary explicit; from there, each intent becomes a small product flow, not just a canned reply.

The skills menu: everything the bot understands.

Training the brain

The classifier is a DistilBERT with a 3-layer head, fine-tuned on the last two transformer layers only, enough to specialise on Italian intents without burning the pre-trained knowledge. The dataset was the real work: heavy augmentation with synonym swaps, politeness variants, punctuation noise and article removal, so the model survives the thousand ways an Italian actually phrases “aggiungi il pane alla lista”.

Training converged in 12 epochs and 42 minutes, landing at 99.5% validation accuracy with balanced F1 across all twelve intents. Modest numbers by 2026 standards, and that's the point: this project is where I learned to be suspicious of my own metrics, to hunt data leakage, and to respect how much of “AI” is actually dataset engineering.

99.5%validation accuracy
12intents classified
42minof training

The classifier is only half the system. In production, API quotas are part of the product too: usage is tracked live, rate limits are visible, and simulated fallbacks keep a conversation useful when a free service temporarily says no.

Live API usage, with rate-limit-aware fallbacks.

The first of many

This is the oldest project in here, and I keep it on purpose. It's where “AI” stopped being a magic API and became tokenizers, class weights and validation curves I actually had to understand. Every model I trained afterwards, SwishAI, RotoAI, the ones still in private repos, stands on the afternoon I first watched a loss curve flatten and knew exactly why. Trained, not wrapped. It's still the rule.

More projects