EstebanBarac's picture
Add panel parental, fix app.py docstring, model card, and open trace
0cd186e
|
Raw
History Blame Contribute Delete
3.55 kB

A newer version of the Gradio SDK is available: 6.20.0

Upgrade
metadata
license: apache-2.0
language:
  - es
tags:
  - agent-trace
  - conversational
  - education
  - spanish
  - build-small-hackathon
pretty_name: Sofía  Agent Trace
size_categories:
  - n<1K

Open Trace — Sofía (mérito 5, "Sharing is Caring")

TL;DR (EN): 12 end-to-end turns of the real Sofía pipeline (intent router → curated content from content/ → safety guard → small fine-tuned LLM), captured as JSONL with the exact prompt sent to the model at each step. Shows the LLM is a small, replaceable "conversational glue" component, not the source of facts — including a turn where the model refuses to invent a story and offers curated content instead, and a turn blocked entirely before reaching the LLM. Part of the sofia-educational-companion project (Build Small Hackathon, track Backyard AI).

agent_trace.jsonl son 12 turnos representativos corridos contra el pipeline real (safety.guard + llm.engine.LumiEngine + content.loader.ContentLibrary), generados con export_trace.py. Cada línea es un turno completo, de punta a punta.

Objetivo: que se vea, con datos reales, lo que dice el "Principio inviolable" de CLAUDE.md: el LLM es solo el pegamento conversacional dentro de un pipeline mayormente determinista (router de intención → contenido curado de content/ → guard de seguridad). El modelo nunca es la fuente de hechos, cuentos ni números.

Formato (JSONL, un turno por línea)

campo qué es
turn número de turno (1-12)
child_age edad simulada (3)
user_message lo que "dice" la niña
safety_input_blocked true si safety.guard.blocks_input frenó el mensaje antes de llegar al motor
intent intención detectada por el router (llm/engine.py:_intent); null si se bloqueó en la entrada
prompt_messages los messages exactos que recibe el LLM: system (persona de Sofía) + historial + bloques <contenido>/<contexto>/<nota> armados por LumiEngine.respond; null si se bloqueó en la entrada
activity la actividad curada elegida de content/ (si aplica), con su id, title y script
reply la respuesta final que recibiría la niña
safety_output_blocked true si safety.guard.blocks_output reemplazó la respuesta por el fallback

Turnos destacados

  • Turno 10 ("¿Qué es una pistola?"): safety_input_blocked: true, prompt_messages: null. El mensaje ni llega al LLM: lo frena safety.guard.blocks_input y responde gentle_redirect().
  • Turno 11 ("Contame un cuento de un dragón que come autos"): no existe ese cuento en content/stories.json. El modelo no inventaLumiEngine elige otro cuento curado existente ("La tortuguita paciente") y el LLM solo lo presenta, con una <nota> que le prohíbe inventar contenido.
  • Turnos 3-9: cada <contenido> es texto literal de content/ (conteo, formas, colores, animales, canción, emoción, cambio de color); el LLM reformula/celebra pero los datos vienen del JSON curado.

Cómo se generó

LUMI_LLM_BACKEND=ollama python trace/export_trace.py

Corre contra Ollama (qwen2.5:7b) en local, usando el mismo SYSTEM_PROMPT y los mismos bloques <contenido>/<contexto>/<nota> que arma llm/engine.py en producción (Qwen2.5-7B-Instruct fine-tuneado vía ZeroGPU). Usa un SQLite temporal para el historial conversacional — no toca parental/lumi.db.