Using AI to Learn Go Without Skipping the Hard Parts

I’ve been fascinated by Go for a while now, but until recently I never really got past building a simple CLI helper that generates large .csv files for testing.
That tool is super helpful and nice to have, but I’ve been itching to build something more substantial with Go. Something where I’d actually have to deal with architecture, testing, Linux, networking, and all the other things you conveniently avoid when building a tiny utility.
My first thought was the obvious one: find a course.
I didn’t really want another course
I started looking at places like YouTube and Coursera for advanced Go courses or one of those “Building XYZ from Scratch” videos.
But the idea of following along with an eight-hour video, constantly skipping backwards to figure out what just happened, didn’t sound particularly fun.
So, books?
I had recently skimmed through Crafting Interpreters by Robert Nystrom and really liked its approach. I implemented parts of the Lox language in TypeScript while going through it, and what clicked for me was the progression: learn a concept, build something with it, then move on to the next piece.
That made me wonder: why not recreate that experience, but make the book interactive?
Instead of finding a course, I could collaboratively create a plan.md for a project I actually wanted to build. An AI could act more like the author or tutor: introduce a chapter, explain the concepts, give me a task, and then walk through the implementation with me when I got stuck.
There was just one important rule: it wasn’t allowed to modify my files.
It can explain things. It can show me code in chat. It can point out that what I just wrote makes absolutely no sense. But I still have to actually build the thing.
So I needed a project
Recently I’ve been really hooked on the idea of running coding agents inside isolated Firecracker microVMs.
Firecracker is a lightweight virtual machine monitor for running small KVM-backed virtual machines. You get much of the isolation of a traditional VM without necessarily needing a giant VM for every workload.
My idea is to eventually use those microVMs as little sandboxes for agents doing refactoring, cleanup, or other tasks across my codebases. Each agent gets its own environment and doesn’t need to know anything about the other agents running next to it.
Before starting the Go project, I had already built a super little POC that bakes two Firecracker VMs into a single IONOS Cloud Cube. Mostly Shell scripts. Nothing fancy.
I deliberately chose IONOS here partly because I wanted this to be something other than yet another AWS or GCP project.
The POC worked, but everything was essentially hardcoded for those two VMs.
That sounded like a pretty good problem to turn into my DIY Go course.
Turning the POC into Knaller
The project is called Knaller, which is German for “firecracker.”
The goal of the Go CLI I’m building is to take that static POC and make it dynamic. Instead of assuming that exactly two predefined VMs exist, Knaller should be able to look at a Linux host, understand the resources available to it, and manage Firecracker sandboxes accordingly.
I’m currently on chapter 8 of 22.
At this point, the CLI can inspect host capacity, load and validate its configuration, and perform a dry run of the create command.
That dry run is one of those small milestones that doesn’t look particularly impressive from the outside, but feels great when you’ve built all the pieces leading up to it. I can give Knaller a name, number of vCPUs, and amount of memory, and it works out what an allocation for that sandbox would look like-including its resource allocation and networking setup-without actually creating anything yet.
root@ubuntu:~/knaller# ./knaller create --name test --cpus 1 --memory 256 --dry-run --config /tmp/knaller-dryrun.yaml
dry-run: would create vm-0001 (test)
uid/gid 12001/12001
vcpus/memory 1 / 256 MiB
guest 172.16.1.2 gw 172.16.1.1 subnet 172.16.1.0/30
transit host 10.200.1.1 ns 10.200.1.2 subnet 10.200.1.0/30
netns/veth/tap kn-vm-0001 kn1-host/kn1-ns tap0
There is still a lot left to build before I have agents running around in dynamically created sandboxes.
And that’s sort of the point.
Maybe building slowly is still allowed
I could probably find a service that already does some version of this for a few bucks a month.
I could also give an agent my requirements and ask it to build the whole thing for me. I use agents for engineering work, so this isn’t an argument against agentic engineering.
But that’s not what I want from this particular project.
I want to learn Go. I want to understand more about Linux networking. I want to figure out why a test is failing, stare at it for a while, finally understand what I did wrong, and get that little buzz when it turns green.
Learning is fun, and I think it’s easy to forget that we’re still allowed to build things from scratch. We’re allowed to spend weeks or months on something even when a faster solution exists.
My project isn’t done.
I’m having a lot of fun building it.
If you’re trying to learn something new, I’d recommend trying the same approach: pick a project you genuinely want to exist, ask an agent to help turn it into a course, and work through it one chapter at a time.
Just make sure the agent doesn’t do all the fun parts for you.