Skip to content

CH 08 · Modelo Mental da Árvore de Plugins: Tudo é um Plugin

Contagem de palavras~4.070 palavrasTempo~15 minPré-requisitosConceitos do CH 02, prática do CH 05NívelConceitual

Objetivo do Capítulo

O CH 02 disse "tudo é um plugin"; este capítulo transforma isso em um modelo mental que você pode levar consigo: o que é um dsh em execução, por que cada parte pode ser trocada e por que a frase "troque um Provider, troque o produto" realmente se sustenta.

Uma Frase para Embasar: Um dsh em Execução = uma Árvore de Plugins

O documento oficial de arquitetura coloca assim: um dsh em execução é uma árvore de plugins, composta por camadas ordenadas na inicialização. Divida em três camadas para memorizar, e toda a arquitetura se sustenta:

Um dsh em execução = uma árvore de plugins (ilustração)

Lendo o diagrama de cima para baixo, a lógica é: ① Primeiro escolha um Profile → ② Empilhe as camadas de plugins em ordem → ③ Todas as camadas rodam no mesmo kernel Cordis. Os três pontos correspondentes:

  • A camada inferior é o kernel Cordis: um contexto compartilhado que permite aos plugins injetar serviços, transmitir eventos e montar efeitos.
  • No meio fica a própria árvore de plugins: vários plugins empilhados em uma árvore, cada um fazendo uma coisa específica.
  • A camada superior é o Profile: ele não adiciona novas capacidades, apenas decide "como essa árvore é" — web, headless ou sua própria combinação personalizada (abordado na próxima seção).

Cordis: O Framework que Move Tudo

O dsh roda sobre um framework de plugins chamado Cordis (o README oficial diz explicitamente "powered by Cordis"). O Cordis tem apenas três convenções centrais:

  1. Plugins injetam serviços em um contexto compartilhado. Quer adicionar uma capacidade? Escreva um plugin e registre-o.
  2. Plugins transmitem eventos tipados. Outros escutam esses eventos para se coordenar, sem precisar importá-los diretamente.
  3. O registro de plugins é um efeito reversível — quando um plugin é descarregado, o que ele registrou é revertido automaticamente, sem deixar bagunça.

A parte mais importante é a última — é por isso que "tudo é um plugin" pode se sustentar: o dsh não tem núcleo privilegiado para modificar. O adaptador de modelo é um plugin, o registro de ferramentas é um plugin, o log de sessão é um plugin, até mesmo o loop principal do agent é um plugin. O jeito de estender o dsh é "pendurar um plugin ao lado", não "ir editar algum arquivo núcleo". Isso torna seu custo de mudança extremamente baixo: se você não consegue mudar, troque; se não consegue trocar, adicione um.

Em que isso difere dos demais? Coloque lado a lado os dois Agents de CLI mais usados, a diferença salta aos olhos:

ComparaçãoAbordagem de extensãoVocê consegue tocar no "esqueleto"?
Claude CodeFerramentas podem ser estendidas (MCP, skills), mas modelo e loop principal não podem ser trocadosSemiaberto: ferramentas podem ser adicionadas, mas adaptação de modelo, sessão, loop do agent estão soldados, e o modelo está preso ao seu próprio ecossistema
CodexFerramentas podem ser estendidas, mas modelo e loop principal não podem ser trocadosSemiaberto: ferramentas podem ser adicionadas, mas adaptação de modelo, sessão, loop do agent estão soldados, e o modelo está preso ao seu próprio ecossistema
dshPendure um plugin ao lado, altere a configuração para trocarTotalmente aberto: até mesmo log de sessão, loop do agent, adaptador de modelo são plugins, sem núcleo privilegiado

Resumo em uma frase: o "esqueleto" do Claude Code e do Codex está soldado; o "esqueleto" do dsh também é um plugin. É por isso que você pode plugar qualquer modelo (a comparação com o Codex no CH 06 é o exemplo), e pode trocar a sessão por sua própria implementação — o esqueleto em si é substituível, o único limite é se você quer mudar.

Veja uma Árvore Real com --dump-config

Dizer a teoria dez vezes não vale uma olhada real. No CH 05 você rodou dsh --profile headless --dump-config uma vez; o que é impresso é uma longa árvore de plugins @deepseek-ai/dsh-*llm (modelo), session (sessão), credentials (chaves), session-persistence-jsonl (persistência de sessão)... esses plugins cada um lida com sua parte, empilhados juntos em um dsh executável.

A equipe oficial lista claramente os plugins centrais; cada um corresponde a um "grande galho" em uma árvore:

Plugin centralO que ele trata
core/sessionLog de sessão append-only (tudo que o modelo vê é registrado)
core/system-promptComo o system prompt é montado, como os schemas de ferramentas são empacotados
core/toolsRegistro de ferramentas e pipeline de execução controlada
core/agentInterface do Agent e registro ao vivo
core/agent-loopDriver padrão do loop "request → chamada de ferramenta"
llm/llmVocabulário de mensagens e streaming + costura do adaptador de modelo

Observe "costura" na última linha — esse é o próximo conceito-chave.

Profile e Bundle: Como os Plugins se Combinam em um "Modo"

Plugin = um prato (arroz com ovo frito, sopa da casa, acompanhamento); bundle = um conjunto de refeição (arroz, prato principal, talheres pré-empacotados); profile = o cardápio (lista quais pratos, em que ordem); a wok na cozinha dos fundos é o kernel Cordis da próxima seção.

O que uma árvore é composta é decidido pelo Profile — pense nele como o cardápio na sua mão:

  • Profile é uma combinação nomeada, armazenada no diretório do Harness. Ele lista quais Bundles empilhar, quais plugins extras instalar e também mantém seu próprio cordis.patch.yml. O cardápio não cozinha pratos, ele apenas diz "o que tem nessa refeição": a fábrica oficial entrega os cards web e headless prontos para usar; os "quatro modos de execução" do CH 02 são quatro presets diferentes de combinação de plugins por baixo, equivalentes a mais alguns cards.
  • Bundle é um formato de distribuição para "um grupo de plugins + a configuração que eles montam", equivalente a um conjunto de refeição pré-empacotado: dsh-base é a primeira camada para todo profile (fundação: modelo, ferramentas, persistência, sandbox, aprovação, configurações, chaves, telemetria); web-app adiciona "ambiente de comer no local" ao conjunto base (interface de navegador); headless adiciona "pra viagem" (linha de comando one-shot, sem servidor).

Primeiro um ponto fácil de confundir: Profile não é um plugin. Um plugin é "algo que faz trabalho" (um prato); Profile é apenas "o cardápio" (apenas faz pedidos, não cozinha). Escolher "Modo mínimo" não instala nenhum plugin novo — ele apenas troca a árvore de plugins por uma combinação mais minimalista — cardápio diferente, mesma cozinha.

O empilhamento de plugins tem uma ordem estrita (oficial), como a cozinha preparando pelo cardápio, e anotações posteriores podem sobrescrever as anteriores:

Cada bundle (na ordem listada no profile)   ← conjunto de refeição primeiro
→ cordis.patch.yml próprio do profile        ← anotações no cardápio
→ nível de diretório do Harness              ← requisitos padrão do chefe
→ overlay --patch da linha de comando        ← anotações extras temporárias, o último vence

Cada camada pode sobrescrever a anterior — os patches localizam uma linha pelo id, substituem sua configuração inteira ou inserem uma nova linha. Então o --patch do CH 05 não é "um furo a mais", é modificar abertamente essa árvore: qualquer linha impressa por --dump-config pode ser substituída pelo seu próprio patch.

Construir seu próprio Profile não significa escrever código do zero — a essência é "copiar um cardápio e modificá-lo":

  • Quer menos que web? → Copie a configuração web e remova o que não quer ("comer no local, mas sem sopa");
  • Quer mais que headless (por exemplo, montar por padrão um plugin de ferramenta que você escreveu)? → Copie headless e adicione uma linha à sua lista de bundles ("pra viagem, mais um acompanhamento que você trouxe");
  • O mais leve é não mudar o cardápio, apenas adicionar anotações: para instalar um plugin em um profile existente, use dsh plugin --profile <nome> add <pacote> ("adicione um acompanhamento ao cardápio existente"), para sobreposição temporária, use --patch ("nesta refeição: troque a sopa por Sprite") — já vimos ambos no CH 05.

Enfileire o processo de carregamento em uma linha do tempo única, e tudo antes se encaixa:

  1. Na inicialização, o dsh primeiro lê o Profile que você escolheu — é um manifesto de carregamento, dizendo "em que ordem empilhar quais camadas";
  2. Carregue camada por camada na ordem do manifesto: primeiro camada 1 base (dsh-base), depois camada 2 adição (web-app / headless / seus plugins), finalmente camada 3 sobreposição (cordis.patch.yml + --patch) — quanto mais tarde carregar, mais pode sobrescrever o anterior;
  3. Todas as camadas se instalam no mesmo kernel Cordis, onde injetam serviços e se comunicam.

Uma frase de fechamento: Profile = ordem dos pedidos na inicialização; árvore de plugins = pratos instalados nessa ordem; Cordis = a wok usada para instalar os pratos.

Eventos e Costuras de Capacidade: Como os Plugins Conversam

Plugins não se importam uns com os outros; eles se coordenam por meio de duas coisas:

Eventos são pontos de extensão, em três domínios:

  • Eventos de sessão: fatos persistentes, anexados ao log e transmitidos, sobrevivendo a reinicializações (ex.: "esta mensagem foi enviada").
  • Eventos de Agent (agent/*): carregam o Agent ao vivo, usados para observar ou interceptar trabalho em execução (ex.: "interceptar antes desta step começar").
  • Eventos de Capability (fs/*, tools/*, telemetry/*): anexam políticas e adaptadores a uma costura sem mudar o loop principal.

Costura de capacidade é uma capacidade substituível; ela tem três papéis fixos:

  • Service Definition: declara como a interface se parece;
  • Service Provider: de fato a implementa;
  • Consumer: a usa (geralmente ferramentas que o modelo chama).

Por que "trocar um Provider, troca o produto"? Porque os providers de sistema de arquivos e subprocesso compartilham o mesmo "mundo de execução" — aponte-os para um sandbox remoto, e Bash, PTY, LSP se movem junto com eles, sem precisar escrever um conjunto separado para cada capacidade. O mesmo vale para o adaptador de modelo: qualquer adaptador registrado em ctx.llm é o modelo que todo o produto usa; nada mais precisa mudar.

O Modelo Mental em Uma Frase

Se você só pode levar três frases, lembre-se destas três (junto com o restaurante pequeno acima):

  1. O dsh não tem núcleo — cada parte é um plugin, incluindo ele mesmo; adicione um prato ao lado, tire um e ele se reverte automaticamente.
  2. O Profile decide como a árvore é — web / headless / custom são todos "cards" diferentes da mesma árvore; não funciona, apenas pede.
  3. Eventos e costuras são a interface de colaboração dos plugins — monte e funciona, tire e se reverte, então troque ou adicione à vontade; troque um Provider, troque o produto.

O que você aprendeu neste capítulo

  • [ ] Afirmar que "um dsh em execução = uma árvore de plugins" e que ela é composta por camadas ordenadas
  • [ ] Afirmar as três convenções centrais do Cordis (injeção de serviço / eventos / efeitos reversíveis), e por que não há núcleo privilegiado
  • [ ] Reconhecer plugins centrais (llm / session / credentials / tools, etc.) na saída de --dump-config
  • [ ] Explicar a relação entre Profile e Bundle, e a ordem de camadas do empilhamento de plugins
  • [ ] Usar a analogia do "pedido" para explicar a relação entre plugin / bundle / profile, e saber que construir seu próprio profile é "copiar um cardápio e modificar", enquanto plugin add / --patch é a modificação mais leve
  • [ ] Nomear os três papéis de uma costura de capacidade (Definition / Provider / Consumer), e explicar por que "trocar um Provider, troca o produto"

Open Source · MIT · Community Driven