DeepSeek’s Super-agent, explained
DeepSeek’s Harness team has designed a single coding agent that lives in a team’s chat and GitHub repository and handles many requests in parallel.
- events from the outside world
- the Router
- Workers
- state and machines
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}[node distance=6mm]
% channels
\node[trig, text width=2.6cm] (im) at (0,3.0) {IM group chat};
\node[trig, text width=2.6cm] (em) at (0,1.9) {Email \& calendar};
\node[trig, text width=2.6cm] (gh) at (0,0.8) {GitHub issues \& PR reviews};
\node[trig, text width=2.6cm] (ci) at (0,-0.3) {CI results};
\begin{scope}[on background layer]
\node[draw=trig, dashed, rounded corners=3pt, fit=(im)(ci), inner sep=6pt, label={[title]above:Triggers}] (chan) {};
\end{scope}
% filter
\node[plain, text width=2.5cm] (fast) at (4.0,2.1) {\textbf{Fast path}\\[-1pt]{\scriptsize rules: source, group, allow-list}};
\node[plain, text width=2.5cm] (slow) at (4.0,0.2) {\textbf{Slow path}\\[-1pt]{\scriptsize an LLM reads the team's written policy}};
\draw[arr] (fast) -- node[lab, right]{passes} (slow);
\foreach \c in {im,em,gh,ci} \draw[arr] (\c.east) -- (fast.west);
% router
\node[rout, text width=3.3cm, minimum height=2.3cm] (router) at (7.7,1.0) {\textbf{Router}\\[2pt]{\scriptsize one resident session\\talks to people\\dispatches work\\lighter model, no Bash}};
\draw[arr] (slow.east) -- (router.west |- slow.east);
% workers
\node[work, text width=2.9cm] (w1) at (12.6,2.7) {\textbf{Worker A}\\[-1pt]{\scriptsize fix bug in PR \#88}};
\node[work, text width=2.9cm] (w2) at (12.6,1.0) {\textbf{Worker B}\\[-1pt]{\scriptsize add font setting}};
\node[work, text width=2.9cm] (w3) at (12.6,-0.7) {\textbf{Worker C}\\[-1pt]{\scriptsize answer review comments}};
\node[note, text width=3.2cm, below=1mm of w3] (wn) {isolated context, full tools,\\strongest model; never\\talks to people directly};
\draw[arr] (router.east) -- (w1.west);
\draw[arr, <->] (router.east) -- node[lab, above=1pt]{dispatch} node[lab, below=1pt]{report back} (w2.west);
\draw[arr] (router.east) -- (w3.west);
% direct delivery
\draw[darr, draw=trig] (fast.north) to[out=70, in=150] node[lab, text=trig, pos=0.45]{follow-ups in a known thread go straight to its Worker} (w1.north west);
% replies
\draw[arr, draw=router, line width=1pt] (router.south) -- ++(0,-1.9) -| node[lab, pos=0.25, text=router]{one voice: replies land in the original thread} (chan.south);
% exec env
\node[stor, text width=2.5cm] (lap) at (16.6,2.0) {Dev laptop\\[-1pt]{\scriptsize daemon only}};
\node[stor, text width=2.5cm] (box) at (16.6,0.0) {Cloud sandbox\\[-1pt]{\scriptsize daemon only}};
\node[title, above=2mm of lap] {Where commands run};
\draw[arr, <->] (w1.east) -- (lap.west);
\draw[arr, <->] (w2.east) -- (lap.west);
\draw[arr, <->] (w3.east) -- (box.west);
% session db
\node[stor, text width=7.5cm] (db) at (10.2,-3.4) {\textbf{Session database}: every session's state lives here, so the cloud containers running the loop can restart at any time};
\draw[arr, dotted, <->] (router.south east) -- (router.south east |- db.north);
\draw[arr, dotted, <->] (wn.south) -- (wn.south |- db.north);
% watchdog
\node[ghost, text width=3.0cm, text=ink] (wd) at (16.6,4.2) {\textbf{Watchdog}\\[-1pt]{\scriptsize timed check-ins: real progress or drifting?}};
\draw[darr, draw=muted] (wd.west) -- (w1.north east);
\end{tikzpicture}
</script> Overview
DeepSeek Harness (the dsh command) is DeepSeek’s open-source agent harness, the program around a model that reads your request, calls tools, runs commands, saves the session and repeats until the job is done. It came out in August 2026 under the MIT licence. Every part of it, from the model adapter to the agent loop, is a plugin you can replace.
Super-agent is what the Harness team wants to build next. Today you open one chat session per task. In their design, one agent sits in the team’s group chat and GitHub repository, picks up requests, starts workers for them in parallel, and replies in the thread where it was asked.
The team shipped two things: a long design essay and a prototype, dsh-superagent-prototype, packaged as a Harness bundle for one GitHub repository with optional Feishu chat. Both are labelled as research, and the prototype covers only part of what the essay describes.
The essay’s rule is to spend as little human attention as possible for as much value as possible. The agent acts only when asked or when a written team rule allows it, and posts only when someone has to act or can use the result.
Attention is the bottleneck
Today’s coding agents treat one session as one unit of work. Sessions don’t share memory, so when you run several in parallel you are the one carrying context between them and switching back and forth. The team puts the limit at about three to five sessions that one person can actively follow. Past that, more agents don’t get more done, because you can’t keep up with them.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
% ---- left panel
\node[title] at (2.6,4.3) {Today: one session per task};
\fill[ink] (0,1.9) circle (0.22); \draw[ink, line width=1.2pt] (0,1.65) -- (0,1.0) (-0.35,1.4) -- (0.35,1.4) (0,1.0) -- (-0.25,0.55) (0,1.0) -- (0.25,0.55);
\node[note] at (0,0.2) {you};
\foreach \i/\y/\t in {1/3.4/auth bug,2/2.55/docs,3/1.7/refactor,4/0.85/flaky test,5/0.0/review}{
\node[work, text width=1.9cm, font=\sffamily\scriptsize] (s\i) at (3.6,\y) {session \i\\ \t};
\draw[arr, <->, draw=muted] (0.45,1.4) -- (s\i.west);
}
\node[ghost, text width=1.9cm, font=\sffamily\scriptsize] (s6) at (3.6,-0.85) {session 6?};
\draw[arr, <->, draw=warn, dashed] (0.45,1.4) -- (s6.west);
\draw[decorate, decoration={brace, amplitude=5pt, mirror}, muted] (4.75,-0.25) -- (4.75,3.75) node[midway, right=6pt, note, text width=2.0cm]{about 3 to 5 is the most one person can follow};
\node[note, text width=4.6cm] at (2.4,-1.75) {you carry the context between sessions and switch by hand; your attention caps throughput};
% ---- right panel
\begin{scope}[xshift=9.2cm]
\node[title] at (3.2,4.3) {Super-agent: one conversation, many workers};
\fill[ink] (0,1.9) circle (0.22); \draw[ink, line width=1.2pt] (0,1.65) -- (0,1.0) (-0.35,1.4) -- (0.35,1.4) (0,1.0) -- (-0.25,0.55) (0,1.0) -- (0.25,0.55);
\node[note] at (0,0.2) {you \& team};
\node[rout, text width=1.9cm] (r) at (3.1,1.4) {\textbf{Router}\\{\scriptsize remembers across tasks}};
\draw[arr, <->, draw=router, line width=1pt] (0.45,1.4) -- node[lab, above=2pt, text width=1.4cm]{asks only when needed} (r.west);
\foreach \i/\y in {1/3.6,2/2.8,3/2.0,4/1.2,5/0.4,6/-0.4,7/-1.2}{
\node[work, minimum width=1.5cm, font=\sffamily\scriptsize] (w\i) at (6.2,\y) {worker \i};
\draw[arr, draw=worker!80] (r.east) -- (w\i.west);
}
\node[note, text width=4.6cm] at (2.6,-1.75) {the Router holds the cross-task picture; work in parallel is no longer capped by what you can track};
\end{scope}
\end{tikzpicture}
</script> The essay asks for an agent with one memory across conversations and channels, that runs many tasks at once, notices work nobody assigned, and stays online. Its example is a group that agrees on plan A in chat and then switches to plan B in a pull-request comment. The agent should see that both are about the same work and change course.
Architecture
The essay compares two simple designs before settling on a third.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
\tikzset{ev/.style={trig, minimum width=0.55cm, minimum height=0.45cm, inner sep=1pt, font=\sffamily\scriptsize}}
% panel A
\node[title] at (1.6,3.7) {A. Everything into one session};
\foreach \i in {1,...,5} \node[ev] (a\i) at (-0.2,2.6-\i*0.55) {e\i};
\node[work, text width=1.8cm, minimum height=2.4cm] (as) at (2.6,0.95) {one session\\{\scriptsize handles e1, then e2, then e3 \dots}};
\foreach \i in {1,...,5} \draw[arr] (a\i.east) -- (as.west);
\node[note, text width=4.0cm] at (1.4,-1.0) {\textcolor{worker}{+} one continuous memory\\\textcolor{warn}{--} one ReAct loop runs serially, so throughput is low};
% panel B
\begin{scope}[xshift=5.6cm]
\node[title] at (1.6,3.7) {B. A new session per event};
\foreach \i in {1,...,5} {\node[ev] (b\i) at (-0.2,2.6-\i*0.55) {e\i};
\node[work, minimum width=1.3cm, minimum height=0.42cm, inner sep=1pt, font=\sffamily\scriptsize] (bs\i) at (1.6,2.6-\i*0.55) {session \i};
\draw[arr] (b\i.east) -- (bs\i.west);
\draw[arr, draw=warn] (bs\i.east) -- (3.1,0.95);}
\fill[ink] (3.4,1.25) circle (0.15); \draw[ink, line width=1pt] (3.4,1.1) -- (3.4,0.7) (3.15,0.95) -- (3.65,0.95);
\node[note, text width=4.0cm] at (1.4,-1.0) {\textcolor{worker}{+} maximum concurrency\\\textcolor{warn}{--} results are fragmented and several sessions may all reply to you};
\end{scope}
% panel C
\begin{scope}[xshift=11.2cm]
\node[title] at (1.8,3.7) {C. Router + Workers};
\foreach \i in {1,...,5} \node[ev] (c\i) at (-0.2,2.6-\i*0.55) {e\i};
\node[rout, text width=1.1cm, minimum height=2.4cm, font=\sffamily\scriptsize] (cr) at (1.3,0.95) {\textbf{Router}};
\foreach \i in {1,...,5} \draw[arr] (c\i.east) -- (cr.west |- c\i.east);
\foreach \j/\y in {1/1.95,2/0.95,3/-0.05} {\node[work, minimum width=1.1cm, minimum height=0.5cm, inner sep=1pt, font=\sffamily\scriptsize] (cw\j) at (3.3,\y) {W\j};
\draw[arr, <->] (cr.east |- cw\j.west) -- (cw\j.west);}
\fill[ink] (1.3,3.05) circle (0.15); \draw[ink, line width=1pt] (1.3,2.9) -- (1.3,2.55) (1.05,2.75) -- (1.55,2.75);
\draw[arr, draw=router, line width=1pt] (cr.north) -- (1.3,2.5) node[lab, right=4pt, pos=0.5, text=router]{one reply};
\node[note, text width=4.0cm] at (1.6,-1.0) {\textcolor{worker}{+} continuous memory at the Router, parallel work below it, one voice toward people};
\end{scope}
\end{tikzpicture}
</script> The Router is one long-lived session. It receives every human message from every channel, keeps track of how tasks relate, decides who does what, and is the only part that talks to people. It doesn’t write code and may not have a shell tool at all. The team found the job easier than they expected, and a smaller, faster model often handles it well.
Each Worker gets a fresh context, the full tool set, and usually the strongest model, since Workers write the code. They never message people. They report to the Router, which answers for them. Inside a hard task a Worker can still start its own sub-agents or an agent team, and the Router never sees that detail.
In a typical “agent team”, a lead agent breaks one big task into parts and coordinates them closely. The Router never splits a task. It tracks how separate tasks relate to each other.
Choosing what to work on
Every piece of work starts as a trigger, such as a chat message, an email, a calendar reminder, a code-review comment or a CI result. Most of what happens in a group chat isn’t a request, so triggers pass two filters. The fast path is ordinary code that lets events through by source, group and allow-list. Whatever gets past it goes to the slow path, where an LLM reads the team’s written policy and decides whether to take the work on.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
% top row: funnel
\node[trig, text width=2.3cm] (in) at (0,0) {\textbf{All events}\\{\scriptsize in the test: $\sim$300 messages, $\sim$20 real requests}};
\node[plain, text width=2.8cm] (fp) at (3.9,0) {\textbf{Fast path}\\{\scriptsize code checks the source, the group and the allow-list; deterministic}};
\node[plain, text width=2.8cm] (sp) at (8.0,0) {\textbf{Slow path}\\{\scriptsize an LLM judges the candidate against the team's prompt policy}};
\node[rout, text width=2.0cm] (r) at (11.7,0) {\textbf{Router}\\{\scriptsize takes it on}};
\draw[arr] (in) -- (fp); \draw[arr] (fp) -- node[lab, above=2pt]{candidate} (sp); \draw[arr] (sp) -- node[lab, above=2pt]{accept} (r);
\node[ghost, minimum width=1.6cm] (d1) at (3.9,-1.7) {dropped};
\node[ghost, minimum width=1.6cm] (d2) at (8.0,-1.7) {dropped};
\draw[darr, draw=muted] (fp) -- (d1); \draw[darr, draw=muted] (sp) -- (d2);
\node[note] at (6.0,1.35) {cheap filter first, expensive judgement second};
% bottom: prototype authorization
\node[title, anchor=west] at (-1.2,-3.1) {How the open-source prototype decides who can start work};
\node[work, text width=3.0cm] (ex) at (0.4,-4.6) {\textbf{Explicit request}\\{\scriptsize a person on the allow-list addresses the agent}};
\node[trig, text width=3.0cm] (inf) at (0.4,-6.6) {\textbf{Inferred candidate}\\{\scriptsize the agent noticed it on its own (bots can only produce these)}};
\node[work, text width=3.2cm] (any) at (8.4,-4.6) {accepted, in any mode};
\draw[arr] (ex) -- (any);
\node[plain, text width=2.7cm] (rule) at (4.4,-6.6) {matches a written team rule and passes assessment?};
\draw[arr] (inf) -- (rule);
\node[plain, text width=3.2cm] (off) at (8.4,-5.5) {\texttt{off}: {\scriptsize ignored}};
\node[plain, text width=3.2cm, line width=1.1pt] (obs) at (8.4,-6.6) {\texttt{observe} {\scriptsize(default)}: {\scriptsize logged as ``would accept'', nothing runs}};
\node[work, text width=3.2cm] (au) at (8.4,-7.85) {\texttt{auto}: {\scriptsize accepted, work starts}};
\draw[arr] (rule.east) -- ++(0.4,0) |- (off.west);
\draw[arr] (rule.east) -- (obs.west);
\draw[arr] (rule.east) -- ++(0.4,0) |- (au.west);
\node[note] at (6.45,-5.1) {mode};
\node[note, text width=3.4cm, anchor=west] at (10.4,-6.1) {suggested rollout: start in observe, read the logged decisions, then switch to auto};
\node[note, text width=3.4cm, anchor=west] at (10.4,-7.5) {each work item records the policy version it was accepted under; weakening a rule can revoke it};
\end{tikzpicture}
</script> The prototype spells out who can start work. An explicit request is a person on the allow-list addressing the agent, and it is handled in every mode. An inferred candidate is something the agent noticed on its own, and it needs a matching written rule. Messages from bots always count as inferred candidates.
Inferred work then depends on the accept mode. off ignores it. observe, the default, records “would have accepted” and runs nothing. auto actually starts the work. The README suggests running in observe first, reading what it would have done, and switching to auto after that. Each work item also records which version of the policy it was accepted under, so tightening a rule can revoke work before it resumes.
Threads
Consecutive events in the same pull request, chat topic or email chain form a thread. The first event goes through the Router, which starts a Worker and subscribes it to that thread. Later events in that thread go straight to the Worker without passing through the Router.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
\draw[trig, line width=1.2pt, -{Stealth[length=6pt]}] (-1.2,3) -- (11.2,3) node[right, font=\sffamily\small, text=trig] {time};
\node[font=\sffamily\bfseries\small, text=trig, anchor=west] at (-1.2,4.35) {Thread T = everything said in PR \#88};
\foreach \x/\n/\t in {0.4/e1/``tildes render as strikethrough'',4.6/e2/``also happens in headings'',8.8/e3/review comment on the diff}{
\node[trig, font=\sffamily\scriptsize, inner sep=3pt] (\n) at (\x,3) {\n};
\node[note, above=1mm of \n, text width=3.2cm] {\t};}
% lanes
\node[rout, minimum width=2.0cm] (r) at (0.4,1.0) {\textbf{Router}};
\node[work, minimum width=2.2cm] (a) at (2.6,-0.6) {\textbf{Worker A}};
\node[work, minimum width=2.2cm] (b) at (6.8,-2.1) {\textbf{Worker B}};
\node[note, below=1mm of b, text width=3.6cm] {busy on PR \#90, which edits the same file};
% e1 via router
\draw[arr] (e1) -- node[lab, left]{slow path} (r);
\draw[arr, draw=router] (r.south) |- node[lab, pos=0.3, left, text width=1.9cm]{spawns A and subscribes it to T} (a.west);
% e2 direct
\draw[arr, draw=worker, line width=1pt] (e2.south) to[out=-90, in=30] node[lab, pos=0.4, right]{delivered straight to A} (a.north east);
% B subscribes
\draw[darr, draw=muted] (b.north) -- ++(0,0.9) node[lab, above, text=muted]{B subscribes to T too};
% e3 to both
\draw[arr, draw=worker, line width=1pt] (e3.south) to[out=-110, in=0] (a.east);
\draw[arr, draw=worker, line width=1pt] (e3.south) to[out=-80, in=0] (b.east);
\node[note, text width=3.6cm, anchor=west] at (9.4,0.3) {many-to-many: both Workers get e3 and can spot the conflict themselves, with no point-to-point messages};
\node[note, text width=5.0cm, anchor=west] at (-1.3,-2.6) {Router stays out of the loop for follow-ups, so it makes fewer decisions};
\end{tikzpicture}
</script> Subscriptions are many-to-many. Two Workers subscribed to the same thread both see its events, so they find out they are touching the same code without messaging each other. In the experiments, turning direct delivery off barely changed how fast tasks finished, but the Router had to make about 30% more decisions and read about 37% more tokens.
Memory
A Router that runs for weeks can’t keep everything in its context. The team treats the context window as a cache. Some information is placed in it directly, the rest is left out behind a reference, and every object has an ID the model can use to look it up.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
% context window bar
\node[title, anchor=west] at (-0.2,2.2) {The context window, treated like a cache};
\draw[ink, line width=0.8pt, rounded corners=2pt] (0,0.6) rectangle (15,1.6);
\fill[worker!14] (0.05,0.65) rectangle (9.2,1.55);
\fill[muted!12] (9.2,0.65) rectangle (14.95,1.55);
\node[font=\sffamily\small, text=ink, align=center] at (4.6,1.1) {\textbf{Inline}: what is probably needed goes in directly\\{\scriptsize e.g. the first 50 characters of each message, the neighbouring chat lines}};
\node[font=\sffamily\small, text=ink, align=center] at (12.07,1.1) {\textbf{Spill}: the rest is cut, with a pointer\\{\scriptsize ``\dots\ [more: trigger \#991]''}};
\draw[decorate, decoration={brace, amplitude=5pt}, muted] (14.95,0.5) -- (9.2,0.5) node[midway, below=5pt, note]{fetched only if the model follows the pointer};
% chain of recall
\node[title, anchor=west] at (-0.2,-0.9) {Chain of Recall: every object carries the IDs of related objects};
\node[trig, text width=2.7cm] (m) at (1.4,-2.6) {\textbf{New IM message}\\{\scriptsize ``is the font thing done?''}\\[2pt]{\scriptsize\texttt{thread:T7}}};
\node[trig, text width=2.7cm] (t) at (5.4,-2.6) {\textbf{Thread T7}\\{\scriptsize last week's chat, first lines inlined}\\[2pt]{\scriptsize\texttt{worker:W3}}};
\node[work, text width=2.7cm] (w) at (9.4,-2.6) {\textbf{Worker W3}\\{\scriptsize status: in review}\\[2pt]{\scriptsize\texttt{pr:\#88}}};
\node[plain, text width=2.4cm] (p) at (13.3,-2.6) {\textbf{PR \#88}\\{\scriptsize switched to plan B in review}};
\draw[arr] (m) -- node[lab, above=2pt]{hop 1} (t); \draw[arr] (t) -- node[lab, above=2pt]{hop 2} (w); \draw[arr] (w) -- node[lab, above=2pt]{hop 3} (p);
\node[note, text width=11cm] at (7.4,-4.0) {the Router recovers an old task that someone raises on a different channel, one hop at a time, instead of keeping all history in its window};
\end{tikzpicture}
</script> When someone asks in chat whether “the font thing” is done, the Router doesn’t need last week’s conversation in memory. The message carries a thread ID, the thread carries the Worker’s ID, and the Worker’s record points at the pull request, where the answer is.
An asynchronous agent loop
Most agents run a ReAct loop: think, call a tool, wait for the result, think again. While a long build runs, the agent can’t read new messages. Super-agent replaces long commands and subtasks with start() and stop(). start() returns “Started” immediately, the result comes back later as a new event, and the model can cancel something that’s taking too long or is no longer wanted.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\usetikzlibrary{patterns}
\begin{tikzpicture}
\tikzset{think/.style={rout, minimum height=0.55cm, inner sep=2pt, font=\sffamily\scriptsize},
job/.style={draw=store, fill=store!14, rounded corners=2pt, minimum height=0.5cm, inner sep=2pt, font=\sffamily\scriptsize, text=ink},
msg/.style={trig, inner sep=2pt, font=\sffamily\scriptsize}}
% ---------- sync
\node[title, anchor=west] at (-1.4,4.7) {Classic ReAct loop: the tool call blocks};
\node[note, anchor=east] at (-0.2,3.0) {model}; \node[note, anchor=east] at (-0.2,1.8) {tool};
\draw[muted!60] (0,3.0) -- (13.3,3.0); \draw[muted!60] (0,1.8) -- (13.3,1.8);
\node[think, minimum width=1.2cm] (s1) at (0.8,3.0) {think};
\fill[muted!14] (1.6,2.78) rectangle (8.9,3.22);
\node[font=\sffamily\scriptsize, text=muted] at (6.6,3.0) {blocked, waiting};
\node[job, minimum width=7.2cm, anchor=west] (sj) at (1.7,1.8) {\texttt{run(build \& test)} \dots\ 8 minutes};
\draw[arr] (1.3,2.72) -- node[lab, left, pos=0.5]{\texttt{run()}} (1.8,2.05);
\node[msg] (sm) at (3.6,4.05) {new message: ``stop, use plan B''};
\draw[arr, draw=warn] (sm.south) -- (3.6,3.25);
\node[note, text=warn, anchor=west] at (3.7,3.45) {has to wait in line};
\draw[arr] (8.9,2.05) -- (9.4,2.72);
\node[think, minimum width=2.4cm] (s2) at (10.6,3.0) {finally reads it};
% ---------- async
\begin{scope}[yshift=-4.4cm]
\node[title, anchor=west] at (-1.4,4.7) {Async loop: \texttt{start()} returns at once; results come back as new events};
\node[note, anchor=east] at (-0.2,3.0) {model}; \node[note, anchor=east] at (-0.2,1.8) {tool};
\draw[muted!60] (0,3.0) -- (13.3,3.0); \draw[muted!60] (0,1.8) -- (13.3,1.8);
\node[think, minimum width=1.2cm] (a1) at (0.8,3.0) {think};
\node[job, minimum width=3.8cm, anchor=west] (aj) at (1.7,1.8) {\texttt{start(build \& test)}};
\draw[arr] (1.3,2.72) -- node[lab, left, pos=0.5]{\texttt{start()}} (1.8,2.05);
\node[note, anchor=north west] at (1.7,1.45) {returns ``Started'' immediately};
\node[msg] (am) at (3.6,4.05) {``stop, use plan B''};
\node[think, minimum width=2.0cm] (a2) at (3.6,3.0) {handles it now};
\draw[arr, draw=trig] (am) -- (a2);
\draw[arr, draw=warn, line width=1pt] (4.5,2.72) -- (5.45,2.05);
\node[font=\sffamily\scriptsize, text=warn, anchor=west] at (5.15,2.5) {\texttt{stop()}};
\node[think, minimum width=1.6cm] (a3) at (6.9,3.0) {replans};
\node[job, minimum width=3.0cm, anchor=west] (aj2) at (7.3,1.8) {\texttt{start(plan B)}};
\draw[arr] (7.4,2.72) -- (7.7,2.05);
\draw[arr, draw=store] (10.3,2.05) -- (10.7,2.72);
\node[think, minimum width=2.8cm] (a4) at (11.9,3.0) {result arrives as an event};
\end{scope}
\node[note, text width=13cm] at (6.0,-3.95) {In DeepSeek Harness this asynchronous mode already exists but is off by default. It is what lets a busy session keep listening.};
\end{tikzpicture}
</script> This asynchronous mode already exists in DeepSeek Harness but is off by default. The Router uses the same mechanism to batch work. Triggers that arrive while it is in the middle of a call are added to its next one.
Where it runs
To keep the agent online, the design separates compute from storage, as many databases do. The code that drives the agent loop runs in stateless cloud containers. Every session’s state lives in a database. If a container crashes, another one loads the state and continues.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
% cloud band
\begin{scope}[on background layer]
\fill[store!5, rounded corners=6pt] (-0.4,2.0) rectangle (13.4,4.7);
\end{scope}
\node[title, anchor=west] at (-0.2,4.3) {Cloud: compute and state, kept apart};
\foreach \i/\x in {1/1.0,2/3.0,3/5.0} \node[rout, minimum width=1.7cm, font=\sffamily\scriptsize] (c\i) at (\x,2.9) {container \i\\agent loop};
\node[note, text width=7cm] at (3.6,3.75) {stateless: scale up, crash or restart any of them without losing anything};
\node[stor, text width=3.6cm, minimum height=1.4cm] (db) at (10.4,2.9) {\textbf{Session database}\\{\scriptsize every session's history and status}};
\draw[arr, <->] (c3.east) -- node[lab, above=1pt]{load / save state} (db.west);
% execution band
\node[title, anchor=west] at (-0.2,-3.2) {Execution: where the work actually happens};
\node[work, text width=3.4cm] (lap) at (1.8,-1.4) {\textbf{Developer laptop}\\{\scriptsize uncommitted changes, local credentials}};
\node[work, text width=3.4cm] (cl) at (6.5,-1.4) {\textbf{Cloud sandbox}\\{\scriptsize disposable environment}};
\node[ghost, text width=3.4cm, text=ink] (ph) at (11.2,-1.4) {\textbf{Intermittent device}\\{\scriptsize offline now; tasks queue and catch up when it returns}};
\foreach \n in {lap,cl,ph} \node[plain, font=\sffamily\scriptsize, inner sep=2pt, text width=3.3cm, below=1mm of \n] {small daemon: runs commands, keeps no state};
\draw[arr] (c1.south) -- node[lab, left, pos=0.55]{commands} ($(lap.north)+(-0.4,0)$);
\draw[arr] ($(lap.north)+(0.4,0)$) -- node[lab, right, pos=0.45]{results} (c2.south);
\draw[arr, <->] (c3.south) -- (cl.north);
\draw[darr, <->, draw=muted] (c3.south east) -- (ph.north west);
\node[note, text width=13cm] at (6.5,-3.95) {``Bring your own machine'': the agent stays online in the cloud but can still work on the computer you already use. The security catch: if the cloud loop is compromised, every connected machine is exposed.};
\end{tikzpicture}
</script> The machines that do the work only run a small daemon that executes commands and returns results. That means your own laptop, with its uncommitted changes and local credentials, can be one of the machines the agent runs commands on. If a device goes offline, its tasks wait and catch up when it reconnects. The essay compares this to Anthropic’s “brain and hands” split, with the difference that the hands here are people’s own computers instead of hosted sandboxes.
The Watchdog
A separate Watchdog session runs on a timer. It handles infrastructure failures like API errors or failed state recovery, and it checks whether each Worker is making real progress or drifting. Maintainers can ask it in plain language why something failed and have it adjust prompts or trigger rules.
An example request
Here is how a bug report moves through the system. A person is involved in only a few of the steps.
TikZJax source
<script type="text/tikz">
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
\tikzset{msgl/.style={font=\sffamily\scriptsize, text=ink, fill=white, inner sep=1.5pt, align=center}}
\foreach \x/\n/\s in {0/Team chat/trig,4.2/Router/rout,8.4/Worker/work,12.6/GitHub/plain}{
\node[\s, minimum width=2.2cm] at (\x,0) {\textbf{\n}};
\draw[muted!70, line width=0.6pt] (\x,-0.4) -- (\x,-11.2);}
% steps
\draw[arr, draw=trig] (0,-1.0) -- node[msgl, above]{1. ``@agent tildes render as strikethrough''} (4.2,-1.0);
\draw[arr, draw=router] (4.2,-1.8) -- node[msgl, above]{2. one short acknowledgement} (0,-1.8);
\draw[arr, draw=router] (4.2,-2.6) -- node[msgl, above]{3. new work item: own session, own directory} (8.4,-2.6);
\node[work, text width=3.0cm, font=\sffamily\scriptsize, anchor=north] (quiet) at (8.4,-3.0) {4. reproduce, fix, run tests\\{\itshape silent: nobody is pinged}};
\draw[arr, draw=worker] (8.4,-5.0) -- node[msgl, above]{5. opens PR \#88} node[msgl, below, text width=3.5cm]{background, changes, how it was verified} (12.6,-5.0);
\draw[arr, draw=worker] (8.4,-6.2) -- node[msgl, above]{6. reports ``PR ready''} (4.2,-6.2);
\draw[arr, draw=router, line width=1pt] (4.2,-7.0) -- node[msgl, above]{7. ``Fix is up in \#88.''} node[msgl, below]{IM replies stay under 100 words} (0,-7.0);
\draw[arr, draw=trig] (12.6,-8.0) -- node[msgl, above]{8. review comment, delivered directly} node[msgl, below]{(Worker is subscribed to this thread)} (8.4,-8.0);
\draw[arr, draw=worker] (8.4,-9.1) -- node[msgl, above]{9. pushes the change} (12.6,-9.1);
\draw[darr, draw=router] (4.2,-10.3) -- node[msgl, above]{only if blocked: one clear question} (0,-10.3);
% annotations
\node[note, text width=2.8cm, anchor=east] at (-0.75,-4.25) {people spend attention at three moments only: the acknowledgement, the result, and a real decision};
\draw[decorate, decoration={brace, amplitude=5pt}, muted] (-0.45,-7.2) -- (-0.45,-1.6);
\end{tikzpicture}
</script> The agent writes differently in each channel. Chat replies are informal and stay under 100 words. On GitHub and email it writes longer, structured text, for example a pull-request description with background, changes and how the fix was tested.
DeepSeek also uses the agent for speculative work. Their Harness user group has a “silently reproduce and fix” rule: when someone reports a problem, the agent tries to reproduce and fix it in the background and says nothing unless it confirms the bug and finds a simple fix. In one case, people were still discussing a bug where tildes rendered as strikethrough when the agent opened a pull request fixing it.
Results
The team ran a synthetic test. Each run fed in about 300 chat and CI messages, of which about 20 were real work requests and the rest chatter, follow-ups, stop requests and CI noise. The coding itself was replaced by a tool that waits for a set time, so the test measures scheduling and coordination and says nothing about code quality. Each setup ran five times.
TikZJax source
<script type="text/tikz">
\usepackage{pgfplots}
\usetikzlibrary{positioning,arrows.meta,fit,backgrounds,calc,shapes.geometric,decorations.pathreplacing}
\definecolor{ink}{HTML}{1B2433}
\definecolor{router}{HTML}{B86A00}
\definecolor{worker}{HTML}{127A74}
\definecolor{trig}{HTML}{5B4BB7}
\definecolor{store}{HTML}{2F64AE}
\definecolor{muted}{HTML}{5F6878}
\definecolor{warn}{HTML}{B3261E}
\tikzset{
base/.style={draw=ink, line width=0.6pt, rounded corners=2pt, align=center, font=\sffamily\small, inner sep=5pt, text=ink},
trig/.style={base, draw=trig, fill=trig!9},
rout/.style={base, draw=router, fill=router!12, line width=1.1pt},
work/.style={base, draw=worker, fill=worker!9},
stor/.style={base, draw=store, fill=store!9},
plain/.style={base, fill=white},
ghost/.style={base, draw=muted, dashed, fill=white, text=muted},
note/.style={font=\sffamily\scriptsize, text=muted, align=center},
lab/.style={font=\sffamily\scriptsize, text=ink, align=center, fill=white, inner sep=1.5pt},
arr/.style={-{Stealth[length=5pt]}, line width=0.7pt, draw=ink!85},
darr/.style={arr, dashed},
title/.style={font=\sffamily\bfseries\small, text=ink},
}
\begin{tikzpicture}
\begin{axis}[name=t, xbar, width=8.2cm, height=6.2cm, bar width=6pt,
xmin=0, xmax=34, xlabel={minutes to finish a task}, xlabel style={font=\sffamily\scriptsize},
symbolic y coords={sub-n,sub-d,nodd,sa}, ytick=data, y dir=reverse,
yticklabels={{single session, neutral prompt},{single session, delegate-first},{Super-agent, no subscriptions},{Super-agent}},
yticklabel style={font=\sffamily\scriptsize, text width=3.2cm, align=right},
ticklabel style={font=\sffamily\scriptsize}, axis line style={muted}, tick style={muted},
legend style={font=\sffamily\scriptsize, draw=none, at={(0.5,1.02)}, anchor=south, legend columns=2, reverse legend}, area legend,
nodes near coords, nodes near coords style={font=\sffamily\tiny, text=ink}, enlarge y limits=0.18,
title={Speed: median and slow tail}, title style={font=\sffamily\bfseries\small, yshift=12pt}]
\addplot[fill=router!55, draw=router] coordinates {(29.5,sub-n) (29.0,sub-d) (15.5,nodd) (15.7,sa)};
\addplot[fill=worker!70, draw=worker] coordinates {(20.4,sub-n) (13.8,sub-d) (12.6,nodd) (12.4,sa)};
\legend{p95 (slow tail), p50 (typical)}
\end{axis}
\begin{axis}[at={(t.east)}, anchor=west, xshift=1.4cm, xbar, width=6.2cm, height=6.2cm, bar width=9pt,
xmin=0, xmax=38, xlabel={cache-read tokens per run (millions)}, xlabel style={font=\sffamily\scriptsize},
symbolic y coords={sub-n,sub-d,nodd,sa}, ytick=data, y dir=reverse, yticklabels={},
ticklabel style={font=\sffamily\scriptsize}, axis line style={muted}, tick style={muted},
nodes near coords, nodes near coords style={font=\sffamily\tiny, text=ink}, enlarge y limits=0.18,
title={Cost: tokens read}, title style={font=\sffamily\bfseries\small, yshift=12pt}]
\addplot[fill=store!60, draw=store] coordinates {(6.05,sub-n) (10.82,sub-d) (31.77,nodd) (23.23,sa)};
\end{axis}
\end{tikzpicture}
</script> With a neutral prompt, the model never used its sub-agent tool in five runs, so everything happened in one session that kept getting interrupted. With a “delegate first” prompt it delegated in four of five runs. In the fifth it decided a task was small enough to do itself, and that run was the slowest.
A separate stress test looked only at the Router. As triggers rose from about 1 to about 40 per minute, it grouped more of them into each model call (from 1.0 to 2.8 on average). Time per request rose from 2.5 to 3.9 seconds, while time per decision fell from 6.4 to 1.6 seconds. The team concluded that one Router session is enough for a team their size.
The authors call these results preliminary, given the synthetic load and simplified environment.
Sources
- AgentsPulse: review of the design essay, with the experiment numbers
- Developers Digest: what the prototype ships, its accept modes and execution caveats
- deepseek-ai/dsh-superagent-prototype on GitHub
- The original design essay (Chinese, WeChat)
- i-SCOOP: the attention-budget framing
- Bloomberg: news coverage of the release
- DeepSeek Harness
Written from public sources as of November 1, 2026. All numbers come from the DeepSeek Harness team.