Blog

Function calling vs RAG para dados em tempo real

Quando um usuario pergunta "cade meu pedido?", nenhuma base de conhecimento no mundo tem a resposta: o status muda a cada minuto e vive no banco transacional, nao num documento. Ainda assim, muita gente tenta resolver tudo com RAG, indexa FAQ, politicas e manuais, e depois se frustra quando o bot inventa um prazo de entrega que nao existe. O problema nao e o RAG: e usar retrieval para um dado que nao e recuperavel, e sim consultavel. Function calling resolve exatamente essa classe: em vez de buscar um trecho parecido, o modelo chama uma funcao que executa a consulta ao vivo e recebe o dado fresco de volta. Este artigo separa as duas ferramentas por natureza do dado, mostra os fluxos lado a lado, quando cada uma vence, um exemplo real de tool use e como rotear entre elas numa arquitetura unica.

2026-07-07 / IA Aplicada / 12 min

01

O eixo que separa as duas: dado estatico x dado vivo

RAG e function calling nao competem pelo mesmo trabalho; eles resolvem perguntas de naturezas diferentes. RAG e para conhecimento: texto que ja existe escrito em algum lugar (uma politica de troca, um trecho de manual, um artigo) e que voce quer recuperar por similaridade semantica. Function calling e para acao e consulta: um dado que so existe no momento em que voce pergunta (o saldo de hoje, o status atual do pedido, o clima agora) ou uma operacao que muda o mundo (criar um chamado, agendar uma visita, emitir um boleto).

A pergunta que separa as duas e simples: a resposta esta escrita em algum documento ou precisa ser calculada/consultada agora? Se esta escrita, RAG recupera. Se precisa ser consultada, function calling chama uma API. Confundir os dois e a raiz de metade dos bots que alucinam: eles tentam recuperar por similaridade um dado que muda a cada segundo, e o trecho mais parecido que o retrieval encontra e sempre uma versao velha ou generica.

02

Comparacao direta

A decisao entre function calling e RAG cai em poucas dimensoes que puxam claramente para um lado. A tabela abaixo coloca as que mais pesam na hora de desenhar o sistema.

DimensaoRAGFunction calling
Natureza do dadoEstatico: texto ja escrito (FAQ, politicas, manuais, artigos)Vivo: consultado ou calculado no momento da pergunta (status, saldo, estoque)
FrescorDepende da ultima reindexacao; entre reindexacoes o dado envelheceSempre atual: a tool consulta a fonte da verdade a cada chamada
Efeito colateralNenhum: retrieval so le documentosPode agir: criar chamado, agendar, emitir, alterar estado no sistema
Fonte da verdadeUm corpus de documentos indexado em vector storeA API/banco transacional que ja e a autoridade sobre aquele dado
Risco tipicoRecuperar o trecho errado ou desatualizado e responder em cima deleChamar a funcao errada ou com argumento invalido; exige validacao dos args
RastreabilidadeCita o documento e a secao de origemRegistra a chamada, os argumentos e a resposta bruta da API

03

Os dois fluxos lado a lado

Ver os dois caminhos deixa clara a diferenca de mecanismo: RAG recupera texto parecido e injeta no prompt; function calling faz o modelo decidir chamar uma funcao, executa a chamada no seu backend e devolve o resultado para o modelo redigir a resposta final.

RAG (dado estatico)
  Pergunta  ->  Embed  ->  Retrieve top-k  ->  Injeta chunks  ->  Gerar  ->  Resposta
                            (vector store)

Function calling (dado vivo)
  Pergunta  ->  Modelo decide a tool  ->  Seu backend executa a chamada (API/banco)
                                                |
                                                v
                          Resultado fresco  ->  Modelo redige  ->  Resposta

A diferenca central esta no meio do caminho: em RAG o que entra no contexto e um trecho de texto que ja existia; em function calling o que entra e o retorno de uma execucao que aconteceu agora. Por isso function calling nunca esbarra em dado velho: ele nao busca uma versao, ele provoca uma consulta.

04

Quando function calling vence

Function calling e a escolha certa sempre que a resposta nao esta escrita em lugar nenhum e precisa ser consultada ao vivo, ou quando o usuario quer que algo aconteca, nao apenas ser informado.

  • Estado transacional em tempo real: status de pedido, saldo, posicao de entrega, disponibilidade de agenda. Muda a cada minuto e vive no sistema, nao num documento.
  • Dados de terceiros ao vivo: cotacao, clima, rastreamento de transportadora, consulta de CEP. A fonte da verdade e uma API externa, nao um corpus indexado.
  • Acoes com efeito colateral: abrir chamado, agendar visita, emitir segunda via, cancelar pedido. RAG so le; aqui e preciso executar.
  • Calculos deterministicos: frete, juros, parcelas, conversao de unidade. Voce quer o numero exato de uma funcao, nao uma aproximacao gerada pelo modelo.
  • Personalizacao por identidade: "meus dados", "minha fatura", "meu contrato". A resposta depende de quem pergunta e so a consulta parametrizada resolve.

05

Quando RAG vence

RAG continua sendo a ferramenta certa quando a resposta ja existe escrita em algum lugar e o trabalho e encontrar o trecho certo dentro de um volume grande de texto.

  • Conhecimento textual estavel: politicas de troca, termos de uso, manuais, documentacao. O dado nao muda a cada minuto e ja esta redigido.
  • Base grande demais para o contexto: milhares de documentos, anos de artigos. Voce precisa recuperar por similaridade, nao consultar por chave.
  • Perguntas abertas e explicativas: "como funciona a garantia estendida?", "qual a diferenca entre os planos?". A resposta e explicacao, nao um valor vivo.
  • Necessidade de citar a fonte: quando cada afirmacao deve apontar para o documento e a secao de origem, o retrieval entrega esse rastro naturalmente.

06

Exemplo pratico com tool use

O coracao do function calling e a definicao da tool: voce descreve para o modelo qual funcao existe, o que ela faz e quais argumentos ela aceita. O modelo decide quando chama-la e com quais argumentos; o seu backend executa a chamada de verdade e devolve o resultado. No exemplo abaixo, usando a Anthropic Messages API, uma tool consulta o status atual do pedido no seu banco. O modelo nunca inventa o status: ele delega a consulta e so redige a resposta com o dado que voltou.

import Anthropic from '@anthropic-ai/sdk';

const client = new Anthropic();

// A tool que expoe a consulta de status ao modelo.
// O modelo NAO executa nada: ele so decide chamar e com quais argumentos.
const tools = [
  {
    name: 'get_order_status',
    description:
      'Consulta o status atual de um pedido pelo numero. Use sempre que o usuario perguntar sobre um pedido especifico; nunca invente o status.',
    input_schema: {
      type: 'object',
      properties: {
        order_id: { type: 'string', description: 'Numero do pedido, ex: PED-10293' },
      },
      required: ['order_id'],
    },
  },
];

// Execucao real da tool no SEU backend: consulta a fonte da verdade.
async function runTool(name, input) {
  if (name === 'get_order_status') {
    const order = await db.orders.findByPublicId(input.order_id);
    if (!order) return { found: false };
    return {
      found: true,
      status: order.status, // 'em_separacao' | 'enviado' | 'entregue'
      carrier: order.carrier,
      eta: order.estimatedDelivery,
    };
  }
  throw new Error('Tool desconhecida: ' + name);
}

async function ask(question) {
  const messages = [{ role: 'user', content: question }];

  // 1o turno: o modelo decide se chama a tool.
  let res = await client.messages.create({
    model: 'claude-sonnet-4-5',
    max_tokens: 512,
    tools,
    messages,
  });

  // Enquanto o modelo pedir tools, executa e devolve o resultado.
  while (res.stop_reason === 'tool_use') {
    const toolUse = res.content.find((b) => b.type === 'tool_use');
    const result = await runTool(toolUse.name, toolUse.input);

    messages.push({ role: 'assistant', content: res.content });
    messages.push({
      role: 'user',
      content: [
        {
          type: 'tool_result',
          tool_use_id: toolUse.id,
          content: JSON.stringify(result),
        },
      ],
    });

    res = await client.messages.create({
      model: 'claude-sonnet-4-5',
      max_tokens: 512,
      tools,
      messages,
    });
  }

  return res.content.find((b) => b.type === 'text')?.text;
}

// O modelo chama get_order_status('PED-10293'), recebe o status FRESCO
// do banco e so entao redige a resposta. Nada e recuperado por similaridade.
await ask('Cade meu pedido PED-10293?');

Repare no ponto que muda tudo: o dado do status nunca passou por embedding nem por vector store. O modelo apenas decidiu chamar a funcao, o seu backend consultou o banco (a fonte da verdade) e o resultado voltou fresco para o modelo redigir. E impossivel o bot responder um status desatualizado, porque ele nao busca uma versao antiga: ele provoca uma consulta nova a cada pergunta.

07

Arquitetura combinada: roteie por intencao

Num bot de atendimento real, as duas ferramentas convivem: o mesmo usuario pergunta "qual o prazo de troca?" (RAG, conhecimento estavel) e "cade meu pedido?" (function calling, dado vivo) na mesma conversa. A arquitetura robusta nao escolhe uma; ela roteia por intencao. Na pratica moderna, voce nem precisa de um classificador separado: expor tanto a base de conhecimento quanto as tools ao mesmo modelo deixa ele proprio decidir se recupera um documento ou chama uma funcao.

  1. Modele o conhecimento estavel como RAG: politicas, FAQ, manuais viram um corpus indexado ou uma tool de busca semantica que retorna trechos com fonte.
  2. Modele o dado vivo e as acoes como tools: status, saldo, agendamento, emissao. Cada tool tem schema explicito de argumentos e valida a entrada.
  3. Exponha ambos ao mesmo modelo: de a ele tanto a busca semantica quanto as tools transacionais. Ele decide, por pergunta, qual caminho seguir.
  4. Valide os argumentos antes de executar: nunca confie cegamente nos args gerados. Cheque tipo, formato e permissao (o usuario pode ver aquele pedido?) antes de tocar o backend.
  5. Registre a decisao: logue se a resposta veio de retrieval ou de tool, com os argumentos e o retorno. Isso e o que torna o sistema auditavel e depuravel.

O ganho dessa arquitetura e que cada pergunta cai na ferramenta certa pela sua natureza: conhecimento estavel pelo RAG, dado vivo e acao pela tool. O bot para de alucinar prazo de entrega porque nunca mais tenta recuperar por similaridade um dado que so o banco transacional conhece.

FAQ

Perguntas frequentes

Function calling substitui RAG?

Nao. Eles resolvem naturezas diferentes de pergunta. Function calling e para dado vivo (consultado ou calculado agora) e para acoes com efeito colateral; RAG e para conhecimento textual ja escrito que voce recupera por similaridade. Um bot de atendimento serio usa os dois: RAG para politicas e manuais, function calling para status, saldo e agendamento. A arquitetura ideal roteia por intencao entre as duas.

Como o modelo sabe qual tool chamar?

Pela descricao. Cada tool tem um nome, uma descricao em linguagem natural do que faz e um schema dos argumentos que aceita. O modelo le essas descricoes junto com a pergunta e decide se alguma tool se aplica e com quais argumentos chama-la. Por isso a qualidade da descricao importa tanto quanto o codigo: uma descricao vaga leva o modelo a chamar a tool errada ou a nao chama-la quando deveria.

Function calling e seguro para acoes que mudam dados?

E seguro desde que voce nao confie cegamente nos argumentos gerados pelo modelo. O modelo decide chamar e sugere os argumentos, mas quem executa e o seu backend. Antes de tocar o banco, valide tipo e formato dos args, cheque a permissao do usuario sobre aquele recurso e, para acoes de alto impacto, exija confirmacao explicita. O modelo propoe; o seu codigo autoriza e executa.

Escolha pela natureza do dado, nao pela ferramenta da moda

RAG e function calling resolvem perguntas diferentes: retrieval para conhecimento estavel ja escrito, tool use para dado vivo e acoes que mudam o mundo. Posso avaliar o seu fluxo de atendimento e desenhar a arquitetura certa, roteando cada pergunta para a ferramenta que de fato tem a resposta.