
Meu Agente de IA Continuava Comprimindo a Mesma Conversa. Veja Como Corrigi o Bug de Anti-Thrashing.
Eu notei algo estranho. Toda vez que o processo do meu agente de IA reiniciava, ele compactava a conversa novamente — mesmo que as últimas cinco compacções tivessem sido inúteis.
O prompt já estava limpo. O prompt do sistema e os esquemas de ferramentas somavam 30K tokens de piso incomprimível. Reduzir o histórico de mensagens não ajudaria. Mas o agente não sabia disso. Ele executava o loop de compactação toda vez, queimando tokens e tempo sem nenhum benefício.
A causa raiz? Um único contador em memória que desaparecia no reinício.
O Problema
A compressão de contexto é como as conversas de agentes de IA de longa duração permanecem sob a janela de contexto do modelo. Você tem um limite — digamos 50K tokens. Quando o provedor relata que o prompt está se aproximando desse limite, você compacta: resume mensagens antigas em uma única entrada em nível de sistema, descarta o histórico completo e continua.
Simples, certo?
Mas há um caso extremo: quando o prompt do sistema e os esquemas de ferramentas já estão próximos do limite, a compactação não pode ajudar. O histórico de mensagens encolhe, claro, mas o prompt total permanece acima da linha. Então, a próxima rodada aciona a compactação novamente. E novamente. E novamente.
Para parar isso, eu adicionei um guardião contra thrashing — um contador que aumenta cada vez que a compactação é executada, mas não limpa o limite. Após duas rodadas ineficazes, ele bloqueia a compressão adicional. Limpo.
# O guardião anti-thrashing (antes da correção)
class CompressionState:
def __init__(self):
# Somente em memória — desaparece no reinício
self._ineffective_compression_count = 0
def update_from_response(self, usage):
"""Chamado após cada resposta da API com contagens reais de tokens."""
if self._verify_compaction_cleared_threshold:
if self.last_prompt_tokens >= self.threshold_tokens:
self._ineffective_compression_count += 1
else:
self._ineffective_compression_count = 0
def should_compress(self):
"""Verificação de portão — bloqueia a compressão após 2 falhas."""
return self._ineffective_compression_count < 2
O guardião funciona perfeitamente em uma única sessão. Mas ele vive na memória. Quando o processo reinicia — implantação, recuperação de falhas, até mesmo um reinício gracioso — o contador é redefinido para zero. O guardião desarma. E o agente compacta a conversa já compactada mais uma vez.
A Correção
O padrão já estava no código para outros dois contadores: o cooldown de falha de compactação (que impede a tentativa de um provedor que falha) e a sequência de fallback (que rastreia quantos resumos de fallback determinísticos foram inseridos em sequência). Ambos persistiam através de um canal de estado de sessão durável apoiado por SQLite.
Eu apliquei o mesmo padrão ao contador anti-thrashing. Três partes:
1. Uma coluna de banco de dados. Eu adicionei compression_ineffective_count à tabela de sessões, com métodos de acesso que retornam o valor ou o escrevem de volta.
# hermes_state.py — acessores de contador persistente
def get_compression_ineffective_count(self, session_id: str) -> int:
row = self._conn.execute(
"SELECT compression_ineffective_count FROM sessions WHERE session_id = ?",
(session_id,)
).fetchone()
return row[0] if row else 0
def set_compression_ineffective_count(self, session_id: str, count: int) -> None:
self._conn.execute(
"UPDATE sessions SET compression_ineffective_count = ? WHERE session_id = ?",
(count, session_id)
)
2. Um gravador de veredictos centralizado. Toda vez que o método update_from_response() decide se a última compactação foi eficaz ou não, ele passa por _record_ineffective_compression_verdict(). Este método atualiza tanto o contador em memória quanto a linha do banco de dados — atomicamente, no mesmo caminho de código.
def _record_ineffective_compression_verdict(self, was_ineffective: bool):
if was_ineffective:
self._ineffective_compression_count += 1
else:
self._ineffective_compression_count = 0
O artigo aborda um desafio técnico que pode impactar a eficiência de agentes de IA em empresas. A solução proposta pode ser aplicada para otimizar o uso de tokens e melhorar a performance de interações em sistemas de IA, beneficiando negócios que dependem de automação.

