Pular para o conteúdo
MÓDULO 4.5

🗣️ Passo a passo #3: seu buddy local com nome, cara e voz

Agora a gente junta tudo do curso num só lugar: um assistente pessoal local com personalidade própria (system prompt), uma cara (interface), uma voz (TTS) e até ouvidos (STT). Ele roda na sua máquina, lembra de você (RAG) e te acompanha do celular (Tailscale). É o vídeo "dê uma cara, um nome e uma voz ao seu modelo" — virado projeto, passo a passo.

6
Tópicos
~40
Minutos
Avançado
Nível
Prático
Tipo

Conteúdo detalhado

1

🎯 O objetivo: um buddy de verdade

Você já tem as peças espalhadas pelo curso: um modelo rodando (3.1), uma API local (3.5), memória com RAG (3.6) e rede privada com Tailscale (2.4). Este passo a passo costura tudo num companheiro pessoal — com nome, jeito de falar, uma tela pra conversar e uma voz pra te responder em voz alta. Nada sai da sua máquina.

🆕 Novo aqui?

"System prompt" é uma instrução fixa que o modelo lê antes de qualquer conversa: define quem ele é, o tom e as regras. É a personalidade do buddy. "TTS" = text-to-speech (texto → fala) e "STT" = speech-to-text (fala → texto): os dois rodam local também, sem mandar seu áudio pra ninguém.

🔑 As quatro peças do buddy

Um buddy = quatro coisas que você já viu, montadas juntas:

  • Personalidade: um system prompt no Modelfile com nome, tom e regras.
  • Cara: uma interface — Open WebUI (3.2) ou uma página HTML mínima.
  • Voz e ouvidos: Piper (TTS) pra falar e whisper.cpp (STT) pra ouvir.
  • Memória + alcance: RAG (3.6) pra lembrar de você e Tailscale (2.4) pra usar do celular.

✓ Buddy local

  • Personalidade e regras 100% sob seu controle
  • Conversa, voz e memória sem sair da máquina
  • Uso ilimitado — fala o dia inteiro, só paga energia
  • Acessível do celular pela sua rede privada

✗ Assistente de nuvem

  • Personalidade limitada ao que a plataforma deixa
  • Seu áudio e suas conversas passam por terceiros
  • Voz e uso pesado custam por minuto/token
  • Some se cortarem acesso, preço ou região
Nome
system prompt
Cara
interface
Voz
Piper TTS
Memória
RAG + rede
2

🪪 Personalidade via system prompt

A personalidade não vem de "treinar" nada — vem de uma instrução fixa. No Ollama você grava essa instrução num Modelfile (a receita que você viu no módulo 3.1) e cria um modelo nomeado a partir dela. Mude o texto do SYSTEM e você muda quem o buddy é.

⌨️ Copy-run: dê nome e tom ao "Hermes"

Objetivo: criar um modelo local chamado hermes com personalidade definida. Salve como Modelfile e rode os comandos.

# Modelfile — define o "Hermes", seu buddy local
FROM qwen2.5:7b-instruct
# o system prompt = a personalidade fixa do buddy
SYSTEM """
Você é o Hermes, o assistente pessoal local do Nei.
Tom: direto, caloroso e com bom humor leve. Trate por "você".
Regras: respostas curtas por padrão; pergunte antes de assumir;
nunca invente dados — se não souber, diga. Responda em PT-BR.
"""
# afina o comportamento
PARAMETER temperature 0.6
PARAMETER num_ctx 8192
# cria o modelo a partir da receita e conversa
ollama create hermes -f Modelfile
ollama run hermes

Como verificar: pergunte "quem é você?". Ele deve se apresentar como Hermes, no tom definido — e respeitar as regras (curto, sem inventar). Não gostou? Edite o SYSTEM e rode ollama create de novo.

💡 Dica prática

Um bom system prompt tem quatro partes: quem ele é (nome/papel), como fala (tom), o que pode/não pode (regras) e o idioma. Evite parágrafos enormes — o modelo segue melhor instruções curtas e específicas do que um manual. Comece simples e vá ajustando conforme ele te responde.

Papel
quem ele é
Tom
como fala
Regras
o que vale
Idioma
PT-BR
3

🖥️ Uma cara: interface dedicada

"Dar uma cara" é só apontar uma interface pro seu modelo. Dois caminhos: o pronto — reusar o Open WebUI (3.2), que já tem chat com histórico — ou o enxuto: uma página HTML de 20 linhas que conversa direto com a API local (3.5). Comece pela mais simples pra entender o circuito; depois suba pro Open WebUI quando quiser histórico e anexos.

⌨️ Copy-run: uma "cara" mínima em HTML

Objetivo: uma página que manda sua pergunta pro endpoint local e mostra a resposta. Salve como buddy.html.

<!-- buddy.html — fala com o modelo local -->
<!doctype html><meta charset="utf-8">
<h2>🤝 Hermes</h2>
<input id="q" style="width:70%" placeholder="pergunte...">
<button onclick="send()">Enviar</button>
<pre id="out"></pre>
<script>
async function send(){
  const q = document.getElementById('q').value;
  const r = await fetch(
    'http://localhost:11434/v1/chat/completions',{
    method:'POST', headers:{'Content-Type':'application/json'},
    body: JSON.stringify({ model:'hermes',
      messages:[{role:'user', content:q}] }) });
  const j = await r.json();
  document.getElementById('out').textContent =
    j.choices[0].message.content;
}
</script>

Como verificar: abra o arquivo no navegador, digite uma pergunta e clique em Enviar — a resposta do seu modelo local aparece na tela. É o seu buddy com cara própria.

⚠️ Atenção: CORS

Se o navegador bloquear a chamada (erro de CORS ao abrir via file://), libere a origem no Ollama: rode com OLLAMA_ORIGINS=* (ex.: OLLAMA_ORIGINS=* ollama serve). Para o buddy de verdade, prefira o Open WebUI em http://localhost:3000 — ele já cuida disso e te dá histórico, troca de modelo e RAG de documentos.

✓ Open WebUI (pronto)

  • Histórico de conversas e múltiplos chats
  • Troca de modelo e RAG de documentos embutidos
  • Pronto pra usar do celular pela tailnet

📄 HTML mínimo (didático)

  • Mostra o circuito inteiro em 20 linhas
  • Fácil de customizar a "cara" do jeito que quiser
  • Sem histórico/anexos — é só o esqueleto
4

🔊 Dar voz: TTS local (Piper)

A voz é o que transforma um chat num buddy. Em vez de só ler na tela, ele fala. Para isso a gente usa um motor de TTS que roda na sua máquina — o Piper — e canaliza a resposta do modelo direto pro alto-falante.

🆕 Novo aqui?

"TTS" = text-to-speech: transforma texto em fala. O Piper é um TTS local, leve e rápido (roda até em CPU), com várias vozes — inclusive em PT-BR. Cada voz é um arquivo .onnx; troque o arquivo e o buddy muda de voz.

O caminho da voz é um pipeline curto — texto entra de um lado, som sai do outro:

1

A resposta vira texto

O modelo local responde via API (3.5). Você pega só o texto da resposta.

2

Piper sintetiza a fala

O texto entra no Piper com uma voz .onnx; ele gera um arquivo de áudio .wav.

3

O sistema toca o áudio

Um player simples (aplay no Linux, afplay no macOS) reproduz o .wav. O buddy "falou".

⌨️ Copy-run: o buddy fala uma frase

Objetivo: instalar o Piper e fazer um texto virar som no alto-falante. Cole no terminal.

# instalar o Piper (TTS local)
pip install piper-tts # ou baixe o binário do repo
# baixe uma voz PT-BR (.onnx) do repositório do Piper
# texto -> Piper -> arquivo .wav -> alto-falante
echo "Olá, eu sou o Hermes." \
  | piper --model pt_BR-faber-medium.onnx \
      --output_file fala.wav
aplay fala.wav # macOS: afplay fala.wav

Como verificar: você ouve a frase. Trocou o .onnx? A voz muda. Esse mesmo piper ... | aplay é a peça de voz do loop do tópico 6.

5

🎤 Ouvir: STT local (opcional)

Dar voz já é meio caminho. O outro meio é dar ouvidos: poder falar com o buddy em vez de digitar. É opcional — mas com STT local o ciclo fica completo (você fala → ele entende → responde → fala de volta).

🆕 Novo aqui?

"STT" = speech-to-text: transforma fala em texto (o oposto do TTS). O whisper.cpp é uma implementação local e enxuta do modelo Whisper que roda em CPU — grava o microfone, transcreve e devolve texto, sem mandar seu áudio pra nuvem.

⌨️ Copy-run: transcreva sua voz localmente

Objetivo: gravar 5 segundos do microfone e ver o texto do que você falou. Tudo offline.

# whisper.cpp = STT local (fala -> texto), roda em CPU
git clone https://github.com/ggerganov/whisper.cpp
cd whisper.cpp && make
./models/download-ggml-model.sh small # baixa o modelo
# grava 5s do microfone e transcreve em PT-BR
arecord -d 5 -f S16_LE -r 16000 fala.wav
./main -m models/ggml-small.bin -l pt -f fala.wav

Como verificar: o texto do que você falou aparece no terminal. Esse texto é exatamente o que você passaria como content na chamada da API — fechando o ciclo de voz.

✓ Vale dar ouvidos quando

  • Você quer usar de mãos livres (cozinha, dirigindo)
  • Falar é mais rápido que digitar pro seu caso
  • Quer um assistente de voz 100% privado

✗ Fique no texto se

  • Hardware é fraco — STT + LLM + TTS juntos pesam
  • Ambiente barulhento atrapalha a transcrição
  • Você só quer o buddy de texto por enquanto (comece simples)
6

🧠 Memória, voz e celular: tudo junto

Falta encaixar as duas últimas peças e ligar o motor. Memória: com RAG (3.6) o buddy lembra de você — preferências, projetos, conversas antigas — buscando esses trechos e injetando no contexto antes de responder. Alcance: rodando atrás do Tailscale (2.4), você fala com ele do celular, de qualquer lugar, como se estivesse em casa. Veja como tudo se compõe:

🖥️ Cara interface + 🧠 Cérebro LLM + system + 🔊 Voz TTS + STT + 🧠 Memória RAG + rede = 🗣️ Seu buddy nome · cara · voz · memória

Leia como uma equação: cara + cérebro + voz + memória (as peças em ciano que você montou no curso) somam um buddy local completo (em âmbar). Tire qualquer parcela e ele ainda funciona — só fica menos buddy.

💡 Memória + celular, na prática

Memória (RAG, 3.6): guarde notas suas (preferências, fatos, histórico) num vector store e, a cada pergunta, busque os trechos relevantes e cole no prompt — assim o Hermes "lembra" sem retreinar nada. Celular (Tailscale, 2.4): com OLLAMA_HOST=0.0.0.0 e o app Tailscale no telefone, troque localhost pelo IP 100.x da sua máquina e fale com o buddy de qualquer lugar — sem abrir nada pra internet pública.

⌨️ Copy-run principal: o loop do buddy falante

Objetivo: o circuito completo num arquivo — pergunta → API local → resposta → Piper fala. Salve como buddy-voz.sh.

#!/usr/bin/env bash
# buddy-voz.sh — pergunta -> API local -> resposta -> Piper fala
while true; do
  read -rp "você: " pergunta
  [ "$pergunta" = "sair" ] && break
  # 1) manda pra API local (Ollama, OpenAI-compatível)
  resposta=$(curl -s http://localhost:11434/v1/chat/completions \
    -d "{\"model\":\"hermes\",\"messages\":[{\"role\":\"user\",
    \"content\":\"$pergunta\"}]}" \
    | jq -r '.choices[0].message.content')
  echo "hermes: $resposta"
  # 2) Piper fala a resposta
  echo "$resposta" \
    | piper --model pt_BR-faber-medium.onnx --output_file r.wav
  aplay r.wav
done

Como verificar: rode bash buddy-voz.sh, pergunte algo e ouça a resposta do seu buddy. Digite sair pra encerrar. Requer curl, jq, piper e aplay. Quer ouvido também? Troque o read pela transcrição do whisper.cpp (tópico 5).

✓ Buddy bem-feito

  • System prompt curto, claro e testado
  • Tudo local: voz, memória e dados na sua máquina
  • Acesso só pela tailnet, nunca à internet aberta

✗ Erros comuns

  • Expor a porta 11434 direto na internet
  • System prompt gigante que o modelo ignora
  • Empilhar STT+LLM+TTS em hardware que não aguenta

Auto-checagem (opcional): o que dá ao seu buddy local a personalidade — nome, tom e regras?

Nome
SYSTEM
Cara
UI / HTML
Voz
Piper / Whisper
Sempre
RAG + tailnet

📌 Resumo do módulo

Personalidade = system prompt — nome, tom e regras no SYSTEM do Modelfile, criados com ollama create.
Cara = interface — Open WebUI pronto ou uma página HTML mínima que fala com a API local.
Voz e ouvidos = TTS + STT local — Piper fala, whisper.cpp ouve, tudo offline.
Memória + alcance — RAG (3.6) pra lembrar de você e Tailscale (2.4) pra usar do celular.

Próximo módulo:

4.6 — Performance, escala & troubleshooting