Learning to Program with AI Agents
Press Space to continue
I've spent 3 billion tokens in four months. Every single one through a terminal, watching an agent write code I couldn't write myself. You may class me as a 'vibe-coder'. But I think that term overlooks any kind of skill involved in the work itself. Much like 'no-code' did circa 2019 (when I started my no-code education company later acquired by Zapier). I don't read the code. But I read the agent output religiously. And in doing so, I'm picking up a ton of knowledge around how code works, how projects work, where things fail, where they succeed. That's my version of learning to program. The new technical class. ## What I've actually shipped A few things I've actually shipped in these last few months: **Personal Site.** I revamped my personal site and made it look like a terminal CLI tool and it was so much better than my previous attempt at the start of this year. **Feed.** I built a simple social tracker for mentions of Factory on Twitter, posts from our subreddit, and GitHub issues. It's open-source and I've gotten 100+ stars on it with several folks cloning for themselves. **Factory Wrapped.** I built the first version of our 'wrapped' product. Showed it to the team and they loved it, so they wanted to bake it into the actual product itself, which is now live. Adding new guides, rearranging things. This wouldn't technically feel like coding, but to me it is. It's still the same process. **Custom CLIs.** I've created a few CLIs—like a Pylon CLI which then has been picked up by the team to help with customer support queries. I built a CLI to help users with adding tokens to their accounts. Plus a Linear and Gmail CLI. **A crypto tracker.** I invested in a co that accurately predicts positive, negative or neutral signals in dynamic data (financial, weather, fitness, protein folding). So I built a tracker that automatically opens and closes short/long positions based on the predictions - kinda like a mini-hedge fund. **Droidmas.** Twelve days, twelve experiments or games that touched the different themes people are talking about on Twitter—memory, context management, vibe coding, things of that nature. **An AI-directed video demo system.** Effectively, I give it a prompt to create a video. It opens up ghostty, runs the commands, can open other windows like a browser, records the screen. Acts as its own director, producer and editor. The agent itself is watching what's happening during the recording and can respond as and when things happen. If there's an issue or a bug or it needs to wait for a response, it will do that. I used this to create a video that was posted by OpenAI. **A Telegram bot powered by Droid Exec** so I could have my local repos synced on a VPS and just chat to my repos as a chatbot. I try to as closely mimic the CLI experience but from a messaging app (I dislike Telegram but couldn't be bothered with the arduous Whatsapp for Business setup). And about 50 other things I'm not mentioning or have been left to die. ## How I actually work I use a CLI exclusively. Terminal over web interfaces, always. It's just more capable as a general agent, and I get to see it work. I may have an idea for something, or a pain, or there's an issue with something that I feel like could be solved with code (basically everything these days). So I'll just spin up a new project in Droid (Factory's CLI). I generally just talk to the model a couple of times to start feeding in context about what I'm trying to do, then I'll switch into spec mode to start getting a plan going on what I wanna build. In spec mode I'll basically question a bunch of things. Like I don't understand what this is, or why would we need that over this, can't we do it this way? I'll link docs and GitHub repos for the agent to explore. Then I let Opus 4.5 with autonomy high just rip. I'll watch the stream, see what's happening, and when there are any errors. I may jump in to question it or guide it down a different path. I start the server, test it, give feedback and iterate. So I kind of build ahead of myself first. I try and just build the thing. And then all of the gaps and all of the issues that I run into are the opportunities for me to learn. Is that a thing that is part of the system that I've seen across other repos that I should build up a sort of templated system to handle? Should this go into an agents.md that actually follows me around and does the same thing on all of the other repos I'm going to be working on? ## My agents.md setup I've been spending more time trying to figure out the best agents.md setup for myself because this is effectively like the instruction manual. I've got a repos folder locally—that's where all my coded projects go. In that repos folder is an agents.md that says to explicitly set up each new repo with what to do and not to do, how to do things with GitHub, how to commit, all that kind of stuff. And whether it should use my work GitHub account or my personal GitHub account. Running tests. End-to-end tests is one of these things I never really paid attention to previously. But now I'm really keen to have end-to-end tests on everything. Given my current knowledge and capability, when I'm building things and testing them, there often might be silly bugs that I just should have caught or tested had there been tests in the first place. And I often look at others' agents.md files to see what I can borrow for my own. I'm constantly trying to improve my doc to make each and every new working session smoother. ## Coding on the go I'm also making sure that I install the Droid GitHub app on every repo that I create. So when I'm deploying to GitHub, I make sure I'm submitting pull requests so I can have Droid review it—and I can tag Droid to make fixes itself with a custom prompt. I can trigger it from issues or from pull requests. It lets me code from my phone, and add new things when I'm out and about. That in combination with my Telegram bot makes it really easy for me to do things when I'm not at my desk. I also use Slack with my agent. I create a new channel for each repo and just fire off things as and when. I often spin up new channels for new ideas. Slack's a great 1-person product (+ agent(s)). ## What I've been learning **Bash commands.** It really clicked for me when I'd been running the changelog process for a while—it's the same process over and over. I finally understood the 'workflow'. So I got droid to create the slash command flow and it's the first slash command that I actually have used properly, which runs a number of bash commands and also prompts the model to do certain things like reading through GitHub diffs, checking what is behind a feature flag and what's not, putting things into the right sections of new features, bug fixes, that kind of thing. From there I started getting more into bash + cli's. I've stopped using MCPs—I use the CLI versions of most things over MCPs. Yes, because MCPs take up context but mostly I feel like it's simpler - I usually only need a few of the tools an MCP would include. So with Supabase, Vercel and Github, I'm always using the CLI's over the MCP's. I often build my own CLIs for things. For example, I built my own Linear CLI so I could query my own issues and run everything from the terminal instead of going to the desktop or web interface. **VPS.** I abstractly knew what it was—it's like another computer that is on all the time somewhere else. But until I truly needed one I didn't really know what I needed to do there, and there's still a lot I need to learn. But effectively, now when I'm running the crypto tracker, I have a ton of data that's being pulled every single minute and I need that to always stay on. I also use the VPS when using my Droid Telegram bot and use something called SyncThing to sync my local repos to my VPS so that my repos are always up to date and they're in the same state as I left it. So I can just pick it up on the go. **Skills.** I've tried to use them a bit more. I've been using them not only just as knowledge, but also with bash commands + CLIs. I've got a Gmail CLI that I can pull into any projects, it's portable, it lives at my root directory. So anytime I need Gmail in my system—I've got a Gmail triage system that I use—it just uses the CLI. ## The new programmable layer of abstraction Not to be like everyone else on Twitter when they see Andrej Karpathy tweeting something, but this really rang true to me: **there's a new programmable layer of abstraction to master.** When it was the no-code days, the abstraction layer that I was mastering was drag and drop tools like Webflow, Zapier, and Airtable—stitching them together and making it feel like real software (until you hit a limit). But now instead of me thinking I've got to learn to write code from scratch in order to be able to do all of this, what I need to learn is actually **how to work with an AI agent.** How can I prompt it well? How can I make sure it's got the right context? And also how can it help me understand what we're doing, how do the pieces work together, how can I improve my own system over time? Including all of the things like agents, subagents, prompts, context, memory, skills, hooks, etc. ## Learning from others I read people like Peter Steinberger who is an *actual* programmer and is shipping a ton like crazy. And seeing in his posts almost the simplicity of his system, where he just talks to the model, lets it do its thing, doesn't really worry about extra slash commands, subagents, hooks, skills(although he's coming round to skills) - this just gives me permission and confidence that I don't need some ultra complex system. Looking at Twitter you see a lot of people really optimising or potentially over-optimising their own system. That can feel daunting for folks like me, but also that's what I think some of the beauty of this is: it's a completely customizable system, so you can make it work for you however you'd like it to work. You can have a plan mode that you create with a custom slash command that runs for twenty minutes like Kieran does, or you can just talk to the model like Peter does. Another thing while following other engineers is seeing their open source software, cloning it, using it myself, trying to improve it, or just taking parts of it and making that my own. Like Peter's recent summarize YouTube for example, I just took it, removed the Chrome extension part, kept it as the CLI, and now I can just talk to that anywhere I want to. And like Mario, reading things like his MCP post where he talks about CLIs over MCPs, gave me the nudge to dive in more to bash and CLIs. ## The learning process I'm not building things for tens of thousands of people to use in production. So there are going to be bugs, there are gonna be issues, and I run into them plenty. And it's just a reminder that this is a gap in your knowledge, not in the capability that you have now. My role is identifying the gaps or finding those gaps and thinking: how do I make sure this never happens again? Or how do I make sure I understand this part of the system enough that if it's gonna happen again, I'll catch it. Even the simplest things from when I first started using agents to code—like, why can't I use GitHub Pages when I've got dynamic data and I want multiple users to be able to use something? That's a very, very simple thing that programmers know. But it was something I just learned because I was building something, I was trying to build something different than the tools allowed me. So then I said, okay, so what do we need to do? Like all you need to do is just ask the model. The model knows everything that you don't. You can just keep asking it. **It's your ever patient, over-your-shoulder, expert programmer.** You can add in your agents.md "I am not a programmer, you need to explain things very simply for me." You can just tweak it exactly how you want to. ## Contributing to real products I've even contributed improvements to our own product—some simple things, but improvements nonetheless. There's a team of engineers at Factory that are extremely experienced and good at what they do, and I'm learning a lot by just watching them, looking at their PRs. We have internal lunch and learns where people say "this is how I scope new product features", "here's how I bug fix", things like that, which have been really helpful. So this whole thing is just a really big learning experience for me, and I'm really enjoying learning "to code", or, learning to work with code. ## Why this is different I've tried to learn to code many times in my life, and every time it was type in these characters, hit enter, and do you see hello world? It was kind of do this, then that, then this happens. And maybe it would have been helpful for me to learn all that, but I just still think that's so different to what it is today. For me to be able to build the things I've built now, if I'd taken that other path, I would have had to code for many months, many years to get to a point where I could feel like I could write the code myself. So instead I'm coming at it from a point of view of I understand systems thinking for projects built with code. I accidentally learned that when I was running my last company with no-code education. You're still learning that okay, Webflow is the front end, Zapier is the API routes, the connective tissue, the data flows, and Airtable is your database. So I learned the systems of that previously, and I think that's helping me today understand some of those pieces. There is so much you can learn. And often I'll see something that someone posts on Twitter and I'm like, I have no idea what that is or what I can do with it, but I'll bet you I can play around with it. **No piece of software feels unattainable.** I can just git clone it and say, what the hell does this thing do? Okay, I've been thinking about this—is this thing gonna do anything related to what I thought? And it's just all exploration. It's so much fun. ## Asking the "silly" questions There have been countless times where I think about silly questions—to me or silly questions that other programmers would never ask—that I have the permission to ask, because there's no one watching me and no one shooting me down for being stupid or saying the wrong thing. Like, why do we use all these frameworks, these different types of frameworks? Because they are abstractions for humans writing code. So why—if an LLM is super smart—why couldn't it just be simpler code written, less dependencies, less potential surface areas for bugs? Is that a silly thought or a good thought? And I can learn that it might not be a silly thought. But okay, yes, there are these many projects that the model has been trained on, which is why often things will be built in certain frameworks. So it's just building up this understanding of the code world, the engineering world that I didn't deserve to be in, but I'm absolutely part of now. ## Beyond "vibe coding" Yes, you can call it vibe coding, but I think vibe coding misses the point. I'm trying to actually learn the systems. I'm trying to really understand what is going on, how can I improve, how can I be a new age programmer, what is this new technical class? That's what I think is the most interesting thing here. I can't categorically call myself non-technical but I also can't call myself a programmer. Nor would I want to. **I'm part of this new technical class and I don't know what it's called.** But I think vibe coding gives a negative connotation to it, much like no-code gave a negative connotation to that group. ## It feels like a game Some people have likened this new way of programming to a game. Factorio is the one that people talk about. I've never played it. I'm not much of a gamer. But this whole paradigm feels like a real game to me, and the output is I'm building stuff that I want to build. A ton of things just don't end up anywhere on GitHub. They don't end up live. They are just mere explorations of parts of a system or a topic. Others end up published and other people use it - I had a CTO fork my personal site and use it for himself! Big boss stuff (for me!) If someone posts "oh, I built this React grab tool for example". Okay, cool, can I build my own? Like why? This one looks really good. Well, just because I want to. I can just explore things for the sake of exploring things. **Every idea you've ever had can be exercised, can be explored, and it doesn't need to be good.** And you'll learn along the way. ## Permission to throw things away Previously, if I'd learnt to code to build a really crappy version of something I was thinking of, like a big idea that I had, and then no one wanted it, I'd be too emotionally invested in that idea to be able to just throw it away. With no-code, I could effectively build a version of that big idea in an hour, a couple of hours, a weekend. And if no one liked it, no one wanted to pay for it, it was rubbish, then I could just throw it away. It wasn't that much of my time or my energy into something that ultimately wasn't going to be something good for someone else. And I feel like the same is true today. We're gonna see an explosion of software. Many of it won't be good, but lots of it is already great. There are expert programmers who are shipping things like absolute crazy that are all good projects. So we're just gonna have this absolute plethora of coded projects out there that you can use, clone, tweak, remix. It'll take a lot less time than if you had to learn to code or if you're reading the files or you're writing the files or anything like that. It's just a lot quicker. The feedback loop is quicker. The process is quicker. You can just do anything at any time and just consistently keep churning out stuff. ## Fail forward The way to learn about code is to build ahead of your capability and fail forward. I feel like everyone who is not technical today who wants to be in this world, who wants to do stuff like this, can absolutely do it. They just need some permission to do that. To play around. You must think of it like play. Sign up to a CLI agent like Droid. Say you want to build a personal website. Say you want to build a little RSS feed tracker, a little to-do list, a little workout app. Whatever you want to do, you just spin it up, start working on it. Every little hiccup, bug, or issue you run into—question it. Okay, why did this come up? Why did you hit those errors? You know you don't know how to code, so you shouldn't get bogged down with bugs - expert programmers hit bugs all the time. And you can take it to other places. You can go to ChatGPT or Claude and give it to different models for different perspectives. You're always gonna have all of the choice up there and all the different variations. ## Just pick one There are just so many different tools, so many different options. Ultimately, just pick one and just stick with it. Just learn that system. They all look fairly similar. They all work similarly. Obviously, I use Droid because I work at Factory. But also they get the best output of any models. (yay for model agnostic) Ultimately, what I want and what I need from a tool is: **is this one gonna help me get the furthest I can in the least amount of time with the least amount of trouble?** The more I have to do with using the tools themselves, the harder it is. Things like IDEs—I've tried a bunch. I used to use one in particular for a long time. It's just got so much extra stuff that I just don't need or care about. I just want to talk to a model, have code written. If I need to inspect some markdown files, I can now use what I've just recently discovered is a file manager in the terminal. So I can just look through that, or I can open it up in Zed, which is what I use now, just to view markdown files, edit them. If it's a changelog, for example, I want to tweak something briefly, go back to the CLI, and then just let it rip from there. And any tool or feature I think I'm missing, I'll have a crack at building it myself - like a terminal file viewer. *This whole thing is just a really big learning experience for me, and I'm really enjoying it. Build, fail forward, and keep shipping.*