Voltar as noticias
Meu Agente de IA Continuava Comprimindo a Mesma Conversa. Veja Como Corrigi o Bug de Anti-Thrashing.
Agentic SEOMediaEN

Meu Agente de IA Continuava Comprimindo a Mesma Conversa. Veja Como Corrigi o Bug de Anti-Thrashing.

Dev.to - MCP·25 de julho de 2026

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
Contexto Triplo Up

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.

Noticias relacionadas

Gostou do conteudo?

Receba toda semana as principais novidades sobre WebMCP.