Agents are just files: how Google's newest Gemini agent replaces code with markdown
A Google conference talk rebuilds the same GitHub PR agent three times, replacing more and more code each round with plain markdown files, until version three barely has any code left at all.
A recent conference talk from Google's Gemini API team made a case that stuck with me: the same coding agent, built three separate times, gets simpler each time, and the third version barely has any code left. What replaces it is a handful of markdown files.
Same agent, three builds, less code every time
The talk opened with Simon Willison's definition of an agent: an LLM running tools in a loop until it achieves a goal. To make the idea concrete, the speaker rebuilt one GitHub pull request review agent three separate times, and each version deleted more code than the one before. By the third build, there was no agent code directory left at all, just a markdown file with instructions and a bash script.
Version one: a Python loop
The first build was the classic approach from about a year and a half ago. A Python class runs the loop, a JSON schema defines each tool, a Python function implements it, and the code checks every model response to see whether it's a function call or a plain text answer before deciding what to do next. It works, but everything has to be spelled out by hand: the schemas, the routing, the retries, the state.
That first version also showed the ceiling of this approach. Ask the agent to review a pull request and it works fine, because reviewing a PR is exactly what its tools were built for. Ask it something outside that list, like the weather in San Francisco, and it just says it can't do that. The agent is only as capable as the tools someone remembered to wire up.
Worth mentioning here is Google's new Interactions API, the API this whole talk was built around. It's a unified interface for calling Gemini models directly or calling managed agents, and one detail matters more than it sounds: conversation history stops being a back-and-forth of user turns and model turns and becomes a flat timeline of steps, distinct events for user input, reasoning, function calls, and function results. Once you're building agents instead of chatbots, you have more than a user role and a model role to represent, and forcing everything through two roles was always a workaround.
Version two: an agent framework
The second build swapped raw Python for Google's ADK, an agent framework that owns the tool loop, the function-call routing, retries, and error handling. It even derives the JSON schema for each tool straight from a Python function's signature instead of making you write it separately. Whole categories of boilerplate just disappeared.
What didn't disappear was the ceiling. Ask the framework-built agent about the weather and you get the same polite refusal as before, because the framework manages the loop, not the agent's actual capabilities. You still own every tool in Python, you still decide in advance exactly what the agent is allowed to do, and you still have to host the thing somewhere yourself.
Version three: a remote agent that owns its own sandbox
The third build is where the source directory disappears entirely. In its place: an AGENTS.md file with instructions, and a small bash script that installs the GitHub CLI if it isn't already there. No tool schemas. No Python functions for reading a pull request. Just a note telling the agent it has a GitHub CLI, a bash tool, and a file system, and that it should use them.
This is the Antigravity agent, a general-purpose managed agent newly available through the Gemini API, running on the same underlying harness as the Antigravity IDE (a coding-specific agent, not the same thing, just built on the same foundation). The part that makes this version different is a new "environment" parameter: instead of a fixed toolbox, the agent gets a hosted, isolated Linux sandbox where it can run bash commands, install what it needs, and save files. You can point that environment at a GitHub repo, a Cloud Storage bucket, or inline files as sources.
Credentials get handled through a network proxy sitting around the sandbox. The agent never actually sees your GitHub token, it just knows it can call the GitHub API, and the proxy injects the real credential only when a request leaves the sandbox. You can scope that down to specific domains, or leave it open to the whole web with no credentials attached, which is the default because forcing everyone to pre-declare every domain up front is its own kind of friction.
For anyone who wants to reuse a setup instead of repeating an API call with the same configuration every time, there's an Agents API on top of this: give an agent a custom ID with its own system instructions, tools, and environment, and call it afterward exactly the way you'd call a Gemini model.
Run the same weather question against this version and it actually answers, which is the moment that sold me on the whole design. It reaches for Google Search on its own, the same way a person would reach for a browser tab without being told to. Nobody defined a weather tool. Nothing had to be defined at all.
What this changes about extending an agent
Adding a new capability to the first two versions meant writing a Python function, hand-building a schema for it, and wiring it into the tool list. Adding a capability to the third version usually means writing a markdown file. Want the agent to run a security scan on a pull request? Tell it which CLI tool to use, or just put that tool in the sandbox. No code change, no redeploy, just another file for the agent to read.
A few real examples came up that make the pattern feel less theoretical. At a European AI Engineer conference, Cursor described replacing roughly 12,000 lines of hand-written TypeScript orchestration for git worktrees with about 200 lines of agent instruction files. Manus rebuilt its own agent harness five separate times over six months last year. A well-known open deep research framework went through three architecture rewrites in a single year. Windsurf cut 80 percent of its own tool list and got fewer steps, faster responses, and better accuracy out of what was left.
The rule of thumb the talk left me with: if your harness keeps getting more complicated as the underlying model gets better, that's a sign you're overengineering it, not a sign the problem is hard.
Agents that write their own notes
One detail deserves its own mention, since it's the part that changed how I'd plan a long agent session: this same file-based approach lets an agent build its own memory. Tell it during a session to remember a preference or a rule, and it writes that down to a file it can read again later. If a session runs long and something else comes up mid-task, you can tell the agent to hand off that context to a file for a future session to pick up, instead of losing it when the conversation ends.
Where this leaves things
The advice from the talk boiled down to a few plain rules. Stop micromanaging execution paths. Give the agent general tools and let it reason its way to a solution instead of hand-holding every step. Spend your actual effort on what's genuinely yours to own: domain instructions, workflows, evals, clean tool definitions, and checking that the outcomes are actually right. And build with the expectation that you'll delete most of what you write. Every time the underlying model gets meaningfully better, more of the code written around it turns out to be unnecessary scaffolding rather than a permanent asset.
Follow us
TikTok · LinkedIn · X · Instagram · Telegram
Ready to automate?
Let’s build a system that works for you — not the other way around.