👨🏫 Haciendo videos educativos con AI
Mirar clases grabadas de la pandemia (método altamente utilizado por profesores universitarios) es lo más parecido a un método de tortura que se vio en el ámbito académico. Y la peor forma de atraer a los estudiantes a lo que estás intentando enseñar. Salvo escasas excepciones (no conozco ninguna, pero para ahorrarme puteadas).
Siempre fui muy fan de los divulgadores de ciencia, y sobre todo de los que enseñan de forma intuitiva y entretenida. Casos como El Traductor de Ingeniería, Quantum Fracture o mi favorito 3blue1Brown.
Este último es quien importa ahora, porque para hacer sus videos animados invento su propia librería de python llamada Manim, la cual hizo open source.
En mi cerebro fue una asociación simple, dos más dos es cuatro. Hay que lograr que cualquier profesor pueda usar esto para crear buenas clases, sin necesidad de saber escribir código y con la menor fricción posible. Una necesidad generada por la tortura ya mencionada anteriormente.
Así que me senté un sábado que tenía libre hace dos meses en la Melian House y desarrolle la primera versión (link acá). Una plataforma estilo v0.app que te permite describir el video y un AI agent se ocupa del resto.
AI Agent: un programa de software que utiliza inteligencia artificial para percibir su entorno, razonar, planificar y tomar medidas para lograr un objetivo de forma autónoma. (Según ChatGPT, no revise que dijo, copie y pegue).

Un par de semanas después, modifique el agent y la interfaz para que el video estuviera dividido en escenas. Lo cual lo ayudaba a no perderse y según yo (no hable con ningún usuario, no voy a mentir) era más fácil editar partes específicas del video.
A partir de ahí no le dedique mucho tiempo más, y seguirá así hasta que este de vacaciones de la facultad. ¿Excusa? Seguramente. Pero la aproveché para decidir hacerlo open source, y que cualquier persona que le cope la idea pueda colaborar o crear su versión, cosa que ya empezó a suceder.
¿Ahora, que conclusiones saque de estas primeras versiones y cuáles son los próximos pasos?
Anichar la solución. Al igual que Vercel, que en sus inicios dejo de ser un servicio de cloud para todo para pasar a ser solo un servicio de cloud para sitios web estáticos, Claiss debe dejar de ser una solución para hacer cualquier tipo de videos para ser muy bueno en un solo tipo en específico. Por ejemplo, la creación de videos educativos de matemática.
Sea cual sea el nicho, los videos necesitan dos cosas que hoy no tienen para ser buenos. La primera es poder agregarle voz encima, la cual explique lo que se ve en las animaciones. La segunda, menos importante, es la música de fondo para los videos.
Empezar a mostrar muchos más esto, contactar profesores, divulgadores o creadores de contenido que puedan querer esto, así también verificamos que los puntos 1 y 2 tengan sentido alguno lo antes posible.
Dado que Claiss no será algo prioritario en mi vida, pero que igualmente quiero que existe, seguirá siendo open source. Quien quiera forkear y/o contribuir, totalmente invitado.
Cualquier feedback, como siempre, es bienvenido.
¿Cómo funciona Claiss? (Explicación técnica)
El agente fue creado 100% utilizando AI SDK de Vercel (v5, migrando a v6 beta en este momento). La única librería de este tipo en ser ‘provider agnostic’. Voy a ir mostrando el razonamiento junto al código para que se entienda bien que se buscó hacer.
La parte más linda del desafío de construir esto, fue empezar a entender lo que implica crear software no determinístico. Algo a lo que nadie que haya construido software en el pasado está acostumbrado y que por momentos puede ser contraintuitivo.
Lo más lógico fue leer que decían los que saben, artículos y videos de OpenAI y Antrophic fueron debidamente consumidos.
Orquestadores, prompts, modelos, ventanas de contexto, RAGs, fine-tuning, workflows, evals, guardrails y 20 millones de conceptos más que podés tocar o agregar a la hora de construir este tipo de sistemas. Pero el consejo general fue siempre el mismo: mantenelo tan simple como puedas
Use orchestration patterns that match your complexity level, starting with a single agent and evolving to multi-agent systems only when needed. - “A practical guide to building agents” by OpenAI
Si les digo que estoy seguro de cuál es el punto justo en cuando a tools, contexto, modelo y demás para maximizar la performance les estaría mintiendo. Por lo cual lo pensé desde lo más simple que podía hacer y preguntándome a mí mismo: “Si yo tuviese que hacer este video a mano, que necesitaría?”
Primero que nada necesitaría saber escribir código en python, esto con la capacidad actual de los modelos no era un problema.
Luego necesitaba conocer como funcionaba la librería. Esto, el modelo, por sí solo no podía, iba a necesitar darle documentación y ejemplos, y encontré en Context7 una herramienta ideal.
const { client, tools: context7Tools } = await createContext7Client(); //Pueden ver en el repo como funciona esto
mcpClient = client;const tools = {
...context7Tools, ...sceneTools,};Esto es todo lo que necesitas para tener un agent que utilice las tools que vos le diste para resolver lo que sea que le hayas pedido. En la versión v6 del AI SDK introducen la interfaz Agent, pero tema para otro blog.
const result = streamText({
model: google("gemini-2.5-pro"),
system: getVideoGeneratorScenePrompt(currentVideo, videoStructure), //El prompt cambia dependiendo de si estamos editando un video o creando de cero
messages: convertedMessages, tools,stopWhen: stepCountIs(10),
onStepFinish: ({ toolCalls, finishReason }) => {console.log(`[VIDEO-GEN-SCENE] 📋 Step completed:`);
console.log(`[VIDEO-GEN-SCENE] - Reason: ${finishReason}`);
console.log(`[VIDEO-GEN-SCENE] - Tool calls: ${toolCalls?.length || 0}`);
.if (toolCalls && toolCalls.length > 0) {
toolCalls.forEach((call, index) => {
console.log(`[VIDEO-GEN-SCENE] - Tool ${index + 1}: ${call.toolName}`);
}); } },onFinish: async ({ steps }) => {
const endTime = Date.now();
const duration = endTime - startTime;
.console.log(`[VIDEO-GEN-SCENE] 🎉 Stream completed successfully!`);
console.log(`[VIDEO-GEN-SCENE] - Total duration: ${duration}ms`);
console.log(`[VIDEO-GEN-SCENE] - Total steps: ${steps?.length || 0}`);
.if (mcpClient) {
await mcpClient.close();
console.log("[VIDEO-GEN-SCENE] ✅ MCP client closed");
} },onError: async ({ error }) => {
const endTime = Date.now();
const duration = endTime - startTime;
.console.error(`[VIDEO-GEN-SCENE] ❌ Streaming error after ${duration}ms:`, error);
.if (mcpClient) {
await mcpClient.close();
console.log("[VIDEO-GEN-SCENE] ✅ MCP client closed after error");
} }, });Cada vez que intenta hacer algo, el modelo puede pedirle ejemplos concretos o hacer preguntas de como funciona la librería. Hay detalles generales que los tendrá siempre como parte de su contexto, pero esta herramienta le provee snippets hechos por la comunidad que le sean útiles para lo que sea que esté haciendo.
Así se ve una query que hace el agent directamente a Context7, quien le contesta con 600 líneas aprox. de Markdown
{"context7CompatibleLibraryID": "/manimcommunity/manim",
"topic": "matrix multiplication animation",
"tokens": 5000
}Luego de eso el siguiente paso es generar el código, también se podría pensar en generar un guion para la generación de voz posterior. Por ahora preferí mantenerlo simple y solo género código.
En el prompt el agent recibe ciertos lineamientos a seguir en este aspecto, como siempre dividir en escenas, usar nombres descriptivos en ciertos lugares y cosas que no debe hacer porque no van a compilar.
Una vez escrito el código, solo queda compilarlo. El detalle de la decisión que tome acá la dejo para los que quieran colaborar y necesitan entender lo que está hecho.
Para compilar el código de python necesito un ambiente con las dependencias listas, como Manim o LaTex. En ese momento todavía el support de python en Vercel no había salido (tampoco estoy seguro si sirve para este caso, no lo mire), por ende luego de un breve research mis opciones eran Vercel Sandbox o Modal.
Descarte Vercel Sandbox al no encontrar manera de tener dependencias pre cargadas en el sandbox, LaTex es demasiado pesada para instalarla una vez por request (tardaba una eternidad) y además no tenía sentido. Tal vez fue skill issue personal de no encontrar como hacerlo bien, no lo descarto.
Me terminé quedando con modal que me ofrecía la posibilidad de un ambiente con todo lo que necesitaba.
Finalmente, compila cada escena por separado en modal y acá tenés un ejemplo del resultado final simplemente habiendo pedido:
Create a video explaining how to find a local max in a 3d function
Conclusión
Ojalá nunca más tenga que mirar una clase grabada, sea por esto o porque deje la carrera. Ambas alternativas son bienvenidas.
Bienvenido quien quiera subirse a este barco, aunque parezca más una balsa con filtraciones y sin rumbo.
Abrazo grande, y gracias por llegar hasta acá.