DEV Community

Cover image for # DeepSeek Harness Deep Dive (2): Everything Is a Plugin — But What Exactly Is a Plugin?
DA SEIN
DA SEIN

Posted on Originally published at daseinsblog.hashnode.dev

# DeepSeek Harness Deep Dive (2): Everything Is a Plugin — But What Exactly Is a Plugin?

As discussed earlier, a mature Harness needs to handle at least tool execution, Context management, Session persistence, and execution control. But once Agents begin taking on more complex tasks, that is no longer enough. Models need access to more tools, file systems and browsers, sandboxed code execution, long-term memory, and sometimes collaboration with other Agents. As a result, more and more capabilities begin to accumulate inside the Harness:

                 Agent Runtime

                      |

 ------------------------------------------------

 |          |          |          |             |

Model     Tools     Memory    Session     Sandbox
Enter fullscreen mode Exit fullscreen mode

Adding capabilities is not the problem by itself. The real problem is that all of them eventually end up inside the Runtime.

The most straightforward approach is simply to add whatever is missing. Need Memory? Add a Memory module to the Harness. Need a Sandbox? Add another Sandbox layer. Need Subagents? Extend the Agent Loop with multi-Agent scheduling. This works reasonably well while the system is small, but as it grows, the modules begin to entangle with one another.

The Agent Loop needs to know when Memory should run. The Tool system needs to know how the Sandbox works. The permission layer has to intervene before a Tool is actually executed. The Session system, meanwhile, needs to record state changes produced by all of these components. Eventually, adding one new capability no longer means adding one isolated module—it means changing relationships across the existing Runtime.

The Harness can easily end up looking like this:

              Harness Runtime

 ------------------------------------------------

 LLM code
 Tool code
 Memory code
 Session code
 Sandbox code
 Permission code
 Agent Loop code
 Subagent code
 ...
Enter fullscreen mode Exit fullscreen mode

The Harness was originally introduced to manage the complexity of an Agent, but it can quickly become the new center of complexity itself.

DeepSeek Harness takes a very direct approach to this problem:

Everything is a Plugin \boxed{\text{Everything is a Plugin}}

The idea is to avoid hard-coding specific capabilities directly into the Runtime whenever possible. Instead, the Runtime becomes a platform responsible for loading, composing, and managing capabilities.

The architecture therefore shifts from “a Harness containing a collection of modules” toward something closer to this:

              Harness Runtime

                    |

              Plugin System

 ------------------------------------------------

 |          |          |          |             |

 Model    Tool     Memory    Session      Agent Loop

Plugin   Plugin    Plugin    Plugin       Plugin
Enter fullscreen mode Exit fullscreen mode

The important point here is that a Plugin in DeepSeek Harness is not just a Tool. Model adapters, Session infrastructure, Agent Loops, and other runtime capabilities can all be brought under the same plugin model. In other words, an Agent is no longer defined primarily by a hard-coded Agent class. It is increasingly defined by the set of capabilities currently loaded into the Runtime.

That is a significant shift.

Traditionally, a Coding Agent might be implemented as something like:

Coding Agent
├── LLM
├── Shell
├── File System
├── Git
└── Memory
Enter fullscreen mode Exit fullscreen mode

Those capabilities are usually tightly associated with the Agent itself.

Under a plugin-based design, the same Agent is better understood as:

Agent Runtime
     +
Model Plugin
     +
Shell Plugin
     +
File Plugin
     +
Session Plugin
     +
Memory Plugin
Enter fullscreen mode Exit fullscreen mode

Change the combination, and you can construct a different Agent. The Runtime does not need separate implementations for a Research Agent, Coding Agent, or Data Agent. Instead, it needs a stable mechanism for composing capabilities.

But this immediately creates a second problem: Plugins inside an Agent system are more complicated than ordinary software plugins.

In conventional software, a plugin is often little more than an extra callable feature. A translation extension in a browser, for example, might simply expose:

translate(text)
Enter fullscreen mode Exit fullscreen mode

You provide text, receive a translation, and the plugin has done its job.

Many capabilities inside an Agent system do not work like that.

Take Memory. If a Memory Plugin were nothing more than:

memory.search()
Enter fullscreen mode Exit fullscreen mode

then it would effectively be just another Tool.

A real Memory system may need to load previous experience when a task begins, retrieve relevant information before model inference, record important outcomes after a Tool executes, and extract durable knowledge when the task finishes.

In other words, it participates in several stages of the Agent lifecycle:

Task begins
   ↓
Load history

Before model inference
   ↓
Inject relevant information

After tool execution
   ↓
Record results

Task ends
   ↓
Persist useful experience
Enter fullscreen mode Exit fullscreen mode

So in DeepSeek Harness, it is more useful to think of a Plugin not as:

Plugin=Function \text{Plugin}=\text{Function}

but as:

PluginCapability+Lifecycle+State \text{Plugin} \text{Capability} + \text{Lifecycle} + \text{State}

A Plugin does not merely describe what it can do. It also needs to participate in questions such as when it should act, within which runtime environment it should act, and what state should remain after it acts.

This also explains why Tools, although extremely important, are only one kind of Plugin.

Formally, we can write:

ToolPlugin \text{Tool} \subset \text{Plugin}

A Shell Tool itself may be as simple as:

shell("pytest")
Enter fullscreen mode Exit fullscreen mode

Its job is to execute a command.

But before that command actually runs, the Harness may need to answer several questions. Does the current Agent have permission to execute it? Does the operation require user approval? Are the arguments valid? Should the command run on the host system or inside a Sandbox? What happens if it times out?

After execution, another set of questions appears. Is the output too long? Should it be truncated? Where should the full log be stored? Which parts of the result should enter the next Context?

The real execution path therefore looks more like this:

Model produces Tool Call

        ↓

Check capability and permissions

        ↓

Validate arguments

        ↓

Enter execution environment

        ↓

Execute Tool

        ↓

Process result

        ↓

Record state and update Context

        ↓

Continue to the next inference step
Enter fullscreen mode Exit fullscreen mode

At this point, ordinary “modularity” is still not enough.

The components inside an Agent Runtime have two additional relationships that are especially important.

The first is:

Who does this capability belong to?

The second is:

When should this capability intervene?

Suppose a Main Agent creates both a Research Agent and a Coding Agent:

                 Main Agent

              /              \

      Research Agent      Coding Agent
Enter fullscreen mode Exit fullscreen mode

The Coding Agent may need Shell, Git, and file-system access, while the Research Agent may need Browser, Paper Search, and Citation capabilities.

If every Plugin is global, both Agents would see every capability. That would be confusing and potentially dangerous. An Agent whose job is only to inspect code has no reason to possess database-write, deployment, or file-deletion privileges.

Capabilities therefore need a scope.

Some capabilities may be inherited by child Agents. Some should remain local to the current Agent. Others may need to be replaced or restricted in a child Agent. This is the kind of problem addressed by Spatial Composability:

What is the scope of a capability within the Agent structure? \boxed{ \text{What is the scope of a capability within the Agent structure?} }

The second problem comes from the way Agents operate over time.

An Agent does not execute a single function and stop. It repeatedly moves through a loop such as:

User input
   ↓
Model inference
   ↓
Produce action
   ↓
Execute tool
   ↓
Receive feedback
   ↓
Infer again
Enter fullscreen mode Exit fullscreen mode

Different Plugins need to intervene at different points in that lifecycle.

A Permission Plugin may need to inspect an action before a Tool executes. A Memory Plugin may need to inject information before the LLM is called. A Logger may need to record results after a Tool returns. These components are not merely attached to the side of the Runtime; they are embedded into the temporal structure of the Agent itself.

That leads to the second concept:

Temporal Composability \boxed{ \text{Temporal Composability} }

In other words: At what point in the runtime lifecycle should a capability appear, what effect should it have, and how should that effect be removed when the capability disappears?

So the real problem behind “Everything is a Plugin” in DeepSeek Harness is not ordinary software modularity.

The deeper goal is:

Turn capabilities inside the Agent Runtime from fixed structure into dynamically composable components, while still controlling where those components apply across Agents and when they intervene throughout the runtime lifecycle.

This is also why DeepSeek does not stop at simply designing a Plugin API.

If Memory, Tools, and Sessions are all converted into Plugins but there is no mechanism for managing their dependencies, scopes, and lifecycles, those Plugins will eventually become tangled again. The complexity has merely been moved somewhere else.

So after “Everything is a Plugin,” the more important question becomes:

Who manages these Plugins, and how can they remain composable inside an Agent Runtime that is constantly changing?

That is where Cordis enters the picture.

Top comments (0)