Files
agent_platform_oci/Manual_Long_Term_Memory_PT.md

12 KiB

Manual de Implementação — Long-Term Memory

Conceito

A Long-Term Memory (LTM) é a capacidade do agent_framework de armazenar e recuperar fatos duradouros além da duração de uma sessão de conversa.

Diferentemente do histórico de mensagens, que normalmente está associado a um session_id, a memória de longo prazo é associada à identidade de negócio do usuário ou cliente. Na implementação atual, essa identidade é composta por:

tenant_id
agent_id
customer_key

Isso permite que um agente recupere preferências, informações de identidade, projetos e restrições mesmo quando uma nova sessão é criada.

Para que serve

A Long-Term Memory serve para:

  • manter continuidade entre sessões;
  • personalizar respostas;
  • evitar que o usuário repita informações já fornecidas;
  • reduzir a necessidade de enviar todo o histórico ao modelo;
  • armazenar preferências, projetos atuais, nomes preferidos e restrições;
  • isolar a memória entre tenants, agentes e clientes.

Exemplo:

Sessão A:
"Me chame de Cris. Minha linguagem preferida é Python."

Sessão B, com outro session_id e o mesmo customer_key:
"O que você lembra sobre mim?"

Resposta esperada:
"Seu nome preferido é Cris e sua linguagem preferida é Python."

Diferença entre os tipos de memória

Conversation Memory

Mantém as mensagens da conversa atual e normalmente está associada ao session_id.

Summary Memory

Mantém um resumo da conversa para reduzir o tamanho do contexto enviado ao modelo.

Long-Term Memory

Mantém fatos duradouros entre sessões e é associada à identidade de negócio, principalmente ao customer_key.

Componentes da funcionalidade

LongTermMemoryManager

Responsável por coordenar:

  • carregamento das memórias;
  • recuperação por identidade;
  • renderização do contexto;
  • extração de novos fatos;
  • persistência dos fatos;
  • deduplicação e atualização.

LongTermMemoryStore

Interface de persistência utilizada pelo manager.

SQLiteLongTermMemoryStore

Implementação de referência baseada em SQLite.

É apropriada para:

  • desenvolvimento local;
  • testes;
  • demonstrações;
  • ambientes de baixa escala.

InMemoryLongTermMemoryStore

Implementação em memória utilizada para testes rápidos.

O conteúdo é perdido quando o processo do backend é encerrado.

LongTermMemoryExtractor

Responsável por identificar fatos duradouros nas mensagens.

Exemplos de fatos:

preferred_name = Cris
preferred_language = Python
current_project = Atlas

LongTermMemoryItem

Modelo que representa um item persistido, incluindo identidade, chave, valor, categoria, confiança e metadados.

AgentRuntime

Carrega a memória antes da execução do agente e injeta o contexto no prompt.

Nó persist_long_term_memory

Nó do LangGraph responsável por persistir os fatos após a geração e validação da resposta final.

Estrutura dos arquivos

libs/
└── agent_framework/
    └── src/
        └── agent_framework/
            └── memory/
                ├── __init__.py
                ├── long_term_extractor.py
                ├── long_term_memory.py
                ├── long_term_models.py
                └── long_term_store.py

Fluxo de execução

Mensagem do usuário
        │
        ▼
AgentRuntime.prepare_memory_context()
        │
        ├── Conversation Memory
        ├── Summary Memory
        └── Long-Term Memory
                    │
                    ▼
          long_term_memory_context
                    │
                    ▼
             Prompt do agente
                    │
                    ▼
                 Agente
                    │
                    ▼
       Guardrails / Judges / Supervisor
                    │
                    ▼
       persist_long_term_memory
                    │
                    ▼
          LongTermMemoryExtractor
                    │
                    ▼
           LongTermMemoryStore

Configuração do framework

Novos módulos

Copie os arquivos:

libs/agent_framework/src/agent_framework/memory/long_term_extractor.py
libs/agent_framework/src/agent_framework/memory/long_term_memory.py
libs/agent_framework/src/agent_framework/memory/long_term_models.py
libs/agent_framework/src/agent_framework/memory/long_term_store.py

Atualização de memory/init.py

Exporte os componentes da Long-Term Memory:

from agent_framework.memory.long_term_memory import (
    LongTermMemoryManager,
    create_long_term_memory_manager,
)
from agent_framework.memory.long_term_models import LongTermMemoryItem
from agent_framework.memory.long_term_store import (
    InMemoryLongTermMemoryStore,
    LongTermMemoryStore,
    SQLiteLongTermMemoryStore,
    create_long_term_memory_store,
)

Atualização de settings.py

Adicione as configurações:

ENABLE_LONG_TERM_MEMORY: bool = False
LONG_TERM_MEMORY_PROVIDER: str = "sqlite"
LONG_TERM_MEMORY_SQLITE_PATH: str = "./data/agent_framework.db"
LONG_TERM_MEMORY_TABLE: str = "agentfw_long_term_memory"
LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS: int = 20
LONG_TERM_MEMORY_MIN_CONFIDENCE: float = 0.70
LONG_TERM_MEMORY_AUTO_EXTRACT: bool = True
LONG_TERM_MEMORY_INJECT_CONTEXT: bool = True

Integração com AgentRuntime

O runtime deve:

  1. verificar se a funcionalidade está habilitada;
  2. criar o manager quando necessário;
  3. recuperar os fatos pela identidade;
  4. preencher o estado;
  5. injetar o contexto no prompt.

Campos adicionados ao estado:

long_term_memories: list[dict]
long_term_memory_context: str
long_term_memory_write_result: dict

Inicialização no AgentWorkflow

O manager deve ser criado no AgentWorkflow:

self.long_term_memory_manager = create_long_term_memory_manager(
    settings,
    telemetry=telemetry,
)

Inicialização correta dos agentes

O long_term_memory_manager não deve ser passado pelo agent_kwargs caso os construtores de BillingAgent, ProductAgent, OrdersAgent e SupportAgent não declarem esse parâmetro.

Esta inicialização causa erro:

agent_kwargs = {
    "telemetry": telemetry,
    "settings": settings,
    "memory": memory,
    "summary_memory": summary_memory,
    "long_term_memory_manager": self.long_term_memory_manager,
}

self.billing = BillingAgent(llm, **agent_kwargs)

Erro resultante:

TypeError: BillingAgent.__init__() got an unexpected keyword argument
'long_term_memory_manager'

A forma recomendada é criar os agentes com a assinatura já existente e injetar o manager como atributo após a inicialização:

agent_kwargs = {
    "telemetry": telemetry,
    "tool_router": getattr(self, "tool_router", None),
    "rag_service": self.rag_service,
    "cache": self.cache,
    "settings": settings,
    "observer": self.observer,
    "memory": memory,
    "summary_memory": summary_memory,
}

self.billing = BillingAgent(llm, **agent_kwargs)
self.product = ProductAgent(llm, **agent_kwargs)
self.orders = OrdersAgent(llm, **agent_kwargs)
self.support = SupportAgent(llm, **agent_kwargs)

for agent in (
    self.billing,
    self.product,
    self.orders,
    self.support,
):
    agent.long_term_memory_manager = self.long_term_memory_manager

Essa abordagem evita alterar os construtores de todos os agentes e mantém a funcionalidade encapsulada no framework.

Configuração do LangGraph

Registre o nó:

builder.add_node(
    "persist_long_term_memory",
    self._node(
        "persist_long_term_memory",
        self.persist_long_term_memory,
    ),
)

Altere o fluxo:

builder.add_edge(
    "supervisor_review",
    "persist_long_term_memory",
)
builder.add_edge(
    "persist_long_term_memory",
    "persist",
)

Implemente o método:

async def persist_long_term_memory(
    self,
    state: AgentState,
) -> dict[str, object]:
    result = await self.long_term_memory_manager.persist_turn(state)

    return {
        "long_term_memory_write_result": result,
    }

Fluxo final:

supervisor_review
        │
        ▼
persist_long_term_memory
        │
        ▼
persist

Variáveis de ambiente

ENABLE_LONG_TERM_MEMORY=true

LONG_TERM_MEMORY_PROVIDER=sqlite
LONG_TERM_MEMORY_SQLITE_PATH=./data/agent_framework.db
LONG_TERM_MEMORY_TABLE=agentfw_long_term_memory

LONG_TERM_MEMORY_MAX_CONTEXT_ITEMS=20
LONG_TERM_MEMORY_MIN_CONFIDENCE=0.70
LONG_TERM_MEMORY_AUTO_EXTRACT=true
LONG_TERM_MEMORY_INJECT_CONTEXT=true

Caminho do banco SQLite

O caminho relativo é resolvido a partir do diretório em que o backend é iniciado.

Para evitar que bancos diferentes sejam criados acidentalmente, prefira um caminho absoluto em ambientes de desenvolvimento:

LONG_TERM_MEMORY_SQLITE_PATH=/mnt/c/Asus_Projects/agent_platform_oci_long_term_memory/data/agent_framework.db

Crie a pasta antes de iniciar:

mkdir -p data

Como testar

Teste 1 — Gravação

Envie:

{
  "session_id": "default:telecom_contas:memory-session-a",
  "customer_key": "11999999999",
  "message": "Me chame de Cris. Minha linguagem preferida é Python e meu projeto atual se chama Atlas."
}

Teste 2 — Recuperação em outra sessão

Utilize outro session_id, mantendo o mesmo customer_key:

{
  "session_id": "default:telecom_contas:memory-session-b",
  "customer_key": "11999999999",
  "message": "O que você lembra sobre mim, minhas preferências e meu projeto?"
}

Resultado esperado:

Seu nome preferido é Cris.
Sua linguagem preferida é Python.
Seu projeto atual se chama Atlas.

Teste 3 — Isolamento

Utilize outro cliente:

{
  "session_id": "default:telecom_contas:memory-session-c",
  "customer_key": "outro-cliente",
  "message": "Qual é meu nome preferido e qual é meu projeto atual?"
}

Os dados de 11999999999 não devem aparecer.

Teste 4 — Reinicialização do frontend

Reinicie ou resete o frontend e confirme que ele continua enviando o mesmo customer_key.

A memória deve sobreviver à troca do session_id. O reset do frontend não apaga o SQLite.

Teste 5 — Reinicialização do backend

Reinicie o Uvicorn e repita a consulta.

Com:

LONG_TERM_MEMORY_PROVIDER=sqlite

a memória deve continuar disponível.

Com:

LONG_TERM_MEMORY_PROVIDER=memory

a memória será perdida quando o processo for encerrado.

Verificação direta no SQLite

Localize o banco:

find . -name "agent_framework.db" -type f

Abra:

sqlite3 ./data/agent_framework.db

Consulte:

SELECT
    tenant_id,
    agent_id,
    customer_key,
    memory_type,
    memory_key,
    memory_value,
    confidence,
    created_at,
    updated_at
FROM agentfw_long_term_memory
ORDER BY updated_at DESC;

Critérios de sucesso

A implementação está funcionando quando:

  • a memória é recuperada com outro session_id;
  • o mesmo customer_key recupera os fatos anteriores;
  • outro customer_key não acessa esses fatos;
  • reiniciar o frontend não apaga a memória;
  • reiniciar o backend não apaga a memória quando o provider é SQLite;
  • o nó persist_long_term_memory é executado;
  • o prompt recebe long_term_memory_context.

Boas práticas

  • Persistir somente fatos duradouros.
  • Não armazenar a conversa completa como Long-Term Memory.
  • Isolar dados por tenant_id, agent_id e customer_key.
  • Não utilizar session_id como identidade permanente do usuário.
  • Persistir somente depois das validações finais.
  • Evitar armazenar resultados temporários de ferramentas.
  • Registrar telemetria de leitura, escrita, atualização e falha.
  • Definir políticas de retenção e exclusão.
  • Usar caminho absoluto para SQLite em ambientes com múltiplos diretórios de execução.
  • Migrar para um banco corporativo em ambientes de produção e alta disponibilidade.

Limitações da implementação de referência

A implementação atual utiliza extração baseada em regras e SQLite como provider de referência.

Evoluções recomendadas:

  • extração de fatos com LLM;
  • memória semântica com vetores;
  • memória episódica;
  • expiração e versionamento;
  • deduplicação semântica;
  • política de consentimento;
  • API de consulta e exclusão;
  • provider Oracle Autonomous Database;
  • criptografia e classificação de dados sensíveis.