· 7 min read
How to Build an AI Coding Workflow Using Only Open Source Tools
By B. Haddad
- guides
Yes: you can build a productive AI coding workflow using only open-source software and locally run models. Start with a local model server, put a terminal-first coding agent in front of it, and make Git plus automated tests—not the model—your source of truth.
The important caveat is that “open source AI” gets used loosely. An inference tool can be open source while a model’s weights have a restrictive license; an open-weight model can expose weights without publishing its training data. If your requirement is genuinely strict, check the license for every layer: the runtime, agent, model weights, editor extension, and any tools that agent can call.
Build a boring stack first
A good local workflow has four jobs, and each job should have one obvious owner. A model runtime generates text. A coding agent turns that text into proposed file edits and shell commands. Your development environment runs tests, linters, formatters, and containers. Git records every meaningful change and gives you a cheap way back when the agent gets inventive.
For a terminal-centered setup, llama.cpp is a strong foundation: it is an open-source inference project designed to run models locally and includes server functionality. Pair it with Aider, an open-source terminal coding assistant that works against a Git repository and can use models exposed through compatible APIs. If you want a fully auditable model family rather than merely open weights, OLMo is worth evaluating because its project publishes model, training, evaluation, and inference resources. [1][2][3]
- Run local inference behind an HTTP endpoint. Keep it bound to localhost unless you deliberately need network access.
- Use a Git-aware coding agent from the repository root. Give it only the files and commands required for the task.
- Make the agent run your existing formatter, type checker, and narrow test target before it claims success.
- Review the diff, run the full relevant test suite yourself or in CI, then commit one coherent change.
Set up the repository so the agent has guardrails
An LLM is much more useful when the repository explains how to work in it. Add a short instruction file at the root—call it AGENTS.md, CONTRIBUTING.md, or whatever your agent supports. This is not a manifesto. It is a compact operating manual for code changes.
Write down the commands a new engineer would need: how to install dependencies, run one targeted test, run the full suite, format code, type-check, start local services, and seed test data. Then add the rules that are easy to violate: which directories are generated, whether database migrations need review, which APIs must remain backwards-compatible, and what must never be edited automatically.
This improves results because you are replacing vague prompt context with versioned project context. More importantly, it makes model swaps less disruptive. Your workflow stays recognizable if you move from a small laptop-friendly model to a larger machine-hosted one, because the repository—not a chat transcript—defines the contract.
Use a three-pass task loop
Don’t start by asking the agent to “implement the feature.” That creates the highest-risk behavior: broad exploration, broad edits, and a confident summary that may not match reality. Instead, split normal work into investigation, implementation, and verification.
First, ask for investigation only. Have the agent identify relevant files, trace the current behavior, name likely tests, and propose a minimal plan. Tell it not to edit files. Read that plan like you would read a teammate’s approach in a pull request; correct mistaken assumptions before they become a patch.
Second, allow implementation with a tight scope. Ask it to edit specific files or implement the first step of the agreed plan. Require a diff after each meaningful unit of work. Small requests make failures legible: you can see whether the model misunderstood the interface, chose the wrong abstraction, or simply made a mechanical error.
Third, make verification adversarial. The agent should run the narrowest relevant tests, then the formatter and type checker. Ask it what behavior is still untested and which assumptions it made. A test pass means the repository’s tests passed; it does not mean the design is right, the security boundary holds, or production data will behave the same way.
Keep tool access deliberately narrow
Local models solve a data-egress problem, not a safety problem. A coding agent with shell access can still delete files, change lockfiles, read secrets from environment variables, or make destructive database calls. Treat shell access as a capability you grant in layers.
Start with read-only investigation where possible. For edits, work in a disposable branch or worktree. Allow commands such as package installation, tests, formatting, and builds only after you understand what they do in your project. Keep production credentials out of the environment used by the agent, and point integration tests at disposable local services. Containers help here, but they are not permission prompts: review mounted directories, exposed sockets, and injected environment variables.
Choose models based on the task, not the leaderboard
A small local model can be excellent at narrow edits, test failure interpretation, documentation updates, repetitive migrations, and explaining unfamiliar code. It will usually be less dependable at architecture changes, cross-repository refactors, or long debugging sessions where it must preserve many constraints. The practical answer is not to pretend those limitations disappear. It is to design tasks that reveal a failure early.
Benchmark on your own repository. Create a handful of representative tasks: add a validation rule, fix a real regression, update a dependency safely, write a unit test for an edge case, and make a small refactor. Measure more than whether the final code compiles. Track how often the agent touches unrelated files, whether it runs the right commands, whether the diff needs substantive correction, latency, and the hardware cost you are willing to accept.
This also prevents an easy trap: optimizing for chat quality rather than engineering throughput. A model that sounds insightful but produces sprawling diffs is often worse than a less eloquent one that consistently makes a 20-line change, runs the right test, and stops.
Make CI the final authority
Your local workflow should end where every normal code change ends: a pull request and CI. Have the agent create a focused commit or leave an uncommitted diff for you to inspect. Then let CI independently run the checks that matter, including tests the local machine skipped for speed. Never merge because an agent says it fixed the issue; merge because the diff is understandable, reviewable, and verified by the same engineering system that protects human-written code.
That is the durable version of an open-source AI workflow. You retain control of the runtime, the code context, the data path, and the approval path. The model becomes a fast, fallible collaborator inside an existing development discipline—not a replacement for it.