memoria-recall-flow

star 0

Use ao tocar Modules/Copiloto/Services/Memoria/, ContextSnapshotService, recall hybrid (Meilisearch + HyDE + reranker), MCP memory sync (git→DB→Scout), ou tabela copiloto_memoria_facts/memoria_metricas. Carrega contrato MemoriaContrato + 3 ângulos faturamento (ADR 0052) + os 14 gotchas catalogados em RETRIEVAL-GOTCHAS.md (Sprint 9). Skill mais específica que copiloto-arch — ativa só em retrieval/recall, não em IA-em-geral.

wagnerra23 By wagnerra23 schedule Updated 6/8/2026

name: memoria-recall-flow description: Use ao tocar Modules/Jana/Services/Memoria/, ContextSnapshotService, recall hybrid (Meilisearch + HyDE + reranker), MCP memory sync (git→DB→Scout), ou tabela copiloto_memoria_facts/memoria_metricas. Carrega contrato MemoriaContrato + 3 ângulos faturamento (ADR 0052) + os 14 gotchas catalogados em RETRIEVAL-GOTCHAS.md (Sprint 9). Skill mais específica que copiloto-arch — ativa só em retrieval/recall, não em IA-em-geral. trust_level: L1 owner: wagner parent_mission: meta-skill-roi-erp-autonomo charter_adr: 0080 tier: B parent_adr: 0095

Memória do Copiloto — fluxo de recall canônico

Quando ativa

  • Edit/Write em Modules/Jana/Services/Memoria/ (drivers, HyDE, reranker, cache)
  • Edit/Write em ContextSnapshotService.php
  • Mexer em Modules/Jana/Services/Mcp/IndexarMemoryGitParaDb.php ou McpSyncMemoryCommand
  • Migração / query em copiloto_memoria_facts ou copiloto_memoria_metricas ou mcp_memory_documents
  • Mudar config Scout / Meilisearch / Ollama / qwen3-embedding
  • Pergunta com termos: "recall", "hybrid search", "embedding", "HyDE", "reranker", "RAGAS", "negative cache", "ContextoNegocio"

Para arquitetura geral do Copiloto, ver skill copiloto-arch

Esta skill é o sub-fluxo de recall. Pra stack inteira (laravel/ai, Agents, métricas, OTel), ative copiloto-arch em paralelo.

Pipeline de recall (não pular nenhum estágio)

query → NegativeCache.miss? → HyDE.expandir → Meilisearch hybrid (semanticRatio 0.7) → LlmReranker → top-K
                  │
                  └── hit? retorna [] sem chamar Meilisearch (economia)
Estágio Service Por quê existe
1. Negative cache NegativeCacheService Query anterior retornou 0; evita re-buscar mesmo termo em janela TTL
2. HyDE HydeQueryExpander Gera "fato hipotético" → embedda; sobe recall@5 ~15%
3. Hybrid MeilisearchDriver BM25 + vector via callback Scout (semanticRatio configurável)
4. Rerank LlmReranker LLM pequeno re-ordena top-K bruto pra top-K final
5. Persistência tabela copiloto_memoria_facts (Searchable + SoftDeletes) Append-only; valid_until setado = superseded

Ingress (sync git→DB): IndexarMemoryGitParaDbmemory/* do worktree, faz upsert em mcp_memory_documents com PII redactor automático, dispara Scout observer pra re-embedar. Comando wrapper: McpSyncMemoryCommand.

§Crítico — ContextoNegocio expõe 3 ângulos (ADR 0052)

ContextSnapshotService::faturamento90d() retorna 3 valores distintos por mês — não 1:

Ângulo Fonte SQL Significado
bruto SUM(transactions.final_total) WHERE type='sell' Vendi
liquido bruto - SUM(... WHERE type='sell_return') Faturamento líquido
caixa SUM(transaction_payments.amount) GROUP BY paid_on O que entrou no caixa

Por que importa: Larissa (biz=4) testou 3 perguntas distintas em prod e recebeu o MESMO valor R$ [redacted Tier 0] Causa-raiz: faturamento90d retornava 1 número só. Fix em commit fac96a19. Princípio formalizado em ADR 0052 — quando métrica admite múltiplos recortes legítimos, expor TODOS.

BC-compat: campo valor mantido como alias do bruto. Se for adicionar nova métrica que admite recortes (custos / lucro / inadimplência), seguir mesmo padrão.

§Crítico — 14 gotchas catalogados

Fonte: memory/requisitos/Jana/RETRIEVAL-GOTCHAS.md. Cada um já queimou ≥30min. Top dos perigosos:

# Gotcha Sintoma Mitigação
1 Embedding model com idioma dominante errado Cosine ~0.97 uniforme em PT-BR Validar MTEB Multilingual ANTES de instalar; usar qwen3-embedding:4b ou multilingual-e5-large-instruct
2 Scout observer em qualquer update() 383 requests Ollama a cada sync NÃO chamar $doc->update(['indexed_at' => now()]) no branch "sem mudança"
3 Meilisearch v1.43+ SSRF protection Bloqueia IPs privados (Ollama na LAN) Usar Tailscale ou whitelist explícita
4 semanticRatio=0.0 ≠ keyword puro Recall pior que esperado Pra keyword puro, usar driver dedicado, não ratio 0
5 Meilisearch BM25 sem stopwords PT-BR < MySQL FT Recall@5 cai vs FULLTEXT NL Configurar stopwords PT-BR no índice
6 scout:import re-embeda TUDO Custo OpenAI explode Sempre usar mcp:sync-memory (incremental)
8 content_excerpt não strippa frontmatter YAML Excerpt mostra ---\nname: ... em vez de conteúdo Strippar ---...--- antes do mb_substr
10 Filter Meilisearch — aspas em PHP business_id = '4' quebra parser Usar aspas simples DENTRO de double-quoted PHP string
13 Tasks Meilisearch travadas em SSRF retry Fila empacada Verificar meilisearch tasks list periodicamente

Antes de mexer em retrieval, ler RETRIEVAL-GOTCHAS.md inteiro — 14 itens, 5min de leitura.

§Crítico — Ingress sync git→DB (mcp:sync-memory)

Fluxo: webhook GitHub → roda php artisan mcp:sync-memory no CT 100 → IndexarMemoryGitParaDb → upsert em mcp_memory_documents → Scout observer → embedding → Meilisearch index.

Etapa Onde
Source-of-truth git (memory/*.md)
Cache governado mcp_memory_documents (tabela)
Index buscável Meilisearch (CT 100, FrankenPHP)
Quota / governança QuotaEnforcer
Audit mcp_audit_log (IMUTÁVEL — só INSERT)

Latência alvo: webhook → tools MCP enxergarem doc novo < 60s.

ZERO auto-mem privada (ADR 0061): hook block-automem.ps1 BLOQUEIA Write/Edit em ~/.claude/projects/*/memory/*.md. Tudo vai pra git.

Métricas obrigatórias (ADR 0050) — apuração diária

Tabela copiloto_memoria_metricas (14 colunas):

8 obrigatórias:

  • memoria_recall_chars (alvo: > 100 em chat real)
  • recall_at_5 (gate: ≥ 0.80)
  • precision_at_5
  • mrr_at_10
  • latency_p50_ms / latency_p95_ms
  • cost_token_in / cost_token_out

6 RAGAS-aligned (golden set MEM-MET-5 destrava):

  • context_relevance
  • groundedness
  • answer_relevance
    • 3 derivadas

Apurador: MetricasApurador → cron 23:55 daily via ApurarMetricasCommand --business=all.

Pegadinhas críticas

  • NÃO chamar Meilisearch sem passar por NegativeCache. Query "vendi quanto" repetida 5×/dia = 5 chamadas inúteis se cache miss.
  • NÃO setar semanticRatio=1.0 esperando "puro vetorial". A camada lexical complementa em queries com nome próprio (Larissa, ROTA LIVRE) — perde precisão.
  • NÃO confiar que LLM deriva matemática que ContextoNegocio não fornece. Princípio ADR 0052: expor todos os ângulos legítimos como dados; o LLM só precisa escolher qual citar.
  • NÃO fazer DELETE em copiloto_memoria_facts. Append-only — usar valid_until = now(). Esquecer LGPD = SoftDelete (esquecer()).
  • NÃO testar com RefreshDatabase — migrations core UltimatePOS quebram em SQLite. Usar beforeEach com Schema::create da tabela alvo.
  • NÃO mascarar PII na ponta do LLM e esquecer no log. Sanitizar via LaravelAiSdkDriver::mascararDocumentos() ANTES de qualquer call (LLM, log, audit).

Multi-tenant (skill multi-tenant-patterns)

Todo recall é scoped por business_id + user_id:

  • MeilisearchDriver::buscar(int $businessId, int $userId, ...) — assinatura impõe scope
  • Filtro Meilisearch: business_id = X AND user_id = Y
  • Validação Pest: 1 fato de biz=4 nunca aparece em recall de biz=1

Validação local antes de comitar mudança em retrieval

# 1. Lint
php -l Modules/Jana/Services/Memoria/MeilisearchDriver.php

# 2. Suite Copiloto inteira
vendor/bin/pest Modules/Jana/Tests/

# 3. Recall sanity check (precisa de Meilisearch + golden set)
php artisan copiloto:gabarito:avaliar --business=4 --top=5

# 4. Teste embedding model NÃO degradou (gotcha #1)
# 2 docs muito diferentes devem ter cosine < 0.9
php artisan tinker --execute="..." # ver RETRIEVAL-GOTCHAS.md §1

Documentos-fonte canônicos

ADRs canônicos (alta densidade)

  • ADR 0036 — Meilisearch first; benchmark 95.2% LongMemEval; 5 triggers reavaliar
  • ADR 0037 — Roadmap memória (Tier 7+)
  • ADR 0049 — 6 camadas memória (Working/ConvHist/Episodic/Semantic/Procedural/Reflective) + gate Recall@3>0.80
  • ADR 0050 — 8 métricas obrigatórias + tabela copiloto_memoria_metricas
  • ADR 0051 — schema próprio + adapter sobre Laravel\Ai\Contracts\ConversationStore + OTel GenAI
  • ADR 0052 — ContextoNegocio múltiplos ângulos
  • ADR 0061 — zero auto-mem privada (todo conhecimento → git → MCP)
Install via CLI
npx skills add https://github.com/wagnerra23/oimpresso.com --skill memoria-recall-flow
Repository Details
star Stars 0
call_split Forks 0
navigation Branch main
article Path SKILL.md
More from Creator