diff options
| author | elvis <elvis@claros.ar> | 2026-09-06 22:05:14 -0300 |
|---|---|---|
| committer | elvis <elvis@claros.ar> | 2026-09-06 22:05:14 -0300 |
| commit | 71764752f28d31028b9c2ca486c0fc1bcea1cf95 (patch) | |
| tree | ffd463969826157819f5a3319e1895c3f51deb22 /docs/RENDIMIENTO.md | |
| parent | f8f98e83481e7376a235fb305a095552433f79ab (diff) | |
| download | asist-p-71764752f28d31028b9c2ca486c0fc1bcea1cf95.tar.gz asist-p-71764752f28d31028b9c2ca486c0fc1bcea1cf95.zip | |
Web search and camera vision
Dos capacidades nuevas en un crate aparte, asist-tools, registradas desde
asist-app: son el ejemplo de que el punto de extensión documentado funciona
sin tocar el orquestador.
Buscar admite tres buscadores intercambiables. Tavily devuelve una respuesta ya
redactada, que es lo que se puede leer en voz alta sin gastar otra vuelta del
modelo en resumir (0,54 s para «capital de Australia»); ddgs no necesita clave
y devuelve fragmentos que el modelo sintetiza (2,24 s). El tercero es un
backend de comando genérico: ejecuta un programa y lee JSON de su salida, así
que añadir otro buscador —o un puente a un servidor MCP— es escribir un guion.
Sobre DuckDuckGo, comprobado y no supuesto: curl contra html.duckduckgo.com
devuelve HTTP 202 con una página anti-bot y ni un resultado, y la API sin clave
api.duckduckgo.com devuelve vacío para casi todo lo que no sea una entidad de
enciclopedia. La librería ddgs —la misma que hay bajo duckduckgo-mcp— sí
funciona porque rota buscadores y cabeceras, y es la que usa
scripts/buscar-ddgs.sh.
Mirar aprovecha que el servidor ya carga el proyector multimodal: el mismo
modelo que conversa describe lo que capta la cámara. La pregunta del usuario
viaja hasta ahí, porque «¿de qué color es mi camiseta?» y «¿cuánta gente hay?»
necesitan la misma imagen y descripciones distintas. La imagen no entra en el
historial —cientos de tokens por turno para algo ya descrito— ni toca el disco.
Tres cosas más que salieron de medir, en docs/RENDIMIENTO.md:
- La resolución de captura manda en la latencia: 7,8 s a 1280x720 frente a
2,9 s a 640x480, con la misma descripción útil. 640x480 pasa a ser el valor
por defecto.
- Una herramienta ejecutándose en silencio deja el turno seis segundos mudo y
parece un cuelgue. Tool::acknowledgement pronuncia una frase antes de
ejecutar y baja el primer audio de ~8,4 s a 4,1 s.
- Con la instrucción de voz a secas en la pasada de redacción, el modelo
anunciaba lo que acababa de hacer en vez de contar lo que averiguó, ignorando
el resultado que tenía delante. general.tool_result_prompt lo corrige; ahí sí
se puede añadir estilo sin riesgo, porque la llamada ya ocurrió.
Con tres herramientas declaradas el modelo elige bien entre ellas (15 de 16
medido), pero le cuesta abstenerse y busca cosas que ya sabe. Intentar
corregirlo con instrucciones empeora los aciertos sin reducir los falsos
positivos, coherente con la fragilidad ya documentada.
Corregido además un fallo que dejaba mudo al asistente tras la primera
respuesta: el anillo de reproducción no bajaba nunca su bandera de actividad,
así que el segmentador mantenía el micrófono cerrado creyendo que seguía
hablando. El segmentador se guía ahora por la cola, que no puede desfasarse, y
hay pruebas del anillo con un mando sin dispositivo detrás.
Claude-Session: https://claude.ai/code/session_01FNxz5cSdQSscJH9H7b8uGU
Diffstat (limited to 'docs/RENDIMIENTO.md')
| -rw-r--r-- | docs/RENDIMIENTO.md | 131 |
1 files changed, 131 insertions, 0 deletions
diff --git a/docs/RENDIMIENTO.md b/docs/RENDIMIENTO.md index 543ee62..b51f392 100644 --- a/docs/RENDIMIENTO.md +++ b/docs/RENDIMIENTO.md @@ -17,6 +17,8 @@ Linux 7.2 (CachyOS) · PipeWire. | El TTS decodificaba el audio en bloques de 24 s | 4948 ms al primer audio | 585 ms | **8,5×** | | La plantilla del LLM abría `<think>` y no lo cerraba | 8630 ms al primer token | 413 ms | **21×** | | 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×** | 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. @@ -120,6 +122,122 @@ estilo. Se compensa en parte porque `clean_for_speech` quita el markdown antes de hablar, y `max_tokens` acota la longitud. Con `tools.dedicated_prompt = false` se invierte la prioridad. +## 4. La cámara: la resolución manda en la latencia + +El servidor ya carga el proyector multimodal, así que el mismo modelo que +conversa describe lo que capta la cámara. Lo que cuesta es la imagen: cada +píxel se convierte en tokens que el modelo tiene que procesar. + +Misma escena, misma pregunta, sólo cambia la resolución de captura: + +| Resolución | Tamaño | Respuesta del modelo | Calidad | +|---|---|---|---| +| 320x240 | 3 KB | **1,33 s** | «Una pared blanca con un interruptor» | +| 640x480 | 9 KB | **2,88 s** | «Una pared blanca y un interruptor blanco en la pared izquierda» | +| 960x540 | 15 KB | 5,23 s | describe además el marco de la puerta | +| 1280x720 | 24 KB | 7,81 s | equivalente a 960x540 | + +640x480 es el punto de equilibrio: sigue distinguiendo objetos y colores, y +cuesta la tercera parte que la resolución máxima. Por encima de 960x540 el +tiempo se duplica sin que la descripción mejore. + +La captura en sí es barata: **0,45 s** con ffmpeg, y descartar unos fotogramas +para que la exposición automática se asiente sale prácticamente gratis (0,53 s +sin descartar ninguno frente a 0,45 s descartando tres; el brillo medio baja de +176 a 174 mientras el sensor se ajusta). + +## 4 bis. Los tres caminos a DuckDuckGo, y cuál funciona + +Buscar sin clave es posible, pero no por donde parece. Comprobado aquí: + +| Camino | Resultado | +|---|---| +| `curl` a `html.duckduckgo.com/html/` | **HTTP 202** con página anti-bot (`anomaly.js`), cero resultados | +| API sin clave `api.duckduckgo.com` (Instant Answer) | **vacío** para «capital de Australia» y para «qué tiempo hace en Buenos Aires» | +| Librería `ddgs` (la que usa `duckduckgo-mcp`) | **funciona**, 1,5–5,8 s | + +La librería rota buscadores y cabeceras, y por eso pasa donde curl no. + +Comparado con Tavily sobre las mismas preguntas: + +| | «capital de Australia» | «tiempo hoy en Buenos Aires» | Forma del resultado | +|---|---|---|---| +| tavily | **0,54 s** | 2,88 s | respuesta ya redactada | +| ddgs | 2,24 s | 3,59 s | fragmentos de tres páginas | + +Lo que decide no es el tiempo sino la forma. Con Tavily el asistente lee la +respuesta; con ddgs el modelo tiene que resumir los fragmentos, y con 2B eso +sale bien casi siempre —en el pipeline completo devolvió «Hoy en Buenos Aires +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. + +## 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 +vez, sobre 11 preguntas y dos intentos cada una: + +| Tipo de pregunta | Acierto | +|---|---| +| «¿Qué hora es?», «¿Qué día es hoy?» | 4 / 4 | +| «¿Qué tiempo hace?», «¿A cuánto está el dólar?», «Busca noticias» | 6 / 6 | +| «¿Qué ves?», «¿De qué color es mi camiseta?», «Mira por la cámara» | 5 / 6 | +| Sin herramienta: «¿Por qué el cielo es azul?», «Cuéntame un chiste», «¿Cuánto es 15 por 4?» | 1 / 6 | + +**Elegir entre las tres se le da bien (15/16).** Lo que falla es abstenerse: +busca en internet cosas que ya sabe. Cuesta unos 2,5 s de más, pero la +respuesta sigue siendo correcta, así que es un problema de latencia y no de +exactitud. + +Intentar corregirlo con instrucciones no funcionó, coherente con lo del +apartado 3: + +| Guía de herramientas | Aciertos | Falsos positivos | +|---|---|---| +| Sola | **16 / 22** | 5 | +| + «No uses ninguna herramienta para conocimiento general» | 16 / 22 | 6 | +| + «Las herramientas son sólo para datos que cambian» | 13 / 22 | 6 | + +Añadir la prohibición no reduce los falsos positivos y sí empeora los +aciertos. Se queda la guía sola. + +## 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 +dos pasadas del modelo. El turno entero sale por encima de los 7 s, y sin nada +que oír se lee como que el asistente se ha colgado. + +Por eso `Tool::acknowledgement` devuelve una frase que se pronuncia **antes** +de ejecutar —«Déjame que lo busque», «Voy a mirar»—. Medido en turnos reales: + +| | Primer audio | +|---|---| +| Turno con búsqueda, sin acuse | ~8,4 s (estimado: suma de las dos pasadas) | +| Turno con búsqueda, con acuse | **4,1 s** | +| Turno con cámara, con acuse | **3,2 s** | + +El turno sigue durando lo mismo; lo que cambia es cuándo empieza a oírse algo, +que es lo único que percibe quien pregunta. + +## 7. El resultado de la herramienta hay que mandarlo usar + +Con la instrucción de voz a secas en la pasada de redacción, el modelo anunciaba +lo que acababa de hacer en vez de contar lo que averiguó: + +> He tomado una foto de la cámara para mostrarte lo que hay delante. Ahora +> puedo responderte sobre el objeto o color, pero si quieres saber más +> información actualizada como precios, noticias o datos específicos, ¡puedo +> buscarlo por internet! + +El resultado —«Un hombre con gorro sostiene un teléfono»— estaba en la +conversación y lo ignoró. Con `general.tool_result_prompt` añadido a esa +pasada: + +> Se ve un hombre con una chaqueta de peluche y el capuchón puesto, +> sosteniendo un teléfono en su mano y mirando directamente a la cámara. + +Aquí sí se puede añadir estilo sin romper nada, al contrario que en el +apartado 3: la llamada ya ocurrió, así que no queda nada que estropear. + --- ## Un turno real, medido de punta a punta @@ -146,6 +264,16 @@ turno #1 — desglose de latencia - **Latencia percibida: 3213 ms sin herramienta, 6320 ms con ella.** La diferencia es la segunda pasada del modelo, que sólo ocurre si llama. +Turnos con las herramientas nuevas, también medidos de punta a punta: + +| Turno | ASR | LLM 1ª | Herramienta | LLM 2ª | Primer audio | +|---|---|---|---|---|---| +| «¿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** | + +El primer audio llega mucho antes que el final del turno porque suena el acuse +mientras la herramienta trabaja. + ## La GPU es de 4 GB y no caben los dos `tts-server` deja residentes unos 3,2 GB (1765 MB del hablante, 177 del @@ -210,6 +338,9 @@ RUST_LOG=info,latencia=info cargo run --release -- run # Cada ventana del ASR, cada síntesis, cada frase RUST_LOG=info,asr=debug,tts=debug cargo run --release -- run +# Qué busca y qué mira +RUST_LOG=info,herramientas=info,camara=info cargo run --release -- run + # Comprobar de nuevo las cifras de arriba scripts/servidores.sh arrancar cargo test --release -p asist-app --test integracion -- --nocapture |