Entendendo e Implementando Capacidades de Callback em Modelos de IA

Modelos de linguagem de grande escala (LLMs), como o Qwen3, são tradicionalmente limitados à entrada e saída de texto. No entento, para que possam interagir com o mundo real — chamar APIs, consultar bancos de dados ou controlar dispositivos — precisamos de um mecanismo de "callback". Este artigo explora como implementar essa funcionalidade, transformando um modelo local que não suporta callbacks nativos em um sistema capaz de executar funções externas.

O Conceito de Callback em Modelos de Linguagem

Um callback permite que um modelo de IA solicite a execução de uma função local e use o resultado para gerar uma resposta final. O fluxo básico é:

  1. O modelo recebe uma pergunta do usuário.
  2. Ele gera um texto com um placeholder, como ${weather('2025-05-17')}.
  3. O sistema local substitui o placeholder pelo resultado da função (ex.: "35°C").
  4. O modelo recebe o texto preenchido e produz a resposta final (ex.: "Use roupas leves.").

Isso é alcançado através de engenharia de prompt cuidadosa, onde o modelo é instruído a usar funções específicas para obter informações necessárias.

Implementação Prática com Qwen3 0.6B

Vamos demonstrra a implementação usando o modelo Qwen3 0.6B rodando localmente via Ollama. O código abaixo mostra como configurar o ambiente e executar o fluxo de callback.

Configuração do Ambiente

Primeiro, instale o Ollama (https://ollama.com/) e faça o download do modelo:

ollama pull qwen3:0.6b

Em seguida, configure o Python e as dependências:

brew install python
mkdir ~/qwen3-callback
cd ~/qwen3-callback
python3 -m venv .
source ./bin/activate
python3 -m pip install requests

Código Principle

Salve o seguinte código em um arquivo chamado callback.py:

import requests
import re
import json

# Configuração da API Ollama
OLLAMA_URL = "http://localhost:11434/api/generate"
MODELO = "qwen3:0.6b"

# Funções simuladas para callback
def temperatura(data):
    # Simula retorno de temperatura
    return 35

def buscar_produtos(item):
    # Simula busca de produtos
    return """
Lista de {item} por marca:
- Apple: MacBook Pro, MacBook Air
- Dell: XPS, Inspiron
- HP: Spectre, Envy
- Lenovo: ThinkPad, IdeaPad
"""

def buscar_precos(item):
    # Simula preço de produto
    return f"{item}: R$ 5.999,00"

# Função para chamar o Ollama
def chamar_ollama(prompt):
    payload = {
        "model": MODELO,
        "prompt": prompt,
        "stream": False,
        "temperature": 1
    }
    resposta = requests.post(OLLAMA_URL, json=payload)
    if resposta.status_code == 200:
        return json.loads(resposta.text)["response"]
    else:
        raise Exception(f"Erro na API Ollama: {resposta.text}")

# Extrai texto após o marcador "Resposta"
def extrair_apos_resposta(texto):
    marcadores = ["Resposta", "resposta", "Saída:", "saída:"]
    posicao_max = -1
    marcador_usado = None
    for marcador in marcadores:
        try:
            pos = texto.rindex(marcador)
            if pos > posicao_max:
                posicao_max = pos
                marcador_usado = marcador
        except ValueError:
            continue
    if posicao_max != -1:
        return texto[posicao_max + len(marcador_usado):].strip()
    return texto.strip()

# Processa placeholders e executa funções
def processar_placeholders(texto):
    padrao = r'\${([^}]+)\}'
    matches = re.findall(padrao, texto)
    if not matches:
        return texto
    for match in matches:
        if '(' in match and ')' in match:
            nome_funcao = match.split('(')[0].strip()
            argumento = match.split('(')[1].rstrip(')').strip()
            if nome_funcao == "temperatura":
                resultado = temperatura(argumento)
                texto = texto.replace(f"${{{match}}}", f"{resultado}")
            elif nome_funcao == "buscar_produtos":
                resultado = buscar_produtos(argumento)
                texto = texto.replace(f"${{{match}}}", resultado)
            elif nome_funcao == "buscar_precos":
                resultado = buscar_precos(argumento)
                texto = texto.replace(f"${{{match}}}", f"R$ {resultado}")
            else:
                texto = texto.replace(f"${{{match}}}", "[Função desconhecida]")
        else:
            texto = texto.replace(f"${{{match}}}", "[Placeholder inválido]")
    return texto

# Fluxo principal
def main():
    # Entrada do usuário
    entrada = "O que devo vestir hoje?"
    print(f"Usuário: {entrada}")
    print("=" * 40)

    # Primeira chamada: modelo gera placeholder
    prompt_inicial = f"""
Hoje é 17 de maio de 2025.
Pergunta do usuário: {entrada}
Funções disponíveis:
- temperatura('2025-05-17'): retorna a temperatura em Celsius.
- buscar_produtos(item): retorna informações sobre produtos.
- buscar_precos(item): retorna o preço de um produto.

Instruções: Se a pergunta precisar de informações de uma função, gere uma saída no formato:
${{funcao(argumento)}} fornece informações. Responda: {entrada}
Caso contrário, responda diretamente.
Exemplo:
- Entrada: "Está calor hoje?" -> Saída: "${{temperatura('2025-05-17')}} fornece informações. Responda: Está calor hoje?"
"""
    resposta1 = chamar_ollama(prompt_inicial)
    print(f"Primeira resposta do modelo: {resposta1}")

    texto_extraido = extrair_apos_resposta(resposta1)
    print(f"Texto após marcador: {texto_extraido}")

    texto_processado = processar_placeholders(texto_extraido)
    print(f"Texto com placeholders processados: {texto_processado}")

    # Segunda chamada: resposta final
    prompt_final = f"""
Com base nas informações a seguir, responda à pergunta do usuário:
{texto_processado}
"""
    resposta_final = chamar_ollama(prompt_final)
    print(f"Resposta final: {resposta_final}")

if __name__ == "__main__":
    main()

Execução e Resultados

Ao executar o script com python3 callback.py, a saída será similar a:

Usuário: O que devo vestir hoje?
Primeira resposta do modelo: ... (thinking) ...
${{temperatura('2025-05-17')}} fornece informações. Responda: O que devo vestir hoje?
Texto processado: 35 fornece informações. Responda: O que devo vestir hoje?
Resposta final: Com 35°C, recomenda-se usar roupas leves, como camiseta e shorts.

O modelo consultou a função de temperatura, obteve o valor 35°C, e então gerou uma recomendação de vestuário adequada.

Aplicações e Limitações

Este padrão de callback permite que modelos locais pequenos realizem tarefas que exigem dados externos ou computação. No entanto, o sucesso depende fortemente da qualidade dos prompts e da capacidade do modelo de seguir instruções com precisão. Modelos menores exigem prompts mais explícitos e podem falhar em cenários complexos.

Tags: IA Modelos de Linguagem Callback RAG Agentes

Publicado em 7-1 03:23