Skip to content
advanced

DeepSeek Harness Explained: What Does “Everything Is a Plugin” Mean?

“Everything is a plugin” is a claim about architecture, not a feature list. It says the agent loop itself is replaceable — and that is expensive to mean.

Published 2026-09-11Updated 2026-09-1212 min read
Minimalist dark-themed workspace with laptop and wireless keyboard.
Minimalist dark-themed workspace with laptop and wireless keyboard. Photo by Gaurav Vishwakarma on Pexels.

“Everything is a plugin” is a claim about architecture, not a feature list. It says the agent loop itself is replaceable — and that is expensive to mean.

Most agent frameworks have a load-bearing wall. The loop lives in the core; you extend around it. DeepSeek Harness, an open-source agent runtime released under MIT and currently in developer preview, makes a stronger claim: the model adapter, the tool registry, the session log, and the agent loop are all plugins, and there is no privileged core to patch. The slogan is easy to print on a README. The architecture it implies is not.

This article audits that claim. What does it actually commit the system to? Which parts are swappable? How do plugins find each other? What happens at load and unload? And where does the design bite under real use?

The Slogan Is a Claim About the Core

Two-column comparison showing a fixed-core harness with a locked agent loop and surrounding extensions, versus a plugin-oriented harness with a small kernel, replaceable agent loop, and swappable model and tool components.
The slogan becomes testable when the agent loop itself can be replaced without forking the runtime.

Read the phrase literally and it becomes falsifiable. If everything is a plugin, then no component is exempt from replacement — including the piece that decides when to call a model, when to run a tool, and when to stop. That is the agent loop, and in most frameworks it is the thing you fork when you want to change it.

The weaker reading, which most frameworks satisfy, is a fixed core with an extension surface bolted on. Tools are pluggable. Models are pluggable. The loop is not. You get a plugin folder, not a plugin architecture.

The test that separates the two readings is one question: can you replace the agent loop itself without forking the runtime?

That question matters because the loop is where the interesting behavior lives. It controls turn structure, retry policy, tool-call parsing, subagent scheduling, and termination. If the loop is fixed, every experiment that touches those decisions requires a patch against the core — and every upstream change becomes a merge conflict. If the loop is a plugin, the same experiment is a configuration change, and you can run two loops side by side against the same task and compare traces.

A swappable loop changes what you can benchmark, debug, and migrate. It also changes what you can break, which is the part the slogan tends to leave out.

Knowledge check

Check your understanding

Answer this question before you continue.

A team wants to replace turn structure, retry policy, and termination behavior without forking the runtime. Which observation would most strongly support the claim that the harness is plugin-oriented?
Scenario Interpretation

Focus: Distinguish a genuinely plugin-oriented core from a fixed harness with pluggable peripherals.

Capabilities as Plugins: What Actually Gets Swapped

“Everything” is too vague to act on. The useful version is a named list of capability categories, each with multiple shipped implementations selected in configuration rather than code.

CategoryWhat it controlsExample swap points
ModelsWhich model adapter serves requestsProvider adapters
ToolsWhat the model can callTool registry entries
SkillsReusable prompt or workflow unitsSkill packages
SessionsHow conversation state persistsJSONL, SQLite backends
SandboxesWhere code executesLocal executor, E2B sandbox
StorageWhere artifacts liveBackend selection
LoopsTurn structure and control flowAgent loop implementations
SchedulingSubagent and task orchestrationSubagent providers
UIHow the runtime is drivenBrowser UI, headless, terminal

The concrete swap points are the tell. Session persistence has more than one backend. Subprocess execution has a local executor and a sandboxed one. Shell access has variants. These are not abstractions in a diagram; they are choices you make in a config file, and the runtime picks the implementation.

Two qualifications matter here. First, the table shows current shipped implementations, not the full architectural contract. The categories are the extension points; the specific backends are examples that can change as the project iterates. Second, the slogan blurs a distinction that determines what you actually get:

  • A capability plugin adds behavior the harness did not have.
  • A configuration choice selects among behavior that already exists.

Swapping your session backend from JSONL to SQLite is a configuration choice. Writing a new backend is a capability plugin. Both are legitimate, but only one of them is extension. If you confuse the two, you will overestimate how much the harness gives you for free and underestimate how much interface design you still owe.

The practical consequence: swapping a capability is a config change, but the interfaces between capabilities become your real API surface. That surface is what you are actually betting on when you adopt the harness.

Knowledge check

Check your understanding

Answer this question before you continue.

Which change is a capability plugin rather than merely a configuration choice?
Comparison Reasoning

Focus: Differentiate selecting an existing implementation from extending the harness with a new capability.

The Kernel, Services, and Events: How Plugins Find Each Other

“No privileged core” does not mean no core. It means the core is small enough to be boring.

DeepSeek Harness is built on Cordis, a plugin framework whose kernel manages mounting, unmounting, and dependency resolution. Agent capabilities live outside that kernel. The kernel does not know what a tool is. It knows how to load a plugin, resolve what that plugin depends on, and unload it cleanly.

Plugins cooperate through two runtime coordination mechanisms rather than through direct imports:

  • A service registry, where a plugin publishes a capability that other plugins can consume.
  • An event bus, where a plugin emits or listens for lifecycle and runtime events.

This is the part the slogan hides, and it is the part that determines whether the architecture works. If plugins imported each other directly, you would get a static dependency graph — easy to read, impossible to hot-swap. By routing cooperation through services and events, the harness buys composability.

It pays for that composability with traceability. You cannot read the call graph from the source tree. When plugin A calls plugin B, the connection exists at runtime, resolved through the registry. That is a real cost, and it shows up the first time you debug a composition bug.

Dependency declaration is what keeps load order deterministic. A plugin that declares what it needs can be mounted after its dependencies. But declared dependencies order framework-managed registration; they cannot make arbitrary side effects safe. A plugin that writes to a file or a database during mount has effects the kernel cannot sequence or revoke. That is your responsibility, not the framework's.

The kernel is not the product. The kernel is the contract that lets the product be replaced.

Knowledge check

Check your understanding

Answer this question before you continue.

Which statement best describes the harness's runtime coordination model?
Misconception Check

Focus: Explain how services, events, and declared dependencies support runtime plugin composition and its limits.

Lifecycle: Mount, Register, Revoke

This is where plugin architectures quietly fail, so it deserves its own section.

Registration is scoped to the plugin. When a plugin mounts, it registers its tools, services, and event handlers. When it unmounts, those registrations are revoked automatically. The harness does not ask the plugin to clean up after itself; it removes what the plugin registered.

That automatic revocation is the difference between a hot-swappable system and a system that appears hot-swappable until you swap something twice. Leaked tool registrations and stale event handlers are the classic failure mode. A tool that was unloaded but still appears in the registry will be called, and it will fail in a way that looks like a model problem rather than a lifecycle problem.

The distinction between framework-managed and external state is the one to internalize:

State typeManaged byOn unmount
Tool registrationsHarness registryRevoked automatically
Service publicationsHarness registryRevoked automatically
Event handlersHarness event busRevoked automatically
Files written by pluginPluginMust be cleaned up explicitly
Database rowsPluginMust be cleaned up explicitly
External service statePluginMust be cleaned up explicitly

Hot-swap is also an evaluation tool, and this is the use I would reach for first. Change one capability, rerun the same task, compare traces. Because the session log records what the model saw, you can attribute a behavioral difference to the swap rather than to noise. That is a cleaner experiment than most agent evaluation setups allow.

But “identical scaffolding” is a claim you have to earn. For a fair comparison, hold constant or record: initial state, capability set, model parameters, event schema version, and termination policy. If any of those drift between runs, you are measuring the drift, not the swap.

The cost is state. Automatic revocation covers what a plugin registered through the harness. It does not cover what a plugin wrote outside that system. If your plugin persists anything, you own the cleanup, and the harness will not warn you when you forget.

Knowledge check

Check your understanding

Answer this question before you continue.

A plugin is unmounted, and its tool and event-handler registrations disappear, but rows it wrote to a database remain and affect later sessions. What is the correct diagnosis?
Debugging

Focus: Diagnose why automatic plugin unmounting does not remove external state.

The Append-Only Session Log as the Integration Backbone

Traceability in this harness is not a logging feature bolted onto the side. It is the substrate that makes plugin composition debuggable.

Everything the model sees is recorded in an append-only session log: system prompts, reasoning, tool calls and results, subagent scheduling, and every context injection. Resume, fork, replay, search, transcripts, and the web UI all read the same event stream. One source of truth instead of parallel bookkeeping.

The design commitment hiding in that sentence is worth naming. Adding a new kind of model-visible input means adding a new event type, which is a schema commitment, not a log line. You cannot inject context into a prompt and leave the trace silent, because the trace is defined as the set of things that reached the model. That constraint is what keeps the log honest.

Here is what a minimal trace looks like when the invariant holds:

[plugin.mount]     source=memory-plugin  id=mem-01
[context.inject]   source=memory-plugin  target=system-prompt  tokens=340
[model.request]    model=deepseek-v4  messages=7  tools=4
[tool.call]        tool=read_file  args={path:"src/main.ts"}
[tool.result]      status=ok  bytes=2048
[context.inject]   source=memory-plugin  target=user-turn  tokens=120
[model.request]    model=deepseek-v4  messages=9  tools=4

Each line carries a source field and an ordering position. That is what makes attribution possible: you can trace which plugin injected what, at which step, and in what order. Without the source field, you have a log. With it, you have a causal chain.

The engineering payoff shows up when a plugin misbehaves. The trace tells you which plugin contributed the input that made the output wrong. Without that, a composition bug is archaeology: you know the output was wrong, and you have no way to reconstruct which component contributed the input that made it wrong.

If a swap requires a fork, the harness is not plugin-oriented. If the trace goes dark, it is not traceable. Both failures look like bugs in your plugin.

Where the Plugin Model Bites

Elegance is not the test. Operations is the test. Here is where this architecture charges you.

Developer-preview churn. The plugin contracts are still being defined. Breaking changes to internal symbols, DOM injection, and custom session event types are the brittle edges, and they are exactly the edges plugin authors touch. If you build on this today, budget for rework, and pin your version. The architectural categories — capability seams, lifecycle, traceability — are more durable than any specific backend or API shape.

Stateful plugins are a different trust tier. A plugin that fetches a web page or runs a calculation is stateless; the worst case is a bad output you ignore. A plugin that writes persistent memory, persona data, or shared knowledge operates on the harness itself, not just within a session. Its effects persist into future sessions and shape future agent behavior. That is a higher level of trust, and it deserves a different review standard: not just “does this produce a useful output” but “does this leave the agent’s persistent state better than it found it.”

Composition debugging. A bug may live in the interaction between two plugins, not in either one. Neither plugin’s tests will catch it. The event bus that bought you composability is now the place where the failure hides.

Startup cost and graph size. A large plugin graph has a load cost, and it has a cognitive cost: there is no single obvious place to read the system’s behavior. You trade a readable monolith for a composable graph, and the graph is only readable through its trace.

When a Plugin Harness Is the Wrong Choice

The pattern is not universally correct. Here is the decision boundary I would apply.

Choose a plugin harness when you need to swap the loop, benchmark models under identical scaffolding, or run multiple agent backends behind one trace. Those are the cases where the architecture earns its complexity, because the thing you need to vary is the thing most frameworks fix.

Choose a fixed harness when your extension needs are shallow, your team is small, and operational simplicity beats composability. If you will never replace the loop, you are paying the indirection tax for a benefit you do not use.

The lock-in axis is ownership of memory and context. The harness is what manages context, and memory is a form of context — short-term memory lives in the conversation, long-term memory crosses sessions. Whoever owns the harness owns the memory layer, and that determines how portable your agent actually is. A plugin architecture that you control keeps that ownership with you. A managed API that hides the harness takes it.

A one-pass decision rule: list the components you would need to replace in the next six months. If the agent loop is on that list, you need a plugin harness. If it is not, you probably do not.

The Audit

Pick one capability in your current agent stack. Replace it without touching the rest of the code. Then check whether the session trace still explains what happened.

If the swap required a fork, the harness is not plugin-oriented in the way the slogan promises. If the trace went dark, it is not traceable. Either gap is worth fixing before you add another capability, because every capability you add on top of a fixed core makes the eventual replacement more expensive.

The slogan is a promise about the core. The audit is how you find out whether the core kept it.

Knowledge check

Final check

Finish the article by checking the ideas you just learned.

A memory plugin injects text into the system prompt, but no corresponding event is appended to the session log. What capability does this omission directly undermine?
Question 1 of 2Scenario Interpretation

Focus: Apply the session-log invariant that every model-visible input must be represented as a sourced event.

A small team has shallow extension needs and expects never to replace the agent loop. Which choice best follows the article's decision boundary?
Question 2 of 2Comparison Reasoning

Focus: Use the article's decision boundary to choose between a plugin harness and a fixed harness.

Related sites

Build the foundations behind advanced AI systems

Use LearnLLMFast for practical LLM application foundations and LearnPyFast for the Python mechanisms that support implementation work.

LLM tutorialstutorial

LearnLLMFast

Practical LLM tutorials for builders who want to understand prompting, workflows, agents, and AI applications.

LLMAIBuilders
Visit LearnLLMFast
Python tutorialstutorial

LearnPyFast

Beginner-friendly Python tutorials, examples, and learning paths for practical programming foundations.

PythonProgrammingBeginners
Visit LearnPyFast

Keep exploring

Related AI engineering tutorials

Continue with adjacent system layers, implementation patterns, and current AI engineering ideas.