DeepSeek Harness vs Pi Agent: The Maintenance Burdens Decide, Not the Feature Lists
If you want ready-made capabilities like a web interface, MCP, and sub-agents, start with DeepSeek Harness; if you prefer working in the terminal and want to keep a small core, adding only what you need, start with Pi Agent.
The two have different starting points. DeepSeek Harness starts from a set of replaceable parts, Pi starts from a minimal core. After choosing poorly, the first thing that gives you a headache is often maintenance: people who want to save configuration effort end up assembling extensions, and people who want minimalism end up managing runtimes. When picking a tool for AI, you may end up with a part-time job as a configuration engineer.
Model, version, and task all affect results. To find out which set suits you, first look at what they give by default and what you still need to add, then run a pilot with the same task.
Don't mix up models, harnesses, and finished agents
When talking about harnesses, asking "which model is stronger" easily mixes two things up. A harness is the tooling and runtime environment a model uses to do its work; switching workbenches won't change the model's brain.
- DeepSeek Harness (dsh) is an open-source Agent runtime by DeepSeek, MIT-licensed, currently in developer preview, with the official announcement that there will be breaking changes. It is not a DeepSeek model; you still need to configure a model, which can be DeepSeek or other compatible APIs or local models.
- Pi Agent (Pi Coding Agent) is an open-source terminal coding harness, also MIT-licensed, following a minimalist approach. It supports multiple models and providers, and can switch models within a session.
When comparing, pin down the model, task, and prompt, then look at default capabilities, extension methods, and operational burden. Otherwise, if the model changes, the praise and blame may be aimed at the wrong target.
What exactly differs between the two
| Dimension | DeepSeek Harness | Pi Agent |
|---|---|---|
| Design philosophy | Plugin-based runtime: model, tools, Skill, session, sandbox, storage, loop, scheduling, and interface are all replaceable | Minimal terminal core: give a working loop first, add capabilities as needed |
| Interface | Browser Web UI, also headless | Terminal interaction, also supports print/JSON output, RPC, SDK embedding |
| Default tools | Combines capabilities via profile/bundle/plugins, including sub-agents, planning mode, etc. | Four built-in: read file, write file, edit file, run command; other capabilities via extensions |
| Extension method | Plugins can hook into runtime events like turn start, before tool execution, and even replace the loop itself | TypeScript extensions, Skill, prompt templates, themes, packages; add capabilities around a small core |
| MCP | Built-in generic MCP client | No built-in MCP; needs extension or following docs to integrate |
| Approval & isolation | Built-in fail-closed approval service; sandbox currently mainly covers filesystem effects, not full network and process isolation | No built-in permission system or sandbox; docs recommend external means like containers for isolation |
| Session | Composable session plugins and services; logs support recovery, forking, search, and replay | JSONL tree sessions, support branching, forking, recovery, compression; convenient for repeated attempts |
| Model selection | Default DeepSeek, also supports other compatible APIs and local models | Multiple providers and models, can switch in session |
| Maturity | Developer preview, features and interfaces change fast; suitable for piloting, not as production standard | Small core, few concepts, easy to get started; peripheral capabilities still need your own selection and maintenance |
DSH has a built-in approval service, but the sandbox currently mainly manages the filesystem; the full isolation boundary still needs to be filled by deployment methods. Pi has few built-in capabilities, but after extensions it can still get work done; reviewing extension sources and container isolation are the user's responsibility. You can't judge security just by the number of built-in features.
How to try: run the same task on both sides
A disposable frontend demo project is enough; you don't need to risk real business code. Both sides start from the same code base, with the same task, prompt, acceptance criteria, and check commands; only the harness changes. Don't let the later one continue from the previous one's work.
Step 1: Prepare a disposable demo project
# Copy the demo project first, or use worktree to check out a separate branch
git worktree add ../demo-pi-dsh-test -b demo-pi-dsh-test HEAD
cd ../demo-pi-dsh-test
git status --short
Confirm the worktree is clean and this code can be discarded at any time. Also create a separate low-spending API Key; don't bring your main Key into this experiment.
Step 2: Start DSH and verify configuration
# Requires Node.js 22.19+
node -v
npx @deepseek-ai/dsh web
The default Web UI is at http://127.0.0.1:3080. In settings, fill in the model configuration, key, and select the model, then start a session. Before comparing, confirm:
- The Web UI opens and the session can talk normally;
- The model actually used is the one you configured, not confused with the default model;
- The plugin and MCP toggles have been confirmed item by item; know which are on; don't assume all are on.
Record the DSH version number. It is still in developer preview; settings locations and plugin behavior may change with versions. Without recording the version, next month when reproducing, it's easy to doubt how you ran it last time.
Step 3: Start Pi and get the basic operations working first
Install the pi command according to Pi's official installation guide, then do a small-scope check:
pi --version
# Enter session, confirm provider and model connect normally
# First make a single-file small change, see if the diff is clean
git status --short
git diff --stat
Confirm these items:
pi --versionoutputs the installed version;- Provider and model connect normally and can chat;
- The single-file small change only produces a diff of the expected scope, without touching unrelated files.
Don't add MCP, sub-agents, and extension packages until basic operations work. The more you pile on, the harder it is to find the original problematic link. After this small-change check, the formal comparison still starts from a clean code base.
Step 4: Use the same task and record results
You can use a product list filtering task to see if they can honestly hold the scope of changes. The prompt is identical on both sides:
Add a price-range filter to the product list. Use derived values for the filter result; don't modify the original array. Put filter state only in the current component; don't write it into the global store; don't change public component props; don't upgrade dependencies. When done, output a list of changed files and run the related tests.
Record these items:
- Change scope: How many files changed? Did it touch public components, global store, or unrelated files?
- Acceptance results: Is the filter logic correct? Does the order mess up when switching back to "All"? Do the related tests pass?
- Scope discipline: Did it do "incidental refactoring" or "incidental upgrades"? If you ask for a filter and get an architecture overhaul, that's a deduction.
- Long-task behavior: After interruption, can it recover, branch, roll back? How much context is lost after recovery?
- Isolation and approval: Were dangerous operations blocked or flagged? Is isolation provided by built-in capabilities or by a container you set up?
- Cost and time: How many tokens consumed, how long did it take, how many retries after failures?
If the models on the two sides differ, write that clearly in the record. In that case, the results reflect the whole combination's performance; you can't attribute all differences to the harness.
Step 5: Count maintenance time too
DSH's default capabilities may save you configuration time, but plugin upgrades and version changes also take time; Pi's core is easy to get started, but integrating MCP and adding approval and isolation may require assembly yourself.
Don't just record installation time; count the tinkering with configuration afterward as your own hobby.
If the code written on both sides is similar, look at which one your team is better at maintaining. A longer feature list doesn't relieve the team of maintenance work.
Which situations to try which first
If you want ready-made capabilities, a web interface, and a full set of default configuration, try DSH first. If you prefer the terminal, like a small core, and want to decide what to add yourself, try Pi first.
Then consider who maintains it. If you can review plugin sources and are willing to follow preview changes, DSH's plugin route is appropriate. If you don't want to chase version changes, Pi's small core might be less hassle; but the extensions you add still need someone to manage.
If long tasks are frequent, focus on testing session mechanisms: how to recover after interruption, how to branch, and whether repeated attempts are convenient. If isolation requirements are high, check how far the approval and sandbox actually cover, and which boundaries you need to fill with containers or other means. The word "security" on a feature list is not informative enough.
During the pilot phase, you can use both. They both can read Skills and connect to models; one can handle daily changes, the other can do long-task or plugin experiments. Once the scorecard has results, choose the main tool; there's no need to migrate the whole workflow based on first impressions.
When things don't go smoothly, check these first
- If DSH goes haywire after installing plugins: check whether profile/bundle has stacked too much, whether plugin sources were reviewed, and whether versions were recorded. Plugin conflicts also count as usage cost.
- If DSH's behavior changes after an upgrade: developer preview has breaking changes. Treat pilot and production differently; before upgrading, rerun the pilot task in the demo project; don't move the latest version to production directly.
- If Pi can't connect to MCP: confirm whether you're following the extension route or the documented integration method; don't look for a toggle based on the expectation of a "built-in generic MCP client".
- If Pi's long task breaks and can't reconnect: first test the session's branching, recovery, and compression mechanisms, then decide whether you need external session management or checkpoints.
- If results differ greatly between the two: first check the model, prompt, task, and test commands. If the model isn't aligned, it's not yet time for the harness to take credit or blame.
A pilot template you can copy directly
The prompt is identical on both sides:
Task: [a specific frontend task; write clearly what to change and what not to change]
Acceptance criteria: [how to know it's done right; the more specific the better]
Prohibitions: [don't change public components, don't upgrade dependencies, don't do incidental refactoring; write them clearly]
Check command: [which test or lint command to run]
Output requirements: [list of changed files + points requiring human confirmation]
Before starting, verify:
- Whether you want ready-made capabilities or self-assembly, who manages plugins, and what long-task and isolation requirements are, have all been clarified
- Both sides start from the same code base, with the same task, prompt, acceptance criteria, and test commands
- The demo project is disposable, and the API Key is a separate low-limit Key
- DSH's version, plugin status, and MCP toggles have been confirmed
- Pi's version, provider, model connection, and single-file diff have been verified
After running, fill in the record, and choose by results, not by feature list length or first impressions:
- Change scope: number of files, unrelated changes, whether public code was modified, any incidental refactoring or upgrades
- Acceptance results: whether functionality, edge cases, and related tests pass
- Long tasks: whether it can recover, branch, roll back after interruption; what context was lost after recovery
- Isolation and approval: whether dangerous operations were blocked or flagged; whether isolation is provided by built-in capabilities or a self-built environment
- Cost and time: tokens, time, number of retry attempts after failures
- Maintenance cost: how much time plugin/extension upgrades and version changes took
- Model record: model, model version, and harness version on both sides
Top 1 from juejin.cn, machine-translated. The original thread is authoritative.
Good article, thanks for sharing.