JARVIS/verde/ESCALERA.md
sito 1e3e5ca20d carril verde (Hermes Agent): documentacion, panel, voz local y RAG
Rama JARVIS-GREEN, independiente de master (el nucleo naranja queda intacto).

- README propio del carril verde con diagrama de arquitectura y capturas del panel.
- verde/: arranque, panel web, puente de voz (escucha local con faster-whisper +
  habla con la voz del naranja), pruebas (07 voz, 08 escucha), config y notas.
- Integracion RAG: nucleo/saber/busca_cli.py + skill buscar-en-apuntes, para que
  el agente consulte el mismo indice que el nucleo.
- Todo local (127.0.0.1); sin datos personales (rutas y modelo de GPU scrubeados).
2026-08-18 11:26:42 +02:00

224 lines
7.5 KiB
Markdown

# La escalera del primer arranque
Lo que `pruebas/` no puede contestar. Las siete comprobaciones automáticas dicen
que las piezas están donde tienen que estar; esto dice si **sirve**, y eso solo
lo juzga alguien escuchando y leyendo.
Se sube **en orden y se para en el primer escalón que falle**. Es a propósito:
el escalón que falla es el que informa, y seguir subiendo con uno roto convierte
un fallo de una línea en una tarde de adivinar.
Antes de empezar:
```bash
./verde/arrancar.sh # mide, configura y dictamina
./verde/pruebas/ejecutar.sh # las 7; ninguna abre el TUI
./verde/verde-launcher.sh # el TUI, en verde fosforo
```
Los tiempos se anotan aquí mismo. El del naranja está para comparar, pero **léete
antes el aviso del final**: hoy no miden lo mismo.
Los escalones 1 a 4 también se pueden pasar sin abrir el TUI, que es como se
subieron la primera vez:
```bash
hermes -z "hola, ¿quién eres?" # una pregunta y a callar
```
Y para ver **qué herramientas llamó de verdad**, que `-z` no enseña:
```bash
python3 -c "
import sqlite3
c = sqlite3.connect('file:$HOME/.hermes/state.db?mode=ro', uri=True)
for r in c.execute('SELECT role, tool_name, tool_calls, content FROM messages ORDER BY rowid DESC LIMIT 10'):
print(r)
"
```
Sin eso, un fallo de rutas se atribuye al modelo. Pasó, y está contado en el
escalón 3.
---
## 1 · Que conteste
> hola, ¿quién eres?
Contesta que **el endpoint responde y el prompt fijo cabe**. No prueba nada más:
aquí no hay herramientas ni memoria, es la señal de vida.
| | |
|---|---|
| Tiempo | _______ |
| ¿Se presenta como asistente, sin inventarse una identidad rara? | _______ |
Si falla: no es cosa de Hermes. Vuelve a `arrancar.sh`, que separa el modelo del
arnés.
---
## 2 · Una herramienta, la más simple
> ¿cuánto espacio libre queda en el disco?
Primera llamada real. Tiene que **ejecutar `df`**, no describir cómo se ejecuta
`df`. Un modelo que explica el comando en vez de llamarlo ha entendido la
pregunta y ha fallado la tarea.
| | |
|---|---|
| Tiempo | _______ |
| ¿Llama a la herramienta o lo cuenta en prosa? | _______ |
| ¿El número coincide con `df -h /`? | _______ |
---
## 3 · Leer un fichero
> lee verde/README.md y resúmelo en una línea
Otra familia de herramienta (ficheros, no terminal) y, de paso, si el resumen
tiene que ver con lo que pone el fichero o se lo inventa a partir del nombre.
| | |
|---|---|
| Tiempo | _______ |
| ¿El resumen se parece al fichero de verdad? | _______ |
**Si el resumen no pega ni con cola, mira el directorio antes que el modelo.**
La primera vez que se subió esta escalera, este escalón devolvió un resumen
perfecto de Gitleaks. No era una alucinación: el agente arranca en `$HOME`, así
que resolvió `verde/README.md` contra `~`, donde efectivamente hay un
`README.md` — el de Gitleaks. Lo leyó entero y lo resumió bien.
Es un fallo traicionero porque **no deja ni un error**: la herramienta se
ejecuta, devuelve un fichero de verdad y el modelo acierta el resumen. Solo que
no es el fichero que pediste.
Ni el `cd` delante ni `--in DIR` lo arreglan (`--in` se ignora en modo `-z`). Lo
que lo arregla es `terminal.cwd` en `~/.hermes/config.yaml`, ya puesto y
comprobado por `pruebas/03_config.sh`. El detalle, en `NOTAS.md`.
---
## 4 · Encadenar — **el escalón que importa**
> dime cuál de los .md de verde/ es el más largo
Aquí se separa un chatbot de un agente. No hay una herramienta que conteste esto:
hay que **listar, medir y razonar sobre el resultado de la vuelta anterior**, y
decidir cuándo se ha terminado.
Es el escalón que más probabilidades tiene de romperse en un 4B, y el que
justifica el carril entero: si esto sale, el arnés aporta algo sobre el núcleo.
| | |
|---|---|
| Tiempo | _______ |
| Número de vueltas que da | _______ |
| ¿Acierta el fichero? (comprueba con `wc -c verde/*.md`) | _______ |
| ¿Se queda en bucle o sabe parar? | _______ |
---
## 5 · Una skill
> _(algo que dispare una de las skills instaladas; `hermes skills list` las lista)_
El paso del vídeo que el núcleo no tiene. Lo que se mira no es que la skill
funcione —eso es de quien la escribió— sino si el modelo **decide sola** que esa
skill viene a cuento.
| | |
|---|---|
| Skill probada | _______ |
| ¿La eligió sin que se la nombraras? | _______ |
| **¿Salió a la red para resolverlo?** | _______ |
**Esa tercera fila se añadió después de subir la escalera la primera vez, y es
la que más pesa.** Pidiéndole un cartel en ASCII, el agente eligió la skill solo
—bien—, descubrió que `pyfiglet` no estaba instalado y **se fue a una API de
terceros por su cuenta**, sin que nadie le dijera que podía.
Así que al probar una skill, mira siempre las llamadas, no solo el resultado:
```bash
ss -tnp | grep -v 127.0.0.1 # mientras corre
```
Ningún ajuste lo impide: el agente tiene terminal y la terminal tiene `curl`.
Es la contrapartida de lo que hace valioso este carril, y está desarrollado en
`NOTAS.md`.
---
## 6 · Que hable
> _(cualquier respuesta, con el TTS puesto)_
Tiene que sonar **exactamente igual que el naranja**: mismo Piper 1.2.0 MIT,
mismo `es_ES-davefx-medium`, mismo tono 1.0. `pruebas/07_voz.sh` ya comprueba
que el fichero sale a 22050 Hz mono y con la voz del núcleo; lo que falta es tu
oído en la cadena entera, dentro de Hermes y no llamando al script a mano.
| | |
|---|---|
| ¿Suena igual que el naranja? | _______ |
| ¿Corta frases o se come el final? | _______ |
---
## 7 · Que escuche — **el último, y por un motivo**
> _(dictar una orden por micrófono)_
Va el último porque es el que puede tirar todo lo demás. whisper `small` pide
**839 MiB en el pico de la transcripción** —no en reposo, que fue el error de
medida que costó una tarde— contra una tarjeta que ya tiene el modelo dentro.
| | |
|---|---|
| ¿Transcribe? | _______ |
| Tiempo de la primera (arranca el servidor, ~4 s) | _______ |
| Tiempo de las siguientes | _______ |
Si sale `CUDA error: out of memory`, **no es un fallo nuevo**: es el mismo
reparto que documenta el README del naranja. Salidas por orden:
1. Fiarse de `stt.local.unload_after_idle_seconds: 300`, que ya está puesto:
whisper suelta la VRAM tras cinco minutos de silencio.
2. Bajar el modelo de escucha a `base` (80 % de acierto en vez de 93 %).
3. Probar la escucha con el modelo de texto descargado (`ollama stop`).
Y recuerda que el envoltorio `~/.local/bin/whisper-server` del naranja ya tiene
la red de seguridad: por debajo de 950 MiB libres arranca en CPU (2,17 s en vez
de 1,05) en vez de morirse.
---
## Antes de comparar los dos carriles
**El verde va a medir más lento, y no será culpa del modelo.**
El naranja tiene **150 acciones rápidas que se saltan el cerebro**: "¿cuánto
espacio queda?" es un `df` directo, no una inferencia. En Hermes no existe ese
atajo — toda orden pasa por el modelo, con las 19 herramientas, las skills y la
memoria en contexto **en cada vuelta**.
Comparar el escalón 2 contra el naranja es comparar una inferencia contra un
`df`. Para comparar de verdad hacen falta frases que en el naranja **también**
acaben en el cerebro: están en `config/jarvis-sin-accion.jsonl`.
## Al terminar, devolver la máquina a su sitio
```bash
./verde/verde-launcher.sh --stop
ollama stop qwen3.5:4b-verde
./nucleo/arranca.sh # el naranja, como siempre
```
Y comprobar que el naranja vuelve con su VRAM de siempre. `pruebas/02_modelo.sh`
del verde ya verifica que sus cuatro parámetros siguen intactos, pero eso mira el
Modelfile, no que arranque.