Starting with a Question
You built an Agent in Python. A few tools, a loop, runs fine locally. Now you want to ship it.
- How do you persist conversation history so a process restart doesn't lose context?
- How do you make sure User A's Agent can't touch User B's tools?
- The Agent executes shell commands — how do you stop it from deleting files it shouldn't?
- How many times was each tool called? How many tokens did each call cost?
- You want to swap model providers — how many places do you have to touch?
If you're using LangChain, LangGraph, or AutoGen, these questions either have no official answer, or the answer is "assemble it yourself."
DeepSeek Harness (dsh) was built for exactly these problems. It's not a library that wraps LLM calls — it's a production-grade Agent runtime that ships the infrastructure every deployed Agent needs, built in.
What dsh Is
The official one-liner:
DeepSeek Harness (
dsh) is an open-source agent harness developed by DeepSeek AI, built on an everything-is-a-plugin architecture.
Breaking it down:
Agent Harness: "Harness" is an engineering term for a structure that holds components together so they work safely and in coordination. An Agent Harness is the runtime that keeps an Agent's components — model calls, tool execution, memory management, permission controls — running in an orderly, safe way.
Everything-is-a-plugin: The core design philosophy of dsh. Model adapters are plugins. Tool registration is a plugin. The Agent loop itself is a plugin. Even logging and permission enforcement are plugins. There is no unpatchable "core" — you can swap any part and the system keeps running.
Open-source: MIT license, full source on GitHub.
What It Does
Feature Overview
| Feature | Description |
|---|---|
| Tool calling | Register tools, auto-generate schemas, approval gates, execution sandbox |
| Multi-agent | Subagent invocation, Agent Teams (experimental) |
| Session persistence | Append-only conversation log, fully restorable after restart |
| Sandbox isolation | File writes and shell execution confined to safe boundaries |
| Observability | Token metering, session telemetry, OTel integration |
| Dynamic prompts | Plugins contribute prompt sections; assembled into one coherent system prompt |
| Hot reload | Update plugin config without restarting the process |
| Multiple run modes | Web UI, headless CLI, SDK, ACP service |
One Command to Start
# No need to clone anything
npx @deepseek-ai/dsh web
This single command starts a full Agent service with Web UI at http://127.0.0.1:3080. It ships with: a model connection, the full built-in tool set (file editing, shell commands, web search), Session persistence, and a default permission policy — all ready out of the box.
Architecture Overview
The dsh architecture has three layers:
┌─────────────────────────────────────────────────────────┐
│ Application Layer │
│ Web UI │ headless │ SDK │ ACP API │
├─────────────────────────────────────────────────────────┤
│ Core Subsystems Layer │
│ Agent Loop │ Tools │ Session │ System Prompt │
│ LLM Adapter │ Sandbox │ Subagent │ Observability │
├─────────────────────────────────────────────────────────┤
│ Cordis Plugin Framework │
│ Plugin │ Context │ Service │ Event │ Effect │
└─────────────────────────────────────────────────────────┘
Bottom: Cordis Plugin Framework
The foundation everything else rests on. Every feature above is mounted as a Cordis plugin. Cordis provides: plugin registration/unregistration, service dependency injection, typed events, and reversible registration effects.
Once you understand Cordis, you understand dsh. That's what Series Part 2 covers.
Middle: Core Subsystems
This is where dsh actually does work:
-
Agent Loop (
ctx.agentLoop): The main loop. Accepts user input, drives tool calls, manages the conversation flow. -
Tools (
ctx.tools): The tool registry. Manages tool registration, schema generation, and the execution pipeline. -
Session (
ctx.sessions): Conversation persistence. Append-only log storage. -
System Prompt (
ctx.systemPrompt): Dynamic prompt assembly. Plugins contribute their own sections; this merges them. -
LLM (
ctx.llm): Model adapter registry. Supports multiple model providers. -
Sandbox (
ctx.sandbox): Sandboxed execution. Protects the host system.
Top: Applications
The same core composes into different run shapes:
-
dsh web: Interactive Agent with Web UI -
dsh --profile headless: CLI one-shot task runner -
dsh --profile sdk: SDK mode for external callers -
dsh --profile acp: Automation Control Protocol server
Profiles and Bundles: Configuration as Product
How a dsh instance runs is determined by configuration, not code.
Bundle: A set of plugin configurations that says "mount these plugins." The dsh-base bundle contains the model adapter, the full tool set, persistence, sandbox, and safety defaults.
Profile: An ordered stack of bundles plus your own override patches. The web profile stacks web-UI plugins on top of dsh-base; the headless profile stacks the one-shot CLI runner.
// A minimal custom profile
{
"name": "my-profile",
"dsh": {
"profile": {
"bundles": ["@deepseek-ai/dsh-base"]
}
}
}
Want to see every plugin in the current profile?
dsh --profile web --dump-config
This prints the complete plugin tree. Every row is overridable by your own config.
How dsh Differs from Other Frameworks
Many frameworks claim to do Agent work. Where does dsh actually sit?
dsh vs LangGraph
| LangGraph | DeepSeek Harness | |
|---|---|---|
| Core abstraction | Stateful graph | Plugin tree |
| Execution control | Graph nodes + conditional edges | Agent Loop events |
| Extension model | Custom nodes, Runnables | Register plugins to ctx
|
| Persistence | Bring your own Checkpointer | Built-in Session append-only log |
| Production-ready | Substantial custom work needed | Ships with sandbox/permissions/telemetry |
| Best for | Complex flow orchestration, precise graph control | Deploying a production Agent directly |
LangGraph is "design the graph first, then run it." dsh is "just run — add plugins for whatever you need."
dsh vs AutoGen
| AutoGen | DeepSeek Harness | |
|---|---|---|
| Core abstraction | Conversational multi-agent | Plugin-based Agent runtime |
| Multi-agent | Core feature, conversation-centric | Extension capability (Subagent) |
| Tool support | Present, but needs configuration | Built-in full tool set + sandbox |
| Persistence | Minimal | Built-in Session log |
| Best for | Multi-agent coordination research | Engineering single- or multi-agent deployments |
dsh vs Dify / n8n
| Dify/n8n | DeepSeek Harness | |
|---|---|---|
| Type | Workflow-driven Agent (low-code) | AI Native Agent (code-driven) |
| How you use it | Visual drag-and-drop | Code + config files |
| Flexibility | Preset flows, limited runtime dynamism | Fully programmable |
| Best for | Non-engineers, rapid prototypes | Engineers who need precise control |
In One Sentence
- LangGraph: I need precise control over execution flow; I want to describe it as a graph.
- AutoGen: I want multiple Agents to talk to each other.
- Dify/n8n: I don't want to write code; give me a drag-and-drop workflow builder.
- dsh: I need to deploy an Agent to production, with persistence, sandboxing, permissions, and monitoring all working out of the box.
When to Use dsh
dsh fits when:
- You're deploying a real Agent — not a demo
- Your Agent executes actual shell commands or file operations and needs sandbox protection
- You need Session persistence so users can resume conversations across restarts
- You need fine-grained permission control (which tools require user confirmation)
- You want monitoring — token usage, latency, error rates — built in
- You want a plugin architecture that lets you extend without forking the framework
dsh may not fit when:
- You're quickly prototyping an Agent idea (LangGraph + LangChain is lighter)
- You need complex graph-based workflow orchestration (LangGraph is better suited)
- Your team has no TypeScript experience (dsh's core is TypeScript)
- You need a framework with stable commercial support — dsh is still in active developer preview and changes rapidly
First Agent in Five Minutes
You need Node.js 18+ installed.
# Launch the Web UI
npx @deepseek-ai/dsh web
The browser opens to http://127.0.0.1:3080. Fill in your API key (DeepSeek, OpenAI, and others are supported) in settings, and you can start talking to the Agent.
Out of the box you get:
- File read/write (confined to the working directory)
- Shell command execution (sandboxed)
- Web search and HTTP fetch
- Task tracking
Prefer the CLI?
# One-shot task, no Web UI
npx @deepseek-ai/dsh --profile headless "List all Python files in the current directory"
Series Roadmap
This is the first article. The rest of the series goes one module at a time:
| Part | Topic | What You'll Learn |
|---|---|---|
| 01 (this one) | What is dsh | Global picture, positioning, how it differs |
| 02 | Cordis plugin system | The foundation for understanding everything |
| 03 | Tool system | How to add tools, how to control permissions |
| 04 | Agent Loop | How a conversation turn actually runs |
| 05 | Sessions & memory | How history is stored and resumed |
| 06 | System prompt assembly | Engineering dynamic prompts |
| 07 | Capability seams | Swap the entire execution environment with one config change |
| 08 | Multi-agent | Subagents and Agent Teams |
| 09 | Observability | Knowing what your Agent is doing |
| 10 | Build a complete plugin | From requirement to production |
You can jump straight to whichever module interests you. If this is your first time with dsh, Part 02 — Cordis — is the one prerequisite worth reading in order. It's the key that unlocks everything that follows.
Check out PrimeSkills — a curated marketplace of AI agents and skills validated in real-world, enterprise-grade workflows. Not demos — things that actually work in production.
Find more on my Homepage
Top comments (0)