A Tale of Two Agent Harnesses
Pi and DeepSeek Harness, two philosophies for controlling complexity, preserving engineering judgment, and building agent-native software.
For the past two years, most discussions about coding agents have focused on the model.
Which model scores higher on coding benchmarks? Which one reasons better? Which has the longer context window or more reliable tool calling?
The more I use these systems, though, the more I think the model is only half the story.
What determines how an agent actually behaves is the harness around it.
DeepSeek puts it nicely on the DeepSeek Harness page:
The model is the soul of an agent.
A harness lets an agent understand its environment, use tools, and keep working in real-world settings.
DeepSeek Harness, or DSH, makes its own architectural principle equally explicit:
Everything is a plugin.
I have been spending quite a bit of time with Pi recently, so the release of DSH gave me an interesting comparison point.
Both are open-source agent harnesses. Both care deeply about extensibility.
But once you move beyond the README and start looking through the codebase, commit history, AGENTS.md, and skills, they reveal two rather different engineering philosophies.
I personally prefer Pi’s minimalist approach. But there are interesting things in DSH that I would very much like to borrow.
Pi: Keep Complexity Out
Pi’s creator, Mario Zechner, describes it as an opinionated and minimal coding agent.
At its conceptual core, the agent operates with a very small set of primitives: read files, write or edit them, and execute shell commands. More capabilities can be layered on through extensions, skills, prompt templates, and packages.
Pi’s contribution philosophy is deliberately conservative. If a feature does not need to belong in the core, it should probably be an extension instead.
I like this attitude because the most dangerous form of software complexity rarely comes from obviously bad code.
It comes from reasonable features added one by one. Each addition is justified, but eventually the system becomes too complex for anyone to hold in their head.
Pi takes an older approach to this problem:
Do not manage complexity you could have avoided owning in the first place.
That is also what makes Pi’s extensibility interesting.
Extensible does not have to mean feature-rich.
A system can provide powerful extension points while remaining extremely conservative about what it includes by default.
DSH: Give Complexity Structure
DSH takes a different route.
Instead of aggressively minimizing capabilities, it makes capability itself a first-class architectural unit.
Models, tools, skills, sessions, storage, agent loops, and even parts of the UI can be composed through its plugin architecture.
Open the packages/ directory and that philosophy becomes obvious.

There are separate packages around filesystem access, shells, LSP, skills, web interaction, context compaction, etc.
At that point, this starts to look less like a coding agent and more like an agent runtime platform.
Interestingly, DSH does understand minimalism. It offers a minimal mode with a much smaller tool surface.
But there is a subtle difference:
Pi treats minimalism as the architectural starting point.
DSH treats minimalism as one configuration the architecture can produce.
What Keeps Complexity in Check?
When looking at the Pi and DSH repositories, I am most interested in asking how each project prevents complexity from getting out of control.
Pi’s answer is largely structural restraint: its contribution rules repeatedly push toward a smaller surface area and fewer concepts for maintainers to carry in their heads.
One principle I especially like is effectively you must understand your code. Using AI to write code is not the issue; what matters is whether the person submitting a change can explain what it does and how it interacts with the rest of the system. The more useful question here is Do you understand what you are adding?
DSH takes a more institutional approach. It relies on explicit architecture rules, service boundaries, strict typing, coverage gates, documentation requirements, change-scope analysis, and repository-level skills.
New behavior is expected to enter through defined extension points, and even a change to the agent loop carries architectural obligations. Where Pi tries to create fewer things that require governance, DSH assumes that some complexity is unavoidable and turns it into explicit, verifiable contracts.
I still lean toward Pi’s instinct because every guardrail is itself another piece of complexity. Even so, DSH is clearly serious about making large-scale agent engineering manageable, and I am interested in seeing how that approach evolves.
Git Tells the Truer Story
This is where the comparison becomes especially visible. Architecture documents tell you what a project wants to be; commit history often tells you how the project actually works.
At the time of writing, Pi has 5,683 commits, while DSH has 12,293—more than twice as many. The totals alone do not say much about quality, but the shape of those histories does.
Pi’s recent main-branch history is easy to scan. Its commits tend to have narrowly scoped intent:

Most entries answer a simple question immediately: what changed here? The history reads like a sequence of engineering decisions rather than a transcript of the development process.
DSH’s history looks different. Merge commits, branch syncs, CI fixes, and release work are much more visible:

At first glance, that can make its main branch look messier than Pi’s. But the branch graphs reveal that this is not simply untidy commit hygiene. The real organizational unit in DSH is not the individual commit; it is the PR graph.
Pi’s graph has a dominant mainline. Short-lived feature branches collect a small group of related commits and then merge back:

DSH’s graph is a much denser weave of parallel agent and worktree branches, with frequent synchronization merges from master:

The difference is more than visual. Pi’s history emphasizes a readable sequence of completed engineering decisions. DSH’s graph also records the coordination required to keep many concurrent streams of agent work aligned.
That density is partly a consequence of DSH’s explicit use of stacked pull requests. Imagine a dependency chain like:
A ← B ← C
If review finds a problem in B, the expected behavior is to fix it where the problem was introduced and propagate the correction upward through the stack, rather than patching C and moving on.
They have dedicated workflows around stacked PR review, rebasing, protected history rewriting, and post-sync validation.
That is solving a very agent-native problem: when many agents are working in parallel, how do you preserve reasoning boundaries?
Traditional development often looks like:
developer → branch → PR
DSH increasingly looks like:
task → agent/worktree → PR layer → stack → review → merge
At that point, Git is no longer just version control. It becomes part of the harness.
Results vs. Engineering Memory
This leads to another contrast I find useful. Pi’s philosophy feels close to the idea that Git can preserve the history while the current state remains simple. Past reasoning does not need to live forever in the active codebase; whether each abstraction, comment, or mechanism still earns its place. That attitude fits Pi’s minimalism.
DSH begins from a different concern. If more and more code is written by agents, where should the engineering judgment behind that code live?
One of its answers is: skills.
For example, its pre-push workflow does not simply tell the agent to run every possible test.
It tells the agent to reason about the scope of the change first, then gather the smallest body of evidence sufficient to establish confidence in that change. Full platform coverage can remain the job of CI.
There is also a simplification skill whose purpose is specifically to look for dead, duplicated, speculative, overbuilt, or unnecessarily hand-rolled code.
This one is my favorite because it mirrors what I find myself doing again and again when reviewing agent-generated code.
The same philosophy appears in documentation. The repository has guidance for stripping away reasoning transcripts, duplicated explanation, and historical debris while retaining the parts that are genuinely load-bearing.
This changed the way I think about skills. I used to see a skill primarily as a way to teach an agent to do one more thing, but DSH suggests a broader role: encoding senior engineering judgment into executable organizational memory.
That judgment includes how code review should be performed, which tests are appropriate for a particular change, when an abstraction should be deleted, and how a stacked PR should be repaired. It also includes deciding which architectural choices need to remain visible and which reasoning can disappear once a decision has been made.
These are usually forms of tacit knowledge carried around in the heads of experienced engineers. DSH begins placing that knowledge inside the repository, where agents can access and apply it consistently. That may be the part of the project I find most worth borrowing.
DSH Borrows From Pi
If you look only at their architectures, it is easy to frame Pi and DSH as competing projects, but their actual relationship is more interesting. DSH includes a package called @deepseek-ai/dsh-llm-pi-ai, which uses Pi’s pi-ai abstraction to connect DSH to non-DeepSeek models.
This is more fundamental than borrowing a model-selection interface. Pi’s multi-provider LLM adapter and model catalog already handle one of the most tedious problems every agent harness eventually encounters: provider APIs and model metadata differ, reasoning and streaming capabilities vary, and compatibility quirks accumulate over time. Rather than rebuilding that layer simply to own it, DSH reused an abstraction that already worked.
Tianyi Cui from the DSH team later made that relationship explicit:

Good engineering is not about writing everything yourself; it is about knowing which abstractions are important enough to own and which problems have already been solved well enough to reuse.
Rivals or Collaborators?
Open-source projects are often described through a predictable competitive framing: who replaces whom, or who outperforms whom. The interaction around Pi and DSH has been more interesting. Armin Ronacher publicly described DSH as one of the first projects in this space in a long time that had genuinely inspired him to revisit some of Pi’s own design choices, while still making clear that he did not consider it perfect.
Tianyi’s response explained that the influence already ran in both directions: Pi was a daily tool for DeepSeek researchers and developers, and its LLM adapter had become part of DSH. Mario Zechner answered the exchange with a single handshake emoji:

I like that small detail because it changes the story from Pi versus DSH into two different engineering traditions watching and learning from each other. Pi demonstrates that a small harness can become infrastructure for other systems when its abstractions are clean enough, while DSH shows how far plugin architecture, structured engineering memory, and agent-native Git workflows can go once agent development begins operating at a larger scale.
That is what a healthy open-source ecosystem should look like: not every project converging on the same architecture, but each one borrowing the best ideas from the others.
The Harness I’d Build
If I were building a harness of my own, I would anchor it in Occam’s razor and follow a philosophy closer to Pi’s. I would start with a small core, resist abstractions that had not yet earned their place, and keep optional capabilities outside the default system whenever possible. The goal would not be minimalism for its own sake, but a codebase whose behavior I could still understand as it evolves.
At the same time, I would be interested in integrating parts of DSH’s agentic approach. Skills that encode code-review practices, test selection, and simplification could preserve useful engineering judgment, while structured memory and Git-aware workflows could help multiple agents work together without losing the reasoning behind their changes.
The challenge would be adding those capabilities without undermining the simplicity of the core. Every mechanism for coordinating agents introduces machinery of its own, so the experiment would require constant judgment about which parts genuinely improve the system and which merely make it more elaborate. That tension would make the work difficult, but it is also what would make it interesting to try.
The lesson for me from both projects is simple: keep the code like Pi and the engineering memory like DSH. Occam’s razor can decide what deserves to enter the system, while DSH’s structured practices can preserve the judgment behind what remains.