Pi Agent's Ruthless Subtraction: Why Cutting Features Is the Real Design Work
From a "bare shell" to a "lightweight Harness" — what Pi Agent cut away speaks more about its design philosophy than what it kept. This article dissects six key decisions and offers five practical suggestions for building your own Harness.
Recently, while studying Pi's design, I organized some thoughts and decided to share them.
The Conclusion First
In one sentence: A lightweight Harness — cede the context to the model, push complexity to the boundary (push it to your todo.md, to the extension store, to that extra terminal you keep open).
This piece won't list features; it dissects one thing: why Pi dared to cut features so ruthlessly. Cut to the point where you realize its "doesn't have" list explains its design philosophy better than its "has" list.
I Initially Thought It Was a Bare Shell
The first time I opened Pi's default configuration, my reaction was four words: this is way too bare. No todo, no plan, no permission control, no MCP, not even background commands — I've seen minimalism, but never this brutal.
The reason, according to author Mario Zechner's blog: top-tier models, after extensive RL training, perform well even with a lean context. A Zhihu post "Pi Agent Bare Shell Renovation Pitfalls" puts it more plainly: many harness features are just carving flowers in the context; every rule added steals a share of the model's attention. Add to that Databricks' benchmark showing Pi leading Codex and Claude Code in pass rate/cost ratio with the same model, and the reasoning seems solid.
— But don't take this at face value yet. All three data points are second-hand; I haven't verified the original texts word for word. Treat them as directional indicators.
After using it for a while, it clicked: Pi isn't "lacking features," it's deliberately not doing them. A bare shell hasn't been renovated yet; Pi weighed the options and decided not to renovate. The result of that weighing: the scarce resource isn't features, it's context; don't pile complexity into the prompt, push it outside the system. This aligns perfectly with the logic in "memory management frameworks": what an Agent remembers and forgets is fundamentally a negotiation with a scarce resource.
The Most Elegant Cut: Constraints Written into the API
Pi has no rule text like "do not delete files" — its approach is simpler: go full YOLO, bash can run any command.
But there's a design direction worth savoring here: sinking "what not to do" from the rule layer down to the capability layer. Having a non-existent tool block it is more effective than writing ten "do not delete" rules. Pi itself didn't take this path — it chose full YOLO, no negative constraints. But its "lightweight" philosophy inspired this direction: if a constraint can be written into the API, don't write it into the prompt. I initially thought the author was lazy; later I realized it was clever.
The same knife is used a second time: low-frequency capabilities don't enter the context. Pi's extension tools (like CLI tools) are loaded on demand, their tool definitions not registered in the default context — only mounted when used, not consuming long-term budget. This is the ultimate application of the "attention tax."
The One I Most Want to Refute: No Sub-Agents
First, let's clarify three levels to avoid misreading: Pi's core has no sub-agents by default; the community has a subagent extension; the author doesn't completely reject them (the future Lane is seriously working on it). What it opposes isn't multi-agent, but uncontrollable multi-agent.
I've heard many arguments for the affirmative, but Pi's author's own take is the most interesting — "sub-agents are black boxes within black boxes": the parent Agent cannot see the sub-Agent's thought process, only the final output, "poor controllability, because it barely looks," hence the need to "let Pi generate itself, not spawn clones."
Official guides from OpenAI and Anthropic stand on similar ground: OpenAI says "start with one Agent, only split into multi-agent when complexity or reliability issues arise" — specific signals include choosing the wrong tool, too many prompt branches, or tool overlap causing confusion; Anthropic warns that multi-agent brings "higher costs, and the potential for compounding errors," along with "extra layers of abstraction" from frameworks. Three flawed sub-agents mean the final synthesizer stacks three sets of errors together.
But I must leave room for the opposing view: there is one scenario it cannot solve — a single task context exceeding a single model window. Cross-repo refactoring, full-repo audits — having "the same Pi continue" inevitably exceeds the window limit. Here, sub-agents/parallel isolation is the only solution. So my conclusion isn't "sub-agents are useless," but: low frequency ≠ non-existent. You need to prepare a pathway for low-frequency cases, but don't let that pathway become a default, resident mechanism. This aligns with Pi's own approach: the pathway is built as an extension, as a v2 design, not baked in by default.
I Half-Agree with YOLO, But Error Prevention Must Be Done Right
"Default YOLO, all access granted." The author's original words: "pi runs in full YOLO mode, unrestricted access to your filesystem, no permission prompts". His meaning is straightforward: models can always find ways around permissions, so don't flinch; if you flinch, don't play. I half-agree with this statement — two points need clarifying on security:
- Permission systems don't guard against "malice" . A model that can bypass permissions won't be stopped by prompt constraints — the author is right here;
- Permissions truly guard against "mistakes" : a model hallucination deleting a production directory, without permissions, means an uncontrollable blast radius. So YOLO only holds under "trusted environment + reversible operations" (personal machine + git safety net), it does not hold in team scenarios.
This is the sentence I disagree with most in the entire article: the permission problem has two dimensions. The author only guarded against "malice" and cut the line on the "radius of error." Fine for personal use; when migrating to a team, remember to take permissions back.
Those "Doesn't Haves" — Why It's Not a Problem (Quick Answer List)
| Doesn't Have | Why | My Stance |
|---|---|---|
| todo / plan mode | Forms a "human-machine co-readable md file" , not a framework-internal state machine | Convinced |
| MCP | Tool schemas fully loaded into prompt, tax is too heavy | Partially Agree |
| Background Commands | Invisible means uncontrollable; multiple open terminals don't interfere with each other | Partially Agree |
| All Built-in Mechanisms | Complexity is a liability; being resident means being uncontrollable | Convinced |
The "Pie in the Sky" I Most Want to Critique: Lane
Let me pour cold water first: Harness v2 is currently just a design document in the repo (harness-v2.md), not delivered. (Unverified original text, paraphrased from community discussion) But the design looks like this:
sequenceDiagram
participant Parent as Parent Agent
participant Fork as Fork History Tree
participant Child as Child Agent
participant Log as Operation Log
Parent->>Fork: Copy history tree
Parent->>Child: Spawn subtask
Child->>Log: Record deterministic ID + operation
Child->>Parent: Return result
Parent->>Fork: Reference child Agent history
Note over Child,Log: Can replay back to same session after crash
Note over Parent,Fork: Parallel write conflict semantics undefined
Fork copies the history tree; the parent Agent can reference the child Agent's history (fixing the "invisible" problem); deterministic ID + operation log ensures crash recovery can replay back to the same child session.
Sounds good. I have three questions:
- Deterministic ID only guarantees "reconnecting to the same session," not "identical rerun results" : a child Agent's tool calls are all side effects (running commands, writing files). The transcript can replay, the side effects cannot. The design doc is vague on this.
- Parent both shares and writes: the conflict semantics for parallel writes to the same tree are currently undefined.
- "Statelessness" disappears: recovery requires persistence, requires transactionality. Pi, which claims to be stateless, is actually patching this itself — "lightweight" isn't a religion; when conditions change, it yields.
When Not to Use (or Copy) It
- Not using a top-tier model — "lightweight" is the effect of the model, not the cause;
- Want something out-of-the-box — by default, it doesn't even have internet access;
- Team scenarios requiring compliance — YOLO + statelessness inherently conflict with permission auditing.
If You Want to Copy the Homework (Building Your Own Harness)
- Before every feature enters the system prompt, ask: Is this attention tax worth it? If it can be written into the API, don't write it into the prompt;
- Low-frequency capabilities are not installed by default; mount them only when needed;
- Put state in .md files, don't invent your own private state machine;
- For multi-agent, start with tracing and replay, not "concurrency";
- Don't copy YOLO. It's fine for personal machines, give it a git safety net. In a team, replace it with a "permission funnel."
Closing
The biggest gain from studying Pi isn't "how to use it," but what its "doesn't have" list reminded me: the real trade-off isn't in "what you did," but in "what you resisted doing." Subtraction is harder than addition, and far more valuable.
Top 2 of 4 from juejin.cn, machine-translated. The original thread is authoritative.
666
[Rose][Rose][Rose]
The cover image is well chosen; clicks are guaranteed.
[Grin]