Capítulo 7 de 13

Memória: fazer o atendente lembrar da conversa

Sem isto, cada mensagem começa do zero e o cliente repete tudo. Com isto, a conta pode disparar. O meio-termo, com código.

Manual gratuito de Certu · Atualizado em 30 de agosto de 2026 · ver o manual inteiro

Como fazer a IA lembrar do que o cliente já disse?

Resposta curta

Você guarda as últimas mensagens da conversa em um banco simples, com o telefone como chave, e manda esse histórico junto na próxima chamada ao modelo. Guardar as últimas dez trocas resolve quase todo atendimento sem encarecer a resposta.

O que ter aberto antes de começar

Por que o modelo não lembra sozinho?

Cada chamada ao modelo é independente. Ele não guarda nada entre uma mensagem e outra: quem guarda é você.

Sem memória, o cliente diz "quero marcar pra sexta" e a próxima resposta pergunta de novo o que ele quer. É o defeito que mais entrega que tem robô do outro lado.

O código

Guarda as últimas dez trocas por telefone e apaga sozinho depois de 24 horas.

CONVERSAS é um espaço de chave e valor. No Cloudflare, você cria com npx wrangler kv namespace create CONVERSAS e cola a linha que ele imprime no wrangler.jsonc.

Qualquer banco serve. O que importa é a chave ser o telefone e o valor ser a lista das últimas mensagens.

src/index.jsjavascript
const MAX_TROCAS = 10;      // 10 do cliente + 10 do atendente
const VALIDADE = 60 * 60 * 24; // 24 horas, em segundos

async function lerHistorico(env, telefone) {
  const bruto = await env.CONVERSAS.get('hist:' + telefone);
  return bruto ? JSON.parse(bruto) : [];
}

async function salvarHistorico(env, telefone, historico) {
  const cortado = historico.slice(-MAX_TROCAS * 2);
  await env.CONVERSAS.put('hist:' + telefone, JSON.stringify(cortado), {
    expirationTtl: VALIDADE,
  });
}

// A chamada do capitulo 5, agora com historico
async function pensarResposta(env, cerebro, historico, mensagemDoCliente) {
  const contents = [
    ...historico.map((m) => ({ role: m.papel, parts: [{ text: m.texto }] })),
    { role: 'user', parts: [{ text: mensagemDoCliente }] },
  ];

  const resposta = await fetch(
    'https://generativelanguage.googleapis.com/v1beta/models/gemini-2.5-flash-lite:generateContent',
    {
      method: 'POST',
      headers: {
        'x-goog-api-key': env.GEMINI_API_KEY,
        'Content-Type': 'application/json',
      },
      body: JSON.stringify({
        system_instruction: { parts: [{ text: cerebro }] },
        contents,
        generationConfig: { temperature: 0.4, maxOutputTokens: 300 },
      }),
    },
  );

  if (!resposta.ok) return null;
  const dados = await resposta.json();
  return dados?.candidates?.[0]?.content?.parts?.[0]?.text?.trim() ?? null;
}

// No webhook, depois de responder:
// const historico = await lerHistorico(env, de);
// const resposta = await pensarResposta(env, CEREBRO, historico, texto);
// if (resposta) {
//   await enviarWhatsApp(env, de, resposta);
//   historico.push({ papel: 'user', texto });
//   historico.push({ papel: 'model', texto: resposta });
//   await salvarHistorico(env, de, historico);
// }

Quanto histórico guardar?

Dez trocas é o ponto em que quase todo atendimento cabe e o custo ainda é de centavos. Acima disso você paga para o modelo reler o que não vai usar.

TamanhoEfeito na conversaEfeito no custo
NenhumO cliente repete tudo a cada mensagemO mais barato
5 trocasResolve pergunta e resposta curtasQuase o mesmo
10 trocasAguenta um agendamento inteiroCerca de duas vezes a entrada
Conversa inteiraLembra de tudo, inclusive do que não importaCresce sem parar e fica caro

Arraste a tabela para o lado para ver todas as colunas.

A armadilha do limite de escritas

O nível gratuito do armazenamento de chave e valor da Cloudflare permite 100 mil leituras por dia, mas só mil escritas por dia.

Como o código acima escreve uma vez por mensagem respondida, mil respostas por dia é o teto do plano gratuito. É bastante para começar e é a primeira coisa que estoura quando o volume sobe.

Onde as pessoas se queimam

Guardar conversa é guardar dado de cliente. Coloque prazo de validade desde o primeiro dia, como o expirationTtl acima, em vez de deixar tudo para sempre. O capítulo 11 explica a parte legal disso.

Perguntas frequentes

Preciso de banco de dados?

Um espaço simples de chave e valor resolve. Banco relacional só passa a valer quando você quiser relatório, busca por cliente ou histórico ligado a um cadastro.

Por quanto tempo devo guardar a conversa?

O suficiente para o atendimento fazer sentido. Vinte e quatro horas cobre a maioria dos casos; se você quiser retomar depois, guarde um resumo curto em vez do histórico inteiro.

Dá para resumir a conversa em vez de guardar tudo?

Dá, e é o caminho quando as conversas ficam longas: a cada dez trocas, peça ao modelo um resumo de três linhas e guarde só o resumo mais as últimas mensagens.

O que acontece se dois avisos chegarem ao mesmo tempo?

Um pode sobrescrever o outro, porque os dois leem e escrevem a mesma chave. Em volume baixo isso quase não aparece; em volume alto, use um banco com escrita atômica.

E onde entra Certu

Em Certu cada conversa vira contato, negócio e tarefa num lugar só, e o histórico é o que o dono lê quando assume a conversa no meio. É a mesma memória deste capítulo, com uma tela em cima e prazo de guarda decidido no lugar certo.

Ver o que Certu faz e quanto custa

Continuar o manual