Skip to content

πŸ“‹ Resumo Executivo: SoluΓ§Γ£o de Contexto Persistente

βœ… Problema Resolvido

Antes:

Usuario1: "Qual Γ© o preΓ§o do produto X?"
Agent:    "Custa R$ 100"
---
Usuario1: "O que vocΓͺ respondeu antes?"
Agent:    "Não tenho histórico 😞" ❌

Depois:

Usuario1: "Qual Γ© o preΓ§o do produto X?"
Agent:    "Custa R$ 100"
---
Usuario1: "O que vocΓͺ respondeu antes?"
Agent:    "VocΓͺ perguntou sobre o preΓ§o, que Γ© R$ 100" βœ…


πŸ—οΈ Arquitetura Implementada

β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ SLACK_BOT.PY                                               β”‚
β”‚ - Rate Limiting: 2 simultΓ’neas, 3/min por usuΓ‘rio          β”‚
β”‚ - ConcorrΓͺncia: AsyncApp com locks                         β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                  β”‚
                  ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ADK RUNNER (google.adk.runners.Runner)                     β”‚
β”‚ - Orquestra Session + Memory Services                      β”‚
β”‚ - Gerencia ciclo de vida de conversas                      β”‚
β””β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                             β”‚
      ↓                             ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”      β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚SESSION SERVICE   β”‚      β”‚ MEMORY SERVICE     β”‚
β”‚(Firestore)       β”‚      β”‚ (Firestore)        β”‚
β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€      β”œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€
β”‚βœ… Passo 1:       β”‚      β”‚βœ… Passo 2:         β”‚
β”‚ get_session()    β”‚      β”‚ add_session_to_    β”‚
β”‚ + session.events β”‚      β”‚ memory()           β”‚
β”‚                  β”‚      β”‚                    β”‚
β”‚ append_event()   β”‚      β”‚ search_memory()    β”‚
β”‚ = salva eventos  β”‚      β”‚ = busca histΓ³rico  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
      β”‚                             β”‚
      β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”¬β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ FIRESTORE (Google Cloud)                                   β”‚
β”‚                                                             β”‚
β”‚ collections:                                               β”‚
β”‚  β”œβ”€ agente_busca_produtos_sessions                        β”‚
β”‚  β”‚   └─ session_id β†’ {events: [...], messages: [...]}    β”‚
β”‚  β”‚                                                         β”‚
β”‚  └─ agente_busca_produtos_memory                          β”‚
β”‚      └─ user_id_timestamp β†’ {content, events_count}      β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜
                 β”‚
                 ↓
β”Œβ”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”
β”‚ ROOT_AGENT (LlmAgent)                                      β”‚
β”‚ - Tools:                                                   β”‚
β”‚   βœ… PreloadMemoryTool() ← NOVO (Passo 2)               β”‚
β”‚   βœ… busca_produtos_tool                                 β”‚
β”‚   βœ… tem_variacao_tool                                   β”‚
β”‚   βœ… ... (outras tools)                                  β”‚
β””β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”€β”˜

🎯 Dois Passos Implementados

Passo 1: Session.events (Contexto na Mesma SessΓ£o)

Arquivo: session/session_service.py

Problema: Agent perdia contexto a cada mensagem SoluΓ§Γ£o: Carregar eventos do Firestore em session.events

async def get_session(app_name, user_id, session_id):
    # Carrega messages do Firestore
    events = []
    for msg in stored_messages:
        event = Event(author=msg.role, role=msg.role, content=...)
        events.append(event)

    # Retorna Session COM eventos
    return Session(id=session_id, events=events)  # ← KEY!

async def append_event(session, event):
    # Runner chama isto apΓ³s cada resposta
    # Salva interaΓ§Γ£o no Firestore para prΓ³xima get_session()
    messages.append(convert_event_to_message(event))
    firestore.update(messages)

Resultado:

Request 1: session.events = []
Request 2: session.events = [evento1, evento2]  ← Agent VÊ HISTΓ“RICO
Request 3: session.events = [evento1, evento2, evento3, evento4]


Passo 2: MemoryService (Contexto Cross-Session)

Arquivo: session/memory_service.py

Problema: Agent nΓ£o sabia de conversas passadas SoluΓ§Γ£o: Armazenar memΓ³ria de longo prazo e permitir busca

async def add_session_to_memory(session):
    # Chamado apΓ³s conversa terminar
    memory_content = extract_knowledge(session)  # "Temos produtos X, Y, Z"
    firestore.save(user_id, memory_content)

async def search_memory(app_name, user_id, query):
    # Agent chama PreloadMemoryTool("vocΓͺ jΓ‘ recomendou algo?")
    results = firestore.search_by_keyword(user_id, query)
    return results  # "Sim, recomendei produtos X, Y, Z"

IntegraΓ§Γ£o:

# slack_bot.py
runner = Runner(
    agent=root_agent,
    session_service=session_service,
    memory_service=memory_service  # ← Passo 2
)

# ApΓ³s conversa
await memory_service.add_session_to_memory(completed_session)

# agent.py
root_agent = LlmAgent(
    tools=[
        PreloadMemoryTool(),  # ← Agent pode buscar histΓ³rico
        busca_produtos_tool,
        ...
    ]
)

Resultado:

SesiΓ³n A (semana passada): User fala sobre viagem
  β†’ Salvo em MemoryService βœ…

SessΓ£o B (hoje, novo canal): User "Lembra de mim?"
  β†’ Agent usa PreloadMemoryTool()
  β†’ "Claro! VocΓͺ tinha interesse em viagem!" βœ…


πŸ“Š Dados no Firestore

Collection: agente_busca_produtos_sessions

{
  "user123_slack_channel456": {
    "id": "user123_slack_channel456",
    "user_id": "user123",
    "messages": [
      {"role": "user", "parts": [{"text": "Qual produto?"}], ...},
      {"role": "assistant", "parts": [{"text": "Temos X, Y, Z"}], ...}
    ]
  }
}

Collection: agente_busca_produtos_memory

{
  "user123_1731834000000": {
    "user_id": "user123",
    "session_id": "user123_slack_channel456",
    "content": "P: Qual produto?\n\nTemos X, Y, Z",
    "event_count": 2
  }
}

πŸ§ͺ Como Testar

# 1. Execute a validaΓ§Γ£o completa
cd /Users/glauberportella/Projects/ifriend/ifriend-agents/busca_produtos
python validate.py

# 2. SaΓ­da esperada
βœ… Passo 1 (session.events): βœ… PASSOU
βœ… Passo 2 (MemoryService): βœ… PASSOU
βœ… IntegraΓ§Γ£o Completa: βœ… PASSOU

πŸŽ‰ TODAS AS VALIDAÇÕES PASSARAM!

πŸ“š DocumentaΓ§Γ£o

  • PASSO_1_SESSION_EVENTS.md - Detalhe tΓ©cnico do histΓ³rico de mesma sessΓ£o
  • PASSO_2_MEMORY_SERVICE.md - Detalhe tΓ©cnico do histΓ³rico cross-session
  • validate.py - Script de validaΓ§Γ£o automΓ‘tica

πŸš€ Deploy Checklist

  • βœ… CΓ³digo compilado (sem erros de imports)
  • βœ… Firestore collections criadas
  • βœ… SessionService persistindo eventos
  • βœ… MemoryService funcionando
  • βœ… PreloadMemoryTool integrada ao agent
  • βœ… Testes de validaΓ§Γ£o passando

PrΓ³ximo: Deploy em Cloud Run


πŸ“ˆ BenefΓ­cios Finais

MΓ©trica Antes Depois
Contexto na mesma sessΓ£o ❌ Nenhum βœ… 100%
Contexto cross-session ❌ Nenhum βœ… DisponΓ­vel
PersonalizaΓ§Γ£o do Agent ❌ BΓ‘sica βœ… AvanΓ§ada
ExperiΓͺncia do UsuΓ‘rio ⭐⭐ ⭐⭐⭐⭐⭐

πŸ’‘ PrΓ³ximos Melhoramentos

  1. Busca SemΓ’ntica - Usar embeddings para busca inteligente
  2. Limpeza AutomΓ‘tica - Remover memΓ³ria antiga (>6 meses)
  3. Analytics - Dashboard de hits/misses de memΓ³ria
  4. ExportaΓ§Γ£o - Permitir usuΓ‘rio baixar histΓ³rico
  5. Privacidade - EncriptaΓ§Γ£o de dados sensΓ­veis em memΓ³ria

πŸ“ž Suporte

DΓΊvidas sobre a arquitetura? - Revisar PASSO_1_SESSION_EVENTS.md para detalhes de session.events - Revisar PASSO_2_MEMORY_SERVICE.md para detalhes de MemoryService - Executar validate.py para confirmar funcionamento