Larry Profe — portando Larry a Math Challenge
Resumen ejecutivo
Larry ya existe en IOS como copiloto EN/ES sobre Workers AI (kimi-k2.6 → gpt-oss-120b → respuesta enlatada), con un prompt de sistema bilingüe único, un protocolo de "tool calling" hecho a mano (JSON en una línea) y auditoría durable en D1. Nada de esto usa la API de Claude — sería la primera integración de Claude en este repo.
El dueño ya decidió: Larry Profe usa la API de Claude con ruteo por dificultad (Haiku/Sonnet/Opus). El precedente más cercano en el repo no es el chat libre sino src/larry/contador/explain.ts: un hallazgo determinístico entra, un LLM lo explica en lenguaje natural sin recalcular nada, con fallback a plantilla. Larry Profe debe seguir exactamente ese patrón: el motor de calificación decide qué está bien o mal; Claude solo explica, en el idioma, edad y tono correctos, nunca avergonzando al niño.
Este documento fue traducido del original en inglés por Claude (Anthropic) y verificado automáticamente contra la fuente: cada número, URL, marcador de cita y marca [unverified] coincide con el original. La prosa todavía no ha sido revisada por un hablante nativo humano.
Estado de verificación
Este documento no lleva ninguna marca [unverified]. Cada afirmación está atada a una fuente numerada de abajo.
[unverified] quiere decir que la afirmación está en la investigación pero no se confirmó contra una fuente primaria en la sesión que la produjo. Se publica en vez de borrarse, porque un corpus que esconde sus huecos no es verificable.
Cómo se produjo esta investigación
Los 47 documentos se hicieron el 2026-07-31 por agentes independientes, cada uno con instrucción explícita de no inventar citas y de marcar como [unverified] lo que no pudiera confirmar contra una fuente primaria. La cuota de búsqueda web de la sesión se agotó a media investigación y los agentes posteriores trabajaron por descarga directa contra fuentes primarias. Varios sitios (ftc.gov, ico.org.uk) bloquean la descarga automatizada, y por eso ciertas afirmaciones legales están marcadas a propósito.
Esto es investigación, no asesoría legal, médica ni financiera. Nada aquí reclama un resultado de aprendizaje de Math Challenge; ese estudio todavía no existe.
Lo que existe hoy — rutas de archivo y referencias de línea de este repo
- Persona/canon.
docs/larry.md:1-16— “rinoceronte naranja, entrenador honesto”, frase característica “¡Ya vas!” solo al aceptar una tarea, humor dirigido siempre solo hacia sí mismo. - La cadena de modelos es Workers AI, no Claude.
src/larry/chat.ts:40-41:PRIMARY_MODEL = '@cf/moonshotai/kimi-k2.6',FALLBACK_MODEL = '@cf/openai/gpt-oss-120b'(mismo par ensrc/larry/contador/explain.ts:16-17).docs/wiki/decisions.md:42-47(ADR-006): “nuestro propio modelo (Workers AI) atiende el 70–90 % de tráfico rutinario; una API de frontera atiende los casos difíciles” más una caché semántica y un presupuesto por rol — una forma conceptualmente parecida a lo que necesita Larry Profe, pero IOS es Workers-AI-first con Claude como excedente; el brief del dueño para Math Challenge es Claude-first con ruteo por dificultad del problema, no la misma política. - Patrón de prompt único bilingüe.
src/larry/prompts.ts:24-57,buildSystemPrompt(locale, context)— cada línea de persona/regla se escribe dos veces, EN y luego ES, en una sola cadena (p. ej.:29); solo la instrucción “responde en el idioma X” (:47) es específica del locale. No escala a 5 idiomas (ver abajo). - Lista dura de “nunca”.
src/larry/prompts.ts:38-44— cinco viñetas: nunca borrar datos del cliente, nunca leer el contenido de un objeto, nunca tocar facturación sin confirmación, nunca crear/rotar llaves por chat, nunca cambiar código/configuración; reformulado en prosa endocs/larry.md:96-102(§4.2). Este es el hueco de plantilla donde Larry Profe necesita sus propias reglas de seguridad infantil. - Protocolo de herramientas hecho a mano. El modelo debe responder con solo una línea
{"tool": "<name>", "args": {...}}(prompts.ts:50-51), no con los bloques de contenidotool_usede Anthropic. Analizado porparseToolCall(chat.ts:273-289); iterado porgenerateReplyWithTools(:236-267), con tope deMAX_TOOL_HOPS = 2(:44). La seguridad de alcance por inquilino vive ensrc/larry/tools.ts:47-48, 342-394. - Cadena de respaldo, sin reintento ni backoff.
chat.ts:295-314generateReplyprueba cada modelo una vez, cae acannedErrorReply(locale)(prompts.ts:67-71) si ambos fallan. - Sumidero de auditoría.
migrations/0011_larry_audit.sql:5-23— tabla D1, tipos de filachat/tool, columnas que incluyentenant_id,locale,tools_used,outcome,latency_ms,prompt_tokens,completion_tokens. Los escritoressrc/larry/audit.ts:36-67, 70-97son de mejor esfuerzo, nunca lanzan excepción. Los conteos de tokens son una estimación tosca detext.length / 4(audit.ts:31-33), no elusagereal del modelo — las respuestas de Claude traen conteos exactos de tokens, que la auditoría de Larry Profe debería registrar con precisión en su lugar. - La detección de locale es solo EN/ES.
src/larry/locale.ts:9, 63-71— lista de palabras en español codificada a mano más comprobación de caracteres acentuados, el inglés es el valor por defecto. No existe infraestructura FR/PT/DE; extender esta heurística es frágil (ver abajo). - El precedente real:
src/larry/contador/explain.ts.:67-75la regla dura del prompt de sistema (“Every number… MUST appear verbatim in the provided JSON. Never compute, convert, round, or invent a figure… Temperature is 0.”);:106-145explainFinding()elimina el campoexplanationprecalculado antes de enviarle el hallazgo al modelo (:113, para que no pueda simplemente repetir una cadena enlatada), pide JSON bilingüe{"en":..., "es":...}, y cae arenderTemplateExplanation()(:41-60) — un volcado de hechos plano, sin LLM — ante cualquier fallo. Esto es arquitectónicamente lo que necesita Larry Profe. - Avatar + máquina de estados.
packages/design-system/larry/LarryAvatar.tsx:4-13— estadosorb|face|idle|thinking|working|happy|denying|celebrating|presenting;larry.css:1-121un@keyframespor estado, deshabilitado bajoprefers-reduced-motion(:113-120).packages/design-system/src/larry-chat/useLarryChat.ts:1-9,30documentaidle → thinking → working → idle. Reutilizable tal cual para Larry Profe. - Ningún uso de la API de Claude en ningún lugar de este repo hoy — no hay importación de
@anthropic-ai/sdkbajosrc/nipackages/. Esta es una primera integración, no una extensión.
Qué debe cambiar para un tutor de matemáticas infantil
- Tono, no “entrenador honesto”. La persona de IOS apunta a ingenieros B2B adultos que pueden aceptar una corrección directa. Un niño nunca debe sentirse avergonzado — más estricto que “el humor nunca se burla de las características de las personas”.
- Cinco idiomas, no dos. El tipo
'en'|'es'delocale.tsy su detector por lista de palabras no se extienden a FR/PT/DE, y el patrón de “escribir cada línea dos veces” deprompts.tsmultiplicaría por 5 los tokens del prompt para contenido en su mayoría no usado por llamada — construir en su lugar un prompt de un solo idioma por locale. - La corrección matemática no puede depender del LLM. Una respuesta incorrecta de una herramienta de IOS es una pista de UI mala; una explicación incorrecta de Larry Profe enseña activamente matemáticas incorrectas. Esta es exactamente la razón por la que la forma “el LLM explica, nunca calcula” de
contador/explain.tses correcta y el bucle libre dechat.tsno lo es. - Vocabulario por edad, explícito en el prompt (banda de edad como parámetro), no dejado a que el modelo lo infiera del tono.
- El ruteo de modelos es nuevo — ADR-006 describe un ruteo híbrido Workers-AI-first; Larry Profe lo invierte (Claude-first, tres niveles de dificultad, sin Workers AI), según el brief del dueño.
- Retirar o suavizar el estado de avatar
denyingpara un producto infantil — el lenguaje corporal de negación con la cabeza (larry.css:87-98) se lee como “estás equivocado”; preferirthinking→presentingpara las correcciones.
Tabla de ruteo de modelos
Los precios/IDs de modelo vienen de la skill claude-api (en caché desde 2026-06-24; el precio de introducción de Sonnet 5 corre hasta 2026-08-31), no de la memoria de entrenamiento. Las estimaciones de costo asumen un prefijo de prompt de sistema compartido (cubierto bajo el cacheo más abajo) más una carga por llamada de {problema, pasos del alumno, veredicto de calificación}; las cifras son estimaciones a validar contra prompts reales, no mediciones.
| Banda de dificultad | ID de modelo | $/MTok entrada / salida | Tokens est. entrada → salida | Costo est. / 1.000 explicaciones | Objetivo de latencia |
|---|---|---|---|---|---|
| Aritmética básica | claude-haiku-4-5 | $1,00 / $5,00 | ~300 → ~150 | ~$1,05 | < 1,5 s, sin necesidad de streaming |
| Nivel medio (fracciones, álgebra, geometría) | claude-sonnet-5 | $3,00 / $15,00 (intro $2/$10 hasta 2026-08-31) | ~500 → ~300 | ~$6,00 (intro ~$4,00) | 2–4 s, streaming si > ~3 s |
| Avanzado (cálculo tensorial, integrales dobles, demostraciones) | claude-opus-5 | $5,00 / $25,00 | ~800 → ~600 + razonamiento adaptativo | piso de ~$19, realistamente $35–60 una vez contados los tokens de razonamiento | 5–15 s; debe usar streaming |
Notas:
- El costo de Opus 5 está dominado por los tokens de razonamiento. Según la skill, el razonamiento está activado por defecto en Opus 5 — una solicitud que nunca fija
thinkingde todos modos razona, y el razonamiento se factura como salida a $25/MTok. Una explicación difícil puede gastar entre 1.000 y 2.000 tokens de razonamiento antes de la respuesta de 600 tokens, añadiendo por sí solo ~$25–50 por cada 1.000 llamadas. Deshabilitar el razonamiento tiene modos de fallo reales (llamadas a herramientas o etiquetas<thinking>que se filtran al texto visible, segúnshared/model-migration.md), así que la palanca más segura esoutput_config.effort— empezar Opus 5 enmediumy subir solo si la evaluación muestra explicaciones superficiales. - Haiku 4.5 necesita un prefijo cacheable de 4.096 tokens. Según la tabla de mínimos por modelo de
shared/prompt-caching.md, el piso de Haiku 4.5 es de 4.096 tokens (el más alto de cualquier modelo actual; Opus 5/Fable 5 necesitan solo 512). Un prompt de sistema de aritmética básica (persona + reglas + una banda de edad + un idioma) probablemente queda bastante por debajo de eso, lo que significa que las llamadas de Haiku podrían nunca alcanzar el cacheo de prompt a menos que el prefijo se rellene deliberadamente — hay que señalarle esto al dueño en vez de asumir que el cacheo “simplemente funciona” en el nivel más barato. - La Batch API (50 % de descuento) encaja con la pregeneración, no con el tráfico en vivo. Una explicación en vivo dentro de una sesión no puede ir por lotes, pero pregenerar los N conceptos erróneos más conocidos por tema/edad/idioma antes del lanzamiento es exactamente el caso de uso de la Batch API (hasta 100K solicitudes por lote, no sensible a la latencia).
La arquitectura del prompt — esqueleto propuesto, 5 idiomas, reglas duras
Apartándose del patrón de “cada línea dos veces” de prompts.ts, construir un prompt por (locale, banda de edad, nivel), mostrado en inglés (FR/PT/DE/ES son renders paralelos de un solo idioma, no concatenaciones):
You are Larry Profe, Larry the orange rhinoceros, teaching math to
[AGE_BAND] students. Same character as always — just teaching math now.
WHAT YOU RECEIVE: a JSON verdict from the grading engine (problem, student
steps, which were correct, where the error started, its classification).
You do NOT grade or recompute. Every number/step you reference MUST come
verbatim from that JSON.
WHAT YOU DO:
1. Say specifically what the student did right (not just "good job").
2. Explain what went wrong and why — the real misconception, not "wrong answer."
3. Walk through the correct process, like a patient professor, at a level a
[AGE_BAND] student can follow.
4. End on encouragement, never on the mistake.
HARD RULES:
- Never call a student "bad at math," "slow," or any variant — mistakes are
how math is learned.
- Never use sarcasm, exasperation, or a disappointed tone, even softened.
- Never invent or alter a number/step/verdict not in the provided JSON.
- Never compare the student to other students or a class average.
- Never skip "what you did right," even if everything was wrong — find
something true and specific (effort, a correct partial step, right
approach/wrong arithmetic).
- If asked something outside math tutoring, redirect kindly to a
parent/teacher.
LANGUAGE: Reply only in [LOCALE_NAME]. Never mix languages or offer translation.
VOCABULARY: [age-band guidance — e.g. ages 6-8: concrete objects, no jargon;
ages 13+: precise terminology expected.]
Reservar output_config.format / esquemas de herramienta strict: true para el traspaso motor-de-calificación → Larry-Profe (el propio backend de Math Challenge valida ese JSON, no Claude) — la salida de este prompt es prosa fluida en streaming, no datos estructurados.
Estrategia de cacheo y control de costos
Dos capas independientes:
- Cacheo de prompt de Claude sobre el prefijo estable (persona + reglas + un idioma + una banda de edad). Por modelo, por prefijo — las escrituras cuestan 1,25× (TTL de 5 min) o 2× (1 hora), las lecturas ~0,1×. Un TTL de 1 hora con precalentamiento periódico (solicitudes
max_tokens: 0, segúnshared/prompt-caching.md) conviene para el tráfico irregular de las horas de tarea. Omitir para Haiku a menos que el prefijo supere los 4.096 tokens (ver arriba). - Caché de conceptos erróneos a nivel de aplicación (D1/KV) — el mecanismo que el brief del dueño en realidad pide. Cachear la explicación generada completa, indexada por
(topic, misconception-classification, age-band, locale)— no la instancia exacta del problema, para que distintos problemas de fracciones con el mismo error de “olvidó el denominador común” caigan en una sola entrada de caché. Refleja el patrón de búsqueda estática existenteS3_ERROR_KB/METRIC_KB(src/larry/tools.ts:59-135), salvo que se puebla con la salida de Claude al momento de la generación; recurrir a una llamada en vivo cuando falle la caché y poblarla, reflejando la forma de IA-y-luego-plantilla decontador/explain.ts. Registrarcache_hit: booleany losusage.input_tokens/usage.output_tokensreales en una tabla de auditoría análoga a la migración0011— no la estimación detext.length/4que usaaudit.tshoy. - Batch API para la siembra en frío — pregenerar los N conceptos erróneos más comunes por tema antes del lanzamiento con 50 % de descuento, convirtiendo la mayor parte del tráfico temprano en lecturas de caché desde el día uno.
Implicaciones de diseño
- Larry Profe es una integración nueva de la API de Claude; no enrutarla a través del gateway de Workers AI de IOS — el dueño quiere Claude, y ADR-006 es una arquitectura distinta, Workers-AI-first, para un producto distinto.
- Modelar el motor de calificación como fuente de verdad, Claude solo para explicar — seguir la forma de
contador/explain.ts, no el bucle libre de herramientas dechat.ts. - Abandonar el patrón de prompt bilingüe en línea; un prompt por locale, ya que 5 idiomas hace que la deriva entre idiomas dentro de un solo prompt sea a la vez costosa y propensa a errores.
- Tomar el locale como un parámetro explícito del cliente (Math Challenge ya tiene una configuración de idioma) en vez de inferirlo como hace
locale.tspara IOS. - Construir el ruteador de nivel de dificultad en el backend de Math Challenge (junto a la calificación, que ya conoce tema/nivel) — nunca dejar que Claude elija su propio nivel de modelo.
- Tratar
effortcomo un segundo eje de ruteo independiente de la elección de modelo; empezar de forma conservadora (mediumen Opus 5) ya que es la palanca principal contra el descontrol de costo por tokens de razonamiento. - Registrar los campos
usagereales de Claude en el sumidero de auditoría desde el día uno en vez de repetir la estimación por conteo de caracteres deaudit.ts. - Escribir un canon de reglas duras de seguridad infantil paralelo a la lista de cinco puntos de
docs/larry.md§4.2, pero desde cero — las reglas de IOS son sobre seguridad de datos, no seguridad emocional. - Reutilizar
LarryAvatary su máquina de estados sin cambios, pero reconsiderar sidenyingdebería dispararse alguna vez ante un niño. - Mantener la caché de conceptos erróneos y el cacheo de prompt de Claude como sistemas distintos — resuelven problemas diferentes (evitar el reenvío del prefijo vs. evitar regenerar salida semánticamente idéntica) y confundirlos hace que se cumpla mal el objetivo de “una generación, no mil”.
- Usar la Batch API para sembrar de antemano la caché de conceptos erróneos antes del lanzamiento y para rellenar tipos de concepto erróneo nuevos encontrados en producción.
- Cada regla dura y cada línea de prompt necesita copia EN/ES/FR/PT/DE revisada por humanos — un tono que se lee como alentador en un idioma puede sonar condescendiente en otro; no dejar esto a la traducción en tiempo de ejecución.
Preguntas abiertas para el dueño del proyecto
- ¿El ruteador de nivel de dificultad vive en el backend de Math Challenge (el motor de calificación etiqueta tema/nivel), o Larry Profe debería reclasificar la dificultad a partir del texto del problema?
- ¿Cuáles son las bandas de edad reales (K-2/3-5/6-8/9-12, o por grado)? Esto determina tanto las variantes de vocabulario como el número de combinaciones de prompt cacheadas que hay que autorar (locale × banda de edad × nivel podría ser 5×4×3 = 60).
- ¿El
effortde Opus 5 debería fijarse por nivel, o ser ajustable por tema dentro de “avanzado” (una integral doble y una demostración completa de cálculo tensorial plausiblemente necesitan un esfuerzo distinto)? - ¿Existe un presupuesto de latencia a nivel de producto (p. ej., “debe empezar a hacer streaming en menos de 2 s o mostrar un estado de carga”) que debería condicionar el streaming por defecto por nivel?
- ¿Quién revisa la copia de reglas duras y prompts en FR/PT/DE — un revisor de contenido educativo multilingüe, o traducción automática como primer borrador a partir de la versión EN/ES?
- ¿La caché de conceptos erróneos necesita un TTL, o está bien servir indefinidamente una explicación cacheada para un concepto erróneo poco común?
- ¿“Lo que el alumno hizo bien” siempre debe encontrar algo, incluso para una respuesta en blanco o adivinada — y si es así, cuál es el piso honesto (p. ej., “lo intentaste”)?
Fuentes
Este documento cita archivos del repositorio y otras investigaciones, no una lista numerada de fuentes.
Preguntas que este documento le deja abiertas al dueño
Están sin responder a propósito. Se listan, no se resuelven — convertirlas en preguntas frecuentes obligaría a inventar respuestas que el documento no tiene.
- Does the difficulty-tier router live in Math Challenge's backend (grading engine tags topic/tier), or should Larry Profe re-classify difficulty from problem text?
- What are the actual age bands (K-2/3-5/6-8/9-12, or by grade)? This drives both vocabulary variants and the number of cached prompt combinations to author (locale × age-band × tier could be 5×4×3 = 60).
- Should Opus 5's effort be fixed per tier, or tunable per-topic within "advanced" (a double integral and a full tensor-calculus proof plausibly need different effort)?
- Is there a product-level latency budget (e.g. "must start streaming within 2s or show a loading state") that should gate default streaming per tier?
- Who reviews the FR/PT/DE hard-rule and prompt copy — a multilingual education content reviewer, or machine translation as a first draft from the EN/ES version?
- Does the misconception cache need a TTL, or is a cached explanation for a rare misconception fine to serve indefinitely?
- Must "what the student did right" always find something, even for a blank/guessed answer — and if so, what's the honest floor (e.g. "you tried")?
Uno de 51 documentos de investigación, 168.346 palabras en total, contadas en el build sobre los archivos mismos. Leer este documento en el repositorio