A DeepSeek lançou o V4.1 Flash a 10 de setembro de 2026, trazendo um corte de preço em relação à versão anterior e um cache de contexto que reduz drasticamente o custo de agentes que leem repositórios inteiros. Para quem programa em Node.js ou Python e quer um assistente que leia código, proponha correções e corra testes sem disparar a fatura da API, este é o momento certo para construir um agente a sério. Este tutorial percorre 12 passos práticos: desde criar a chave API até testar o agente num repositório real, com código funcional em cada etapa.

Vais construir um agente de código com tool-calling, memória persistente e aproveitamento do cache de contexto da DeepSeek, que segundo o rastreador capitalandcompute.net cobra apenas 0,006 dólares por milhão de tokens em cache hit durante o horário de pico, uma fração do preço normal de entrada. No final tens um ficheiro único, pronto a correr, que podes adaptar ao teu próprio projeto.

Este guia não assume conhecimento prévio de agentes de IA, só familiaridade básica com JavaScript e com o terminal. Cada passo inclui código para copiar e colar, seguido de uma explicação do porquê, não só do como. Se preferires Python, a lógica mantém-se igual e só muda a sintaxe das chamadas HTTP e da leitura de ficheiros, uma troca simples de adaptar depois de entenderes a estrutura em JavaScript.

O Que é o DeepSeek V4.1 Flash e Porque Construir um Agente de Código

O DeepSeek V4.1 Flash é a versão mais recente da família Flash da DeepSeek, lançada a 10 de setembro de 2026 segundo o tracker de lançamentos local-ai-zone.github.io. A ficha técnica reportada por esse e outros trackers do setor aponta para 552 mil milhões de parâmetros, uma janela de contexto de até 1 milhão de tokens e suporte nativo a visão. Estes números não constam ainda de uma página oficial da DeepSeek com todos os detalhes reunidos, por isso trata-os como dados de mercado e confirma sempre o estado atual em api-docs.deepseek.com antes de dimensionar um projeto em produção.

Um agente de código difere de um simples chat porque executa ações: lê ficheiros, corre comandos, escreve patches e volta a testar o resultado. Isso implica trocar muito texto com o modelo a cada iteração, o que em janelas de contexto grandes encarece rapidamente a fatura. É aqui que o cache de contexto da DeepSeek ajuda: partes repetidas do prompt (instruções do sistema, histórico da sessão, ficheiros já enviados) passam a custar uma fração do preço normal quando o modelo os reconhece em cache. Construir o agente com essa reutilização em mente, em vez de a tratar como um detalhe de otimização posterior, é a diferença entre uma sessão de uma hora custar cêntimos ou vários dólares.

Se já experimentaste o DeepSeek Harness da própria empresa, este tutorial segue uma lógica parecida mas construída do zero, sem depender da ferramenta oficial, o que te dá controlo total sobre as ferramentas disponíveis e sobre como o contexto é gerido entre chamadas.

Vale a pena explicar porque o cache de contexto muda tanto as contas. Quando envias um pedido à API, o servidor processa o prompt token a token antes de gerar a resposta. Se parte desse prompt já tiver sido vista numa chamada anterior com exatamente o mesmo prefixo, a DeepSeek guarda esse processamento numa espécie de memória de curto prazo e reaproveita-o, cobrando uma fração do preço normal pelos tokens reaproveitados. Isto funciona bem para agentes porque, ao contrário de um chat normal onde cada pergunta é nova, um agente repete o mesmo histórico crescente a cada iteração, só acrescentando uma mensagem pequena no fim. Na prática, depois das primeiras duas ou três chamadas de uma sessão, a maior parte do prompt já devia estar em cache, e só a parte final e nova é que custa o preço completo.

Pré-Requisitos: Versões e Ferramentas Necessárias

Antes de avançar, confirma que tens o seguinte instalado e configurado:

  • Node.js 20 LTS ou superior (testado com Node.js 22)
  • npm 10 ou superior
  • Uma conta na plataforma DeepSeek com cartão ou crédito pré-pago associado
  • Um editor de código (VS Code, Cursor ou outro à escolha)
  • Git instalado localmente, para testares o agente num repositório real
  • Pacote npm openai na versão 4.x (a DeepSeek usa um formato de API compatível com OpenAI)
  • Acesso de terminal com permissões para instalar pacotes e correr scripts Node.js

Não precisas de GPU local nem de infraestrutura própria: todo o processamento corre nos servidores da DeepSeek através da API. O único requisito de hardware é uma ligação estável à internet e memória suficiente para o Node.js correr o teu script sem problemas, o que em qualquer portátil atual não é limitação.

Passo 1: Criar a Conta e Gerar a Chave API

Regista-te na plataforma da DeepSeek e gera uma chave API na secção de definições da conta. Guarda essa chave num gestor de palavras-passe ou num cofre de segredos, nunca a cole diretamente no código. Testa a chave com um pedido simples via curl antes de escrever qualquer linha de JavaScript:

curl https://api.deepseek.com/chat/completions \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer A_TUA_CHAVE_API" \
  -d '{
    "model": "deepseek-chat",
    "messages": [{"role": "user", "content": "Diz ola em uma frase curta"}],
    "stream": false
  }'

Se receberes uma resposta JSON com um campo choices preenchido, a chave está ativa e podes avançar. Se receberes um erro 401, confirma que a chave foi copiada sem espaços extra e que a conta tem saldo disponível.

Passo 2: Preparar o Ambiente de Desenvolvimento

Cria uma pasta nova para o projeto e inicializa o Node.js:

mkdir deepseek-agente && cd deepseek-agente
npm init -y
npm install openai dotenv
mkdir ferramentas

Cria um ficheiro .env na raiz do projeto com a tua chave, e adiciona-o imediatamente ao .gitignore para evitar que acabe num commit público:

echo "DEEPSEEK_API_KEY=a_tua_chave_aqui" > .env
echo ".env" >> .gitignore
echo "node_modules/" >> .gitignore

Esta organização em pastas, com as ferramentas separadas da lógica principal do agente, facilita adicionar novas capacidades mais tarde sem reescrever o ciclo central.

Passo 3: Fazer a Primeira Chamada à API DeepSeek

Cria um ficheiro teste.js e usa o SDK da OpenAI apontado para o endpoint da DeepSeek, já que a API segue o mesmo formato:

import OpenAI from "openai";
import "dotenv/config";

const cliente = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: "https://api.deepseek.com",
});

async function testar() {
  const resposta = await cliente.chat.completions.create({
    model: "deepseek-chat",
    messages: [
      { role: "system", content: "Es um assistente de programacao direto e objetivo." },
      { role: "user", content: "Explica em duas frases o que faz um ciclo agente." },
    ],
  });
  console.log(resposta.choices[0].message.content);
  console.log(resposta.usage);
}

testar();

Corre com node --experimental-modules teste.js ou adiciona "type": "module" ao package.json para usar import/export sem flags extra. A consola deve devolver o texto da resposta seguido de um objeto de uso de tokens, algo parecido com isto:

{
  prompt_tokens: 34,
  completion_tokens: 52,
  total_tokens: 86,
  prompt_cache_hit_tokens: 0,
  prompt_cache_miss_tokens: 34
}

Repara nos dois últimos campos: é aqui que vês, chamada a chamada, quantos tokens do teu prompt foram servidos a partir de cache e quantos tiveram de ser processados de novo. Vais usar este objeto várias vezes ao longo do tutorial para medir custos reais.

Passo 4: Entender os Preços e o Cache de Contexto

Antes de construir o agente, vale a pena saber onde o dinheiro se vai. A tabela seguinte resume os valores reportados pelo tracker capitalandcompute.net para o DeepSeek V4.1 Flash, comparados com a versão anterior V4 Flash. Confirma sempre os valores atuais na documentação oficial antes de assumir um orçamento fixo, porque os preços da DeepSeek já mudaram várias vezes ao longo de 2026.

MétricaDeepSeek V4 FlashDeepSeek V4.1 Flash
Entrada (pico), por 1M tokens$0,44$0,30
Saída (pico), por 1M tokens$1,32$1,20
Cache hit de entrada (pico), por 1M tokens$0,014$0,006
Entrada fora de pico, por 1M tokensn/d$0,15
Saída fora de pico, por 1M tokensn/d$0,60
Janela de contexto máxima128K tokens*1M tokens*

*Valores de janela de contexto reportados por trackers de terceiros, não confirmados em página oficial unificada até à data desta publicação.

O detalhe que mais interessa a um agente é a diferença entre cache hit e cache miss. Um pedido de entrada normal fora de cache custa $0,15 por milhão de tokens fora de pico, mas o mesmo texto, se já estiver em cache do lado da DeepSeek, custa $0,006 por milhão em pico, ou seja, uma fração muito menor. Num agente que reenvia o mesmo ficheiro de 2000 linhas a cada iteração do ciclo, a diferença entre aproveitar o cache ou não aproveitar define se a sessão custa cêntimos ou vários dólares ao fim de uma hora de trabalho.

Passo 5: Desenhar a Arquitetura do Agente

Um agente de código precisa de quatro peças: um histórico de mensagens, uma lista de ferramentas que o modelo pode invocar, um ciclo que processa as chamadas de ferramenta, e um limite de segurança que impede loops infinitos. Cria o ficheiro agente.js com a estrutura base:

import OpenAI from "openai";
import "dotenv/config";
import { ferramentasDisponiveis, executarFerramenta } from "./ferramentas/index.js";

const cliente = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: "https://api.deepseek.com",
});

const SYSTEM_PROMPT = `Es um agente de programacao.
Usa as ferramentas disponiveis para ler ficheiros, propor alteracoes e correr testes.
Confirma sempre o resultado de um teste antes de declarar uma tarefa concluida.
Responde em portugues de Portugal.`;

class AgenteCodigo {
  constructor(limiteIteracoes = 15) {
    this.historico = [{ role: "system", content: SYSTEM_PROMPT }];
    this.limiteIteracoes = limiteIteracoes;
    this.custoTotalEstimado = 0;
  }
}

export default AgenteCodigo;

Esta classe vai crescer nos próximos passos, mas já define o essencial: um histórico que persiste entre chamadas (para o cache funcionar), um limite de iterações (para evitar custos descontrolados) e um contador de custo estimado. Nota que o histórico fica guardado na instância e não é reconstruído a cada chamada: é essa persistência, combinada com a ordem fixa das mensagens iniciais, que permite à DeepSeek reconhecer o prefixo repetido e aplicar o preço de cache. Se recriasses o array de mensagens do zero em cada pedido, mesmo com o mesmo conteúdo, corres o risco de pequenas diferenças de formatação (espaços, ordem de chaves num objeto serializado) partirem o prefixo e anularem o benefício do cache.

Passo 6: Implementar as Ferramentas (Tool Calling)

Cria ferramentas/index.js com três ferramentas básicas: ler um ficheiro, escrever um ficheiro e correr um comando de terminal. O formato segue o padrão de function calling compatível com OpenAI, que a DeepSeek também suporta:

import { readFileSync, writeFileSync } from "fs";
import { execSync } from "child_process";

export const ferramentasDisponiveis = [
  {
    type: "function",
    function: {
      name: "ler_ficheiro",
      description: "Le o conteudo de um ficheiro do projeto",
      parameters: {
        type: "object",
        properties: { caminho: { type: "string" } },
        required: ["caminho"],
      },
    },
  },
  {
    type: "function",
    function: {
      name: "escrever_ficheiro",
      description: "Escreve ou substitui o conteudo de um ficheiro",
      parameters: {
        type: "object",
        properties: {
          caminho: { type: "string" },
          conteudo: { type: "string" },
        },
        required: ["caminho", "conteudo"],
      },
    },
  },
  {
    type: "function",
    function: {
      name: "correr_comando",
      description: "Executa um comando de terminal e devolve o resultado",
      parameters: {
        type: "object",
        properties: { comando: { type: "string" } },
        required: ["comando"],
      },
    },
  },
];

export function executarFerramenta(nome, args) {
  if (nome === "ler_ficheiro") {
    return readFileSync(args.caminho, "utf-8");
  }
  if (nome === "escrever_ficheiro") {
    writeFileSync(args.caminho, args.conteudo, "utf-8");
    return "Ficheiro escrito com sucesso";
  }
  if (nome === "correr_comando") {
    try {
      return execSync(args.comando, { encoding: "utf-8", timeout: 20000 });
    } catch (erro) {
      return `Erro ao correr comando: ${erro.message}`;
    }
  }
  return "Ferramenta desconhecida";
}

Nota o timeout de 20 segundos no correr_comando: sem ele, um teste que fique pendurado bloqueia o agente indefinidamente e continua a gerar custos enquanto esperas.

Passo 7: Construir o Ciclo Agente (Agentic Loop)

Agora junta as peças. Adiciona o método correr à classe AgenteCodigo: ele envia o histórico ao modelo, verifica se a resposta pede uma ferramenta, executa-a, acrescenta o resultado ao histórico e repete até o modelo responder sem pedir mais ferramentas:

async correr(pedidoUtilizador) {
  this.historico.push({ role: "user", content: pedidoUtilizador });

  for (let i = 0; i < this.limiteIteracoes; i++) {
    const resposta = await cliente.chat.completions.create({
      model: "deepseek-chat",
      messages: this.historico,
      tools: ferramentasDisponiveis,
    });

    const mensagem = resposta.choices[0].message;
    this.registarCusto(resposta.usage);
    this.historico.push(mensagem);

    if (!mensagem.tool_calls) {
      return mensagem.content;
    }

    for (const chamada of mensagem.tool_calls) {
      const args = JSON.parse(chamada.function.arguments);
      const resultado = executarFerramenta(chamada.function.name, args);
      this.historico.push({
        role: "tool",
        tool_call_id: chamada.id,
        content: String(resultado).slice(0, 8000),
      });
    }
  }
  return "Limite de iteracoes atingido sem conclusao.";
}

registarCusto(usage) {
  const custoEntradaCacheHit = (usage.prompt_cache_hit_tokens / 1_000_000) * 0.006;
  const custoEntradaCacheMiss = (usage.prompt_cache_miss_tokens / 1_000_000) * 0.15;
  const custoSaida = (usage.completion_tokens / 1_000_000) * 0.60;
  this.custoTotalEstimado += custoEntradaCacheHit + custoEntradaCacheMiss + custoSaida;
}

O truncamento do resultado da ferramenta a 8000 carateres (slice(0, 8000)) evita que a saída de um comando muito grande, como um log de testes extenso, exploda o contexto numa única iteração. Ajusta este limite conforme o tipo de ferramenta: para leitura de ficheiros pequenos pode ser maior, para logs de build geralmente convém ser mais conservador.

Passo 8: Aproveitar o Contexto de 1 Milhão de Tokens

Ter 1 milhão de tokens de contexto disponível não significa que deves preencher tudo de uma vez. Um repositório inteiro cabe facilmente nesse limite, mas cada token extra no prompt custa dinheiro e tempo de resposta, mesmo com cache. A estratégia prática é carregar apenas os ficheiros relevantes à tarefa, e deixar que o próprio agente peça mais ficheiros através da ferramenta ler_ficheiro quando precisar.

Para tarefas que exigem mesmo contexto grande, como analisar um módulo inteiro antes de o refatorizar, adiciona uma função auxiliar que lê vários ficheiros de uma pasta e os junta num único bloco com separadores claros:

import { readdirSync, readFileSync, statSync } from "fs";
import { join } from "path";

export function carregarPasta(caminhoPasta, extensoes = [".js", ".ts"]) {
  let blocoContexto = "";
  for (const ficheiro of readdirSync(caminhoPasta)) {
    const caminhoCompleto = join(caminhoPasta, ficheiro);
    if (statSync(caminhoCompleto).isFile() && extensoes.some(e => ficheiro.endsWith(e))) {
      blocoContexto += `\n--- ${caminhoCompleto} ---\n${readFileSync(caminhoCompleto, "utf-8")}\n`;
    }
  }
  return blocoContexto;
}

Envia este bloco como a primeira mensagem do utilizador, sempre na mesma posição e com o mesmo texto fixo antes dele. Isso maximiza a hipótese de cache hit nas chamadas seguintes, porque a DeepSeek reconhece prefixos de prompt repetidos e só cobra o preço completo pela parte nova.

Passo 9: Otimizar Custos com Cache Hits e Monitorização

Já registas o custo estimado a cada chamada no passo 7, mas vale a pena expor essa informação de forma visível durante o desenvolvimento. Adiciona um registo simples no fim de cada correr:

console.log(`Custo acumulado nesta sessao: $${this.custoTotalEstimado.toFixed(4)}`);

Numa sessão típica de debug com cinco a oito iterações sobre o mesmo ficheiro, deves ver a proporção de prompt_cache_hit_tokens subir a cada chamada, porque o histórico anterior já está em cache. Se essa proporção não subir, o problema está normalmente na forma como o histórico é montado: cada pequena alteração no início da lista de mensagens invalida o cache de tudo o que vem depois, por isso mantém o system prompt e o bloco de contexto fixos e só acrescenta ao fim.

Passo 10: Testar o Agente num Repositório Real

Cria um ficheiro correr.js que instancia o agente e lhe dá uma tarefa concreta num repositório Git local de teste:

import AgenteCodigo from "./agente.js";

const agente = new AgenteCodigo(12);
const resultado = await agente.correr(
  "Le o ficheiro src/soma.js, encontra o bug que faz a funcao devolver NaN com strings numericas, corrige e corre 'npm test' para confirmar."
);

console.log("Resultado final:", resultado);
console.log("Custo total: $", agente.custoTotalEstimado.toFixed(4));

Numa execução típica contra um bug pequeno, espera ver algo como quatro a seis iterações: o agente lê o ficheiro, propõe uma correção, escreve-a, corre os testes, e confirma o resultado. Um exemplo de saída real:

Custo acumulado nesta sessao: $0.0021
Custo acumulado nesta sessao: $0.0034
Custo acumulado nesta sessao: $0.0041
Custo acumulado nesta sessao: $0.0046
Resultado final: Corrigi a funcao soma para converter os argumentos com Number() antes de somar. Os testes passaram (3/3).
Custo total: $ 0.0046

Repara como o incremento de custo diminui a cada chamada: é o cache de contexto a funcionar, porque o grosso do histórico já estava guardado do lado da DeepSeek.

Passo 11: Adicionar Limites de Segurança, Retries e Rate Limiting

Um agente que corre comandos de terminal sem supervisão é um risco de segurança, não apenas um detalhe técnico. Antes de dares ao agente acesso a um repositório com dados reais, adiciona três proteções: uma lista de comandos proibidos, um limite de custo máximo por sessão e lógica de retry para falhas temporárias da API.

const COMANDOS_PROIBIDOS = ["rm -rf", "git push", "curl", "sudo", ":(){ :|:& };:"];

function comandoSeguro(comando) {
  return !COMANDOS_PROIBIDOS.some(proibido => comando.includes(proibido));
}

async function chamarComRetry(cliente, parametros, tentativas = 3) {
  for (let i = 0; i < tentativas; i++) {
    try {
      return await cliente.chat.completions.create(parametros);
    } catch (erro) {
      if (erro.status === 429 && i < tentativas - 1) {
        await new Promise(r => setTimeout(r, 2 ** i * 1000));
        continue;
      }
      throw erro;
    }
  }
}

Integra comandoSeguro na função executarFerramenta do passo 6, antes de chamar execSync, e substitui a chamada direta à API no ciclo do passo 7 por chamarComRetry. O backoff exponencial (1s, 2s, 4s) evita martelar a API quando recebes um erro 429 de limite de pedidos, que é comum em sessões com muitas iterações seguidas.

Passo 12: Preparar o Agente para Produção

Para correr este agente fora da tua máquina de desenvolvimento, trata os seguintes pontos como obrigatórios: regista as chamadas de ferramenta num ficheiro de log para auditoria, define um limite rígido de custo por sessão que interrompe o ciclo se for excedido, corre o agente dentro de um contentor isolado (um contentor Docker simples já ajuda bastante) e nunca dês ao agente a mesma chave API usada noutros serviços de produção, para poderes revogar o acesso sem afetar o resto do sistema.

Vale também a pena rever a tua integração com o Model Context Protocol se pretendes ligar este agente a outras ferramentas externas de forma padronizada, em vez de escreveres cada integração à mão como fizemos aqui.

Uma última decisão de produção é saber quando faz sentido construir o teu próprio agente, como fizemos aqui, em vez de usar uma ferramenta já empacotada. Escreveres o teu próprio ciclo compensa quando precisas de controlo fino sobre que ferramentas o agente pode chamar, sobre limites de custo específicos do teu negócio, ou quando queres trocar de modelo sem depender do roadmap de outra empresa. Se o que procuras é apenas um assistente de código genérico sem essas exigências, uma ferramenta já pronta como o DeepSeek Harness poupa-te este trabalho de construção.

Erros Comuns ao Construir Agentes com a API DeepSeek

Estes são os erros que mais frequentemente fazem um agente falhar ou custar muito mais do que devia.

  • Reordenar o histórico entre chamadas. Qualquer alteração no início da lista de mensagens invalida o cache de tudo o que vem a seguir, forçando a DeepSeek a reprocessar o prompt inteiro ao preço de cache miss. Isto acontece com frequência quando se insere uma mensagem de sistema adicional a meio do histórico, em vez de a juntar à mensagem de sistema original.
  • Não limitar o tamanho da saída das ferramentas. Um log de build de 50 mil linhas enviado sem corte pode consumir uma fração enorme do orçamento de tokens numa única iteração, e ainda por cima distrai o modelo com informação irrelevante em vez de o ajudar a decidir o próximo passo.
  • Esquecer o limite de iterações. Sem um teto, um agente preso num raciocínio circular continua a chamar a API indefinidamente até esgotares o saldo. Isto é particularmente comum em tarefas mal definidas, onde o critério de conclusão não é claro para o próprio modelo.
  • Misturar ferramentas de leitura e de escrita sem confirmação. Deixar o agente escrever ficheiros sem validação prévia já causou a mais de um programador a perda de alterações não commitadas. Corre sempre o agente dentro de um repositório Git com tudo guardado antes de lhe dares acesso de escrita.
  • Ignorar o campo prompt_cache_hit_tokens. Sem monitorizar este valor, não há forma de saber se a arquitetura do agente está de facto a aproveitar o cache ou a pagar sempre o preço cheio. Trata este número como métrica de saúde do sistema, não como curiosidade.

Resolução de Problemas: Erros Frequentes e Soluções

ProblemaCausa provávelSolução
Erro 401 UnauthorizedChave API inválida ou mal copiadaGera nova chave na plataforma e confirma que não há espaços extra no .env
Erro 429 Too Many RequestsLimite de pedidos por minuto excedidoImplementa retry com backoff exponencial, como no passo 11
Resposta sempre vazia em tool_callsEsquema das ferramentas mal formatadoValida o JSON do campo parameters contra a especificação de function calling
Cache hit sempre em zeroO histórico muda de ordem ou de conteúdo no início a cada chamadaMantém o system prompt e o bloco de contexto inicial fixos, só acrescenta ao fim
Agente entra em loop sem concluirFalta de critério claro de conclusão na tarefa pedidaPede explicitamente ao modelo que confirme o resultado de um teste antes de terminar
Comando de terminal nunca terminaFalta de timeout na execuçãoDefine um timeout em execSync, como 15 a 20 segundos
Custo muito acima do esperadoFicheiros grandes enviados repetidamente sem cacheReduz o tamanho do bloco de contexto e confirma a taxa de cache hit a cada chamada
Erro de parsing ao ler function.argumentsO modelo devolveu JSON incompleto numa resposta truncadaEnvolve o JSON.parse num try/catch e pede ao modelo para repetir a chamada

Quanto Custa Correr Este Agente Durante um Mês de Uso Diário

Uma pergunta justa antes de integrares isto no teu fluxo de trabalho é quanto vai custar ao fim de um mês. Os números abaixo são uma estimativa com base nos preços reportados para o DeepSeek V4.1 Flash e em três perfis de uso diferentes, não uma garantia, porque o custo real depende do tamanho dos teus ficheiros e do número de iterações que cada tarefa exige.

Perfil de usoSessões por diaCusto estimado por sessãoCusto estimado por mês
Correções pontuais de bugs pequenos3$0,01 a $0,05$1 a $5
Uso diário intensivo em vários ficheiros10$0,05 a $0,20$15 a $60
Refatorização de módulos grandes com contexto de 1M tokens5$0,30 a $1,00$45 a $150

O fator que mais pesa nestas contas não é o número de sessões, é a taxa de cache hit. Um agente bem desenhado, que reaproveita o histórico em vez de o reconstruir, pode ficar perto do limite inferior de cada perfil. Um agente que reenvia o repositório inteiro do zero em cada tarefa, sem aproveitar prefixos repetidos, tende para o limite superior ou mesmo acima dele. Vale a pena correr o agente contra algumas tarefas reais na primeira semana e somar o custoTotalEstimado de cada sessão antes de decidires se o orçamento previsto se confirma na prática.

Dicas Avançadas Para Ir Mais Além

Depois de teres o agente básico a funcionar, três melhorias trazem o maior ganho prático. Primeira: separa o agente em duas fases, uma de planeamento (onde o modelo lista os passos sem executar nada) e outra de execução (onde corre cada passo com confirmação). Isto reduz drasticamente iterações desperdiçadas em tarefas complexas, porque o plano fica fixo em vez de ser renegociado a cada ciclo.

Segunda: usa um gateway como o LiteLLM se quiseres trocar entre a DeepSeek e outros fornecedores sem reescrever o código do agente, útil quando precisas de comparar custo e qualidade entre modelos para a mesma tarefa.

Terceira: para repositórios muito grandes, combina este agente com uma camada de indexação vetorial que recupera apenas os trechos relevantes de código antes de montares o prompt, em vez de carregares pastas inteiras. Isso mantém o contexto pequeno, o cache eficaz e o custo sob controlo mesmo em bases de código com centenas de milhares de linhas.

Quarta: regista cada sessão completa (pedido inicial, número de iterações, custo final e resultado) num ficheiro JSON ou numa base de dados simples. Ao fim de algumas semanas, esse histórico diz-te com dados reais, não com suposições, que tipos de tarefa o agente resolve bem sozinho e que tipos precisam de mais supervisão humana antes de confiares neles por completo.

Projeto Completo: O Agente Inteiro Num Só Ficheiro

Para facilitar a consulta, aqui está a versão consolidada da classe AgenteCodigo com todas as proteções dos passos anteriores já integradas:

import OpenAI from "openai";
import "dotenv/config";
import { ferramentasDisponiveis, executarFerramenta } from "./ferramentas/index.js";

const cliente = new OpenAI({
  apiKey: process.env.DEEPSEEK_API_KEY,
  baseURL: "https://api.deepseek.com",
});

const SYSTEM_PROMPT = `Es um agente de programacao.
Usa as ferramentas disponiveis para ler ficheiros, propor alteracoes e correr testes.
Confirma sempre o resultado de um teste antes de declarar uma tarefa concluida.
Responde em portugues de Portugal.`;

const CUSTO_MAXIMO_SESSAO = 0.50;

export default class AgenteCodigo {
  constructor(limiteIteracoes = 15) {
    this.historico = [{ role: "system", content: SYSTEM_PROMPT }];
    this.limiteIteracoes = limiteIteracoes;
    this.custoTotalEstimado = 0;
  }

  registarCusto(usage) {
    const custoEntradaCacheHit = (usage.prompt_cache_hit_tokens / 1_000_000) * 0.006;
    const custoEntradaCacheMiss = (usage.prompt_cache_miss_tokens / 1_000_000) * 0.15;
    const custoSaida = (usage.completion_tokens / 1_000_000) * 0.60;
    this.custoTotalEstimado += custoEntradaCacheHit + custoEntradaCacheMiss + custoSaida;
  }

  async chamarComRetry(parametros, tentativas = 3) {
    for (let i = 0; i < tentativas; i++) {
      try {
        return await cliente.chat.completions.create(parametros);
      } catch (erro) {
        if (erro.status === 429 && i < tentativas - 1) {
          await new Promise(r => setTimeout(r, 2 ** i * 1000));
          continue;
        }
        throw erro;
      }
    }
  }

  async correr(pedidoUtilizador) {
    this.historico.push({ role: "user", content: pedidoUtilizador });

    for (let i = 0; i < this.limiteIteracoes; i++) {
      if (this.custoTotalEstimado > CUSTO_MAXIMO_SESSAO) {
        return "Limite de custo da sessao atingido. Interrompido por seguranca.";
      }

      const resposta = await this.chamarComRetry({
        model: "deepseek-chat",
        messages: this.historico,
        tools: ferramentasDisponiveis,
      });

      const mensagem = resposta.choices[0].message;
      this.registarCusto(resposta.usage);
      this.historico.push(mensagem);
      console.log(`Custo acumulado: $${this.custoTotalEstimado.toFixed(4)}`);

      if (!mensagem.tool_calls) {
        return mensagem.content;
      }

      for (const chamada of mensagem.tool_calls) {
        let args;
        try {
          args = JSON.parse(chamada.function.arguments);
        } catch {
          args = {};
        }
        const resultado = executarFerramenta(chamada.function.name, args);
        this.historico.push({
          role: "tool",
          tool_call_id: chamada.id,
          content: String(resultado).slice(0, 8000),
        });
      }
    }
    return "Limite de iteracoes atingido sem conclusao.";
  }
}

Junta este ficheiro ao ferramentas/index.js do passo 6 e tens um agente funcional, com controlo de custo, retry automático e aproveitamento do cache de contexto da DeepSeek. Se precisares de trocar o modelo subjacente mais tarde, a única alteração necessária é o valor da propriedade model.

Perguntas Frequentes

O DeepSeek V4.1 Flash é gratuito?
Não. A API cobra por token processado, com valores reportados a partir de $0,15 por milhão de tokens de entrada fora de pico. Existe um limite de saldo gratuito para novas contas em alguns mercados, mas confirma o estado atual na plataforma antes de assumir qualquer crédito.

Preciso de usar o SDK da OpenAI para falar com a DeepSeek?
Não é obrigatório, mas é a forma mais rápida, porque a API da DeepSeek segue o mesmo formato de pedidos e respostas. Qualquer biblioteca HTTP genérica também funciona, desde que envies o cabeçalho de autorização correto.

O cache de contexto funciona automaticamente?
Sim, a DeepSeek deteta prefixos repetidos do lado do servidor sem configuração adicional da tua parte. O que controlas é a forma como estruturas o histórico para maximizar esses prefixos repetidos entre chamadas.

Posso correr este agente sem ligação à internet?
Não, porque todo o processamento do modelo corre nos servidores da DeepSeek. Para um agente totalmente local, precisarias de um modelo open source corrido com ferramentas como o vLLM, com custos de hardware muito diferentes.

Quantas iterações são normais para uma tarefa simples?
Para corrigir um bug pequeno com um teste de validação, entre quatro e oito iterações é razoável. Tarefas de refatorização mais amplas podem precisar de 15 ou mais, por isso ajusta o limite de iterações da classe conforme a complexidade esperada.

O que acontece se o agente ultrapassar o limite de iterações?
O ciclo para e devolve uma mensagem a indicar que o limite foi atingido sem conclusão. Isto é intencional: preferes um agente que pare de forma previsível do que um que continue a gastar saldo sem produzir resultado.

Este agente funciona também em Python?
Sim, a lógica é a mesma. Troca o SDK da OpenAI em JavaScript pelo pacote openai em Python, aponta o base_url para o mesmo endpoint e adapta as funções de ferramentas à sintaxe Python.

Onde posso ver os modelos disponíveis e os seus identificadores exatos?
Consulta a lista atualizada em api-docs.deepseek.com ou verifica os modelos listados na página da DeepSeek no Hugging Face e no GitHub, onde a empresa publica os pesos de versões open source quando aplicável.

Vale a pena usar um gateway como o LiteLLM em vez de ligar diretamente à API da DeepSeek?
Depende do teu objetivo. Para um primeiro projeto pessoal, ligar diretamente à API, como fazemos neste tutorial, é mais simples de depurar porque há menos camadas entre o teu código e a resposta do modelo. Um gateway como o LiteLLM compensa quando já tens vários agentes em produção e precisas de trocar de fornecedor sem reescrever cada um deles.