🎨 Design da Interface de Captura no Telegram
A qualidade do segundo cérebro depende da frequência de captura. Interface com fricção é abandonada. O design correto torna a captura tão natural quanto pensar em voz alta.
🎨 Princípios UX para Captura
✓ Design correto
- ✓Texto livre capturado automaticamente, sem comandos
- ✓Confirmação imediata com emoji e resumo de 1 linha
- ✓Sugestão contextual de páginas do vault relacionadas
- ✓Comandos avançados disponíveis mas não obrigatórios
✗ Design com fricção
- ✗Exigir /comando antes de qualquer captura
- ✗Pedir tag ou categoria antes de salvar
- ✗Sem confirmação — usuário não sabe se foi salvo
- ✗Resposta muito longa que esconde a confirmação
⌨️ Comandos Customizados
Comandos explícitos criam intenções declaradas — o usuário sabe exatamente o que o sistema vai fazer. Crítico para operações como ingestão e auditoria que não devem acontecer acidentalmente.
# No BotFather: /setcommands
# Selecione seu bot, depois:
ingere - Capturar URL ou texto no vault
consulta - Busca híbrida SQLite+wiki
audit - Auditar vault (órfãos, gaps)
status - Estatísticas do vault e memória
compilar - Compilar raw/ pendentes
sync - Sincronizar vault → SQLite
from telegram.ext import CommandHandler
# Registrar todos os comandos
handlers = [
CommandHandler("ingere", ingere_handler),
CommandHandler("consulta", consulta_handler),
CommandHandler("audit", audit_handler),
CommandHandler("status", status_handler),
CommandHandler("compilar", compilar_handler),
CommandHandler("sync", sync_handler),
]
for h in handlers:
app.add_handler(h)
async def audit_handler(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
"""Executa lint do vault e reporta problemas"""
await update.message.reply_text("🔍 Auditando vault...")
wiki_dir = VAULT_DIR / "wiki"
index = (wiki_dir / "index.md").read_text()
# Páginas no index
indexed = set(re.findall(r'\[\[([^\]]+)\]\]', index))
# Arquivos existentes
files = {f.stem for f in wiki_dir.glob("*.md") if f.stem != "index"}
orphans = files - indexed # Arquivos sem entrada no index
missing = indexed - files # Entradas no index sem arquivo
report = f"📊 **Auditoria do Vault**\n\n"
report += f"✅ Páginas indexadas: {len(indexed)}\n"
report += f"📄 Arquivos wiki: {len(files)}\n\n"
if orphans:
report += f"⚠️ Órfãos ({len(orphans)}):\n"
for o in list(orphans)[:5]:
report += f" • {o}\n"
if missing:
report += f"\n❌ Faltando ({len(missing)}):\n"
for m in list(missing)[:5]:
report += f" • {m}\n"
if not orphans and not missing:
report += "✅ Vault saudável! Nenhum problema encontrado."
await update.message.reply_text(report, parse_mode='Markdown')
async def status_handler(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
wiki_dir = VAULT_DIR / "wiki"
conn = sqlite3.connect(DB_PATH)
wiki_count = len(list(wiki_dir.glob("*.md")))
mem_count = conn.execute("SELECT COUNT(*) FROM memories").fetchone()[0]
vault_mems = conn.execute(
"SELECT COUNT(*) FROM memories WHERE source='vault'"
).fetchone()[0]
# Última página modificada
pages = sorted(wiki_dir.glob("*.md"), key=lambda f: f.stat().st_mtime)
last_page = pages[-1].stem if pages else "—"
report = (
f"📊 **Status do Segundo Cérebro**\n\n"
f"📖 Páginas wiki: {wiki_count}\n"
f"🧠 Memórias SQLite: {mem_count}\n"
f"🔗 Memórias do vault: {vault_mems}\n"
f"📝 Última página: {last_page}\n"
)
await update.message.reply_text(report, parse_mode='Markdown')
📎 Envio de Arquivos Multi-Modal
PDFs, imagens de whiteboard, gravações de reunião — tudo pode se tornar conhecimento estruturado no vault via Telegram. O pipeline multi-modal converte cada tipo de arquivo para texto antes de salvar em raw/.
📎 Pipeline Multi-Modal
from telegram.ext import MessageHandler, filters
import io, base64
async def document_handler(update: Update, ctx: ContextTypes.DEFAULT_TYPE):
"""Processa PDFs, imagens e áudios enviados pelo Telegram"""
msg = update.message
timestamp = datetime.datetime.now().strftime('%Y-%m-%d-%H%M')
content = ""
if msg.document and msg.document.mime_type == 'application/pdf':
# PDF: extrai texto com pypdf
file = await ctx.bot.get_file(msg.document.file_id)
pdf_bytes = await file.download_as_bytearray()
from pypdf import PdfReader
reader = PdfReader(io.BytesIO(bytes(pdf_bytes)))
content = "\n".join(page.extract_text() for page in reader.pages)
tipo = "pdf"
elif msg.photo:
# Imagem: descreve com vision model
photo = msg.photo[-1] # Maior resolução
file = await ctx.bot.get_file(photo.file_id)
img_bytes = await file.download_as_bytearray()
b64 = base64.b64encode(bytes(img_bytes)).decode()
# Chama LLM com vision (OpenRouter)
content = await describe_image_with_llm(b64)
tipo = "imagem"
elif msg.voice or msg.audio:
# Áudio: transcreve com Whisper
audio = msg.voice or msg.audio
file = await ctx.bot.get_file(audio.file_id)
audio_path = f"/tmp/audio-{timestamp}.ogg"
await file.download_to_drive(audio_path)
import openai
client = openai.OpenAI()
with open(audio_path, 'rb') as f:
content = client.audio.transcriptions.create(
model="whisper-1", file=f
).text
tipo = "audio-transcricao"
if content:
filename = VAULT_RAW / f"{tipo}-{timestamp}.md"
caption = msg.caption or ""
filename.write_text(
f"---\ntipo: {tipo}\norigem: telegram\ndata: {timestamp}\n"
f"legenda: {caption}\n---\n\n{content[:8000]}"
)
await msg.reply_text(f"✅ {tipo.upper()} processado e salvo em raw/")
else:
await msg.reply_text("❓ Formato não suportado.")
# Registrar handler para todos os tipos de arquivo
app.add_handler(MessageHandler(
filters.Document.ALL | filters.PHOTO | filters.AUDIO | filters.VOICE,
document_handler
))
🔔 Notificações Inteligentes
O Intelecto como assistente proativo — em vez de esperar perguntas, ele lembra, sugere e monitora. Um segundo cérebro que fala com você, não apenas responde.
from telegram.ext import Application
from datetime import time as t
import sqlite3, pathlib, datetime
async def daily_vault_health(context):
"""Enviado diariamente: saúde do vault e pendências"""
wiki_dir = pathlib.Path.home() / "vault" / "wiki"
raw_dir = pathlib.Path.home() / "vault" / "raw"
# Conta arquivos raw/ não compilados
raw_pending = len(list(raw_dir.glob("*.md")))
# Páginas sem atualização há 90+ dias
stale = []
cutoff = datetime.datetime.now().timestamp() - (90 * 86400)
for f in wiki_dir.glob("*.md"):
if f.stat().st_mtime < cutoff and f.stem != "index":
stale.append(f.stem)
msg = "🌅 **Relatório Diário do Vault**\n\n"
if raw_pending:
msg += f"⏳ {raw_pending} arquivo(s) em raw/ aguardando compilação\n"
msg += " Use /compilar para processar\n\n"
if stale:
msg += f"📅 Páginas com 90+ dias sem revisão:\n"
for s in stale[:3]:
msg += f" • {s}\n"
msg += "\n"
if not raw_pending and not stale:
msg += "✅ Vault em dia! Nada pendente.\n"
await context.bot.send_message(
chat_id=YOUR_USER_ID, text=msg, parse_mode='Markdown'
)
async def suggest_connections(context):
"""Semanalmente: sugere conexões entre novas capturas e páginas"""
conn = sqlite3.connect(DB_PATH)
# Novas memórias da última semana
new_mems = conn.execute(
"SELECT content FROM memories WHERE source='conversation' "
"AND created_at > date('now', '-7 days') LIMIT 5"
).fetchall()
if new_mems:
# Usa LLM para sugerir conexões (chamada simplificada)
await context.bot.send_message(
chat_id=YOUR_USER_ID,
text="💡 Esta semana você falou sobre:\n" +
"\n".join(f"• {m[0][:80]}..." for m in new_mems[:3]) +
"\n\nAlgum desses merece virar página wiki?"
)
# Registrar jobs
app.job_queue.run_daily(daily_vault_health, time=t(8, 0, 0)) # 8h
app.job_queue.run_weekly(suggest_connections, day_of_week=0) # Domingo
Relatório de raw/ pendentes e páginas wiki sem revisão há 90+ dias.
Sugestão de conexões entre capturas recentes e páginas existentes no vault.
Alerta quando nova página wiki é compilada com sugestão de link bidirecional.
👥 Grupos e Segundo Cérebro Colaborativo
O Intelecto em um grupo Telegram permite que uma equipe construa um vault compartilhado. Cada membro contribui, o conhecimento coletivo cresce e o Intelecto serve como interface única.
👥 Configuração para Grupos
Em grupos, o Intelecto usa metadados de autoria para cada captura:
# Em vault/raw/raw-2026-01-15.md
---
tipo: texto
origem: telegram-grupo
autor: @joao_silva
data: 2026-01-15-1430
grupo: equipe-engenharia
---
Discutimos hoje a migração do
banco de dados para PostgreSQL...
Adaptar o handler para grupos:
async def group_message_handler(update, ctx):
user = update.message.from_user
# Só processa se marcado com hashtag
if '#captura' not in text and \
not text.startswith('/ingere'):
return # Ignora conversas normais
autor = f"@{user.username}"
# Salva com metadados de autoria
...
📊 Casos de Uso em Equipe
- #captura — Qualquer mensagem com #captura vai para raw/ do vault compartilhado
- /consulta [query] — Busca no vault coletivo com atribuição de autoria
- /audit — Auditoria do vault compartilhado, visível para toda a equipe
- Reuniões — Áudio da reunião enviado → transcrição → wiki de decisões
- Onboarding — Novo membro consulta o vault e recebe contexto completo da equipe
🏗️ Construindo Seu Pipeline Completo
Um roteiro de 4 semanas para ter o sistema completo funcionando, com entregas de valor em cada fase — você pode parar em qualquer etapa com um sistema já útil.
Semana 1 — Intelecto básico no Telegram
MVP funcional- • Clone e configure o Intelecto com .env e BotFather
- • Personalize SOUL.md com seu perfil e tom desejado
- • Converse normalmente — memórias começam a se formar
- • Valor entregue: assistente pessoal funcional no Telegram
Semana 2 — Consciência do vault via USER.md
Integração leve- • Adicione catálogo do vault ao USER.md (domínios, projetos, páginas)
- • Intelecto começa a referenciar páginas do wiki nas respostas
- • Adicione handler /ingere para captura de URLs pelo Telegram
- • Valor entregue: captura via Telegram + Intelecto ciente do vault
Semana 3 — bridge.py e consulta híbrida
Integração profunda- • Implemente bridge.py e execute a primeira sincronização
- • Configure watcher.py para sincronização automática
- • Adicione lógica de consulta híbrida ao handler de mensagens
- • Valor entregue: respostas com conhecimento específico do vault
Semana 4 — Automações e pipeline completo
Sistema completo- • Registre /audit, /status no BotFather e implemente handlers
- • Configure JobQueue para notificações proativas diárias
- • Adicione handler de arquivos (PDF, imagem, áudio)
- • Valor entregue: segundo cérebro completo e proativo
🎯 Princípio fundamental
O segundo cérebro é uma prática, não um sistema. O Intelecto + vault Obsidian é a infraestrutura — mas o valor real vem da consistência da captura e compilação. Um sistema simples usado todos os dias supera um sistema perfeito nunca usado. Comece na Semana 1 e vá adicionando ao seu ritmo.
🎉 Trilha 5 Concluída!
Você completou a Trilha 5 — Intelecto. Agora tem o conhecimento e os scripts para construir um segundo cérebro integrado: vault Obsidian como memória permanente, Intelecto como assistente via Telegram, e SQLite como contexto de curto prazo.