From fb5f3bd47a87d3a93a88175af174a3a89f7a4bfe Mon Sep 17 00:00:00 2001 From: elvis Date: Tue, 8 Sep 2026 10:14:15 -0300 Subject: Screen vision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cuarta herramienta: captura la pantalla y responde sobre lo que hay en ella. Aprovecha el mismo proyector multimodal que ya usaba la cámara. Como las dos hacen lo mismo —conseguir un JPEG, preguntarle al modelo, devolver texto— y sólo cambian en de dónde salen los píxeles, se unifican tras VisionTool y un trait FrameSource. La captura vive en scripts/capturar- pantalla.sh, que detecta grim, spectacle, maim, ImageMagick o scrot y reduce con ffmpeg: añadir un compositor es editar el guion, no recompilar. El ajuste que decide todo es la resolución, y no coincide con la de la cámara porque el problema no es el mismo: una escena se entiende, un texto hay que leerlo. Medido con tipografía de interfaz de 13 px y preguntando por datos concretos, a 1280 px acierta 3 de 3 en 7,6 s; a 960, 2 de 3; a 640, 1 de 3. Y a 640 px no falla diciendo que no lee: dijo que el error era «no se pudo abrir el archivo involution» y que la reunión era «a las 10:00», cuando ponía /dev/video0 y 15:30. Para un asistente de voz, decir una hora equivocada con aplomo es peor que tardar cuatro segundos más, así que 1280 px por defecto aunque cueste el triple que la cámara. Al prompt se le añade además que no complete lo que no se distinga, y funciona: en una prueba real contestó que el texto de la barra de direcciones era ilegible en vez de inventárselo. Con cuatro herramientas declaradas el riesgo era confundir pantalla con cámara. No pasa: 18 de 20, con cero confusiones entre ambas. Corregido de paso un fallo del lanzador de procesos que la captura destapó. Esperaba con try_wait en bucle sin vaciar las tuberías, así que un hijo que escribiera más de los 64 KB del búfer se quedaba bloqueado y moría por plazo vencido aunque estuviera trabajando. Los tres usos anteriores cabían de sobra —una fecha, un JSON, un fotograma de 9 KB—; la primera captura, de 174 KB, no. Ahora se vacían en hilos aparte, con una prueba por tubería. Ese lanzador es además nuevo: había tres copias del mismo patrón —plazo máximo, sin shell de por medio, distinguir fallo de cuelgue— en la shell, la búsqueda y la cámara. Ahora está una sola vez en asist_core::proc. Claude-Session: https://claude.ai/code/session_01KSfMfDsRwNAaXcCA6V5RTe --- docs/RENDIMIENTO.md | 73 +++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 73 insertions(+) (limited to 'docs/RENDIMIENTO.md') diff --git a/docs/RENDIMIENTO.md b/docs/RENDIMIENTO.md index b51f392..bed4f33 100644 --- a/docs/RENDIMIENTO.md +++ b/docs/RENDIMIENTO.md @@ -19,6 +19,8 @@ Linux 7.2 (CachyOS) · PipeWire. | El prompt de estilo anulaba las llamadas a herramientas | 0 de 8 aciertos | 8 de 8 | — | | La cámara capturaba a 1280x720 | 7,8 s por imagen | 2,9 s a 640x480 | **2,7×** | | Una herramienta se ejecutaba en silencio | ~8,4 s hasta oír algo | 4,1 s con acuse hablado | **2×** | +| La pantalla se leía a 640 px | 1 acierto de 3, con datos inventados | 3 de 3 a 1280 px | — | +| Las tuberías no se vaciaban mientras se esperaba | captura de 180 KB colgada 20 s | 0,3 s | — | Los tres son de configuración, no de código. Ninguno da error: el sistema funciona, sólo que despacio o mal, que es lo que los hace difíciles de ver. @@ -171,6 +173,50 @@ sale bien casi siempre —en el pipeline completo devolvió «Hoy en Buenos Aire hace soleado esta mañana y por la tarde tendremos nubes con temperaturas alrededor de 9°C», correcto— pero es una oportunidad más de equivocarse. +## 4 ter. Mirar la pantalla: por debajo de 1280 px el modelo se inventa el texto + +Una pantalla no es una escena, es **texto**, y ahí este modelo tiene un modo de +fallo que no perdona. Medido sobre una captura de 1920x1080 con tipografía de +interfaz de 13 px, reducida a distintos anchos y preguntando por datos +concretos (tres preguntas: qué dice el error, a qué hora es la reunión, cuánto +es el total): + +| Ancho | Texto resultante | Tiempo | Aciertos | +|---|---|---|---| +| 640 px | 4 px | 2,4 s | **1 de 3** | +| 960 px | 6 px | 4,5 s | 2 de 3 | +| 1280 px | 8 px | 7,6 s | **3 de 3** | + +Lo grave no es que falle, es **cómo** falla. A 640 px no dijo «no lo leo»: + +> El error indica que el programa no pudo abrir el archivo **"involution"** y +> que el código de error es 13. +> +> La reunión es **a las 10:00**. + +Ninguna de las dos cosas estaba en la imagen. El error era «no se pudo abrir +/dev/video0» y la reunión, a las 15:30. Para un asistente de voz, decir una +hora equivocada con aplomo es peor que tardar cuatro segundos más, así que el +valor por defecto son **1280 px** aunque cueste el triple que la cámara. + +Con letra grande (26 px) la cosa cambia: a 640 px transcribió las seis cifras +de prueba sin un fallo. Es el tamaño del texto *después de reducir* lo que +manda, no la resolución en sí. + +Dos cosas más que salieron de aquí: + +- **La instrucción importa tanto como los píxeles.** Al prompt de la pantalla + se le añade «lee sólo lo que de verdad pone y no completes lo que no se + distinga». Funciona: en una prueba real el modelo contestó que «el texto de + la barra de direcciones es ilegible por estar borroso» en vez de + inventárselo. +- **Una pantalla real cuesta más que una sintética.** La medición de 7,6 s es + con una captura de texto sobre fondo liso; con un navegador y un vídeo + abiertos subió a 10,8–12,4 s, porque hay mucho más que describir. + +Capturar es lo barato: `grim` tarda **0,03 s** en JPEG y el guion entero, +reducción incluida, **0,30 s**. + ## 5. Con tres herramientas el modelo elige bien, pero busca de más Con `hora_actual`, `buscar_en_internet` y `mirar_por_la_camara` declaradas a la @@ -200,6 +246,13 @@ apartado 3: Añadir la prohibición no reduce los falsos positivos y sí empeora los aciertos. Se queda la guía sola. +Al añadir la cuarta herramienta —mirar la pantalla— el riesgo era que se +confundiera con la cámara, que se le parece mucho. No pasó: **18 de 20**, con +cero confusiones entre las dos. «¿Qué ves ahora mismo?» va a la cámara y «Lee +lo que pone en la ventana que tengo delante» a la pantalla. El único fallo +sigue siendo el mismo de siempre, buscar en internet «¿por qué el cielo es +azul?». + ## 6. Sin acuse hablado, una herramienta son seis segundos de silencio Una búsqueda tarda unos 2,4 s y la cámara unos 4,5, y a eso hay que sumarle las @@ -270,6 +323,7 @@ Turnos con las herramientas nuevas, también medidos de punta a punta: |---|---|---|---|---|---| | «¿Qué tiempo hace en Buenos Aires?» | 194 ms | 2243 ms | 2132 ms (búsqueda) | 4079 ms | **4122 ms** | | «¿Qué ves por la cámara?» | 185 ms | 1649 ms | 5229 ms (captura + visión) | 1602 ms | **3153 ms** | +| «¿Qué hay en mi pantalla?» | 207 ms | 1219 ms | 12434 ms (captura + visión) | 4113 ms | **3032 ms** | El primer audio llega mucho antes que el final del turno porque suena el acuse mientras la herramienta trabaja. @@ -345,3 +399,22 @@ RUST_LOG=info,herramientas=info,camara=info cargo run --release -- run scripts/servidores.sh arrancar cargo test --release -p asist-app --test integracion -- --nocapture ``` + + +## 8. Un proceso que escribe mucho se cuelga si no le vacías la tubería + +La captura de pantalla funcionaba desde la shell en 0,3 s y desde el asistente +vencía el plazo de 20 s. El guion era el mismo y el entorno también. + +La causa estaba en el lanzador de procesos compartido: esperaba con +`try_wait()` en bucle **sin leer las tuberías**. Un hijo que escribe más de lo +que cabe en el búfer (64 KB en Linux) se queda bloqueado escribiendo, nunca +termina, y el bucle acaba matándolo por plazo vencido aunque estuviera +haciendo su trabajo. + +Costó verlo porque los tres primeros usos cabían de sobra: una fecha, un JSON +de búsqueda y un fotograma de cámara de 9 KB. La primera captura de pantalla, +de 174 KB, no. + +Ahora las dos tuberías se vacían en hilos aparte mientras se espera. Hay dos +pruebas que lo fijan, una por cada tubería, generando 512 KB y 200 KB. -- cgit v1.2.3