My most recent build: a private AI lab running entirely on one Mac Studio. A local agent runs as a background service on open-weight models, and I can text it from my phone through an iMessage bridge that only answers allowlisted numbers. It searches a private knowledge base of my own documents, indexed locally with CPU embeddings in SQLite and OCR'd where they were scans, so none of that material ever leaves the machine. It sends a morning brief and a weekly recap on a schedule, and hands heavy coding work off to hosted agents only when I ask it to.
On top of that sits a fine-tuning lab. It captures real conversations, builds training data, runs LoRA fine-tunes through mlx-lm on Apple Silicon, and grades the results with both rule-based checks and a model judge, because rule graders happily pass answers that are confidently wrong. The most fun part is the weights visualizer: a Three.js view that renders the model as a tower of layers, where height and brightness show how far each block moved during training. You can watch that training concentrated in the upper layers, mostly in attention.
I also run refusal-direction interpretability work on it, finding the direction in activation space tied to refusals, measuring how it shows up layer by layer, and writing every number to JSON so each result traces back to a run. Running all of this on 36GB taught me that memory is the real budget: two large models at once gives you Metal out-of-memory crashes, one 27B run churned about 147GB of intermediate files, and jobs now pause the assistant before they start.
All of this is a personal test bench. It runs on hardware I own, the models and data stay on that machine, and the interpretability work exists to measure and understand what training changes, not to ship anything.
My Creative Inquiry research with the Watt AI program: can a model read a molecule's spectra and write down its structure? I trained Transformers to predict SMILES strings from IR, Raman, and X-ray (XANES) spectra across 107,126 QM9 molecules. Adding the X-ray spectra helps a lot, up to +18.3 points of top-1 accuracy on molecules whose frameworks the model has never seen (33% to 52%), and the carbon edge carries about 86โ90% of that gain on its own. Selected for an oral presentation at the APS Southeastern Section meeting in November 2026 (here's the abstract), with the manuscript in progress.
The other half of my Watt AI work. Hospitals collect enormous piles of self-reports from frontline staff, 73,000+ in this dataset, and nobody has time to read them all. So I built a RAG app that lets non-technical staff ask questions in plain English and get answers grounded in the real reports: Llama 3 8B over a ChromaDB vector store, hybrid dense + BM25 retrieval, user auth, and saved chat history. Moving inference to vLLM on Clemson's Palmetto cluster cut query time 58%, from 20.4 seconds down to 8.5.
BoardAgent <- Click that! It's a forum where only AI agents post and humans browse read-only. Agents register themselves, start threads, argue about the day's news, and govern the board through public proposals and votes, with no human accounts involved. The tricky part was proving an agent is autonomous without tying it to a person, which the board does with its own two-round challenge. Joining takes one sentence pasted into any agent. It runs on Cloudflare Workers + D1 on the free tier, so it costs about $10 a year for the domain.
My consulting project for ENTR 4060, built for a live sports-card seller. During a Whatnot stream, cards sell every 20 seconds and nobody has time to write down what went for what, so a Chrome extension watches the live tabs, catches every "Sold" event, and sends the card screenshot to Claude to identify the player, set, and grade. Each sale lands in a dashboard the seller can glance at mid-show, next to market comps and an alert when a known big spender joins the chat. Identification started out weak on about 26% of cards; an adaptive crop window and a retry rule brought that down to roughly 6% over a 357-sale session. The hosted half lives at compbreak.com, where each streamer logs in and sees only their own sales.
A server in my apartment that has quietly become the thing I learn the most from. 27 Docker containers on an 8-core Ubuntu box, 95 days into an uptime streak the last time I checked, with about 23TB of TrueNAS and NAS storage behind it and Tailscale so I can reach any of it from anywhere. Caddy handles TLS and reverse proxying; Uptime Kuma watches 22 services and publishes a status page; Dozzle, Diun, and Portainer cover logs, image updates, and container management; a cron job backs up every config to the NAS weekly, with retries after one partial backup taught me why you need them.
I also build on top of it. There's a custom dashboard (nginx serving the frontend with GET-only routes except two deliberate POSTs, and a Python backend with pollers for network speed, library health, incidents, and system stats) plus a LAN scanner that has to run as a host cron job, because a container can't see the network it's sitting on. Home Assistant runs the apartment (Sonos, Hue), a Raspberry Pi 4 runs a wall kiosk on a systemd service in Chromium kiosk mode, and an old Kindle Voyage got turned into a server-rendered e-ink touch dashboard. Ollama serves Gemma 4 locally on an RTX 3060 Ti, which is exactly 8GB of VRAM and therefore a constant exercise in picking models that fit.
The best lessons came from things breaking. After a NAS outage took the whole stack down, I learned that Docker aborts a container start outright when a bind-mount source is missing, so the fix was restart policies and dependency ordering, not restarting things by hand. Getting touch input working on the Kindle meant holding an exclusive X11 pointer grab from gdb, since there's no compiler on the device, and a tap leak to the stock interface turned out to be the wrong process being stopped. A four-line preamble in a log once shifted my event parser by exactly one position, which took embarrassingly long to find.
An agent swarm running on Clemson's RCD LLM cluster. A Queen agent sizes the fleet based on how hard the task looks and splits up the work; workers research with live web search and can spawn their own helpers; then a Critic, Writer, Judge, and Verifier take turns until the answer is actually grounded in evidence. Workers may only trade claims that carry a URL, so one confused agent can't poison the rest, and if the verifier itself fails the run ships with a loud UNVERIFIED banner instead of quietly pretending.
A run in progress, sped up. The Queen is the star in the middle and every orbiting body is a worker, labelled with the model running it and the tokens it has burned. Workers spawn, report, and wink out as the fleet resizes itself around the task.
Once you're running several coding agents at once, the hard part isn't the agents, it's knowing which one is stuck waiting on you. herdr-web is a local dashboard for watching, messaging, and approving them, with an inbox grouped into Needs you / Working / Ready and a graph view of every workspace. A UI that can approve things on an agent's behalf had better not misfire, so: loopback-only, a fixed action whitelist, a minimum button age so a stray click can't approve anything, and an audit log of everything it does.
The part that took the most work is that it is not tied to one agent. herdr recognises 24 kinds, from OpenCode, Claude Code and Codex through to Hermes, Cursor, Gemini, Droid, Letta and Grok, and herdr-web can start any of them into a pane and then watch it. Detection works off what the agent prints to its own terminal, so a tool nobody has written a parser for can report its own state instead and show up in the dashboard automatically. Approvals are the exception: I only trust the inline allow and reject buttons for OpenCode and Claude Code, because those are the two whose prompt format I verified against live agents. Everything else is marked blocked on purpose and you send raw keys, which is the honest answer rather than guessing at a prompt I have not tested.
Parking at my university is a nightmare, so I built Parking Buddy, a crowd-sourced app for finding open spots on campus. It runs on a trade: you give another student a ride out to their car, and you get their spot when they pull out. The idea scales to any campus with the same problem, which is most of them.
Working on weather balloon related projects is (so far) the only way I can get close to space. I have launched 3 weather balloons, with each one building on the failures and successes of the last. All three have been successful in their own way, and are a reminder of what teamwork and perseverance can accomplish.
Better Advisor combines open-source models with grade distributions and professor feedback to point students at the best class and professor combination available to them. It started as Clemson Companion, a simple interface that let new students ask questions about campus and get accurate answers back. That version was basic, but it was where I worked out how to combine several APIs into one better answer, and it planted the idea for this. The second image here is V1, before it handled PDF uploads. A V2 would add file uploads for grade distributions and a Rate My Professor scraper on top of a cleaner interface.
Semester Countdown <- Click that! Semester Countdown is one of my latest mini projects, designed to help myself and other students find motivation. It also helps get track of important events like holidays and finals. It then provides a visual countdown, showing how much time is left in the semester and for each event. The goal is to help students stay organized and motivated by giving them a clear view of their academic timeline. I plan on adding more features, like a selectable menu to other schools, with their own major dates.
RoboCrop was a school project that used Arduino IoT and an array of sensors to monitor and take care of plants. Featuring a user interface to view sensor information, and then make decisions based off of that data. This project opened my eyes to the world of possibilites that connected devices can create.
Cat Bot was a project designed to help cat owners take care of their furry friends while they were away. Using servos and DC motors, it would control a cat toy in intervals. Additionally, it allowed for manual control of the cat toy using two control knobs, one for the x-axis and one for the y-axis. It would also use a stepper motor to open a treat drawer at random. While this project was one of my more rudimentary projects, it gave me a great introduction into the world of computer science.