Guia Prático: Agente de Call Center Completo
Este guia mostra como construir um agente de call center completo que demonstra todas as ferramentas de voz SIP funcionando juntas. Diferente de exemplos simples, esta é uma implementação real que você pode adaptar para uso em produção.
O Que Vamos Construir
Um agente de atendimento ao cliente que:
- Cumprimenta os clientes e pede identificação
- Coleta CPF pelo teclado (
receive_dtmf) para consulta do cliente - Resolve problemas ou...
- Transfere para atendentes humanos (
transfer_call) quando necessário, ou... - Navega URAs externas (
send_dtmf) para consultar outros sistemas - Encerra chamadas (
end_dialog) capturando dados estruturados de resultado
Arquitetura de Integração
┌─────────────┐ ┌──────────────┐ ┌─────────────┐
│ Seu PBX │───SIP INVITE───▶│ SipPulse AI │────▶│ Seu CRM │
│ │ + headers │ │ │ │
│ call-id: │ │ │ │ │
│ abc123 │ x-uid: abc123 │ thread.uid = │ │ Busca por │
│ │ x-additional- │ abc123 │ │ UID abc123 │
│ │ instructions: │ (auto-criada) │ │ │
└─────────────┘ "caller: ..." └──────────────┘ └─────────────┘Pontos de Integração:
- Headers SIP passam UID e contexto—não é necessária chamada de API antes da ligação
- O sistema cria automaticamente a thread quando a chamada conecta
- Após a chamada terminar, busque a thread por UID para extrair resultados
- Use os dados do
end_dialogpara atualizar seu CRM/sistema de tickets
Início Rápido com Template
Quer pular a configuração manual? Vá em Agentes → Criar Agente → Templates e selecione "Agente de Call Center SIP". O template inclui todas as configurações deste guia—basta customizar os destinos de transferência e prompts para o seu negócio.
Pré-requisitos
Antes de começar:
- Conta SipPulse AI com acesso à API
- Implantação SIP configurada (veja o guia de Integração SIP)
- Entendimento básico de agentes (veja Introdução a Agentes)
- Um telefone SIP ou softphone para testes
Limitação do Playground de Voz
As ferramentas de voz SIP só funcionam durante chamadas SIP reais. Não podem ser testadas no Playground de Voz. Você precisa de uma conexão SIP real para testar este guia.
Parte 1: Configuração do Agente
1.1 Criar o Agente de Voz
- Navegue até Agentes e clique em Criar Agente
- Selecione Agente de Voz
- Nomeie: "Agente de Atendimento"
- Escolha um modelo com bom uso de ferramentas: gpt-5-mini ou claude-4-5-sonnet recomendados
1.2 Escrever as Instruções do Agente
Este prompt permite que o agente lide com múltiplos cenários e use todas as ferramentas de voz apropriadamente:
# Agente de Atendimento - Acme Corp
Você é o agente virtual de atendimento ao cliente da Acme Corp. Seu objetivo é ajudar
os clientes de forma eficiente mantendo um tom amigável e profissional.
## Variáveis de Contexto
Você tem acesso a estas variáveis da sessão do cliente:
- {{caller_id}} - O número de telefone do cliente
- {{inbound_did}} - Para qual linha da empresa ele ligou
## Fluxo de Identificação
### Passo 1: Saudação e Solicitação de CPF
Cumprimente o cliente calorosamente e peça que se identifique:
"Por favor, digite seu CPF de 11 dígitos usando o teclado do telefone. Pressione
cerquilha quando terminar, ou asterisco para apagar e recomeçar se cometer um erro."
### Passo 2: Coletar CPF (CRÍTICO)
- Use receive_dtmf para coletar exatamente 11 dígitos
- Timeout: 30 segundos
### Passo 3: Confirmar o CPF (OBRIGATÓRIO)
Após receber os dígitos, você DEVE:
1. Ler de volta CADA dígito individualmente: "Recebi: um, dois, três..."
2. Perguntar: "Está correto?"
3. Se NÃO: Peça desculpas e colete novamente
4. Se SIM: Prossiga para o atendimento
IMPORTANTE: NUNCA pule a confirmação. NUNCA leia como um número único.
## Fluxo de Atendimento
Após confirmar a identidade:
1. Pergunte como pode ajudar hoje
2. Tente resolver o problema diretamente
3. Se não conseguir resolver, transfira para o departamento apropriado
## Quando Transferir
Transfira a chamada quando:
- Cliente pedir explicitamente para falar com um humano
- Problema requer conhecimento técnico especializado
- Disputas financeiras ou reembolsos acima de R$ 500
- Cliente está frustrado após 2 tentativas de resolução
- Preocupações com segurança ou fraude
Ao transferir, explique o motivo e tranquilize o cliente.
## Destinos de Transferência
- sip:suporte@empresa.com - Suporte geral, dúvidas sobre conta
- sip:financeiro@empresa.com - Reembolsos, pagamentos, cobrança
- sip:tecnico@empresa.com - Problemas técnicos complexos
## Navegando Sistemas Externos
Se precisar consultar nosso sistema parceiro, use send_dtmf para navegar a URA:
- Pressione 1 para status da conta
- Pressione 2 para rastreamento de pedido
## Encerrando Chamadas
Encerre a chamada quando:
- Cliente confirmar que o problema foi resolvido
- Cliente se despedir
- Após transferência bem-sucedida (a ferramenta de transferência cuida disso)
Antes de encerrar, sempre pergunte: "Posso ajudar em mais alguma coisa?"
## Registrando Resultados da Chamada
Ao usar end_dialog, sempre capture:
- reason: Por que a chamada terminou (resolved, transferred, callback_requested, customer_ended)
- satisfaction: Satisfação expressa pelo cliente (1-5) se mencionou
- department: Qual departamento resolveu ou irá tratar
- resolution_notes: Breve resumo do que foi feito1.3 Configurar Ferramentas de Voz
Navegue até Configuração de Chamada > Ferramentas e configure cada ferramenta:

Configuração do Encerrar Diálogo
Ative Encerrar Diálogo e configure o JSON Schema para capturar dados estruturados:
{
"type": "object",
"properties": {
"reason": {
"type": "string",
"enum": ["resolved", "transferred", "callback_requested", "customer_ended"],
"description": "Por que a chamada terminou"
},
"satisfaction": {
"type": "integer",
"minimum": 1,
"maximum": 5,
"description": "Nota de satisfação se o cliente expressou"
},
"department": {
"type": "string",
"description": "Departamento que resolveu ou vai tratar o problema"
},
"resolution_notes": {
"type": "string",
"description": "Breve resumo do que foi resolvido ou do problema"
}
},
"required": ["reason"]
}Descrição:
Encerre a chamada quando o problema do cliente estiver resolvido ou ele quiser desligar.
Sempre pergunte se pode ajudar em mais alguma coisa antes de encerrar. Capture os dados
de resultado incluindo motivo, satisfação e notas de resolução.Configuração do Transferir Chamada
Ative Transferir Chamada e adicione seus destinos:
| Destino | Descrição |
|---|---|
sip:suporte@empresa.com | Equipe de suporte geral |
sip:financeiro@empresa.com | Departamento financeiro |
sip:tecnico@empresa.com | Suporte técnico |
Descrição:
Transferir para:
- suporte@empresa.com: Problemas gerais, dúvidas sobre conta, info de produtos
- financeiro@empresa.com: Reembolsos, disputas de pagamento, erros de cobrança, faturas
- tecnico@empresa.com: Problemas técnicos complexos, indisponibilidades, integraçõesConfiguração do Receber DTMF
Ative Receber DTMF com:
- Timeout Padrão: 30 segundos
Descrição:
Coletar número de identificação do cliente (CPF) ou outra entrada numérica.
Sempre confirme os dígitos antes de prosseguir.Configuração do Enviar DTMF
Ative Enviar DTMF com:
Descrição:
Navegar sistemas de URA externos ao consultar serviços parceiros.
Envie os dígitos apropriados baseado nas opções do menu.1.4 Configurar Saudação
Defina Estratégia de Saudação como "Gerada por IA" com:
Cumprimente o cliente calorosamente, apresente-se como o assistente de IA da
Acme Corp, e inicie o processo de identificação pedindo que digite o CPF
usando o teclado do telefone.Parte 2: Integração com PBX via Headers SIP
2.1 Como Funciona
Para chamadas SIP, o sistema cria threads automaticamente quando a chamada conecta ao seu agente. Você não precisa chamar nenhuma API antes da ligação começar. Em vez disso, você passa contexto para o agente via headers SIP que seu PBX adiciona ao SIP INVITE.
┌─────────────┐ ┌──────────────────────────┐
│ Seu PBX │──── SIP INVITE ─────────────▶│ <agent_id>@sip.sippulse.ai │
│ │ Headers: │ │
│ call-id: │ x-uid: abc123 │ Sistema cria thread │
│ abc123 │ x-additional- │ automaticamente com │
│ │ instructions: ... │ uid = "abc123" │
└─────────────┘ └──────────────────────────┘Fluxo de integração:
- Habilite SIP no seu agente e copie o endereço SIP (ex:
agt_xxxx@sip.sippulse.ai) - Configure seu PBX para rotear chamadas para esse endereço
- Adicione headers SIP para passar contexto (UID, instruções adicionais)
- Após a chamada terminar, busque a thread por UID para extrair resultados
Onde Obter o Endereço SIP
O endereço SIP do agente é configurado na plataforma em Implantar > SIP. Veja o guia de Integração SIP para detalhes.
2.2 Headers SIP Suportados
| Header | Obrigatório | Descrição |
|---|---|---|
x-uid | Recomendado | Vincula a thread ao call-id do seu PBX para busca posterior |
x-additional-instructions | Opcional | Contexto extra para o agente (info do caller, DID, dados do cliente) |
x-vars Ainda Não Suportado
O header x-vars ainda não é suportado. Use x-additional-instructions para passar contexto ao agente como instruções em linguagem natural.
2.3 Configurando Seu PBX
Asterisk (PJSIP)
; extensions.conf
[incoming]
exten => _X.,1,NoOp(Chamada de ${CALLERID(num)})
same => n,Set(PJSIP_HEADER(add,x-uid)=${UNIQUEID})
same => n,Set(PJSIP_HEADER(add,x-additional-instructions)=Caller: ${CALLERID(num)}, DID: ${EXTEN})
same => n,Dial(PJSIP/sippulse-trunk/${EXTEN})FreeSWITCH
<!-- dialplan/default.xml -->
<extension name="route_to_sippulse">
<condition field="destination_number" expression="^(.*)$">
<action application="set" data="sip_h_x-uid=${uuid}"/>
<action application="set" data="sip_h_x-additional-instructions=Caller: ${caller_id_number}, DID: ${destination_number}"/>
<action application="bridge" data="sofia/external/agt_xxxx@sip.sippulse.ai"/>
</condition>
</extension>Trunk SIP Genérico
A maioria dos sistemas SIP permite adicionar headers personalizados. Os headers principais a adicionar:
x-uid: <seu-call-id-do-pbx>
x-additional-instructions: Caller: +5511987654321, DID: +551140001234UID vs Thread ID
- Thread ID (
thr_xxx): Identificador interno do SipPulse - UID: Seu identificador externo (call-id, número de ticket, etc.)
Você pode buscar threads usando qualquer um. Se o ID começa com thr_, é tratado como interno. Caso contrário, é buscado pelo UID.
2.4 Buscando Resultados da Chamada
Após a chamada terminar, busque a thread por UID para extrair os dados de resultado:
import json
def get_call_outcome(call_id: str) -> dict:
"""Busca thread pelo call-id do PBX e extrai dados de resultado"""
response = requests.get(
f"{BASE_URL}/threads/{call_id}", # Usa UID diretamente
headers={"api-key": API_KEY}
)
thread = response.json()
outcome = {
"end_dialog": None,
"transfer_destination": None,
"dtmf_collected": [],
}
# Procura no histórico de mensagens por chamadas de ferramentas
for message in thread.get("history", []):
tool_calls = message.get("tool_calls", [])
for tool_call in tool_calls:
func = tool_call.get("function", {})
name = func.get("name")
args = json.loads(func.get("arguments", "{}"))
if name == "end_dialog":
outcome["end_dialog"] = args
elif name == "transfer_call":
outcome["transfer_destination"] = args.get("to")
elif name == "receive_dtmf":
# Resultados DTMF estão nas mensagens de resposta de ferramenta
pass
# Também verifica respostas de ferramentas para dados DTMF
for message in thread.get("history", []):
if message.get("role") == "tool":
content = message.get("content", "")
if "digits" in content:
try:
dtmf_data = json.loads(content)
outcome["dtmf_collected"].append(dtmf_data)
except:
pass
return outcome
# Exemplo de uso
outcome = get_call_outcome("pbx-call-abc123")
print(f"Resultado da chamada: {outcome}")
# {
# 'end_dialog': {'reason': 'resolved', 'satisfaction': 4, 'department': 'suporte'},
# 'transfer_destination': None,
# 'dtmf_collected': [{'digits': '12345678901', 'terminator': '#'}]
# }async function getCallOutcome(callId) {
const response = await fetch(
`${BASE_URL}/threads/${callId}`, // Usa UID diretamente
{ headers: { "api-key": API_KEY } }
);
const thread = await response.json();
const outcome = {
endDialog: null,
transferDestination: null,
dtmfCollected: [],
};
// Procura no histórico de mensagens por chamadas de ferramentas
for (const message of thread.history || []) {
for (const toolCall of message.tool_calls || []) {
const { name, arguments: args } = toolCall.function;
const parsedArgs = JSON.parse(args || "{}");
if (name === "end_dialog") {
outcome.endDialog = parsedArgs;
} else if (name === "transfer_call") {
outcome.transferDestination = parsedArgs.to;
}
}
// Verifica respostas de ferramentas para dados DTMF
if (message.role === "tool" && message.content?.includes("digits")) {
try {
const dtmfData = JSON.parse(message.content);
outcome.dtmfCollected.push(dtmfData);
} catch {}
}
}
return outcome;
}
// Uso
const outcome = await getCallOutcome("pbx-call-abc123");
console.log("Resultado da chamada:", outcome);2.5 Verificando Destino de Transferência (Pós-Chamada)
Quando o agente transfere uma chamada, o sistema automaticamente executa um SIP REFER para rotear a chamada ao destino. Este código serve para consultar para onde a chamada foi transferida após ela terminar—útil para relatórios e atualizações de CRM:
def get_transfer_destination(call_id: str) -> str | None:
"""Verifica se a chamada foi transferida e retorna o destino"""
response = requests.get(
f"{BASE_URL}/threads/{call_id}",
headers={"api-key": API_KEY}
)
thread = response.json()
for message in thread.get("history", []):
for tool_call in message.get("tool_calls", []):
if tool_call["function"]["name"] == "transfer_call":
args = json.loads(tool_call["function"]["arguments"])
return args.get("to")
return None
# Uso
destination = get_transfer_destination("pbx-call-abc123")
if destination:
print(f"Chamada foi transferida para: {destination}")
else:
print("Chamada não foi transferida")async function getTransferDestination(callId) {
const response = await fetch(
`${BASE_URL}/threads/${callId}`,
{ headers: { "api-key": API_KEY } }
);
const thread = await response.json();
for (const message of thread.history || []) {
for (const toolCall of message.tool_calls || []) {
if (toolCall.function.name === "transfer_call") {
const args = JSON.parse(toolCall.function.arguments);
return args.to;
}
}
}
return null;
}2.6 Exemplo Completo de Integração
Como as threads são criadas automaticamente pelo sistema quando chamadas SIP conectam, você só precisa tratar o evento de fim de chamada para extrair resultados. Aqui está um exemplo de webhook handler:
from flask import Flask, request, jsonify
import requests
import json
app = Flask(__name__)
API_KEY = "sua_chave_api"
BASE_URL = "https://api.sippulse.ai"
@app.route("/webhook/call-end", methods=["POST"])
def handle_call_end():
"""
Chamado quando a chamada termina - busca thread por UID e atualiza CRM.
O UID corresponde ao header x-uid que seu PBX adicionou ao SIP INVITE.
"""
data = request.json
call_id = data["call_id"] # Mesmo valor que você definiu no header x-uid
# Busca thread do SipPulse usando o UID
response = requests.get(
f"{BASE_URL}/threads/{call_id}",
headers={"api-key": API_KEY}
)
thread = response.json()
# Extrai dados de resultado do histórico da thread
outcome = extract_outcome(thread)
# Atualiza seu CRM/sistema de tickets
if outcome["end_dialog"]:
update_crm_ticket(
call_id=call_id,
reason=outcome["end_dialog"].get("reason"),
satisfaction=outcome["end_dialog"].get("satisfaction"),
notes=outcome["end_dialog"].get("resolution_notes"),
)
if outcome["transfer_destination"]:
log_transfer(call_id, outcome["transfer_destination"])
return jsonify({"status": "processed"})
def extract_outcome(thread: dict) -> dict:
"""Extrai dados de end_dialog e transferência do histórico da thread"""
outcome = {"end_dialog": None, "transfer_destination": None}
for message in thread.get("history", []):
for tool_call in message.get("tool_calls", []):
func = tool_call.get("function", {})
name = func.get("name")
args = json.loads(func.get("arguments", "{}"))
if name == "end_dialog":
outcome["end_dialog"] = args
elif name == "transfer_call":
outcome["transfer_destination"] = args.get("to")
return outcome
def update_crm_ticket(call_id, reason, satisfaction, notes):
"""Atualiza seu CRM com resultado da chamada"""
print(f"Atualizando CRM para {call_id}: {reason}, satisfação={satisfaction}")
def log_transfer(call_id, destination):
"""Registra transferência para relatórios"""
print(f"Chamada {call_id} transferida para {destination}")
if __name__ == "__main__":
app.run(port=5000)const express = require("express");
const app = express();
app.use(express.json());
const API_KEY = "sua_chave_api";
const BASE_URL = "https://api.sippulse.ai";
/**
* Chamado quando a chamada termina - busca thread por UID e atualiza CRM.
* O UID corresponde ao header x-uid que seu PBX adicionou ao SIP INVITE.
*/
app.post("/webhook/call-end", async (req, res) => {
const { call_id } = req.body; // Mesmo valor que você definiu no header x-uid
// Busca thread do SipPulse usando o UID
const response = await fetch(`${BASE_URL}/threads/${call_id}`, {
headers: { "api-key": API_KEY }
});
const thread = await response.json();
// Extrai dados de resultado do histórico da thread
const outcome = extractOutcome(thread);
// Atualiza seu CRM/sistema de tickets
if (outcome.endDialog) {
await updateCrmTicket(
call_id,
outcome.endDialog.reason,
outcome.endDialog.satisfaction,
outcome.endDialog.resolution_notes
);
}
if (outcome.transferDestination) {
await logTransfer(call_id, outcome.transferDestination);
}
res.json({ status: "processed" });
});
function extractOutcome(thread) {
const outcome = { endDialog: null, transferDestination: null };
for (const message of thread.history || []) {
for (const toolCall of message.tool_calls || []) {
const { name, arguments: args } = toolCall.function;
const parsedArgs = JSON.parse(args || "{}");
if (name === "end_dialog") {
outcome.endDialog = parsedArgs;
} else if (name === "transfer_call") {
outcome.transferDestination = parsedArgs.to;
}
}
}
return outcome;
}
async function updateCrmTicket(callId, reason, satisfaction, notes) {
console.log(`Atualizando CRM para ${callId}: ${reason}, satisfação=${satisfaction}`);
}
async function logTransfer(callId, destination) {
console.log(`Chamada ${callId} transferida para ${destination}`);
}
app.listen(5000, () => console.log("Servidor webhook rodando na porta 5000"));Parte 3: Exemplos de Conversas
Chamada Resolvida com Identificação DTMF
Agente: "Olá! Bem-vindo ao atendimento da Acme Corp. Sou seu assistente de IA. Para atendê-lo, por favor digite seu CPF de 11 dígitos usando o teclado do telefone. Pressione cerquilha quando terminar, ou asterisco para recomeçar se errar."
Cliente digita: 1-2-3-4-5-6-7-8-9-0-1-#
Agente: "Obrigado! Recebi: um, dois, três, quatro, cinco, seis, sete, oito, nove, zero, um. Está correto?"
Cliente: "Sim, está certo."
Agente: "Perfeito, encontrei sua conta, João. Como posso ajudar você hoje?"
Cliente: "Preciso verificar o status do meu pedido."
Agente: "Posso ajudar com isso. Deixa eu consultar seus pedidos recentes... Vejo que o pedido #12345 foi enviado ontem e deve chegar até sexta-feira. Gostaria do código de rastreamento?"
Cliente: "Não, está ótimo. Obrigado!"
Agente: "De nada! Posso ajudar em mais alguma coisa?"
Cliente: "Não, é só isso."
Agente: "Ótimo! Obrigado por ligar para a Acme Corp. Tenha um excelente dia!"
Agente encerra a chamada com:
{reason: "resolved", satisfaction: null, department: "suporte"}
Transferência para Atendente Humano
Cliente: "Fui cobrado duas vezes pelo meu pedido e quero reembolso!"
Agente: "Peço desculpas pelo inconveniente. Vejo que isso é uma questão de cobrança que nossa equipe financeira pode resolver diretamente para você. Vou transferir você agora—eles poderão processar seu reembolso. Por favor, aguarde um momento."
Agente transfere para
sip:financeiro@empresa.com
Tratamento de Erros na Coleta DTMF
Agente: "...Recebi: um, dois, três, quatro. Está correto?"
Cliente: "Não, eu errei."
Agente: "Sem problemas! Vamos tentar novamente. Por favor, digite seu CPF de 11 dígitos. Lembre-se, pressione asterisco para apagar e recomeçar, cerquilha quando terminar."
Cliente pressiona asterisco, depois digita o número correto
Parte 4: Como Funciona Internamente
Fluxo de Transferência
Quando o agente decide transferir:
- LLM gera chamada de ferramenta com o destino
- Sistema de voz recebe a solicitação de transferência
- Agente termina de falar ("Vou transferir você...")
- SIP REFER é enviado para seu trunk SIP
- Chamada é transferida para o destino
Agente fala → Aguarda TTS completar → SIP REFER → Chamada transferidaFluxo de Coleta DTMF
A coleta DTMF tem tratamento sofisticado:
- Buffer antecipado: Cliente pode começar a digitar antes do agente terminar de falar
- Término inteligente: Encerra na quantidade esperada de dígitos OU tecla terminadora (#)
- Capacidade de reset: Asterisco (*) limpa o buffer para recomeçar
- Tratamento de timeout: Fallback gracioso se não receber entrada
Agente: "Digite seu CPF..."
│
├── Cliente digita imediatamente (buffer)
│
└── Agente termina de falar
│
└── Coleta inicia/continua
│
├── # pressionado → Retorna dígitos
├── 11 dígitos → Retorna dígitos
├── * pressionado → Limpa, aguarda entrada
└── Timeout → Retorna parcial ou vazioParte 5: Solução de Problemas
DTMF Não Está Sendo Coletado
| Sintoma | Causa Provável | Solução |
|---|---|---|
| Ferramenta nunca dispara | Ferramenta não habilitada | Verifique Configuração de Chamada > Ferramentas |
| Nenhum dígito recebido | Problema de codec SIP | Verifique método DTMF (RFC 2833 ou SIP INFO) |
| Dígitos parciais | Latência de rede | Aumente timeout, verifique conexão |
| Dígitos não confirmados | Problema no prompt | Atualize instruções do agente para sempre confirmar |
Transferência Não Funciona
| Sintoma | Causa Provável | Solução |
|---|---|---|
| Transferência falha | URI SIP inválido | Verifique formato: sip:usuario@dominio |
| Destino errado | Instruções não claras | Seja mais específico na descrição da ferramenta |
| Loops de transferência | Agente confuso | Adicione condições mais claras no prompt |
| Erro SIP | Trunk não suporta REFER | Verifique com seu provedor SIP |
Problemas com Encerrar Diálogo
| Sintoma | Causa Provável | Solução |
|---|---|---|
| Nunca encerra | Ferramenta não habilitada | Habilite Encerrar Diálogo nas ferramentas |
| Encerra muito cedo | Condições muito amplas | Refine descrição e prompt |
| Dados faltando | Schema não corresponde | Verifique se JSON Schema é válido |
| Dados parciais | Agente não preenche todos os campos | Torne campos obrigatórios explícitos no prompt |
Busca por UID Falha
| Sintoma | Causa Provável | Solução |
|---|---|---|
| Thread não encontrada | UID não corresponde | Verifique correspondência exata do UID |
| Thread errada | UIDs duplicados | Garanta UIDs únicos por organização |
| Histórico vazio | Thread não usada | Verifique se a thread foi realmente usada na chamada |
Documentação Relacionada
- Referência de Ferramentas de Voz - Especificações completas das ferramentas
- Integração SIP - Configuração de implantação SIP
- Configuração de Agentes - Referência completa de configuração
- Guia de API REST - Detalhes de integração via API
- Prompts para Agentes - Escrevendo instruções eficazes
