Ilustração de código Python sendo executado em um terminal, com ícones de LLMs ao fundo
llms-chatbots

Function Calling na Prática: Tutorial Python para Chatbots com LLMs que Executam Ações em 2026

NeuralPulse|9 de junho de 2026|10 min de leitura|Read in English
Preparando avatar...
🎬 NeuralPulse Shorts

Seu chatbot sabe responder perguntas. Mas ele consegue agir? Em 2026, essa é a linha que separa um protótipo de um produto de verdade.

Dados da OpenAI mostram que 70% dos desenvolvedores já usam function calling em chatbots de produção (OpenAI DevDay 2025). O motivo é simples: sem isso, o LLM é apenas um papagaio digital. Com function calling, ele vira um orquestrador de sistemas.

Neste tutorial, você vai aprender a implementar function calling na prática com Python. Vamos usar as APIs das três principais plataformas — OpenAI, Anthropic Claude e Google Gemini — para construir um chatbot que consulta clima, acessa banco de dados e envia notificações.

O que é Function Calling (e por que você precisa disso)

Function calling, também chamado de tool use, é a capacidade do LLM de identificar quando deve chamar uma função externa. O modelo não executa o código — ele retorna um objeto JSON estruturado com os parâmetros da função. Seu sistema executa a função e devolve o resultado para o modelo.

"Function calling transforma LLMs de geradores de texto em agentes de software. É a ponte entre linguagem natural e APIs." — Documentação oficial da Anthropic sobre tool use (2025)

O fluxo básico é:

  1. Você define funções com descrições e parâmetros (como um schema JSON).
  2. O modelo decide se deve chamar alguma função com base no prompt do usuário.
  3. Seu código executa a função real e retorna o resultado.
  4. O modelo incorpora esse resultado na resposta final.

O custo médio de uma chamada de função via LLM é de US$ 0,003 (Anthropic pricing, 2025). Para chatbots de alto volume, isso representa um custo operacional baixo comparado ao ganho em utilidade.

Mão na massa: Implementação com OpenAI

A OpenAI foi pioneira em function calling. A API é madura e bem documentada. Vamos criar um assistente que consulta o clima e gerencia tarefas.

Primeiro, instale a biblioteca:

pip install openai

Agora, defina as funções que o modelo poderá chamar:

import json
from openai import OpenAI

client = OpenAI(api_key="sua-chave-aqui")

tools = [ { "type": "function", "function": { "name": "get_weather", "description": "Obtém a temperatura atual de uma cidade", "parameters": { "type": "object", "properties": { "city": { "type": "string", "description": "Nome da cidade, ex: São Paulo" }, "unit": { "type": "string", "enum": ["celsius", "fahrenheit"] } }, "required": ["city"] } } }, { "type": "function", "function": { "name": "add_task", "description": "Adiciona uma tarefa à lista do usuário", "parameters": { "type": "object", "properties": { "task": { "type": "string", "description": "Descrição da tarefa" }, "priority": { "type": "string", "enum": ["alta", "media", "baixa"] } }, "required": ["task", "priority"] } } } ]

Crie as funções reais que serão executadas:

def get_weather(city: str, unit: str = "celsius"):
    # Simulação de consulta a API externa
    temperaturas = {"São Paulo": 22, "Rio de Janeiro": 30, "Brasília": 25}
    temp = temperaturas.get(city, 20)
    if unit == "fahrenheit":
        temp = temp * 9/5 + 32
    return json.dumps({"city": city, "temperature": temp, "unit": unit})

def add_task(task: str, priority: str): # Simulação de inserção em banco de dados return json.dumps({"status": "sucesso", "task": task, "priority": priority})

Agora, o loop principal de conversação:

messages = [{"role": "user", "content": "Qual a temperatura no Rio e adicione 'comprar leite' como prioridade alta"}]

response = client.chat.completions.create( model="gpt-4o", messages=messages, tools=tools, tool_choice="auto" )

assistant_message = response.choices[0].message tool_calls = assistant_message.tool_calls

if tool_calls: for tool_call in tool_calls: function_name = tool_call.function.name arguments = json.loads(tool_call.function.arguments)

    if function_name == "get_weather":
        result = get_weather(**arguments)
    elif function_name == "add_task":
        result = add_task(**arguments)
    
    messages.append({
        "tool_call_id": tool_call.id,
        "role": "tool",
        "name": function_name,
        "content": result
    })

final_response = client.chat.completions.create(
    model="gpt-4o",
    messages=messages
)
print(final_response.choices[0].message.content)

Perceba que o modelo pode chamar múltiplas funções em paralelo. Ele entende que precisa do clima e também adicionar uma tarefa. Isso é nativo na API da OpenAI.

Implementação com Anthropic Claude

A Anthropic chama de tool use. A API é similar, mas tem diferenças importantes. Vamos ao código.

pip install anthropic
from anthropic import Anthropic

client = Anthropic(api_key="sua-chave")

tools = [ { "name": "get_weather", "description": "Obtém a temperatura atual de uma cidade", "input_schema": { "type": "object", "properties": { "city": {"type": "string", "description": "Nome da cidade"}, "unit": {"type": "string", "enum": ["celsius", "fahrenheit"]} }, "required": ["city"] } }, { "name": "add_task", "description": "Adiciona uma tarefa à lista", "input_schema": { "type": "object", "properties": { "task": {"type": "string"}, "priority": {"type": "string", "enum": ["alta", "media", "baixa"]} }, "required": ["task", "priority"] } } ]

message = client.messages.create( model="claude-3-5-sonnet-20241022", max_tokens=1024, messages=[{"role": "user", "content": "Qual a temperatura em Brasília?"}], tools=tools )

Claude retorna stop_reason="tool_use" quando quer chamar uma função

if message.stop_reason == "tool_use": for content_block in message.content: if content_block.type == "tool_use": tool_name = content_block.name tool_input = content_block.input

        if tool_name == "get_weather":
            result = get_weather(**tool_input)
        
        # Envia o resultado de volta
        response = client.messages.create(
            model="claude-3-5-sonnet-20241022",
            messages=[
                {"role": "user", "content": "Qual a temperatura em Brasília?"},
                {"role": "assistant", "content": message.content},
                {"role": "user", "content": [
                    {
                        "type": "tool_result",
                        "tool_use_id": content_block.id,
                        "content": result
                    }
                ]}
            ],
            tools=tools
        )
        print(response.content[0].text)

A diferença principal: Claude usa stop_reason e blocos de conteúdo estruturados. Ele não aceita múltiplas chamadas paralelas na mesma rodada — cada tool_use precisa ser processada sequencialmente.

Implementação com Google Gemini

O Gemini também oferece function calling nativo. A sintaxe é um pouco diferente, mas o conceito é o mesmo.

pip install google-generativeai
import google.generativeai as genai

genai.configure(api_key="sua-chave")

model = genai.GenerativeModel("gemini-2.0-flash")

Define as funções como dicionário Python

get_weather_tool = { "function_declarations": [ { "name": "get_weather", "description": "Obtém a temperatura atual de uma cidade", "parameters": { "type_": "OBJECT", "properties": { "city": {"type_": "STRING"}, "unit": {"type_": "STRING", "enum": ["celsius", "fahrenheit"]} }, "required": ["city"] } }, { "name": "add_task", "description": "Adiciona uma tarefa à lista", "parameters": { "type_": "OBJECT", "properties": { "task": {"type_": "STRING"}, "priority": {"type_": "STRING", "enum": ["alta", "media", "baixa"]} }, "required": ["task", "priority"] } } ] }

chat = model.start_chat()

response = chat.send_message( "Qual a temperatura em São Paulo?", tools=[get_weather_tool] )

Gemini retorna function_call na resposta

if response.candidates[0].content.parts[0].function_call: function_call = response.candidates[0].content.parts[0].function_call tool_name = function_call.name args = {key: value for key, value in function_call.args.items()}

if tool_name == "get_weather":
    result = get_weather(**args)

# Envia o resultado
response = chat.send_message(
    genai.protos.Content(
        parts=[
            genai.protos.Part(
                function_response=genai.protos.FunctionResponse(
                    name=tool_name,
                    response={"result": result}
                )
            )
        ]
    )
)
print(response.text)

O Gemini usa function_declarations e FunctionResponse. Ele também suporta chamadas paralelas, mas a implementação é mais verbosa que a da OpenAI.

Comparação entre as três plataformas

CaracterísticaOpenAIAnthropic ClaudeGoogle Gemini
Chamadas paralelasSim (nativo)Não (sequencial)Sim (mas verboso)
Formato do schemaJSON SchemaJSON SchemaDicionário Python
Identificação da chamadatool_callsstop_reason: tool_usefunction_call
Retorno de resultadorole: tooltool_resultFunctionResponse
Modelo recomendadogpt-4oclaude-3-5-sonnetgemini-2.0-flash
Custo por chamada~US$0,005~US$0,003~US$0,002

A OpenAI leva vantagem em maturidade e suporte a paralelismo. A Anthropic oferece o menor custo por chamada. O Gemini se destaca pela integração com o ecossistema Google.

Boas práticas para produção

Function calling em produção exige cuidados extras. Aqui vão três regras essenciais.

Valide os parâmetros antes de executar. O modelo pode alucinar valores. Sempre verifique se os parâmetros estão dentro do esperado.

def safe_get_weather(city, unit="celsius"):
    if unit not in ["celsius", "fahrenheit"]:
        unit = "celsius"  # fallback seguro
    # continua...

Defina descrições claras e detalhadas. Quanto melhor a descrição da função e dos parâmetros, maior a chance de o modelo chamar a função correta. Use exemplos.

"description": "Obtém a temperatura de uma cidade. Ex: 'São Paulo' retorna 22°C."

Implemente timeouts e fallbacks. APIs externas podem falhar. Se a chamada de função demorar mais que 5 segundos, retorne um erro amigável para o modelo.

import asyncio

async def call_with_timeout(func, timeout=5): try: return await asyncio.wait_for(func, timeout=timeout) except asyncio.TimeoutError: return json.dumps({"error": "Serviço indisponível no momento"})

O futuro é agêntico

Function calling é a base para agentes autônomos. Em 2026, os chatbots que não executam ações estão fadados a serem substituídos. A diferença entre um assistente útil e um brinquedo tecnológico está na capacidade de integrar sistemas.

Comece pequeno: uma função de clima, uma de banco de dados. Depois adicione envio de email, consulta a CRM, execução de scripts. O padrão é o mesmo. A complexidade vem da orquestração.

O código deste tutorial está disponível em um repositório público. Use como base para seu próximo chatbot. E lembre-se: o LLM é o cérebro, mas as funções são os músculos.

Artigos Relacionados

Confira também: Agentes de IA Autônomos em 2026: como funcionam, onde estão sendo usados e o que esperar Confira também: 7 Passos para um Chatbot sem Alucinação: CoT, Self-Consistency e DSPy em Python Confira também: A Crise Silenciosa dos Multimodais: Por que 1 em Cada 3 Respostas Visuais de LLMs em 2026 é Alucinação

Compartilhar:
NeuralPulse

NeuralPulse

Blog profissional sobre Inteligencia Artificial. Exploramos tendencias, ferramentas, tutoriais e analises profundas sobre como a IA esta transformando negocios, tecnologia e o dia a dia.

Receba as novidades sobre IA

Junte-se a milhares de leitores que acompanham as ultimas tendencias em inteligencia artificial.

Comentarios

Powered by Disqus

Para ativar os comentarios, configure seu shortname do Disqus no componente.

<div id="disqus_thread"></div>