Como Usar Function Calling com a API DeepSeek V4 Pro

Guia prático para a chamada de função do DeepSeek V4 Pro: esquemas de ferramentas, o loop completo do agente Python, chamadas de ferramentas paralelas, modo de pensamento, tratamento de erros, custos de cache e teste de chamadas de ferramentas no Apidog.

INEZA Felin-Michel

INEZA Felin-Michel

13 agosto 2026

Como Usar Function Calling com a API DeepSeek V4 Pro

Apidog para empresas

Implantação local

SSO & RBAC

Conforme SOC 2

Explorar Apidog Enterprise

DeepSeek tirou o V4 Pro da prévia em 12 de agosto de 2026, e a cobertura de lançamento destaca fluxos de trabalho de agente: codificação, uso de ferramentas e tarefas de longo prazo que encadeiam dezenas de etapas sem perder o fio. Esse posicionamento faz com que um recurso da API seja mais importante do que qualquer outro, a chamada de função (function calling), e é o único recurso que os guias da semana de lançamento não abordaram. Todo tutorial até agora para em conclusões de chat.

Este vai além: defina um esquema de ferramenta, faça sua primeira chamada de ferramenta com o SDK Python openai padrão, construa o ciclo completo do agente e, em seguida, teste tudo no Apidog antes de seu agente ser lançado. Se você ainda não tem uma chave de API DeepSeek, configure uma com nosso guia sobre como usar a API DeepSeek V4, e depois retorne.

botão

TL;DR

Por que a chamada de ferramenta é o principal caso de uso do V4 Pro

A DeepSeek construiu o V4 Pro para agentes, e a folha de especificações parece uma lista de verificação de tempo de execução de agente:

Especificação DeepSeek V4 Pro
Arquitetura MoE Esparsa: 1,6T parâmetros totais, 49B ativos por token
Janela de contexto 1M tokens
Saída máxima 384K tokens
Preço de entrada US$ 0,435/M tokens (falha de cache), US$ 0,003625/M (acerto de cache)
Preço de saída US$ 0,87/M tokens
Chamada de função Array tools compatível com OpenAI e respostas tool_calls
Outras interfaces Formato Anthropic Messages, API DeepSeek Responses

Cada linha mapeia um problema do agente: a janela de 1M de tokens carrega o histórico completo de resultados de ferramentas de um agente longo, o limite de saída de 384K deixa espaço para grandes cargas úteis estruturadas, e o cache de prefixo faz a economia do loop funcionar. O modelo está listado no OpenRouter como deepseek-v4-pro-0813 para comparações de provedores.

Uma ressalva antes do código. Na discussão de lançamento no Hacker News, desenvolvedores relataram que o desempenho da chamada de ferramenta é altamente sensível ao ambiente de teste (harness): o mesmo modelo teve pontuações melhores ou piores dependendo do framework, do scaffolding do prompt e do estilo do esquema. Benchmarks não dirão como ele lida com seus esquemas de ferramenta. Teste com suas definições reais.

Como funciona a chamada de função (function calling) da DeepSeek

A chamada de função não significa que o modelo executa qualquer coisa. Ele responde com uma solicitação estruturada, “chame get_order com {"order_id": "ORD-10442"}”, em vez de prosa. Seu código executa a função, retorna o resultado, e o modelo continua com dados reais. O ciclo:

  1. Você envia `messages` mais um array `tools` descrevendo cada função em JSON Schema.
  2. O modelo decide que uma ferramenta é necessária e responde com `tool_calls` e `finish_reason: "tool_calls"`.
  3. Seu código analisa os argumentos e executa a função real.
  4. Você adiciona o resultado como uma mensagem `role: "tool"` vinculada ao ID da chamada.
  5. O modelo solicita outra ferramenta ou produz sua resposta final.

Se você já trabalhou com chamada de função da OpenAI, este é o mesmo formato de comunicação (wire format); a maioria dos códigos de agente são portados alterando a URL base e o nome do modelo. Os documentos oficiais da DeepSeek também cobrem um endpoint de Mensagens compatível com Anthropic e uma API de Respostas, mas este guia se concentra na interface compatível com OpenAI.

Passo 1: Configure o cliente

Instale o SDK e aponte-o para DeepSeek:

pip install openai
export DEEPSEEK_API_KEY="sk-..."
import os
from openai import OpenAI

client = OpenAI(
    api_key=os.environ["DEEPSEEK_API_KEY"],
    base_url="https://api.deepseek.com",
)

Essa é toda a configuração. Cada exemplo usa model="deepseek-v4-pro", que se refere à compilação GA DeepSeek-V4-Pro-0813.

Passo 2: Defina um esquema de ferramenta

Vamos construir um agente de suporte para uma loja online. Sua primeira ferramenta pesquisa pedidos. Uma definição de ferramenta tem três partes: um nome, uma descrição e um JSON Schema para os parâmetros.

tools = [
    {
        "type": "function",
        "function": {
            "name": "get_order",
            "description": (
                "Look up a customer order by its ID. Returns the order status, "
                "carrier, tracking number, and estimated delivery date. Use this "
                "whenever the user asks where an order is or what state it's in."
            ),
            "parameters": {
                "type": "object",
                "properties": {
                    "order_id": {
                        "type": "string",
                        "description": "The order ID, formatted like 'ORD-10442'.",
                    }
                },
                "required": ["order_id"],
            },
        },
    }
]

A descrição não é apenas um enfeite: o modelo decide quando chamar uma ferramenta lendo-a. Descrições vagas são a principal razão para um modelo ignorar uma ferramenta ou escolher a errada.

A função local que o esquema descreve, substituída por um serviço de pedidos real:

def get_order(order_id: str) -> dict:
    """Stub for your real order service."""
    fake_db = {
        "ORD-10442": {
            "status": "shipped",
            "carrier": "DHL",
            "tracking_number": "4281337005",
            "estimated_delivery": "2026-08-15",
        },
        "ORD-10587": {
            "status": "processing",
            "estimated_ship_date": "2026-08-14",
        },
    }
    return fake_db.get(order_id, {"error": f"Unknown order ID: {order_id}"})

Passo 3: Faça sua primeira chamada de ferramenta

Envie uma pergunta que o modelo não consegue responder sem a ferramenta:

messages = [
    {"role": "system", "content": "You are a support agent for an online store."},
    {"role": "user", "content": "Where is my order ORD-10442?"},
]

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)

message = response.choices[0].message
print(message.tool_calls[0].function.name) # get_order
print(message.tool_calls[0].function.arguments) # {"order_id": "ORD-10442"}

Em vez de responder, o modelo pede para você executar get_order. O payload de resposta bruto se parece com isto:

{
  "id": "chatcmpl-8f3a1c",
  "object": "chat.completion",
  "model": "deepseek-v4-pro",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "",
        "tool_calls": [
          {
            "id": "call_0_f1c29a44",
            "type": "function",
            "function": {
              "name": "get_order",
              "arguments": "{\"order_id\": \"ORD-10442\"}"
            }
          }
        ]
      },
      "finish_reason": "tool_calls"
    }
  ],
  "usage": {
    "prompt_tokens": 312,
    "completion_tokens": 24,
    "total_tokens": 336,
    "prompt_cache_hit_tokens": 0,
    "prompt_cache_miss_tokens": 312
  }
}

Três detalhes importam. finish_reason é "tool_calls", o que informa ao seu loop que o modelo deseja execução. Cada chamada carrega um id que você deve ecoar de volta com o resultado. E arguments é uma string JSON que você analisa por conta própria, então espere que ocasionalmente seja malformada.

Passo 4: Execute a função e retorne o resultado

Execute a função e, em seguida, adicione duas mensagens: a vez do assistente contendo tool_calls e uma mensagem tool que carrega seu resultado.

import json

tool_call = message.tool_calls[0]
args = json.loads(tool_call.function.arguments)
result = get_order(args)

messages.append(message) # the assistant turn containing tool_calls
messages.append({
    "role": "tool",
    "tool_call_id": tool_call.id, # must match the id from the response
    "content": json.dumps(result),
})

final = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
)
print(final.choices[0].message.content)
# Your order ORD-10442 shipped with DHL and is estimated to arrive
# by August 15, 2026. Tracking number: 4281337005.

O vínculo do tool_call_id é rigoroso: cada entrada de tool_calls precisa de uma mensagem tool correspondente antes da próxima vez do modelo, caso contrário, a solicitação falhará.

Passo 5: O ciclo completo do agente

Agentes reais encadeiam chamadas: pesquisar um pedido, verificar uma política de reembolso, redigir um e-mail, cada passo dependendo do último. O padrão: continuar chamando o modelo e executando o que ele solicitar até que retorne uma resposta normal.

TOOLS_BY_NAME = {"get_order": get_order}

def run_agent(client, messages, tools, max_rounds=10):
    """Run the model until it produces a final answer or hits the cap."""
    for _ in range(max_rounds):
        response = client.chat.completions.create(
            model="deepseek-v4-pro",
            messages=messages,
            tools=tools,
        )
        message = response.choices[0].message
        messages.append(message)

        if not message.tool_calls: # no tool requests: we're done
            return message.content

        for tool_call in message.tool_calls:
            fn = TOOLS_BY_NAME.get(tool_call.function.name)
            try:
                if fn is None:
                    raise ValueError(f"Unknown tool: {tool_call.function.name}")
                args = json.loads(tool_call.function.arguments)
                result = fn(args)
            except Exception as exc:
                result = {"error": str(exc)} # feed failures back to the model
            messages.append({
                "role": "tool",
                "tool_call_id": tool_call.id,
                "content": json.dumps(result),
            })

    raise RuntimeError(f"Agent did not finish within {max_rounds} rounds")

Frameworks e SDKs de agente são elaborações sobre este ciclo. O limite de max_rounds converte um modelo preso chamando repetidamente uma ferramenta com falha em uma falha limpa, em vez de uma conta sem fim.

Chamadas de ferramenta paralelas

Peça duas pesquisas, “compare o status de ORD-10442 e ORD-10587”, e o V4 Pro frequentemente agrupará ambas em uma única vez:

"tool_calls": [
  {
    "id": "call_0_a7d1",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10442\"}" }
  },
  {
    "id": "call_1_b3e9",
    "type": "function",
    "function": { "name": "get_order", "arguments": "{\"order_id\": \"ORD-10587\"}" }
  }
]

O loop run_agent já lida com isso: o for interno responde a cada chamada com seu próprio tool_call_id (cada chamada precisa de um resultado correspondente antes da próxima rodada), e você pode executar o lote concorrentemente. É uma filosofia diferente da chamada de ferramenta programática do GPT-5.6, onde o modelo escreve código de orquestração em um sandbox; a DeepSeek mantém a execução e o limite de confiança em seu tempo de execução.

Modo de raciocínio (thinking mode) e ferramentas

O V4 Pro vem com três modos de raciocínio (thinking modes), para que você possa aumentar o esforço de raciocínio para rodadas de planejamento difíceis e ignorá-lo para pesquisas rotineiras (consulte os documentos oficiais para nomes e padrões dos modos). Com o raciocínio ativado, a API retorna o rastreamento do modelo como reasoning_content juntamente com quaisquer chamadas de ferramenta:

response = client.chat.completions.create(
    model="deepseek-v4-pro",
    messages=messages,
    tools=tools,
    extra_body={"thinking": {"type": "enabled"}},
)

message = response.choices[0].message
print(message.reasoning_content) # the planning trace
print(message.tool_calls) # the calls it settled on

O rastreamento mostra por que o modelo escolheu uma ferramenta, o que geralmente é onde um esquema ruim se revela. Remova o reasoning_content antes de adicionar a vez do assistente ao histórico e reserve o raciocínio para turnos com muito planejamento, pois o raciocínio é cobrado como saída a US$ 0,87/M.

Tratamento de erros: quando o modelo erra uma chamada

Chamadas de ferramenta malformadas são raras, mas um ciclo de agente amplifica cada modo de falha. O padrão essencial: nunca falhar em uma chamada ruim, retornar o problema como resultado da ferramenta e deixar o modelo tentar novamente. Isso cobre argumentos que falham em json.loads, bem como valores que quebram suas regras de negócio:

from jsonschema import ValidationError, validate

schema = tools[0]["function"]["parameters"]

try:
    args = json.loads(tool_call.function.arguments)
    validate(instance=args, schema=schema)
    result = get_order(**args)
except (json.JSONDecodeError, ValidationError) as exc:
    result = {
        "error": f"Invalid arguments: {exc}",
        "hint": "Call get_order again with an order_id string like 'ORD-10442'.",
    }

O campo hint importa: uma correção de uma linha geralmente produz uma nova tentativa corrigida na próxima rodada. Trate os erros do agente também como eventos de segurança. Um modelo convencido a chamar delete_order com argumentos fornecidos por um invasor é tão perigoso quanto a chave por trás dele, o caso para chaves de API com o menor privilégio para agentes de IA. Defina o escopo das credenciais para que uma chamada errada não se torne um incidente.

Teste e depure chamadas de ferramenta com Apidog antes de lançar

Toda ferramenta é um invólucro fino em torno de uma API, e o modelo agora é um consumidor dessa API. Se o endpoint de suporte for ambíguo ou instável, o modelo herda tudo isso. É aqui que o Apidog ganha seu lugar no ciclo:

  1. Projete a API de suporte primeiro. Defina `GET /orders/{order_id}` como uma especificação no designer visual do Apidog; o JSON Schema de sua ferramenta deriva diretamente da especificação, para que os dois não possam se desviar silenciosamente.
  2. Simule antes que o backend exista. O mock inteligente do Apidog serve respostas realistas do esquema, para que o ciclo do agente seja executado contra `get_order` enquanto o serviço real ainda está sendo construído.
  3. Inspecione os payloads brutos. Envie o mesmo corpo `messages` + `tools` para `https://api.deepseek.com` do Apidog e leia o JSON bruto de `tool_calls` diretamente; uma propriedade `properties` aninhada incorretamente ou argumentos codificados duas vezes aparecem em uma única inspeção.
  4. Transforme conversas em cenários de teste. Afirme `finish_reason` e os formatos dos argumentos, e execute a suíte em cada mudança de esquema; dada a sensibilidade da estrutura de teste relatada no Hacker News, uma suíte de regressão sobre seus esquemas reais é o benchmark que prevê a produção. Veja como conectar um agente de IA a uma estrutura de teste Apidog para um padrão mais aprofundado.

Baixe o Apidog gratuitamente para acompanhar; o servidor de mock e os cenários de teste estão incluídos na camada gratuita.

Quanto custam os ciclos de agente (e por que o cache decide isso)

Os ciclos do agente releem a conversa inteira a cada rodada: na décima rodada, seu prompt do sistema, esquemas de ferramentas e nove rodadas de resultados são cobrados pela décima vez. O cache de prefixo automático do V4 Pro quebra essa curva, a entrada de cada rodada é a da rodada anterior mais um pouco, então quase todo o prefixo é cobrado a US$ 0,003625/M em vez de US$ 0,435/M. Reler uma conversa de 100K tokens custa cerca de US$ 0,0435 sem cache, mas cerca de US$ 0,0004 com cache; prompt_cache_hit_tokens no bloco de uso mostra sua taxa de acertos real.

Para manter essa taxa alta, nunca altere mensagens anteriores e mantenha o array tools estável em bytes entre as rodadas. Nosso guia sobre o que é cache de prompt cobre a mecânica. E se deepseek-v4-flash a US$ 0,14/US$ 0,28 parece tentador: é bom para roteamento de ferramenta de uso único, mas ele regride em ciclos que encadeiam mais de 10 chamadas, então as tentativas consomem as economias, o Pro é o padrão mais seguro para agentes.

FAQ

As definições de ferramentas custam tokens?

Sim, o array tools é uma entrada em cada solicitação. Mantenha-o estável e ele se junta ao prefixo em cache após a primeira rodada, sendo cobrado à taxa de acerto de cache a partir daí.

Posso combinar chamada de função com saídas estruturadas?

Sim. Um padrão comum: as ferramentas buscam os dados intermediários, um esquema de saída estruturado formata a resposta final, para que o código downstream nunca precise analisar prosa.

Conclusão

A chamada de função no DeepSeek V4 Pro é intencionalmente pouco emocionante de implementar: esquemas compatíveis com OpenAI, um array tool_calls, uma mensagem tool com um ID. O loop no Passo 5 é toda a arquitetura, e o preço de acerto de cache o torna mais barato do que a maioria das equipes espera. O que os benchmarks não podem dizer é como o modelo se comporta com seus esquemas; projete as APIs de suporte deliberadamente, simule-as cedo e mantenha uma suíte de regressão de cenários de chamada de ferramenta no Apidog para que as alterações de esquema não quebrem silenciosamente seu agente.

botão

Pratique o design de API no Apidog

Descubra uma forma mais fácil de construir e usar APIs