Introduction

Just after 11 am, we are a couple hours into “deep work” in a dimly lit Helsinki office. Developers are hunched over and whispering commands to a seemingly sentient, yet accessible deity. Our prayers, in the form of prompts, are answered in minutes with clean, lint free and tested code. It feels like cheating compared to the work we were paid to do just a couple of years ago. When the team decides to break for lunch, we all rush to get in a couple final prompts - for long, hard pieces of work - lest our agents waste time sitting there idle.

I work at Homie. The company connects salespeople with potential customers by finding warm connections that can introduce them. Our core competency is building warmness signals, or how well two people know each other based on over twenty types of data points. In just a year, we went from using AI as auto-complete to write code, to becoming an AI native organization.

At lunch, AI is usually a topic of discussion. We ponder questions like, why don’t we just hold meetings all day? We could invite our agents into the room so they can understand the nuances of our decisions, the debates over directions and the core of what we are trying to achieve. Our agents all the while build variations of the features we discuss and present them to us for approval in real time. We are half joking, because we know LLMs are not there yet. But there’s a strong feeling that it is just a matter of time.

For now, our agents spit out a glorious masterpiece, or a mortifying mess of code. They haul in these big, beautiful marble slabs, then we must - through prompting - chip away until we have ourselves a Michelangelo.

Background of Work

At Homie, we are about to finish revamping core backend functionality for the 3rd time in 12 months. Each refactor leaves the codebase faster and more functional. In my 10+ years of coding, these kinds of upgrades happened every 2 to 3 years at best. Such work would also be stretched over several months or years.

The main functionality Homie continuously improves are:

  • the speed of finding search results, and
  • scoring how warm those results are.

Our customers set up their ideal customer profiles (ICPs) when they onboard to the application. ICPs are made up of fields like company size, industry and target positions. New users also connect data sources like CRM and social media accounts. A user could have hundreds or thousands of valuable connections. An important part of the setup process is prioritizing those connections a person would feel comfortable asking for an introduction to a lead. These prioritized connections list consists of about 30 to 100 people, depending on the industry.

Each customer that subscribes to Homie adds 74,000 rows to the database within a few weeks. For a user with a hundred connections, we could find five hundred potential leads for an introduction. But Homie is not a cold sales tool. The feedback we dread hearing is “I don’t know this person well enough to make/ask for an intro”. So a list of five hundred potential leads is whittled down to thirty.

Opus 4.5 - A New Dawn

The first major improvement happened a year ago, around the time Opus 4.5 was released. In a 2023 blog post, Vercel documented the port of their codebase from Go to Rust. They said they had to “introduce a significant amount of complexity into our codebase, so that we could interoperate”. We had no such concerns holding us back.

When the first version of Homie was built in 2024, the team didn’t know the best database structure yet, and iterated while keeping backwards compatibility. When we hit millions of database rows holding people and their experiences and unique histories, queries needs lot of joins and were poorly indexed. Each search would take minutes and embarrassed the founders during product demos on multiple occasions. Our customers wanted to perform multiple searches in a session. They also wanted to search by titles/positions, where our original keyword matching left out a lot of high-quality results.

Before Opus 4.5, we would incrementally improve software. We would use tactics like simplifying a function, adding indexes or caching results. But our database structure had stabilized, and we knew we needed to implement a graph database, and introduce vector embeddings, to reach the level of quality our users were looking for. We also needed to move away from Next.js API routes, to a server based solution like Railway.

In 1986, Fred Brooks put ‘expert systems’ as one of the hopes for the silver bullet that solves the complexity of programming. To him, the biggest benefit of this technology is to “put at the service of the inexperienced programmer the experience and accumulated wisdom of the best programmers”.

Nobody on the team had any serious experience with vector databases or embeddings. Opus 4.6 and GPT 5.2 codex held our hand as they spelled out the benefits and downsides, and suggested and implemented solutions. Together, we methodically implemented a range of test suites, evals, graphs, . In just three months, we got queries down from 120 seconds to under 5 seconds, with significantly better results and a more structured codebase. We probably could have done it much faster if we had the requisite experience in the technologies we were implementing. But we were asking our agents lots of “whys”, as a toddler might do. In fact, this felt more like the adult version of a handwriting teacher holding a toddler’s hand as she traces the letters of the alphabet.

In 2000, Joel Spolsky, founder of Trello, opined that the single worst strategic mistake any software company can make is to rewrite code from scratch. That was still true just a few years ago. A financial institution I previously worked at decided to rewrite the entire codebase for its digital banking products from scratch in 2017. A fatal mistake; in 2023, after delays and cost overruns, that business’s digital arm - a cash cow at one point - was eventually broken up, and pieces of it sold off.

I consider Opus 4.5 to be AI coding’s singularity. We would not have undertaken the effort just months prior, in the summer of 2025. Back then, we mostly used Cursor, and inspected every diff. Claude code was great for repo wide analysis and generating plans, but we still needed to see the diffs inline before accepting. At this stage, it was still critical to review every line of code. I remember catching a bug where the agent triggered a function after an Inngest (a workflow orchestrator) job finished, not realizing it must wait for all the batches of that job to complete first.

The transition from IDE to Terminal

By early 2026, a Cambrian explosion of quality coding tools and model releases transitioned our team from IDEs to the terminal. Letting go of being able to see the inline diffs was not easy. Early on we still missed Cursor’s Tab, but that feature was becoming less and less relevant by the month. (And practically obsolete today.) We started doing diff reviews in Github when merging PRs. We now skim through all the changed files; we know the codebase well enough to catch the rare bug.

An emotional moment between me and claude after a particularly intense two week refactor.

Our Dev Agent

The terminal’s reign did not last long. By June, after the release of models like GPT 5.5 and Claude Fable, we were rarely making any changes to the code that the agent produced. We also got better at prompting. By recording long rambling messages with as much detail as possible, the agents began producing code that was better than what we expected. We had also updated our AGENTS.MD file with a lot of the common errors the earlier models made, but it’s hard to know if instructions that helped weaker models avoid common mistakes make any difference anymore.

In June 2026, we embarked on a journey to allow most of our code to write itself. We looked at a few existing solutions, focusing on autonomous agents with integrations to Linear - the platform where our team spends the most time outside Slack. We evaluated integrations like Devin, Factory and Codex - all underwhelming at the time. We had a specific stack for every PR we created from our terminals. A PR would result in:

  • A railway PR environment (a branch of the backend with only a PR’s changes),
  • A Neon Child branch (a branch of our postgres db with relevant testing data),
  • Vercel frontend (which requires the generated )
  • Github actions (which orchestrated the above, inserting the environment variables at build time)

Trying to replicate this setup with third party web app interfaces did not seem worth it, so no serious attempt was even made. It made more sense for us to simply have a VM instance running Codex. Now, a linear ticket gets assigned to our dev agent, which spins up a Docker sandbox and runs Codex until it opens the relevant PR. This setup, a planner, generator and adversarial review agent , all instances of Codex, was inspired by Anthropic’s blog post on harness design.

I was firmly on the “Buy” side in the Buy vs Build debate until this year. Setting the above up on our own VMs was an easy choice compared to locking in the cost and models of a “software factory”.

Now, anybody on the team that finds an issue, from sales to customer success and even developers, can tag linear in Slack, and, minutes later, get a link to a testable PR with the testing data ready.

From Deterministic Code To Multi Agent Systems

Fred Brooks called most of the code writing we did “accidental difficulties”. Now that we handed over most of the routine syntax typing to the AI agents, we could devote a lot more of our time and attention to what made our application valuable to our customers:

  • Sourcing leads
  • Scoring their warmness to the connectors, and
  • Iterating on customer feedback.

Each of the above points is logically grouped into modules in our backend. Sourcing leads includes activities related to finding connections and understanding the company and person fit. Warmness scoring allows us to understand how well two people know each other and whether there is a good chance they would be willing to spend their limited social capital on making an introduction. Then we must deliver these to the customers, and learn what makes successful introductions. Analyzing signals can get us far, but a single sentence from a customer can provide more context than a TB of data.

Getting the right data to analyze takes time, and there is currently no way around it. For an average customer, it could take about 24 hours to find a handful of potential warm leads out of thousands of potential candidates. So rather than scoring leads when a user searches, we score as many leads as possible in the background, so that the signals are ready. This requires pre-filtering so we don’t spend time on obvious poor fits.

A year ago, these modules were largely deterministic; LLMs were used in various functions, but the structure of the code was traditional. Today, those modules are all agent-first. The entry point is an LLM call, and from there the funnels have access to 44 tools to do everything needed. We are currently heavily focused on building better evals and self improvement loops for these agents.

AI has had another side effect: it has allowed our engineers to get closer to customers. The time freed up from development can now be spent on understanding the customer. I frequently join sales and customer success calls, drop into customer channels with questions, and attend conferences and meetups.

Studies show that weaker ties, the people you interact with only on rare occasions, can unlock more doors (see: Granovetter’s “The Strength of Weak Ties”, one of the most cited papers in sociology ). We find that about 20% of intro requests lead to a meeting. Specifically, half of intro requests are made, and 40% of made intro requests turn into a meeting. The biggest challenge is getting hesitant customers to ask the intro in the first place. Having agents do much of the prefiltering results in a higher quality dataset, allowing us to spend more time helping the customer make those intros.

Developers’ New Roles

Like the QR code in 2020, reading comprehension is making a comeback. Our agents explain the work they accomplished in paragraphs (and sometimes pages). At any given moment, two to three agents have completed work and are waiting for the developer to read through their work. We must become writing specialists. Frontier models have become good at instruction following. If an LLM did something wrong, it’s usually because your instructions gave too much room to wiggle.

We’re now testing a new way of working: blog posts. It’s a mix of a requirements doc and a persuasive argument for why this should be built, and how it should be built. It’s easier for the team to read through an engaging two pager than an LLM generated plan. Of course, AI is used heavily to understand the current state of the codebase, customers and business, which serves as reference, but the reference points are not “AI”, rather a specific line in the code, a customer quote, a field in the database. Routine development work is still handled by the dev agent, which writes its own prompts.

For people like me, who could block out the world and disappear into code for hours, yet are easily distractible, the arrival of LLMs hasn’t been smooth sailing. Now, a prompt is given, and a forced wait, of 5, 10, even 20 minutes ensues. Instead of waiting, we start another agent or two, or three. But any more and my own context limit becomes stretched. Humans do not “compact” context like LLMs.

Conclusion

In the 1939 film “The Wizard of Oz”, Dorothy and her friends seek to have their wishes granted by the Wizard - an intimidating floating head surrounded by fire and a bellowing voice. When their dog pulled back the curtain to revealed an ordinary man tinkering with controls to fake the entire spectacle, the friends felt bamboozled. But it turned out the man was more able to help them than the wizard, who tried to send them away. With more empathy, the man helped Dorothy and her friends discover everything they needed to fulfilling their wishes.

We developers may have been something like this Wizard of Oz. The ability to write coding syntax was considered hard, so much so that ‘coding’ was considered a profession. Now that syntax is ‘exposed’ for what it is, and English as the language is revealed, we can unleash our true skills: the ability to architect systems by spending more time with customers understanding their deepest wishes and solving for making them a reality.