One of the more interesting experiments in the continued development of EZ-Blog has been determining whether a capable AI coding agent can run entirely on my local Windows development machine.

The answer, after quite a bit of experimentation, is: yes, with qualifications.

I now have a local AI coding stack that is fast enough and capable enough to perform useful software-development tasks. It is not yet something I would trust to work independently on complex architectural changes. But, when given a well-configured environment, strong project instructions, bounded tasks, and careful human review, it appears capable of making real progress.

The Goal

My primary AI-assisted development workflow uses ChatGPT for architectural discussion and review and Codex for implementation. That combination has worked extremely well, but cloud-based agents have practical constraints, including usage limits.

The experiment was therefore not about replacing those tools. The goal was to answer a narrower question:

Can I build a useful local coding agent that can continue making productive progress when cloud-agent capacity is unavailable?

My desktop has an NVIDIA RTX 4060 with 8 GB of VRAM. That is enough to run smaller models entirely on the GPU, but not enough to hold the larger coding models that are more interesting for agentic software development.

First Attempt: Qwen Code and Ollama

I initially tested Qwen3-Coder 30B-A3B through Ollama and the Qwen Code agent harness.

Qwen3-Coder is a mixture-of-experts model. Although it contains roughly 30 billion total parameters, only a subset of those parameters is active for each token. That makes it an attractive candidate for local use.

The model itself showed promise. It could inspect the repository, understand much of the architecture, and make reasonable small Java changes. Unfortunately, performance was poor. Ollama reported that most of the model was effectively being serviced by the CPU rather than the GPU. The result was an agent that could think, but did so far too slowly for comfortable interactive development. There was also a second problem: when the agent encountered Maven reactor build issues, it repeatedly tried variations of incorrect commands rather than properly diagnosing the build structure.

At that point it was important to separate two different questions:

• Is the model too slow?

• Is the model not capable enough?

Those are very different problems and needed to be tested independently.

Replacing Ollama with llama.cpp

The next experiment was to keep the same Qwen3-Coder model while replacing Ollama with llama.cpp.

That made an enormous difference.

llama.cpp automatically discovered a much more effective hybrid CPU/GPU configuration. Dense portions of the model could remain GPU-resident while large mixture-of-experts tensors could be serviced from system memory. On simple inference tests, generation increased to roughly 20 tokens per second. A 16K context window produced approximately the same performance, making interactive use entirely practical. For the coding-agent harness, however, 16K was not enough. The agent itself can send tens of thousands of tokens containing instructions, tool definitions, repository context, conversation history, and tool results. The final local server configuration therefore uses a 64K context window and a single inference slot. Under real agent workloads, generation can fall to roughly five or six tokens per second as the context becomes large. That is significantly slower than a small synthetic prompt, but still usable for asynchronous development tasks.

The Better Agent Harness: VS Code

I also found that I preferred the Visual Studio Code Agent interface to Qwen Code.

VS Code can connect to a custom OpenAI-compatible endpoint, which means its Agent and Plan modes can talk directly to the local llama.cpp server. That produced the current local coding architecture:

Human developer and architect

ChatGPT for architecture, planning, and independent review

Codex for primary implementation work

Local VS Code Agent as an additional implementation tier

llama-server

Qwen3-Coder 30B-A3B

RTX 4060 + CPU + system RAM

The important architectural point is that the agent harness and the model runtime are independent. VS Code manages files, tools, terminal execution, planning, and agent orchestration. llama.cpp performs inference. Qwen3-Coder provides the language model. That separation makes each part independently replaceable.

An Unexpected Lesson: Environment Matters as Much as the Model

One of the most useful discoveries from this experiment had very little to do with artificial intelligence. The agent originally performed terribly when running Maven commands. It switched between PowerShell, CMD, Git Bash, Maven Wrapper commands, Windows paths, and POSIX paths. It repeatedly retried equivalent commands with different quoting. That initially looked like a model intelligence problem. It was actually largely an environment problem.

The normal EZ-Blog development environment uses Git Bash, Maven 3.9.11, and a known Java installation. Once the VS Code Agent terminal was explicitly configured to launch Git Bash as a login shell, the environment became deterministic.

Repository-level AI instructions were then added in:

.github/copilot-instructions.md

Those instructions document stable facts that an engineer should not need to rediscover during every task:

• Use Git Bash.

• Run Maven from the reactor root.

• Use -pl and -am for focused module work.

• Handle Surefire test propagation correctly.

• Do not switch shells as a troubleshooting strategy.

• Do not substitute direct javac execution for Maven verification.

• Never report success until the required verification command exits successfully.

The behavioral difference was dramatic. Before those changes, the model spent many attempts unsuccessfully trying to run one Maven test. Afterward, given only the instruction to run a particular focused test, it immediately produced the correct Maven reactor command and succeeded on the first attempt.

The First Real Test

The first meaningful development task was more demanding than changing a line of code. The agent was asked to begin the next SQLite persistence step by creating a reusable contract-test architecture for ArticleRepository. The intent is eventually to run the same behavioral contract against both the existing YAML repository and the future SQLite repository.

This was a good test because it required the model to distinguish between:

• Repository-interface semantics.

• YAML-specific implementation behavior.

• Shared contract tests.

• Adapter-specific tests.

• Future SQLite requirements.

The result was useful but imperfect. The model produced a reasonable abstract contract-test skeleton and a YAML binding. It correctly used temporary storage and covered the main repository operations. But it struggled while debugging the tests. It repeatedly revised fixture setup, ran overly broad test scopes, and eventually weakened one domain-field assertion rather than clearly resolving whether the behavior belonged to the neutral repository contract or was merely a YAML implementation characteristic. Independent review rated the result roughly in the 5.5-to-6-out-of-10 range: useful as a starting point, but not something that should be committed without review and refinement.

Qualified Success

That leads to what I think is the correct conclusion from the experiment: qualified success.

The local system is not a replacement for a stronger coding model such as Codex, nor should it be trusted to independently make large architectural changes. But it has crossed an important threshold.

It can:

• Navigate a real multi-module Java repository.

• Read architecture and implementation documentation.

• Use tools and edit files.

• Run Maven builds and focused tests.

• Produce reasonable small-to-medium implementation drafts.

• Work entirely on local hardware.

Its weaknesses are equally important:

• Long agent sessions become progressively slower as context grows.

• Complex debugging can become repetitive.

• The model can confuse passing some tests with successful verification.

• Semantic distinctions between contract behavior and implementation behavior still require careful review.

• It should currently operate on bounded tasks with human supervision.

The Emerging AI Development Model

This experiment reinforces a development pattern that has been emerging throughout the EZ-Blog project. AI-assisted software engineering works best here not as autonomous replacement of the developer, but as a layered collaboration.

  • The human architect defines intent, requirements, architecture, and acceptance criteria.
  • ChatGPT helps analyze architecture, prepare bounded implementation tasks, and independently review results.
  • Codex performs high-confidence implementation work.
  • The local AI agent provides another implementation path when local capacity is useful or cloud-agent capacity is constrained.

The repository itself serves as the shared memory: architecture documents, implementation plans, tests, build conventions, and explicit agent instructions. The human remains responsible for intent, architecture, acceptance criteria, and final judgment. The agents provide implementation leverage.

A More General Lesson

The most important lesson may be that evaluating an AI coding model without evaluating its environment is misleading. A capable model placed in an inconsistent shell environment with undocumented build conventions can appear incompetent. The same model, given a deterministic tool environment and concise project knowledge, can behave dramatically better. The practical unit of evaluation is therefore not simply the model.

It is the complete system:

  • Model
  • inference engine
  • context window
  • agent harness
  • tools
  • shell environment
  • repository instructions
  • tests
  • review process = effective coding capability

That is the architecture I now have running locally for EZ-Blog. It is not autonomous software engineering, and that is not the objective. It is another capable participant in a human-directed development process. For now, that is enough to make it genuinely useful.