Skip to content

CH 20 · defineTool: Crie uma Ferramenta para o Agent

Número de palavras~2.430 palavrasTempo~20 minPré-requisitosCH 19 (Três Formas de Plugin)NívelReproduzível

Objetivo do Capítulo

No CH 18 e 19, os plugins que escrevemos apenas registraram em log — era apenas para verificar "o plugin está carregado". Este capítulo escreve a coisa verdadeiramente valiosa em plugins: ferramentas.

Ferramentas são as "mãos" do Agent: o modelo diz algo, o código que você escreve é chamado, faz trabalho real, e envia o resultado de volta ao modelo. Nos capítulos anteriores você estava usando ferramentas integradas do dsh (ler arquivos, executar comandos, pesquisar); este capítulo vamos criar uma nós mesmos, deixar o modelo realmente entrar e chamá-la.

Ferramentas São a Alma dos Plugins

Lembre-se do que você usa todos os dias: o Agent do dsh pode ler arquivos, escrever arquivos, executar comandos — essas são ferramentas (capacidades registradas em ctx.tools). O modelo em si só pode "falar"; ferramentas o deixam "agir".

O esqueleto mínimo de um plugin de ferramenta:

js
import { defineTool } from '@deepseek-ai/dsh-tools'

export const name = 'greet-tool'
export const inject = ['tools']

export function apply(ctx) {
  ctx.tools.register(defineTool({
    // As quatro partes de uma ferramenta, detalhadas uma por uma abaixo
  }))
}

inject: ['tools'] declara "eu quero usar o registro de ferramentas", aprendido no CH 19; ctx.tools.register(...) monta uma ferramenta no registro.

As Quatro Partes de defineTool

defineTool recebe um objeto que diz ao dsh "como esta ferramenta se chama, quando deve ser usada, quais parâmetros precisa, como faz seu trabalho". Uma ferramenta = um "JD de contratação para o Agent":

CampoSignificadoUma analogia
nameO nome da ferramenta, o modelo usa para chamarCargo
descriptionDiga ao modelo "o que esta ferramenta faz, quando deve ser usada"Responsabilidades do trabalho
parametersDeclare quais parâmetros são obrigatórios, quais são opcionaisMateriais a submeter
executeA função que realmente faz o trabalhoTrabalho após contratação

Veja uma ferramenta mínima completa (igual ao tutorial oficial, levemente traduzido):

js
import { defineTool } from '@deepseek-ai/dsh-tools'

export const name = 'greet-tool'
export const inject = ['tools']

export function apply(ctx) {
  ctx.tools.register(defineTool({
    name: 'greet',
    description: 'Greet by name',
    parameters: {
      name: { type: 'string', required: true, description: 'Name of the person to greet' },
    },
    output: {
      schema: { type: 'string' },
      render: (_args, value) => [{ type: 'text', text: value }],
    },
    async execute(args) {
      return `Hello, ${args.name}!`
    },
  }))
}

Quatro pontos-chave:

  • parameters é escrito em JSON Schema: type: 'string' declara o tipo do parâmetro, required: true declara que é obrigatório. O framework valida automaticamente os parâmetros que o modelo passa; não conformes dão erro — você não precisa verificar tipos manualmente em execute.
  • execute(args) é a função que realmente faz o trabalho: args foi validado, apenas use com confiança. Ela retorna um "valor canônico" (uma string aqui).
  • output.schema declara a forma do valor de retorno, output.render converte o valor de retorno em conteúdo que o modelo pode ver (um bloco de texto aqui). O valor de retorno primeiro existe em forma canônica, a camada de renderização é responsável por "traduzir" para o modelo.
  • description é extremamente importante: o modelo o usa para julgar "devo usar esta ferramenta agora". Escreva claramente, escreva especificamente, e o modelo vai saber quando chamá-la.

Prática: Escreva uma Ferramenta greet, Faça o Modelo Realmente Chamá-la

Em um workspace onde você quer colocar plugins, crie um diretório:

powershell
New-Item -ItemType Directory -Path "tool-demo\src" -Force

Passo 1: Instale Dependências

defineTool vem de @deepseek-ai/dsh-tools, instale no diretório do plugin primeiro:

powershell
cd "E:\software-workspace\DeepSeek harness demo\tool-demo"   # substitua pelo seu diretório
npm init -y
npm install @deepseek-ai/dsh-tools

Lembre-se de adicionar uma linha "type": "module" em package.json (CH 19 mencionou, sem isso haverá um monte de avisos).

Passo 2: Escreva a Ferramenta

Crie tool-demo\src\greet.js, com a mesma ferramenta greet acima. Adicionei uma linha de log em execute para confirmar facilmente no terminal que foi realmente chamada:

js
import { defineTool } from '@deepseek-ai/dsh-tools'

export const name = 'greet-tool'
export const inject = ['tools']

export function apply(ctx) {
  ctx.tools.register(defineTool({
    name: 'greet',
    description: 'Greet by name',
    parameters: {
      name: { type: 'string', required: true, description: 'Name of the person to greet' },
    },
    output: {
      schema: { type: 'string' },
      render: (_args, value) => [{ type: 'text', text: value }],
    },
    async execute(args) {
      console.log('[greet] called with', args.name)
      return `Hello, ${args.name}!`
    },
  }))
}

Passo 3: Declare e Verifique

Crie tool-demo\cordis.yml (substitua o caminho pelo seu, lembre-se de %20 para espaços):

yaml
- insert:
    - id: greet
      name: 'file:///E:/seu-workspace/tool-demo/src/greet.js'

Use o headless para executar uma vez, deixe o modelo realmente chamá-la:

powershell
cd seu-diretório-de-workspace
dsh --profile headless --patch "./tool-demo/cordis.yml" "You must call the greet tool, say hi to Ada, then tell me verbatim what the tool returned"

Na saída do terminal você verá:

text
[greet] called with Ada

Esta é a evidência de que execute foi realmente chamado pelo modelo — seu código foi realmente executado pelo modelo entrando. E a resposta do modelo conterá o Hello, Ada! retornado pela ferramenta.

O [greet] called with Ada amarelo no terminal é o log de execute sendo realmente chamado pelo modelo; o Hello, Ada! abaixo é o resultado que a ferramenta retorna ao modelo.

Deixe o dsh Fazer: Um Prompt Resolve

O fluxo de escrita de ferramenta é exatamente o mesmo de escrever um plugin, o dsh pode fazer sozinho, e ele conhece os campos de defineTool e como o schema deve ser escrito melhor que você.

Envie este prompt diretamente na caixa de entrada da Web UI:

text
In my current workspace, help me write a tool plugin: use defineTool to define the simplest tool (with one required parameter, returning some text in execute). First read the dsh official docs to understand defineTool's fields and parameter validation rules, implement per the official spec, then run a headless to have the model actually call it, and finally tell me the result and where the files are.

Ele vai procurar a documentação sozinho, instalar dependências, escrever a ferramenta, verificar se o modelo realmente a chamou. Você apenas verifica.

Este é o resultado de eu realmente executar este prompt: ele leu a documentação sozinho, construiu as três peças do plugin (package.json declarando bundle, entrada defineTool index.js, um insert de uma linha cordis.patch.yml), e até descobriu que caminhos do Windows com espaços quebrariam o parsing do comando de instalação, e proativamente moveu o plugin para um caminho sem espaços antes de instalar — ele caiu na armadilha, e se contornou sozinho.

Após executar, ele também organizou as armadilhas em uma lista: requisitos de forma de exportação do plugin, inject deve ser explicitamente declarado, pacotes de workspace precisam de artefatos de build para rodar, armadilha de espaços no caminho.

Armadilhas Comuns

ProblemaO que está acontecendoComo lidar
Reporta Cannot find package '@deepseek-ai/dsh-tools'Diretório do plugin não instalou dependênciasnpm install @deepseek-ai/dsh-tools
Modelo nunca chama sua ferramentadescription é pouco claro, modelo não sabe quando usarTorne a description específica: "Use when user requests X"
Parâmetros não passados corretamenteschema e compreensão do modelo não combinamEscreva uma description clara para cada parâmetro em parameters
Ferramenta reportou um erro de parâmetroModelo passou parâmetros ilegaisMarque itens obrigatórios com required: true, escreva o tipo corretamente
Modelo chamou mas resultado está erradoLógica em execute está erradaAdicione console.log em execute para debug, verifique os logs

O que você aprendeu neste capítulo

Você passa se conseguir completar os itens abaixo:

  • [ ] Indique as quatro partes do defineTool: name / description / parameters / execute
  • [ ] Saiba que parameters é JSON Schema, o framework valida automaticamente os parâmetros
  • [ ] Escreva um plugin de ferramenta e registre-o em ctx.tools
  • [ ] Use o headless para verificar se o modelo realmente chamou sua ferramenta
  • [ ] Saiba que description decide quando o modelo usa sua ferramenta

Open Source · MIT · Community Driven