Usando o Synap
O Synap é um mecanismo de memória local para agentes de IA. Tudo fica em
~/.synap/ na máquina do usuário — sem nuvem, sem contas, sem chaves de API.
Você se comunica com ele através da família de ferramentas mcp__synap__*.
Esta habilidade ensina a árvore de decisão: qual ferramenta, quando, com quais argumentos. Leia os esquemas das ferramentas para a sintaxe exata dos parâmetros; este documento é sobre escolher a ferramenta certa e usá-la bem.
Conceitos principais
O Synap organiza dados em apps. Um app é um namespace (tarefas,
contabilidade, receitas, …) com um esquema. Esquemas são EAV por baixo dos panos, então
você pode adicionar campos depois sem uma migração. Cada app contém entidades
(linhas) com atributos (campos).
Dois apps são integrados e pertencem ao próprio Synap:
synap.memories— memória de longo prazo sobre o usuário. Escritas passam porremember/forget(nuncawrite). Leituras passam porquery/search.synap.sessions— histórico de conversas (turnos, resumos). Somente leitura para você; não escreva nele.
Apps voltados para o usuário, que você ou o usuário criam, ficam em outros nomes (sem
prefixo synap. — esse namespace é reservado).
Árvore de decisão
"Lembre-se de X sobre mim"
Use remember em synap.memories. Dois formatos:
- Atributo de perfil (
type: "attr") — um fato persistente sobre o usuário (idioma_preferido,cidade,alergias). Useop: "set"para sobrescrever,op: "append"para adicionar a uma lista. - Evento (
type: "event") — uma observação com timestamp ("usuário lançou v0.1.0 hoje", "usuário mencionou estar sobrecarregado"). Somente anexar, comdescription,subjectewhenopcional.
Escolha attr quando o fato é um estado duradouro. Escolha event quando é um momento no tempo que importa para contexto futuro.
"O que você sabe sobre mim?"
query em synap.memories com filters=[{field:"subject", op:"eq", value:"user"}]. Não use search a menos que o usuário tenha perguntado algo vago
como "algo sobre meus planos de viagem" — nesse caso search com rank: "time_decay" traz eventos recentes relevantes.
"Esqueça X"
forget. Preciso, baseado em chave. Não faça "query depois escreva nulos" — forget
lida com a limpeza de atributos e exclusão de eventos de forma atômica.
"Rastreie tarefas / receitas / despesas / …" (novo tipo de dado)
list_apps— verifique se já existe um.- Se não existir:
init_appcom um esquema bem pensado. writepara adicionar entidades.opsé um array: um op = escrita única, N ops = lote atômico (tudo ou nada).
Dicas de design de esquema:
- Marque campos de texto longo (descrições, notas) com
vectorized: truepara que a busca possa encontrá-los semanticamente. - Use
entity_typese um app contiver diferentes formatos ("tarefa" + "nota" em um único appworkspace). - Não projete demais a v1 — EAV permite adicionar campos depois.
"Mostre minhas tarefas / notas da semana passada / …"
query com filtros e ordenação. A saída TSV é densa — analise-a, não a jogue
de volta para o usuário crua.
"Encontre algo sobre X"
search. Três modos de classificação:
relevance(padrão) — correspondência semântica + por palavra-chave pura.recency— mais recentes primeiro, ignorando similaridade. Bom para "últimas notas".time_decay— combinação de ambos. Bom para contexto em evolução (eventos, diários) onde tanto novidade quanto relevância importam.
Passe app_id para escopo, ou omita para pesquisa entre apps.
"Leia este arquivo"
read_file — lida com URIs file://, synap:// e caminhos locais. Retorna
páginas divididas (padrão ~4K chars). Use o parâmetro page para navegar.
"O que você me disse antes?" (contexto foi compactado)
Procure por blocos <compressed_segment turn_ids="..."> na conversa.
expand com esses turn_ids busca de volta os originais literais.
<stale_tool_result turn_id="..."> segue o mesmo padrão para resultados de ferramentas recolhidos.
Anti-padrões
- Não escreva em apps
synap.*. O Synap rejeita. Useremember/forgetpara memória. - Não reinvente a memória com um app personalizado.
synap.memoriestem semântica de perfil+evento, classificação por decaimento temporal e injeção pré-turno embutida. - Não divida manualmente em excesso. Texto longo (>1024 tokens) é automaticamente dividido com sobreposição. Basta escrever o conteúdo completo.
- Não ignore o campo subject. A memória é escopada por
subject(padrão é"user"). Se o usuário estiver rastreando outra pessoa ("lembre-se que Alice prefere chá"), passesubject: "alice".
Padrões comuns
Configurando uma nova área da vida do usuário
Usuário: "Quero começar a rastrear minha leitura."
1. list_apps — confirme que não existe app "leitura"
2. init_app name="leitura" com campos:
- titulo (texto, obrigatório)
- autor (texto)
- status (enum: para_ler | lendo | lido)
- iniciado_em, finalizado_em (data)
- notas (texto, vectorized: true)
- avaliacao (número, 1-5)
3. "Pronto — me diga o que você está lendo e eu adiciono."
Trazendo contexto no início de uma conversa
Os blocos [memory: profile] e [memory: events] são injetados automaticamente
para você a cada turno. Você não precisa chamar query para vê-los. Mas
se o usuário perguntar algo que exija recordação mais ampla ("no que tenho trabalhado ultimamente?"), search em synap.memories com rank: "time_decay" é a chamada certa.
Migrando / remodelando dados
O Synap não tem migração formal. Para adicionar um campo: basta começar a escrevê-lo.
Linhas existentes simplesmente não terão o atributo. Para renomear: query para obter todos
os entity_ids, depois write um lote de atualizações mapeando campo antigo → campo novo
→ limpar campo antigo. O custo do EAV é mínimo.
Folha de consulta de ferramentas
| Objetivo | Ferramenta | Notas |
|---|---|---|
| Lembrar um fato do usuário | remember type=attr | op: set ou append |
| Registrar um evento com timestamp | remember type=event | somente anexar |
| Limpar uma memória | forget | chave precisa, não adivinhe |
| Criar um app de dados | init_app | idempotente, suporta evolução |
| Listar apps | list_apps | include_internal: true para ver synap.* |
| Adicionar/atualizar entidades | write | array ops, N = lote atômico |
| Filtrar entidades | query | saída TSV, projeção de campos |
| Busca semântica | search | rank: relevance | recency | time_decay |
| Ler um arquivo | read_file | páginas automaticamente |
| Recuperar turnos compactados | expand | passe turn_ids do bloco comprimido |
| Detectar links entre entidades | detect_links | opt-in, para grafos de conhecimento |