Code agents and assistants
Turing-complete autocorrect, vibe-coding, …
2021-10-14 — 2026-08-09
Wherein Various Coding Harnesses—cloud, Offline, and Terminal-Based—are Surveyed and Compared, With Particular Attention Paid to Whether Each Agent Relies Upon Grep, Embeddings, or Repo-Maps to Locate Relevant Code.
Large Language Models are text writing machines, and code is text. These machines are, it turns out, great at writing code by default, and can be made even better. Here I take notes on practicalities of getting these rather clever program synthesis machines to be a net plus for my life. A cousin to neural automata.
This page is mostly AI slop, i.e. LLM-expanded version of my notes from some recent exploratory projects. However, it is useful, so I am publishing it now rather than waiting for a more polished version.
Terms to know: harness and agent and executor.
Also related: Running backends offline on a Mac, automatic mathematical agents.
It helps to structure coding agents around the particular part of the agent design space that works best with code.
Harnesses run, by default, sequentially, often using automatic verification to determine when they have succeeded and thus may stop (“Did the tests pass?”). That propensity is shaped by the way we (typically) write code: It produces side effects, i.e. the code itself is a side effect from the perspective of the conversation, so it is more difficult to dispatch 50 coding agents without causing them to step on each other’s toes the way we can e.g. fan out fifty proof attempts in a maths loop.
There is a lot of variation within coding agents, however, for example in how each finds the needed code and how much we trade-off ease-of-observation (which we gloss as observability) for power.
Agents can also differ in which model they use.
Here, I explore some coding agents, some of which I find tolerable.
General advice:
I am vaguely concerned about how much of the world’s source code now gets uploaded to a handful of model endpoints servers, with the potential for abuse scaling with the size of the giant fatberg of latent expertise and corporate know-how. Nonetheless, the developer arms race is real, so let’s all ignore that and keep flushing our code into their pipes, eh?
1 How agents find code
When a coding agent needs to find some code relevant to the current operation — the function to edit, the callers it might break — how does it do that? My first instinct was the text-search tools: point the agent at ripgrep and fzf and let ’er grep. For reals, Claude seems to do that. Is that the state of the art, or do we need the fancy vector-database RAG machinery and special vector embeddings?
At the moment it seems that most agents do in fact grep. The agents that feel most capable don’t build much indexing. That is to say, the best agents do Ctrl-F and not Google Search. However, the elite agents don’t do vanilla grep — they do fancy grep.
1.1 Agentic grep
Claude Code, Cline, and OpenCode ship no embedding index. The agent navigates the way a developer does — glob to list, grep to search, read to open — pulling files in just-in-time. Anthropic argues that just-in-time primitives bypass the issues of stale indexing, and increasingly good models are pretty good at exploring. Cline goes so far as to have a no-index manifesto. Moreover, because code is lexical, an exact-string match is often what we want, and grep has a generational head start there in affordances and performance.
1.2 Repo maps
Aider takes issue with this. It runs tree-sitter atop the repo to extract symbol definitions and references, builds a graph with files as nodes and dependencies as edges, and runs personalized PageRank over it to rank the most central symbols, packing the top ones into the prompt. The model gets some kind of structural/dependency map and centrality weighting or something like that.
I don’t use Aider though.
1.3 LSP hacks
IDEs already have some programming language machinery built in via the Language Server Protocol. Serena exposes find_symbol, find_referencing_symbols, go-to-definition, and symbol-level edits as MCP tools, so “find every caller of this function” is an exact graph query rather than a fuzzy guess.
1.4 Embeddings after all
Cursor does embed the codebase — it trained its own embedding model and indexes for retrieval — though Cursor frames this as complementary to grep, not a replacement.
Embeddings seem only worthwhile for really big things, like mega monorepos — which is awkward, because scale is also where they start to come apart. A 2025 DeepMind result (Weller et al. 2025) proves a hard cap on how many query-document relationships a fixed embedding dimension can represent at all, no matter how well trained the model is: past that ceiling there are simply sets of documents that no query can retrieve together. So the regime that justifies paying for an index is the same regime in which the index needs a bigger dimension to keep working, and it all gets terribly messy.
1.5 Search subagents
We can always dispatch subagents to explore off their own bat and report back about what they found. This means they can use any of the other tricks mentioned here but
- in parallel, and
- without blowing the token budget of the main agent.
Morph’s WarpGrep runs grep in its own context window, fires a dozen tool calls in parallel, and returns a digest. I bet we could just set up subagents to do this ourselves with any harness that supports subagents and the right skills.
1.6 Tying all that together
Shaped argues we should use: grep for exact identifiers, LSP for precise navigation, repo-maps for cheap structure, embeddings for the scale where the rest breaks down. Vector-DB vendor Milvus argues grep “burns too many tokens”, but they are trying to sell a thing, so YMMV.
The more elaborate search scaffolding might be especially useful for weaker local models to compensate for being worse at iterative search. If some offline coding agent feels lost in a big repo, Serena or Aider’s repo-map might help.
For the galaxy-brained: Glean is a code inference engine in this space, which I have not tried.
2 Cloud and commercial harnesses
The cloud-hosted and commercial editors. None has a serious local-model path. Where they differ from each other is mostly context — what each pulls into the window and how — with dispatch a distant second and observability an afterthought:
| Context | Dispatch | Observability | |
|---|---|---|---|
| Claude Code | just-in-time grep/read, compaction, sub-agents | one frontier model, plus Haiku screening bash | full transcript, hooks |
| Cursor | a trained embedding index alongside grep | tiered, mostly hidden | the diff, and not much else |
| Copilot | whatever the editor has open, plus chat history | fixed per surface | the diff |
| Warp | codebase embeddings | mixed-model | terminal history |
2.1 Claude Code
anthropics/claude-code is a command-line tool — a nicely designed one that interacts gracefully with a normal IDE. I have little to say about it; it is too thoroughly documented elsewhere/everywhere and in any case moves too fast to be worth explaining. The hooks reference is a handy reference for one of the under-used extension points.
Sebastian Raschka points out that we can force Claude Code to use a local model with ollama launch claude (!).
2.2 Cursor
Cursor is another VS Code fork with its own AI engine and some extra UI affordances. My colleagues assure me it causes far fewer annoying psychoses and sidetracks than Copilot. Cloud by design, though — there is no serious local-model path here.
2.3 GitHub Copilot
GitHub Copilot now uses some generic off-the-shelf GPT model for code completions. The original Codex engine was strikingly good, and for my idiosyncratic purposes, the general-purpose models have matched it, even years later.
GitHub Copilot has a great workflow for automatic completions, and that’s what originally made me pay for it. Still acceptably useful, this bit.
The extra chat interfaces they have rolled out since are janky and only semi-reliable, at least in my experience. They are bad at following instructions, careless with indentation, and prone to forgetting they are supposed to edit code and instead talking about editing code. It’s a bit like coding with a drunk genius: occasionally brilliant, usually messy.
OpenAI squandered their early lead.
Pro-tip: behind a corporate firewall, Copilot needs a specific set of whitelist exceptions.
2.4 Warp
Warp is an all-in agentic terminal/IDE — mixed-model, codebase embeddings, MCP, the lot. Heavily hyped; I haven’t tried it.
3 Model-agnostic and offline harnesses
There is a cornucopia of coding agents now, overflowing to the point of choice paralysis — everyone writes their own agent. All, AFAICT, speak plain OpenAI-compatible HTTP, so I can point them at a commercial token host or a local server. Osaurus on localhost:1337, ds4-server on 127.0.0.1:8000, and Ollama on 11434 are the ones I like. With local models the model ability is a limiting factor.
| Context | Dispatch | Observability | |
|---|---|---|---|
| pi | deliberately little — no sub-agents, no MCP, a sub-1000-token system prompt | whatever we point it at | everything: every byte of every exchange on disk |
| Aider | a repo-map, plus the files we name | one model | a diff — one git commit per change |
| OpenCode | LSP, MCP, plugins | any of 75+ providers | full session transcript |
| MiMo Code | four memory files on four clocks, written by a subagent | fan-out on planning turns | structured memory, over an unindexed trace |
| Codex | sandboxed by default; frugal with tokens | profile-switchable | the transcript |
| Goose | MCP, skills, recipes | many providers, or a subscription over ACP | desktop or CLI transcript |
| Cline | sub-agent teams, MCP, plan mode | switchable at runtime | sidebar, CLI or kanban board |
| Qwen Code | sub-agents, MCP, plan mode, skills | switchable at runtime | CLI transcript |
Some especially peculiar designs: pi is all-in on observability. Aider is all-in on minimalist near-deterministic interventions rather than agentic behaviour. MiMo Code is ultra-keen to handle long-horizon tasks.
3.1 OpenCode
OpenCode is IMO a generic terminal harness, but it codes just like the name suggests. It’s especially useful for coding, working even offline: point it at a local endpoint with a custom-provider baseURL and it wraps LSP, MCP, and a plugin system around the model. The official VS Code extension exists but looks shonky atm.
3.2 MiMo Code
Xiaomi’s MiMo Code (MIT) is a fork of OpenCode that has many tweaks, especially for long-horizon scaling. It inherits OpenCode’s custom-provider faculties but probably works best with Xiaomi’s own model.
Unlike its competitors, the project produces structured memory:
- Four memory files on four clocks, written by a subagent rather than the main agent:
checkpoint.md(“this” session),MEMORY.md(“this” project), a cross-project preferences file (“this” user), and beneath it all an SQLite trace of every message which presumably is useful for something. - The writer fires at roughly 20%, 45% and 70% of the context budget, keeping a “best, latest” summary of the session live
- Xiaomi uses a particular vocabulary for its reliability designs: Max mode (high-temperature fan out for candidate plans, pick with a low-temperature judge), Dynamic Workflow (a JavaScript dialect —
agent(),parallel(),pipeline(),workflow()— that the agent emits and a sandbox runs deterministically), and Goal (the natural-language stopping condition). - Dream (weekly) and Distill (monthly) are the two background cadences for evolution. Distill mints skills, CLI commands and SOP docs from past sessions — audit
.mimocode/occasionally. Dream does… something else, I guess.
3.3 Codex CLI
OpenAI’s Codex CLI (openai/codex, Apache-2.0) is a terminal harness and — surprisingly for OpenAI — open-source. Naming caveat: this Codex is the agent harness, not the lamented original Codex code model that powered early Copilot.
It might be my favourite thing from OpenAI, specifically because it does not need to plug into an OpenAI endpoint. We can instead point it at whatever we want, even a local model mode.
Codex seems to occupy a similar niche to OpenCode but deviates in two ways: First, it sandboxes by default — Apple Seatbelt on macOS, Landlock/seccomp on Linux — reducing the blast radius of rogue agents somewhat. Second, Sebastian Raschka clocked it as the most token-frugal of the three harnesses he measured (Codex < Qwen-Code < Claude Code), which matters especially with a slow or constrained local model. pi is likely even more frugal, at the price of a steeper learning curve.
Configuring Codex to use an open endpoint was not immediately obvious to me. The trick is to configure a ~/.codex/local.config.toml profile invoked as codex --profile local:
# ~/.codex/local.config.toml — overlaid on config.toml by `codex --profile local`
model_provider = "osaurus" # our own provider id (see table below)
model = "qwen3.6:35b" # whatever the server is serving
[model_providers.osaurus]
name = "Osaurus"
base_url = "http://localhost:1337/v1" # OpenAI-compatible endpoint; swap for ds4 on 8000, omlx, etc.
wire_api = "chat" # these servers speak Chat Completions, not OpenAI's Responses APIThere are pre-defined model provider entries for openai/ollama/lmstudio.
Note that the project-level profile .codex/config.toml ignores model_provider/openai_base_url for trust reasons. Interestingly, Raschka also found Qwen3.6 scoring better under Codex than under its parent company’s own Qwen-Code.
3.4 pi
earendil-works/pi (Mario Zechner / badlogic, MIT), a.k.a. Pi Coding Agent, is a generic minimalist harness. pi’s philosophy is idiosyncratic enough that I introduced it in the LLM Agents page as a whole alternate way of doing agent things. What matters here is that it runs offline and is the harness driving antirez’s famous ds4 on a Mac. There’s a learning curve, but notionally a rewarding one.
3.5 Aider
Aider (Aider-AI/aider, Apache-2.0) is “AI pair programming in your terminal.” aider is a git-native AI assistant, in the following sense: we execute it inside a git repository, tell it which files we’re working on, and describe the change we want in plain English at a chat prompt. Aider sends the model those files (plus a repo-map of everything else so it has context), gets an edit back, and writes it straight to the files on disk — then commits each change as its own git commit with a generated message. So we never copy-paste code out of a chat window, and reviewing or undoing what the model did is just git diff and git revert.
That git-per-change discipline is the whole potato. Once we have decided on that, the rest of the workflow just falls into place. It is less an autonomous agent that wanders off and does ten things, more a tightly scoped tool kept in check using git affordances. Harper Reed’s workflow gives us the flavour.
For our purposes it is model-agnostic — point it at any OpenAI-compatible base_url, or use the ollama/ prefix for a local model — and the repo-map means a smaller local model still gets relevant context without us hand-feeding it files.
It has some nifty automations — linting and running the test suite after each change, then feeding the logs back to the model.
Slight variant: --watch-files mode leaves aider running while we work in our normal editor, watching for AI! / AI? comments we drop into the code and acting on them, so we never have to leave the IDE.
Less ambitious, less risky, elegant.
3.6 Goose
Goose (Apache-2.0) is a general-purpose harness — desktop app plus CLI, grown-up enough to have been adopted by the Linux Foundation. For coding specifically it speaks the Agent Client Protocol, so it can back Zed or JetBrains as the agent behind the editor, and also has some code plugins I have not tried yet.
3.7 Cline
Have you, like me, grown flabby on a diet of soft, cosy code editors? If so, and we want, say, VS Code agent sidebars, Cline (cline/cline, Apache-2.0) sees us, and it understands. That sidebar is where Cline began.
With Cline 2.0, the Cline team pulled the agent loop out of the extension into a standalone open-source harness, @cline/sdk, and the same engine now drives a terminal CLI, a JetBrains plugin, the VS Code sidebar, and a web-based multi-agent kanban board. The runtime has all the bells and whistles and rescue knives we’d expect to find strapped to a serious harness — subagent teams, MCP, scheduled cron agents, chat connectors for Slack/Telegram/Discord. They claim impressive performance on something called terminal-bench.
A little dynasty of editors descends from Cline, mostly forks of its old monolithic extension rather than consumers of the new @cline/sdk. Roo Code was the prominent one, and added per-mode permission scoping, but it shut down in May 2026, and the community decamped to ZooCode. Kilo Code (MIT) forks that fork for its extension, and OpenCode for its CLI.
3.8 Qwen Code
Qwen Code is the Qwen team’s terminal coding agent — originally a fork of Google’s Gemini CLI, since gone its own way. Multi-protocol like the rest of this section: OpenAI / Anthropic / Gemini / Qwen APIs plus a local Ollama or vLLM endpoint, switchable at runtime. It aims for Claude Code feature parity — subagents, MCP, plan mode, and the agentskills.io SKILL.md format. Not to be confused with Qwen-Agent, the Python harness library, which is a separate codebase that does not natively consume skills or do that other fancy stuff.
3.9 Pour one out for the departed (and the renamed)
Fauxpilot (the self-hosted Copilot clone, long dead), Cody (Sourcegraph moved on to Amp), Kiro (Amazon’s cloud-bound spec-driven IDE), Codeium (now Windsurf), Amazon CodeWhisperer (now Amazon Q Developer), Codestral Mamba, Llama Coder, replit-code and Code Llama — all had their moment.
4 The models behind them
Choosing a good tool-using model seems to be important for most agentic workflows. tl;dr generic agentic tool-use is reputedly unreliable in models below roughly the 30B class. Online, the answer is boring: take whichever big frontier model is currently on top. These dominate over local unless we have eye-wateringly good local hardware. Which one that is changes month to month, so it is a leaderboard question rather than a blog question — Terminal-Bench and SWE-bench Verified are the boards the harness vendors quote at each other, and Artificial Analysis tracks price and tokens-per-second alongside the scores.
Offline VRAM constrains which models we can use. I have a set of models I use on a Mac. A popular default there is Qwen3.6-35B-A3B.
Those picks are all autoregressive, in the sense of generating tokens one after another. A language diffusion model is a sufficiently different inference paradigm that might benefit from a different sort of interface entirely.
5 MCP
Model Context Protocol is a standard to enable an agent to access tools and data. Here are some fun code-specific servers — find more at the official MCP Registry or punkpeye/awesome-mcp-servers.
oraios/serena gives an agent LSP-style symbol navigation and refactoring across 30-odd languages. Since some heavy hitters (Claude Code) ship no codebase index of their own, Serena might beat groping by grep on a large repo:
For git and GitHub operations — repos, PRs, issues, Actions — the official GitHub MCP server does the job, though in the name of safety, it requires a personal access token and a running docker daemon:
For the well-known problem of models hallucinating outdated APIs, there are docs-fetcher servers (Context7, Git-MCP), but a plain web-search/reader (jina-reader) seems to do the job for me. Browser automation (Playwright MCP, Chrome DevTools MCP) helps debug web apps, but I have not used those, so I will not speak of them further.
For Apple-platform vibecoding — XcodeBuildMCP plus Apple’s own xcrun mcpbridge — see Vibecoding Apple apps.
6 Driving an agent from the editor
If we want the agent to live inside the editor rather than in a terminal beside it, the Agent Client Protocol is how the two talk. Zed and JetBrains speak it natively, community bridges exist for Neovim, Emacs and VS Code, and on this page Goose ships a goose acp server while Claude Code and Codex have adapters. It is a frontend-layer concern.
7 Packing code for AI
Sometimes we just want to flatten a whole codebase into a single blob and paste it into a chat window or seed a fresh context. This matters less than it used to — an agent with the search tools above rarely needs the whole repo at once — but for that one-shot case it’s still handy, since a model can read one text file easily but finds a scatter of files more confusing.
yamadashy/repomix is the classic, also available online at repomix.com. simonw/files-to-prompt is another favourite (background), and my fork supports a handy alternative usage pattern:
Also handy for online usage: cyclotruc/gitingest / Gitingest — “Replace ‘hub’ with ‘ingest’ in any GitHub URL to get a prompt-friendly extract of a codebase”.
8 Workflows
OK, we have a harness. We can still choose how to use it. The vibe coding workflow using git worktrees has been formalized, e.g. in Crystal, which manages a multi-session Claude Code across them (one checkout per session) — this is how we get some of the parallelism back despite the executor doing real work, since the agents no longer collide in the same tree. Modern harnesses often incorporate such a workflow into their design.
ghuntley/groundhog goes the other way and rebuilds a coding agent from first principles as a teaching exercise, written up here, and with an interesting approach to design docs (now paywalled).
9 Incoming
- A better version of this very post by Sebastian Raschka: Using Local Coding Agents
- Secrets of Intelligence Services - by Ben Recht - arg min — this offers an ultra ML-nerd perspective, which is nice.
- Measuring the Impact of Early-2025 AI on Experienced Open-Source Developer Productivity - METR
- AI self-play for algorithm design
- Software²: A new generation of AIs that become increasingly general by producing their own training data
- LMQL — a programming language for language model interaction, which builds prompt templates and intermediate instructions on top of Python
- MLE-bench: Evaluating Machine Learning Agents on Machine Learning Engineering | OpenAI
- Introduction to Program Synthesis is an interesting MIT course that connects modern AI program synthesis to much older literature.


