MODULO 4.5

πŸ’¬ UserPromptSubmit: injecao por turno

O hook mais flexivel. Injeta contexto DIFERENTE dependendo do que voce perguntou. Pergunta sobre DB? Carrega schema. Pergunta sobre deploy? Carrega infra.

6
Topicos
35
Minutos
Avancado
Nivel
CORE
Tipo
1

🎯 Quando usar UserPromptSubmit

Use quando o contexto necessario varia por pergunta. Nao faz sentido carregar schema em toda sessao, so quando alguem pergunta sobre DB.

πŸ”„ Casos tipicos

Quando vale o investimento:

  • β€’Voce tem dominios distintos (DB, infra, frontend) com docs proprios.
  • β€’Long-term tem muitas entradas (100+) e so algumas importam por pergunta.
  • β€’Quer economizar tokens evitando carregar tudo sempre.
  • β€’Tem busca semantica local pronta e quer aproveitar.

πŸ’‘ Se nao tem esses casos

SessionStart + PreCompact basta. UserPromptSubmit e sofistificacao, nao essencial.

2

πŸ” Keyword matching no prompt

80% dos casos resolvem com grep simples na pergunta. Sem LLM, sem embeddings.

πŸ“ Router por keyword

#!/usr/bin/env bash
# UserPromptSubmit hook com routing

INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.user_message' | tr '[:upper:]' '[:lower:]')

CONTEXT=""

# DB topics
if echo "$PROMPT" | grep -qE "sql|postgres|banco|query|schema"; then
  CONTEXT="$CONTEXT\n$(cat ~/.memory/docs/schema.md)"
fi

# Deploy topics
if echo "$PROMPT" | grep -qE "deploy|docker|k8s|nginx|infra"; then
  CONTEXT="$CONTEXT\n$(cat ~/.memory/docs/infra.md)"
fi

# API topics
if echo "$PROMPT" | grep -qE "endpoint|api|webhook|rota"; then
  CONTEXT="$CONTEXT\n$(cat ~/.memory/docs/api.md)"
fi

if [[ -n "$CONTEXT" ]]; then
  python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'UserPromptSubmit',
    'additionalContext': '''$CONTEXT'''
  }
}))
"
else
  echo '{}'
fi

πŸ’‘ Regex generoso

Inclua sinonimos e variantes. 'banco' e 'database' e 'DB' devem bater. Errar no match perde o valor todo.

3

🧠 Busca semantica antes do prompt

Para long-term grande (500+ entradas), keyword nao cobre. Ai entra embedding local.

πŸ“ Pipeline semantico

1. Carregar modelo de embedding local (fastembed)
   Custo: ~200ms uma vez por sessao (cached)

2. Encode query do usuario
   Custo: ~30ms

3. Buscar top 3 no indice (sqlite-vec)
   Custo: ~10ms

4. Retornar como additionalContext

Total: ~40ms por turno (excluindo carregamento inicial)
Qualidade: captura 'a decisao sobre pagamentos' mesmo
          sem a palavra 'decisao'.

πŸ’‘ So se precisar

Nao adicionar antes de sentir falta com keyword. Complexidade adicional, ganho so claro em long-term grande.

4

πŸ“ OrΓ§amento por turno

Cada turno e injetavel, mas tem cap. Mais que 1000 tokens extras por turno polui.

πŸ“Š Token budgets

  • Minimo util: 200 tokens (1 memoria relevante)
  • Ideal: 500-800 tokens (2-3 memorias)
  • Maximo: 1000 tokens
  • Alem disso: re-estrutura o hook, nao injete tudo

⚠️ Sinais de exagero

Se voce adiciona contexto toda pergunta e Claude parece confuso, provavelmente inflou. Corte para o essencial.

5

🚫 Quando NAO usar

Hooks por turno tem latencia e complexidade. Nao vale em casos simples.

βœ“ NAO usar UserPromptSubmit

  • βœ“Contexto e o mesmo em 90% das perguntas
  • βœ“SessionStart ja carrega o necessario
  • βœ“Long-term tem <50 entradas (grep basta)
  • βœ“Voce esta comecando β€” foque em SessionStart + PreCompact

βœ“ Usar UserPromptSubmit

  • βœ—Dominios distintos (DB, infra, tests)
  • βœ—Long-term > 200 entradas
  • βœ—Economia de tokens importa
  • βœ—Time diverso com vocabulario variado
6

πŸŽ“ Exemplo completo: roteador

Script de 30 linhas que serve de base para qualquer adaptacao.

πŸ“ Router pronto para copy

#!/usr/bin/env bash
# ~/.memory/hooks/user_prompt_router.sh

set -e

INPUT=$(cat)
PROMPT=$(echo "$INPUT" | jq -r '.user_message // ""' | tr '[:upper:]' '[:lower:]')

# Mapa topico β†’ arquivo
declare -A TOPICS=(
  ['sql|postgres|banco|schema']='schema.md'
  ['deploy|docker|k8s|infra']='infra.md'
  ['endpoint|api|webhook']='api.md'
  ['test|pytest|unittest']='testing.md'
  ['auth|token|session']='auth.md'
)

CONTEXT=""
for pattern in "${!TOPICS[@]}"; do
  if echo "$PROMPT" | grep -qE "$pattern"; then
    FILE="$HOME/.memory/docs/${TOPICS[$pattern]}"
    if [[ -f "$FILE" ]]; then
      CONTEXT="$CONTEXT\n$(cat "$FILE")"
    fi
  fi
done

# Cap a 800 tokens (~3200 chars)
CONTEXT="${CONTEXT:0:3200}"

if [[ -n "$CONTEXT" ]]; then
  python3 -c "
import json
print(json.dumps({
  'hookSpecificOutput': {
    'hookEventName': 'UserPromptSubmit',
    'additionalContext': '''$CONTEXT'''
  }
}))
"
else
  echo '{}'
fi

πŸ’‘ Versione seu mapa

O array TOPICS cresce com o tempo. Versione esse arquivo para nao perder evolucao.

πŸ“ Resumo do Modulo

βœ“
Dispara a cada mensagem β€” granularidade maxima.
βœ“
Keyword match resolve 80% β€” sem precisar LLM.
βœ“
Semantica para casos densos β€” embeddings locais.
βœ“
Cap de 1000 tokens/turno β€” acima disso polui.

Proximo:

4.6 β€” Lab completo: palavra-codigo