Skip to content

Bennett M. Anderson

Biomedical engineering · Iowa State University

Bennett M. Anderson, kayaking

Senior, graduating May 2027 · Minor in pharmacology · Ames, IA

I’m working to improve my skills, computational and otherwise, to become the best engineer and scientist I can in the pursuit of better global health.

Now
Finishing senior year at Iowa State — reading papers, building small projects and learning new tools after wrapping an undergraduate research role in E. coli genetics.
Looking for
Graduate school in pharmaceutical development, and open to industry. No location preference.
Selected work · 9 projects · 3 complete · updated Sep 23, 2026

Projects

Local-LLM Site Concierge

in progress

The askAI page on this site, answered by a small language model running on an old desktop in my house. No cloud inference, no API key, no data centre. The plumbing is the hard part, not the model. My desktop sits behind NAT with nothing open to the internet, and I wasn’t willing to forward a port to run a toy. So the connection only ever runs outward: the Vercel route pushes a job onto an Upstash Redis queue, the desktop long-polls that queue over HTTPS, runs the question against a local Ollama model, and writes the answer back under the job’s id. Nothing ever reaches in. The desktop also publishes a heartbeat with a short TTL — if it goes stale the site knows the node is down and says so, in plain language, with links, instead of hanging. Making a public-facing model behave is most of the remaining work, and it’s layered rather than clever: - A regex pre-filter refuses instruction-extraction and override attempts before the model is ever called, so the cheapest attacks cost nothing to defend. - A hardened system prompt answers about me only from a single grounding document, in third person, and is told to treat missing sections as “I don’t know” rather than fill them in. - Deterministic rails catch two specific failure modes a prompt alone won’t reliably prevent: impersonating me, and making commitments on my behalf — replying to an offer, agreeing to a date, accepting anything. Those are intercepted rather than negotiated with. - Everything fails closed. A model error, a relay error, a malformed job — all of them produce no answer, which surfaces as the honest offline message. A wrong answer about a real person is worse than no answer. Speed, without pretending. A 3B model on four CPU cores takes 10–20 seconds a question, and no amount of tuning changes that. What does change it is not running the model at all: the box is idle almost all the time, so an idle worker precomputes answers to likely questions, generates several candidates, and scores them against a formal-register rubric — contractions, filler, fourth-wall leaks, sentence count — keeping only the best. Cache matching is normalised-exact on purpose. No embeddings, no fuzzy similarity: a near-miss would serve a confidently incorrect answer about a real person, which is far worse than being slow. The cache is keyed by a fingerprint of the system prompt plus the grounding doc, so editing either retires every stale entry automatically. What the visitor sees. The /ask page shows which model is loaded, the machine it’s running on, your position in the queue, and whether the desktop is even awake. When the desktop is off, the page still shows the last numbers it reported and says when that was, instead of an empty panel. There’s a passphrase fast-lane that jumps the queue for people I’ve given it to. It’s deliberately un-magical: the point is that a small model on a normal computer in a house can do this, and you can watch it happen. Built with Next.js API routes and Upstash Redis on the site side; a single-file Python poller, Ollama and systemd on the desktop side. It must be noted with such a machine running it hard indefinitely is a lot, so it often shuts down and auto-reboot systems fail. I’m working to improve this, which may include switching from Linux Mint, which I am now comfortable enough to do, to something with even less overhead. A headless distro may be in order for such a project.

  • Local LLMs
  • System Design
  • Security Design
completion82%

Bennett-Anderson.com

ongoing

You’re looking at this one! My personal website, built from scratch with Next.js, TypeScript and Tailwind CSS and hosted on Vercel with a custom domain. It started in November 2025 as a project list and a resume. It’s been redesigned twice since then, the second time into the brown and tan look it has now, and a lot got added along the way: - askAI, where a small language model on an old desktop in my house answers questions about me. It has its own entry in this list. - A Recent posts feed that pulls in my YouTube and Substack uploads by itself every 15 minutes. - Software-themed versions of three pages, each with a plain view that phones get by default. Projects is a MATLAB desktop with a working Command Window, askAI is a Jupyter notebook and Contact is a plasmid map. - An activity.mlx tab in the MATLAB view with my latest videos, posts and GitHub commits (the plain view has the same thing under the project list), plus editor tabs that open and close like the real program. - A darkroom photo gallery, and a hidden vault page if you know my cat’s name. - A small local editor so I can add projects without hand-editing TypeScript. - A full pass on accessibility, page metadata and load speed. Feel free to look through the code on GitHub, it was my first public repository. (It took me a while to realize I didn’t need to push every change to see it working, so the early commits are messy and there are a lot of them.) Note: I learned TypeScript web development mostly from LLMs early on, and most of the newer features were built with AI coding tools, with me deciding what gets built, reviewing it and testing it. The more I work on this site, the more of it I can do on my own.

  • TypeScript
  • Web Development
  • UI Design
  • Responsive Design
completion85%

Video Production Workflow

ongoingvideo demo

Two Linux desktop apps that take a video from “it’s on my phone” to “it’s in the recording”. Built because the individual pieces all exist and none of them fit together. All I have to do is choose what clips I want moved, put them in order of when and how I want to talk about them, and begin presenting in OBS to be later trimmed down and edited in Kdenlive (I use EndeavorOS) iPhone Import browses the camera roll over USB and copies what I select into a project folder. That sounds trivial and isn’t: on this machine ifuse silently returns corrupt data for large files. The same 183 MB clip read three times gave three different checksums, at identical file size, with damage starting on a 64 KiB boundary and no USB error logged anywhere. Roughly a third of 4 MB chunks come back wrong on any given read — which is where a long-standing “some of my imports are broken” problem turned out to come from. The fix is a verified copy: read each chunk, drop it from the page cache, read it again, and only accept it when two reads agree. Corruption is random per read, so agreement is strong evidence of correctness — and copies built this way are reproducible where plain copies never are. Every file is then decoded end to end before it counts as imported, and anything that fails is deleted and reported rather than left on disk looking fine. Video Deck Studio is the other half. Order the clips by dragging; mark in and out points that apply instantly, because they’re stored as marks rather than re-encoded, so trimming ruthlessly costs nothing; hide what you’ve skipped; and present the result into OBS. Its most useful feature is pairs: two clips joined into one item, composited into a single frame — a screen recording of a demo beside the phone video of the same thing. Pairs open a two-track timeline where you drag one clip against the other to line them up and drag either end of either clip to trim it. Both sides are scaled to fit their half of a 1920×1080 frame and padded, so neither can ever crop the other, and the layout picks itself: two portrait clips sit side by side, two landscape ones stack. The preview is a real render. The obvious approach — one live filter graph in the player — was built first and then measured against an actual render, and the two disagreed: mpv drives its filter graph from its own playback position, so trims there don’t mean what they mean to ffmpeg. Trims would have previewed as one thing and exported as another. Instead the editor renders a small 360p window around the playhead through the identical code path as the final export, and the two were then verified frame by frame. Presenting plays a full-resolution render, never the proxy. Working with Wayland rather than against it. Window embedding doesn’t exist, and OBS binds its capture to a specific window — so the player is one long-lived window that OBS is pointed at once, and everything else is driven over its JSON IPC socket. Built with Python and PyQt6, driving mpv and ffmpeg, on top of libimobiledevice for the phone.

  • Python
  • FFmpeg
  • Video Processing
  • UI Design
completion80%
What I can do

Skills

  • MATLAB
  • SolidWorks
  • Python
  • Git & GitHub
  • TypeScript
  • React / Next.js
  • Tailwind CSS
  • Node.js
  • Linux
  • Electron
  • PyQt6
  • Vite
  • Redis
  • systemd
  • Vercel
  • Framer Motion
  • Wayland
  • System Design
  • Security Design
  • REST / API Routes
  • Bacterial Experimental Techniques
  • Cloning & Transformation
  • PCR & Gel Electrophoresis
  • SnapGene
  • Bioinformatics Basics
  • PRISM
  • PyMOL
  • CRISPR Gene Editing Concepts
  • gRNA Design
  • Sequence Alignment
  • MATLAB
  • PRISM
  • Experimental Design
  • LaTeX
  • Excel / Microsoft Office Suite
  • Visualization
  • Statistics
  • Python
  • Professional Communication
  • Technical Presentation
  • Team Collaboration & Management
  • Customer Service & Relations
  • Ollama
  • Local LLM Deployment
  • Prompt Engineering
  • Prompt-Injection Hardening
  • Embeddings & Semantic Search
  • Local Speech (TTS / STT)
  • FFmpeg
  • OBS Studio
  • Kdenlive
  • mpv
  • Video Processing
  • Raspberry Pi
  • Electronics
  • Soldering
  • Diagnostic Troubleshooting
  • Lab Equipment Repair
  • 3D Modeling
Lab assistant · quality assurance (naps on keyboards) · morale

Penrose

She answers to her name. Type it anywhere.

Penrose, observation 1
obs_001.jpeg
Penrose, observation 2
obs_002.jpeg
Penrose, observation 3
obs_003.jpeg
Penrose, observation 4
obs_004.jpeg
Penrose, observation 5
obs_005.jpeg
Penrose, observation 6
obs_006.jpeg