Experimental Projects
Dive into my collection of innovative projects spanning AI, Machine Learning, and cutting-edge technology experiments.
Projects by Year
Sorted from newest to oldest.
2026
2025
2024
2023
Want to collaborate on a project?
I'm always open to interesting collaboration opportunities. Feel free to reach out if you have an idea you'd like to discuss!
Awaita (Awi) - AI Guide for Menorca
2026 · Ongoing
Project Overview
Awaita is a private, production-oriented AI guide for Menorca. My work focuses on the conversational product layer: grounded answers, RAG logic, retrieval quality, evaluation, safety controls, observability, deployment flow, and continuous improvement from real usage. The public landing, events experience, and broader web presentation are team-owned areas, with another teammate leading much of that outward-facing work.
My Contribution
- Owned the chatbot logic that turns curated Menorca knowledge into useful, grounded, multilingual answers
- Designed and tuned the retrieval workflow so the assistant can answer from controlled sources instead of generic model memory
- Built evaluation loops for retrieval quality, reranking decisions, prompt behavior, and generated-answer quality before product changes reach users
- Implemented safety and abuse controls around sessions, protected requests, user identity, feedback, rate limits, and public error handling
- Connected feedback, analytics, latency, cost, and quality signals so production conversations can be improved from evidence
- Maintained staged CI/CD workflows and operational checks for controlled releases to staging and production
- Collaborated with teammate-led web areas such as landing, events, and public content presentation while focusing on AI/backend reliability
Public Technical Scope
The product is private, so this portfolio intentionally avoids repository access, provider names, model names, infrastructure details, prompt structure, ranking parameters, and deployment recipes. The relevant signal is the engineering work behind a production AI assistant: retrieval quality, reliability, safety, observability, and release discipline.
I treat the RAG layer as a quality system rather than a demo feature: curated source material, retrieval tuning, comparative evaluation, regression coverage, and user feedback feed into one continuous improvement loop.
The project is still active in 2026, with ongoing work across answer quality, protected user flows, analytics, operational checks, and staged releases.
Real-World Application
Awaita aims to become a virtual tourist guide for Menorca: a practical companion that helps visitors discover places, understand local context, plan better routes, and ask natural questions before or during their trip. The goal is to make island knowledge easier to access through a conversational experience that feels useful, local, and trustworthy.
Contextarium
Created June 2026
Project Overview
Contextarium is a local-first context, memory, and RAG layer for coding agents. It runs a FastAPI web panel and an MCP-compatible HTTP/JSON-RPC endpoint so agents can search indexed documentation, retrieve source chunks, and manage durable project memory without relying on a hosted service.
Core Capabilities
- Runs a local control panel for dashboard status, RAG ingestion, MCP tool toggles, project memory, configuration, and logs
- Ingests documentation from a sitemap or a `txt/` URL list, then crawls, chunks, embeds, and atomically replaces the DuckDB RAG index
- Exposes MCP tools for `hybrid_search`, `chunks_by_url`, and project-scoped item management through HTTP/JSON-RPC
- Stores long-lived project memory, docs, bugs, and todos in SQLite with typed metadata, statuses, direct editing, search, and diff-based doc patching
- Combines dense and lexical retrieval with MMR, optional reranking, output schemas, and graceful degradation when local extensions or rerankers are unavailable
- Provides ready-to-copy integration snippets for Codex CLI, Claude Code, and GitHub Copilot in VS Code
- Supports local and cloud embedding modes, Docker deployment, repository checks, and explicit local-only security guidance
Technical Implementation
This project is still evolving. I may change the name and rework part of the overall logic because I am not fully satisfied yet with the current product shape, especially how the context and memory workflows should feel in daily use.
The backend is a Python 3.12 FastAPI/Uvicorn app with Jinja templates and modular static assets. The MCP server is split into `mcp_server/server.py` for HTTP/JSON-RPC compatibility and `mcp_server/toolset.py` for declarative tool schemas, runtime validation, and structured outputs.
Persistence is intentionally split: DuckDB stores the global RAG corpus (`docs`, `chunks`, and metadata, with VSS/FTS indexes when available), while SQLite stores project-scoped memory/items. The app opens the RAG database read-only while serving queries, validates stored metadata against the active config, and rebuilds indexes through a staging database before atomic swap.
The ingestion and retrieval pipeline includes Crawl4AI crawling, heading/code-aware chunking, local HuggingFace-compatible embeddings or OpenAI cloud embeddings, optional local/cloud reranking, MMR selection, URL penalties, and fallback behavior when optional DuckDB extensions are missing.
The repository includes 49 pytest files covering MCP JSON-RPC behavior, tool schemas, item metadata, UI API contracts, crawling safety, embedding modes, DuckDB lifecycle, docs consistency, and repository hygiene. GitHub Actions runs a lightweight readiness suite on pushes and pull requests.
Real-World Application
Contextarium is useful when a developer wants coding agents to keep project context, decisions, docs, bugs, and todos close to the local workspace. The point is controlled context: choose what to index, choose which tools an MCP client can call, and avoid turning private project memory into an external hosted dependency.
XLFusion
September 2025 · Maintained
Project Overview
XLFusion is an open-source Python toolkit for reproducible SDXL checkpoint merging. It replaces ad-hoc local scripts with repeatable CLI, GUI, batch, analysis, metadata recovery, and checkpoint algebra workflows, with a strong focus on validation before long-running local work and metadata that explains how each checkpoint was produced.
What It Does
- Merges SDXL-derived `.safetensors` checkpoints through legacy, per-resolution, and hybrid merge modes
- Bakes compatible LoRA weights into UNet and text-encoder targets with an auditable report
- Runs preflight validation before execution, covering memory estimates, backbone compatibility, affected blocks, locks, component scope, warnings, and risk alerts
- Supports interactive CLI, GUI, and YAML batch execution from the same validation and runtime contracts
- Saves reusable presets, batch-compatible YAML, embedded metadata, and recovery folders so previous runs can be inspected and recreated
- Adds analysis utilities for checkpoint similarity, compatibility, dominance by region/submodule, merge recommendations, and checkpoint algebra
- Keeps behavior protected with fast unittest coverage, synthetic safetensors fixtures, a smoke-test path, and GitHub Actions CI
Technical Implementation
The current v2.4.1 public version is packaged as `xlfusion` for Python 3.10+, with console entrypoints for `xlfusion` and `xlfusion-gui`. The package keeps the legacy direct script path available through `python XLFusion.py` while moving the implementation into reusable modules.
The architecture centralizes validation, runtime types, execution flow, batch parsing, memory checks, presets, metadata recovery, LoRA handling, block mapping, and analysis so CLI, GUI, and batch mode do not drift into separate behavior.
The repository is intentionally OSS-safe: it includes examples, tests, documentation, CI, release notes, and maintainer guidance, but no real checkpoints, LoRAs, generated images, local configs, logs, or model binaries.
Real-World Application
The project is aimed at SDXL users and maintainers who need repeatable local experiments. Instead of relying on one-off merge scripts and undocumented outputs, XLFusion makes the merge plan, execution settings, source models, metadata, and recovery path explicit enough to review later or rerun from a batch config.
Mas Palabras
May 2025 · Maintained
Project Overview
Mas Palabras is a personal vocabulary app for collecting words while studying, reading, working, or living in another language. It turns scattered notes, spreadsheets, screenshots, and chat messages into a structured personal lexicon with language and tag organization, search, JSON import/export, and adaptive quiz practice for words that need review.
Core Workflows
- Create vocabulary entries with source word, translation, explanation, language, and tag
- Normalize source words to prevent duplicates within the same language
- Browse the lexicon with search, language filters, tag filters, pagination, sorting, editing, deletion, and bulk deletion
- Practice through quiz sessions targeting all words, new words, or entries that need review based on attempts and accuracy
- Import JSON vocabulary lists with duplicate handling, missing-language/tag options, flexible date parsing, and per-item incident reporting
- Export the full vocabulary as JSON so study data stays portable
- Switch the interface between English, Spanish, and Catalan through a cookie-backed language selector
Technical Implementation
The current version is a Next.js 16 App Router application written in strict TypeScript, with React 19, Tailwind CSS, Prisma, SQLite, Zod, and Vitest. Reads happen in server-rendered pages, while mutations are handled through server actions and a small number of route handlers for import/export and quiz ending.
Domain logic is split into focused modules for words, settings, quiz sessions, import/export, text normalization, word metrics, flash messages, validation, and Prisma access. Quiz state is persisted in SQLite and tied to an `httpOnly` cookie, with deterministic mixed-direction questions and transaction-based submit/skip handling to avoid double-counting.
The repository includes unit coverage for normalization, word metrics, search/sorting behavior, flash-message helpers, import/export edge cases, and quiz utilities. GitHub Actions runs dependency install, Prisma client generation, Vitest, and production build on pushes and pull requests.
Real-World Application
The app is built for local study and data ownership. Its value is not just adding words, but keeping vocabulary searchable, reviewable, exportable, and organized enough to become a living personal dictionary rather than another scattered notes file.
Examino
2023 · Refreshed in 2026
Project Overview
Examino is a local-first Flask app for building and practicing multiple-choice exams from private question banks. I originally built it in 2023 while studying DAW, so it is intentionally presented as an earlier-stage project with a simpler codebase than my more recent work. In 2026 I revisited it to fix bugs, improve the public repository, add bilingual UI support, harden the local workflow, and prepare it as an app that anyone can clone and run locally.
Current Capabilities
- Generate multiple-choice tests by subject, topic, and number of questions
- Choose between deferred correction and immediate correction mode
- Shuffle answer options while preserving the correct-answer mapping
- Grade answers with omitted-question handling and standard penalty logic
- Browse loaded questions by subject and topic before creating a test
- Add custom questions from the web UI for local study databases
- Customize the base subject/topic catalog from YAML and reload ignored private question-set scripts
- Switch the interface between English and Spanish
Technical Implementation
The public version is packaged as a Python project with installable CLI commands: `examino`, `examino-init-db`, and `examino-refresh-question-bank`. SQLite is the default storage path for local use, while `DATABASE_URL` can point to another database configuration.
The 2026 refresh moved the project toward a cleaner local-first release: Flask app factory, SQLAlchemy models, WTForms, CSRF protection, Flask-Limiter, Alembic migrations, YAML catalog seeding, ignored private question banks, documentation, issue/PR templates, and GitHub Actions running pytest.
This is not positioned as a polished hosted SaaS or a representation of my current frontend standard. Its value in the portfolio is different: it shows an older DAW-era idea that was later cleaned up, documented, tested, and made usable as a small self-hosted/local study tool.
Real-World Application
Examino is useful when a student wants to keep their own question bank private and practice locally without accounts or cloud storage. The repository ships only a neutral sample catalog; real subjects and questions are expected to stay in the user’s local database or ignored local scripts.
MIDAS
Created March 2025
Project Overview
MIDAS (Multi-agent Intelligent Data Automation System) was my Master’s Thesis Project: a modular multi-agent platform for automating the data science lifecycle. The project combines synthetic dataset generation, natural-language chart creation, automated ML training, model evaluation, deployment helpers, and RAG-based documentation assistants into an eight-component ecosystem.
Key Features
- Eight specialized modules covering Dataset, Plot, Touch, Test, Deploy, Assistant, Architect, and Help workflows
- Synthetic dataset generation with AG2 agents, Faker, Spanish localization, editable outputs, and CSV/Excel export
- Automated ML workflow that loads CSV, Excel, Parquet, or JSON files and infers target column and problem type from natural language
- Adaptive preprocessing, model selection between RandomForest and GradientBoosting, cross-validation, metrics, serialized models, and generated notebooks
- Natural-language chart generation with CrewAI Flow, matplotlib code generation, and secure execution through an E2B sandbox
- RAG assistants for technical documentation, framework guidance, and project support using LlamaIndex, reranking, and model routing
Technical Implementation
Midas Touch is coordinated by an AICortex and an OperationalContext shared state. Specialized agents handle intent extraction, target-column validation, preprocessing, training, validation, notebook generation, and fallback recovery when a dataset or model step fails.
Midas Help implements a Flask-based LLM+RAG+Reranker flow over the MIDAS documentation. It uses LlamaIndex, BGE-M3 embeddings, a BGE V2 M3 reranker, a fine-tuned Spanish BERT classifier for prompt difficulty, and automatic routing between Llama 3.3 70B and Gemini 2.0 Flash.
The wider system combines AG2, CrewAI Flow, Streamlit, pandas, scikit-learn, Faker, LiteLLM, E2B, Supabase Vector, Crawl4AI, and Gemini/OpenAI-compatible model APIs depending on each module.
Real-World Application
The project was built as a complete TFM showcase rather than a single demo app. Its goal was to make ML workflows more accessible by turning common data science tasks into guided, conversational modules that can be inspected, adapted, and run independently from the source code.
LLM StoryTeller
Created November 2024
Project Overview
LLM StoryTeller is a Streamlit app for generating stories through a guided three-step LLM workflow: outline, narrative writing, and final review. It includes a local version for OpenAI-compatible model endpoints and a Streamlit Cloud version backed by OpenRouter free models.
Features
- Structured three-step generation pipeline: outline creation, story writing, and review/refinement
- Separate model selection for each generation step
- Local mode for OpenAI-compatible endpoints running at `localhost:7860`
- OpenRouter cloud mode for Streamlit deployment using free hosted models
- Fallback system that tries alternative OpenRouter models when the selected one is unavailable
- User controls for characters, setting, key action, language, story length, genre, and temperature
- Story cleanup, HTML escaping before render, and one-click `.txt` download
Technical Implementation
The local script calls an OpenAI-compatible `/v1/chat/completions` endpoint with configurable model names for Llama 3.2 1B and Qwen 2.5 1.5B, request timeouts, response validation, and user-facing error handling.
The Streamlit Cloud version initializes an OpenAI client against OpenRouter, reads `OPENROUTER_API_KEY` from Streamlit secrets, and currently exposes Nemotron Nano 9B, Llama 3.3 8B, GPT OSS 20B, and Gemma 3n E2B as selectable free models.
Generated stories are preprocessed to remove common Markdown artifacts, escaped before HTML rendering, and displayed in a custom reading container before being offered as a downloadable text file.
Chatbot CV: RAG vs Context Window
Created March 2025
Project Overview
Chatbot CV implements two Flask chatbot versions for querying my curriculum: a RAG implementation with LlamaIndex and a full-context implementation using Gemini. The project compares retrieval-based answers against loading the complete CV into a large context window, while also experimenting with automatic prompt classification.
Dual Architecture
- RAG approach: LlamaIndex with Groq Llama 3.3 70B, DeepInfra BGE-M3 embeddings, and persistent vector storage built from the CV markdown file.
- Context-window approach: Gemini 2.0 Flash / Flash-Lite through LiteLLM, with the full CV loaded into the system prompt instead of retrieving chunks.
- Prompt classifier: Spanish BERT sequence classifier that routes simple, complex, and out-of-scope questions to the appropriate handling path.
- Session-aware API: Flask backend with localStorage session IDs, conversation history, concurrent-request protection, and a clear-history endpoint.
Technical Implementation
The LlamaIndex version reads `info.md`, creates or reloads an `index_storage` vector index, uses 512-token chunks, retrieves the top 5 similar chunks, and sends the enhanced query plus recent conversation history to Llama 3.3 70B.
The Gemini version uses a local `prompt_analysis` BERT classifier before generation. Simple questions go to Gemini Flash-Lite, complex questions go to Gemini Flash, and unrelated prompts are blocked to control abuse and API cost.
Both versions expose `/query` and `/clear_history` endpoints and use single-page Tailwind templates with Markdown rendering via Marked.js, persistent browser session IDs, processing notices, and responsive chat layouts.
Key Findings
RAG keeps token usage lower and scales better to larger knowledge bases, but depends heavily on chunking and retrieval quality. The full-context version is simpler and more globally aware of the CV, but depends more directly on model context limits and API cost.
Fox-Detector
Created June 2024
Project Overview
Fox-Detector is a binary image-classification project built with Keras and a fine-tuned DenseNet121 backbone. It prepares a labeled dataset of fox and non-fox images, trains a transfer-learning model, and classifies new image batches into fox / non-fox folders.
Key Features
- Dataset normalization script that resizes images to 256x256 and converts them to RGB
- CSV generation mapping each image filename to a binary fox / non-fox label
- Class balancing through oversampling before the train/validation split
- Transfer learning with DenseNet121 ImageNet weights and custom dense/dropout layers
- Data augmentation with rotation, shifts, shear, horizontal flip, and brightness changes
- Inference script that sorts images from `todas_imagenes` into `si_es_zorro` or `no_es_zorro`
Technical Implementation
Training uses TensorFlow/Keras ImageDataGenerator, a 20% validation split, binary cross-entropy, Adam at 0.0001, EarlyStopping on validation loss, and ReduceLROnPlateau to lower the learning rate when validation performance stalls.
The trained `fox_detector_model.keras` file is not committed because of GitHub size limits; the repository documents a Google Drive download and expects the model in the project root for batch inference.
Hard Drive Failure Prediction
Created November 2024
Project Overview
Hard Drive Failure Prediction is a binary classification project built on Backblaze hard-drive reports from 2018 through Q2 2024. It predicts whether a drive is likely to fail using normalized SMART attributes, storage capacity, and manufacturer information extracted from model names.
Key Features
- Backblaze quarterly data ingestion covering 2018 to Q2 2024
- Failure-row aggregation to reduce the severe class imbalance in daily HDD reports
- Feature selection focused on 13 normalized SMART attributes plus capacity and manufacturer
- Manufacturer extraction from HDD model names using Llama 3.1 70B through Groq
- RandomForest and XGBoost training with GridSearchCV optimization
- Weighted ensemble thresholds tuned separately for F1 score, precision, and recall
- Alert-style test script that turns ensemble outputs into practical maintenance recommendations
Technical Implementation
The preprocessing pipeline removes non-predictive infrastructure fields, drops raw SMART values, keeps normalized SMART attributes with acceptable missing-data rates, converts drive capacity to terabytes, and one-hot encodes the manufacturer labels.
The final repository includes train and test CSVs with roughly 266k training rows and 29.5k test rows. The model comparison focuses on RandomForest and XGBoost, then combines both outputs with weighted thresholds to produce F1-oriented, precision-oriented, and recall-oriented failure signals.
XLSX to JSONL
Created October 2024
Project Overview
XLSX to JSONL is a small Python utility for turning Excel datasets into JSONL files ready for ChatGPT fine-tuning. It reads one or more sheets from an `.xlsx` file, treats the first column as user prompts and the second column as assistant responses, then writes role-based training and validation files.
Key Features
- Automatic `.xlsx` discovery with interactive file selection when several spreadsheets exist
- Multi-sheet processing with separate JSONL outputs for each sheet
- System role prompt applied to every generated conversation example
- Configurable train/validation split from the command line
- Optional row shuffling before dataset splitting
Technical Implementation
The converter uses pandas with openpyxl support to inspect the workbook and read each sheet independently. Sheets with fewer than two columns are skipped, which avoids producing malformed examples when a sheet does not match the expected prompt/response layout.
Each row is serialized as a `messages` object with `system`, `user`, and `assistant` roles, using `ensure_ascii=False` to preserve non-ASCII content. Output files follow the `<workbook>_<sheet>_train.jsonl` and `<workbook>_<sheet>_validation.jsonl` naming pattern.
Gather-Tracker
Created June 2024
Project Overview
Gather-Tracker is a lightweight browser script for monitoring a Gather Town office from the web client. After configuring a target user, Telegram bot token, and chat IDs, it reports connection status, movement between office zones, and new chat messages in real time.
Key Features
- Two script variants for Gather's old chat UI and beta/new chat UI
- Telegram alerts for initial state, connect/disconnect events, and room changes
- Configurable coordinate-based zones for mapping office rooms
- Chat forwarding for public, local, and private messages using separate Telegram chats
- Helper functions to discover player IDs and current map coordinates from the browser console
Technical Implementation
The scripts run directly in Gather's browser client because the installable apps do not expose the required runtime context. They use the in-page gameSpace state to read online players, positions, map data, and target-user status.
Movement tracking is implemented with configurable rectangular zones and periodic polling. Chat tracking reads the active Gather chat DOM, compares the latest observed messages, classifies message scope, and sends formatted notifications through the Telegram Bot API.