Skip to content

fix: parar de escutar enquanto ela pensa, e avisar quem pergunta de uma vez - #13

Merged
kerlonr merged 1 commit into
mainfrom
fix/nao-disputar-nucleos
Sep 4, 2026
Merged

fix: parar de escutar enquanto ela pensa, e avisar quem pergunta de uma vez#13
kerlonr merged 1 commit into
mainfrom
fix/nao-disputar-nucleos

Conversation

@kerlonr

@kerlonr kerlonr commented Sep 4, 2026

Copy link
Copy Markdown
Member

O robô estourava o tempo limite e não respondia nada

Não era "um pouco lento". Numa conversa de verdade, no log do robô:

23:17:19  ouvi: qual seu nome
23:18:19  ERROR  o modelo demorou demais para responder: timed out
23:18:27  assistente: ...        ← só a SEGUNDA pergunta foi respondida

Sessenta segundos, e nada.

A causa: pensar e transcrever não cabem juntos em quatro núcleos

O Ollama usa todos os núcleos que encontra, o reconhecimento pede três, a face desenha o tempo todo — oito threads disputando quatro. E o microfone só parava quando ela falava, nunca quando ela pensava.

Medido neste Pi, a mesma pergunta ao mesmo modelo:

Primeiro token Resposta inteira
sozinho 200 ms 1,4 s
disputando 3 300 ms 24,6 s

Dez vezes mais lento — e com uma resposta um pouco maior, os 60 s chegam.

A correção, e o risco que ela cria

A escuta para em ThinkingStarted e volta em SpeechFinished.

O risco disso é o oposto, e é pior: um microfone que fica pausado é um robô surdo. Por isso a volta tem três caminhos:

  1. SpeechFinished — o caminho feliz;
  2. ErrorOccurred — o turno que falha nunca chega a falar, e era exatamente o caso do tempo limite acima;
  3. um relógio com o prazo do próprio modelo mais folga, para o dia em que um caminho novo esquecer de avisar.

Como segunda camada, LLM_NUM_THREAD passa a existir — vazio por padrão, porque numa máquina de mesa o padrão do Ollama está certo.

Quem pergunta tudo de uma vez não ouvia sinal nenhum

O par de sinais só tocava no caminho de duas etapas, porque só ali a janela de escuta abre. Quem diz "Atlas, qual seu nome?" numa tacada — que é como as pessoas de fato falam com ele — não ouvia nada: a primeira coisa a chegar era a resposta.

Agora o sinal de "peguei sua pergunta" sai também quando a pergunta é aceita, e uma vez só por turno, para o caminho de duas etapas não apitar duas vezes.

Verificação

  • 749 testes passam (eram 738), nos dois ambientes
  • os novos cercam o que dá errado sem barulho: o turno que falha devolvendo a escuta, o relógio disparando sem evento nenhum, o relógio sendo cancelado no turno que termina bem, e o sinal não saindo duas vezes

🤖 Generated with Claude Code

https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v

…ma vez

Duas queixas, uma causa comum e uma lacuna que eu tinha deixado aberta.

## O robo estourava o tempo limite e nao respondia nada

Nao era "um pouco lento". No log do robo, uma conversa de verdade:

    23:17:19  ouvi: qual seu nome
    23:18:19  ERROR  o modelo demorou demais para responder: timed out
    23:18:27  assistente: ...        <- so a SEGUNDA pergunta foi respondida

Sessenta segundos, e nada. A causa: **pensar e transcrever nao cabem juntos em
quatro nucleos.** O Ollama usa todos os que encontra, o reconhecimento pede
tres, a face desenha o tempo todo — oito threads disputando quatro. E o
microfone so parava quando ela *falava*, nunca quando ela *pensava*.

Medido neste Pi, a mesma pergunta ao mesmo modelo:

    sozinho       primeiro token   200 ms   resposta inteira   1,4 s
    disputando    primeiro token  3300 ms   resposta inteira  24,6 s

Dez vezes mais lento — e com uma resposta um pouco maior, os 60 s chegam.

Agora a escuta para em `ThinkingStarted` e volta em `SpeechFinished`. O robo ja
esta comprometido com a pergunta que recebeu; transcrever a sala nesse
meio-tempo custa justamente a resposta.

**O risco disso e o oposto, e e pior:** um microfone que fica pausado e um robo
surdo. Por isso a volta tem tres caminhos, e nao um. `SpeechFinished` no caminho
feliz; `ErrorOccurred` no turno que falha (que nunca chega a falar, e era
exatamente o caso do tempo limite acima); e um relogio com o prazo do proprio
modelo mais folga, para o dia em que um caminho novo esquecer de avisar.

Como segunda camada, `LLM_NUM_THREAD` passa a existir: um teto de nucleos para
o modelo, vazio por padrao porque numa maquina de mesa o padrao do Ollama esta
certo. A face desenha o tempo todo, e um modelo que toma a maquina inteira faz
a animacao engasgar bem quando alguem esta esperando resposta.

## Quem pergunta tudo de uma vez nao ouvia sinal nenhum

O par de sinais so tocava no caminho de duas etapas ("Atlas" ... pergunta),
porque so ali a janela de escuta abre. Quem diz "Atlas, qual seu nome?" numa
tacada — que e como as pessoas de fato falam com ele — nao ouvia nada: a
primeira coisa a chegar era a resposta, e ate ela o robo parecia nao ter
escutado. Era a lacuna que ficou registrada no commit anterior, e e a queixa
que veio.

Agora o sinal de "peguei sua pergunta" sai tambem quando a pergunta e aceita —
e uma vez so por turno, para o caminho de duas etapas nao apitar duas vezes.

749 testes passam (eram 738), nos dois ambientes. Os novos cercam justamente o
que da errado sem barulho: o turno que falha devolvendo a escuta, o relogio de
seguranca disparando sem evento nenhum, o relogio sendo cancelado no turno que
termina bem, e o sinal nao saindo duas vezes.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_0173mr3mDsAKQuPUNaPghe9v
@kerlonr
kerlonr merged commit 807a98b into main Sep 4, 2026
5 checks passed
@kerlonr
kerlonr deleted the fix/nao-disputar-nucleos branch September 4, 2026 02:33
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant