From 71764752f28d31028b9c2ca486c0fc1bcea1cf95 Mon Sep 17 00:00:00 2001 From: elvis Date: Sun, 6 Sep 2026 22:05:14 -0300 Subject: Web search and camera vision MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 --- config/asistente.toml | 56 ++++++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 55 insertions(+), 1 deletion(-) (limited to 'config/asistente.toml') diff --git a/config/asistente.toml b/config/asistente.toml index b638acd..a219142 100644 --- a/config/asistente.toml +++ b/config/asistente.toml @@ -30,6 +30,17 @@ es así, llámala primero y espera su resultado; no contestes de memoria. Sólo cuando tengas el resultado, resúmelo en una frase. """ +# Se añade a system_prompt para redactar la respuesta cuando una herramienta ya +# devolvió su resultado. Aquí sí se puede añadir estilo —la llamada ya ocurrió— +# y hace falta: sin esto el modelo anuncia lo que acaba de hacer («he tomado una +# foto, ahora puedo responderte sobre el color») en vez de decir lo que averiguó. +tool_result_prompt = """ +Acabas de recibir el resultado de una herramienta. Contesta a la pregunta \ +usando ese resultado y nada más. No anuncies lo que has hecho ni lo que \ +podrías hacer: di directamente lo que has averiguado. Si el resultado viene en \ +otro idioma, tradúcelo al español. +""" + [audio] # Vacío = el dispositivo por defecto. `asistente devices` los lista. input_device = "" @@ -113,11 +124,54 @@ dedicated_prompt = true # una shell a un modelo que obedece a lo que oye por el micrófono es un cambio # de postura de seguridad, no una comodidad. Actívala aquí o con --shell. shell = false -shell_allowlist = ["date", "uptime", "free", "df", "ls"] +shell_allowlist = ["date", "uptime", "free", "df", "ls", "mkdir", "cat"] shell_timeout_secs = 10 shell_dry_run = false shell_working_dir = "" +# Búsqueda en internet. La clave NO va aquí: se lee de la variable de entorno +# que indique api_key_env, porque este fichero se versiona y un secreto dentro +# acaba en el historial de git. +# +# Tres buscadores, medidos: +# tavily ~2,4 s. Devuelve una respuesta YA REDACTADA además de los enlaces, +# que es lo que se puede leer en voz alta sin gastar otra vuelta del +# modelo en resumir. Necesita clave. +# ddgs 1,5-5,8 s. Sin clave. Consulta DuckDuckGo, Brave, Mojeek, Startpage +# y compañía a través de scripts/buscar-ddgs.sh. Sólo devuelve +# fragmentos: la síntesis la tiene que hacer el modelo, y con 2B sale +# algo peor que con tavily. +# searxng Sin clave, pero hace falta una instancia propia. Como ddgs, sólo +# devuelve resultados. +[search] +enabled = true +backend = "tavily" # "tavily", "ddgs" o "searxng" +api_key_env = "TAVILY_API_KEY" +base_url = "" # sólo para searxng, p. ej. "http://127.0.0.1:8888" +# Programa del backend "ddgs". {consulta} y {max} se sustituyen antes de +# ejecutar, y tiene que escribir JSON por la salida estándar. Vale cualquier +# otro programa que respete eso, incluido un puente a un servidor MCP. +command = ["../scripts/buscar-ddgs.sh", "{consulta}", "{max}"] +max_results = 5 +timeout_secs = 20 + +# Mirar por la cámara. El servidor ya carga el proyector multimodal, así que el +# mismo modelo que conversa describe lo que capta. +[camera] +enabled = true +device = "/dev/video0" +# La resolución manda en la latencia. Medido en esta máquina: 1,3 s a 320x240, +# 2,9 s a 640x480 y 7,8 s a 1280x720. 640x480 es el equilibrio. +width = 640 +height = 480 +# Fotogramas descartados para que se asiente la exposición automática; el +# primero suele salir quemado y descartar unos pocos es casi gratis. +warmup_frames = 5 +timeout_secs = 15 +# Vacío = no se guarda ningún fotograma en disco, que es lo que corresponde. +# Ponle una carpeta sólo para depurar qué está viendo el modelo. +save_dir = "" + [supervisor] manage = true # lanzar los servidores; --no-manage los supone arriba startup_timeout_secs = 180 -- cgit v1.2.3