0Pricing
AI Agents · Aula

Roteamento de tickets e lógica de escalonamento

Classificação da intenção, encaminhamento para agentes especialistas e gatilhos de escalonamento.

Roteamento de tickets e lógica de escalonamento é uma aula grátis de AI Agents no CoddyKit. Esta é a aula 1 de 4. Você pode ler a aula completa abaixo gratuitamente — depois pratica ao vivo no navegador com um editor de código integrado e um tutor de IA 24/7. Faz parte do caminho de aprendizado de AI Agents, e seu progresso é sincronizado entre a web e o app CoddyKit. O curso de AI Agents inclui 4 aulas no total.

O problema do roteamento

Um agente de atendimento ao cliente recebe milhares de mensagens variadas diariamente: contestações de cobrança, redefinições de senha, defeitos de produtos, atrasos no envio e solicitações de recursos. Enviar todas as mensagens ao mesmo responsável produz respostas lentas e de baixa qualidade.

O roteamento de chamados classifica cada mensagem e a envia à equipe mais bem preparada para resolvê-la.

Classificação de intenções com um LLM

A camada de roteamento chama um LLM com um comando de classificação. O modelo retorna uma resposta estruturada com um rótulo de intent e uma pontuação de confidence.

import openai, json

client = openai.OpenAI(api_key='YOUR_OPENAI_KEY')

INTENTS = ['billing', 'technical_support', 'returns_refunds',
           'account_access', 'shipping', 'general_inquiry']

def classify_intent(message: str) -> dict:
    prompt = (
        f'Classify this customer message into exactly one intent.\n'
        f'Intents: {INTENTS}\n'
        f'Message: "{message}"\n'
        f'Respond with JSON: {{"intent": "...", "confidence": 0.0-1.0}}'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

Roteamento para filas de especialistas

Quando a intenção é conhecida, encaminhe o chamado para a fila de especialistas apropriada. Cada fila tem seus próprios modelos de resposta, SLAs e regras de escalonamento.

ROUTING_MAP = {
    'billing':           'queue_billing',
    'technical_support': 'queue_tech',
    'returns_refunds':   'queue_returns',
    'account_access':    'queue_tech',
    'shipping':          'queue_fulfillment',
    'general_inquiry':   'queue_general'
}

def route_ticket(ticket: dict) -> str:
    result = classify_intent(ticket['message'])
    intent = result['intent']
    confidence = result['confidence']
    queue = ROUTING_MAP.get(intent, 'queue_general')
    ticket['intent'] = intent
    ticket['confidence'] = confidence
    ticket['queue'] = queue
    return queue

Limite de confiança para escalonamento

Se o classificador estiver incerto (confiança abaixo de 0,7), o roteamento automático poderá estar errado. Chamados com baixa confiança devem ser escalonados para uma pessoa realizar a triagem manual, em vez de serem encaminhados automaticamente a um especialista.

CONFIDENCE_THRESHOLD = 0.70

def route_with_escalation(ticket: dict) -> dict:
    result = classify_intent(ticket['message'])
    intent = result['intent']
    confidence = result['confidence']

    if confidence < CONFIDENCE_THRESHOLD:
        return {
            'ticket_id': ticket['id'],
            'action': 'escalate_to_human',
            'reason': f'Low confidence: {confidence:.2f}',
            'suggested_intent': intent
        }

    queue = ROUTING_MAP.get(intent, 'queue_general')
    return {
        'ticket_id': ticket['id'],
        'action': 'route_to_queue',
        'queue': queue,
        'intent': intent,
        'confidence': confidence
    }

Escalonamento baseado no SLA

Mesmo os chamados encaminhados automaticamente podem violar o SLA se não forem resolvidos a tempo. Um trabalho em segundo plano verifica a idade dos chamados em relação às metas de SLA e encaminha os chamados atrasados para uma fila de supervisão.

from datetime import datetime, timezone

SLA_HOURS = {
    'queue_billing':      4,
    'queue_tech':         8,
    'queue_returns':      24,
    'queue_fulfillment':  12,
    'queue_general':      48
}

def check_sla_breach(ticket: dict) -> bool:
    created = datetime.fromisoformat(ticket['created_at'])
    age_hours = (datetime.now(timezone.utc) - created).total_seconds() / 3600
    sla = SLA_HOURS.get(ticket['queue'], 24)
    if age_hours > sla and ticket['status'] == 'open':
        ticket['queue'] = 'queue_supervisor_escalation'
        ticket['escalation_reason'] = f'SLA breach: {age_hours:.1f}h > {sla}h'
        return True
    return False

if __name__ == '__main__':
    from datetime import datetime, timedelta, timezone
    old_ticket = {
        'created_at': (datetime.now(timezone.utc) - timedelta(hours=10)).isoformat(),
        'queue': 'queue_billing',
        'status': 'open',
    }
    breached = check_sla_breach(old_ticket)
    print(f'SLA breached: {breached}')
    if breached:
        print('Escalation reason:', old_ticket['escalation_reason'])

Roteamento com vários rótulos para chamados complexos

Algumas mensagens abrangem vários domínios: "Meu pedido chegou quebrado e fui cobrado duas vezes." Um classificador com vários rótulos retorna várias intenções; o chamado é duplicado em ambas as filas, e os agentes coordenam a resolução.

def classify_multi_intent(message: str) -> list[dict]:
    prompt = (
        f'A customer message may have multiple intents.\n'
        f'Intents: {INTENTS}\n'
        f'Message: "{message}"\n'
        f'Return JSON array: [{{"intent": "...", "confidence": 0.0}}]\n'
        f'Include only intents with confidence > 0.5'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    data = json.loads(resp.choices[0].message.content)
    return data.get('intents', [])

# Route to multiple queues
def route_multi(ticket: dict) -> list[str]:
    intents = classify_multi_intent(ticket['message'])
    return [ROUTING_MAP.get(i['intent'], 'queue_general') for i in intents]

Extração de metadados do chamado

Antes do roteamento, extraia metadados da mensagem para ajudar os especialistas: números de pedido, nomes de produtos e IDs de conta. Isso acelera a resolução ao eliminar a primeira rodada de perguntas de esclarecimento.

def extract_metadata(message: str) -> dict:
    prompt = (
        f'Extract structured metadata from this customer message.\n'
        f'Return JSON: {{"order_id": null, "product": null, "account_email": null}}\n'
        f'Use null for fields not mentioned.\n'
        f'Message: "{message}"'
    )
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)

meta = extract_metadata('My order #A12345 for the blue headphones never arrived.')
print(meta)  # {'order_id': 'A12345', 'product': 'blue headphones', 'account_email': None}

Aumento de prioridade com base no sentimento

Clientes irritados têm maior probabilidade de abandonar a empresa. Detecte sentimentos negativos e aumente a prioridade do chamado para que clientes insatisfeitos recebam respostas mais rápidas, mesmo que o prazo do SLA ainda não tenha expirado.

def detect_sentiment(message: str) -> str:
    prompt = f'Classify sentiment as positive/neutral/negative.\nMessage: "{message}"\nReturn JSON: {{"sentiment": "..."}}'
    resp = client.chat.completions.create(
        model='gpt-4o-mini',
        messages=[{'role': 'user', 'content': prompt}],
        response_format={'type': 'json_object'}
    )
    return json.loads(resp.choices[0].message.content)['sentiment']

def set_priority(ticket: dict) -> str:
    sentiment = detect_sentiment(ticket['message'])
    if sentiment == 'negative':
        ticket['priority'] = 'high'
    elif sentiment == 'positive':
        ticket['priority'] = 'low'
    else:
        ticket['priority'] = 'normal'
    return ticket['priority']

Definição da cadeia de escalonamento

Defina uma cadeia de escalonamento clara para que toda fila tenha uma alternativa. Quando a fila de primeiro nível não consegue resolver o chamado dentro do SLA, ele passa para o nível 2, depois para o nível 3 (especialista sênior) e, por fim, para a supervisão.

ESCALATION_CHAIN = {
    'queue_tech':              'queue_tech_tier2',
    'queue_tech_tier2':        'queue_tech_senior',
    'queue_tech_senior':       'queue_supervisor_escalation',
    'queue_billing':           'queue_billing_senior',
    'queue_billing_senior':    'queue_supervisor_escalation',
    'queue_returns':           'queue_supervisor_escalation',
    'queue_fulfillment':       'queue_supervisor_escalation',
    'queue_general':           'queue_supervisor_escalation',
    'queue_supervisor_escalation': None  # terminal — human manager
}

def escalate(ticket: dict) -> str | None:
    next_queue = ESCALATION_CHAIN.get(ticket['queue'])
    if next_queue:
        ticket['queue'] = next_queue
    return next_queue

if __name__ == '__main__':
    ticket = {'queue': 'queue_tech'}
    for _ in range(3):
        nxt = escalate(ticket)
        print(f"Escalated to: {ticket['queue']}")
        if nxt is None:
            break

Fluxo completo de roteamento

Combine classificação, extração de metadados, análise de sentimentos e verificação de SLA em um único fluxo de processamento executado para cada chamado recebido.

def process_ticket(raw_ticket: dict) -> dict:
    ticket = dict(raw_ticket)

    # Step 1: Classify and route
    routing = route_with_escalation(ticket)
    ticket.update(routing)

    # Step 2: Extract metadata
    ticket['metadata'] = extract_metadata(ticket['message'])

    # Step 3: Set priority from sentiment
    ticket['priority'] = set_priority(ticket)

    # Step 4: Check if already breaching SLA
    if ticket.get('created_at'):
        check_sla_breach(ticket)

    return ticket

result = process_ticket({
    'id': 'T001',
    'message': 'I was charged twice for my subscription last month!',
    'created_at': '2026-05-28T10:00:00+00:00',
    'status': 'open'
})
print(result)

Monitoramento da precisão do roteamento

Acompanhe a precisão do roteamento selecionando uma porcentagem dos chamados encaminhados automaticamente para revisão humana. Quando um especialista reencaminha um chamado para outra fila, isso representa um erro de roteamento. Use esses erros para aprimorar o comando ou ajustar um classificador.

import random

def log_routing_decision(ticket: dict, final_queue: str):
    was_correct = ticket.get('queue') == final_queue
    if not was_correct:
        print(f'[ROUTING_ERROR] ticket={ticket["id"]} '
              f'predicted={ticket["queue"]} actual={final_queue} '
              f'confidence={ticket.get("confidence", 0):.2f}')

# Specialist reassigns ticket: log the discrepancy
def specialist_reassign(ticket: dict, new_queue: str):
    log_routing_decision(ticket, new_queue)
    ticket['queue'] = new_queue
    return ticket

if __name__ == '__main__':
    ticket = {'id': 'T-1001', 'queue': 'queue_billing', 'confidence': 0.62}
    specialist_reassign(ticket, 'queue_tech')

Qual limite de confiança deve acionar o escalonamento para uma pessoa em vez do roteamento automático?

A escolha do limite de confiança adequado equilibra a taxa de automação e a precisão do roteamento. Um limite alto demais gera escalonamentos excessivos; um limite baixo demais causa encaminhamentos incorretos.

Recapitulação do roteamento de chamados

O roteamento eficaz de chamados combina a classificação de intenções por LLM com um limite de confiança para o escalonamento para uma pessoa, a extração de metadados para uma resolução mais rápida, a prioridade baseada no sentimento para clientes em risco e uma cadeia de escalonamento de SLA para garantir que nenhum chamado seja esquecido.

Perguntas Frequentes

A aula “Roteamento de tickets e lógica de escalonamento” é grátis?

Sim — o texto completo de “Roteamento de tickets e lógica de escalonamento” é grátis para ler aqui na web. Para praticá-la interativamente (um editor de código integrado e um tutor de IA 24/7) e desbloquear o restante do curso de AI Agents, atualize para CoddyKit PRO. O curso de AI Agents inclui 4 aulas no total.

O que vou aprender em “Roteamento de tickets e lógica de escalonamento”?

Classificação da intenção, encaminhamento para agentes especialistas e gatilhos de escalonamento. Você pratica AI Agents com código prático que executa diretamente no navegador, e um tutor de IA 24/7 responde suas dúvidas enquanto trabalha na aula.

Preciso ter experiência prévia para começar AI Agents?

Nenhuma experiência prévia é necessária. AI Agents no CoddyKit é estruturado para alunos iniciantes até avançados, então você pode começar aqui ou desde o início e aprender no seu ritmo. Esta é a aula 1 de 4.

Quanto tempo leva a aula “Roteamento de tickets e lógica de escalonamento”?

A maioria das aulas CoddyKit leva cerca de 5–10 minutos. Cada uma é compacta e interativa, então você faz progresso constante e retoma exatamente de onde parou entre web e app.

Posso escrever e executar código nesta aula de AI Agents?

Sim. Cada aula de AI Agents inclui um editor de código integrado, então você escreve e executa código real direto no navegador e recebe feedback de IA instantaneamente — nenhuma configuração local necessária.

Todas as aulas deste curso

  1. Roteamento de tickets e lógica de escalonamento
  2. Integração com CRM: Salesforce e HubSpot
  3. Protocolos de transferência para atendimento humano
  4. Gerenciamento do contexto e do histórico do cliente
← Voltar para AI Agents