Cumpliendo con la autodisciplina de dedicar máximo un día a la semana a esta misión, seguimos dándole caña a Jade. Como adelanté la semana pasada, el objetivo sería llevar todo un poco más a la tierra con un esquema general de funcionamiento. Sí, aún no hemos picado ni una línea de código, es lo que hay.
Lo importante es que hemos logrado definir el comportamiento ideal del sistema y hemos conseguido identificar responsabilidades de alto nivel. Aún no sabemos de qué manera implementaremos cada una de las partes, pero distinguimos los siguientes subsistemas:
Enlace al figjam → quiero cotillear
1. Ingesta
Será el encargado de recibir el contenido de manera sencilla y desde cualquier plataforma, disparando el flujo de procesamiento. El input será multimodal (audio, video, pdf, enlaces, etc) y valoramos distintas opciones (bot de Telegram, plugin de Obsidian, servidor de correo electrónico, ...).
Cada estrategia tiene, como todo en la vida, sus pros y sus contras. Lo bueno es que no son excluyentes, por lo que es posible que terminemos implementando más de una forma de enviar contenido. El único requisito imprescindible es que tiene que ser one-click, algo fácil y desatendido.
2. Procesamiento
Se encargará de todo el procesamiento de los inputs, incluyendo transformaciones de formato, transcripciones, compresiones, scrapping, etc. Aunque inicialmente pensamos hacerlo directamente en el entorno de Obsidian, finalmente decidimos externalizarlo por limitaciones técnicas y para mantener la separación de responsabilidades que he comentado en otros posts.
3. Almacenamiento
Plantea varios retos, debido a que Obsidian es independiente del almacenamiento (offline, iCloud, Drive, etc). Probablemente, decidamos implementar un plugin de Obsidian que haga pull de la información procesada (texto + binarios) del servidor del sistema de procesamiento.
4. Visualización
Obsidian 100%.
5. Procesamiento on-demand
Para permitir mayor flexibilidad, hemos pensado que todo el procesamiento más específico debe ser opcional y bajo demanda. Para ello, desarrollaremos una command palette de prompts para post procesar el contenido bajo demanda.
Esta estrategia modular permite que cada parte del sistema sea reemplazable, garantizando la independencia y flexibilidad de cada etapa de flujo. A su vez, dentro del servidor de procesamiento, mantendremos una arquitectura monolítica, pero implementando interfaces para cada servicio y haciendo uso de inyección de dependencias para facilitar el testing y poder reemplazar algunas implementaciones por otras (ej: definición de un servicio de transcripción que pueda ser implementado por una API de Open AI o por cualquier otra sin romper los contratos con el resto de componentes).
Flujo de funcionamiento
Para que entiendan un poco más el flujo, aquí va un ejemplo:
Estoy escuchando un pódcast que me ha resultado interesante.
Decido guardarlo y se lo envío a Obsidian (función share).
Esto disparará el servidor de procesamiento que hará scrapping del podcast, transcribirá el audio y generará una serie de metadatos. El resultado del procesamiento quedará temporalmente almacenado en el servidor.
Una vez entro a Obsidian, se disparará una sincronización que recuperará los últimos elementos guardados generando ficheros para cada elemento a la espera de ser clasificados.
Ya con el documento en Obsidian, podremos lanzar procesamiento personalizado, como:
Sugerir la carpeta en la que almacenar dicho output.
Sugerir enlaces con otros documentos de Obsidian y aplicarlos (buscando referencias con nuestro grafo de documentos).
Generar un resumen y extraer aspectos relevantes.
Escribir un artículo.
Lo que sea que se te ocurra hacer con un LLM.
Stack
En cuanto al stack tecnológico, empezaremos por algo sencillo. Valoramos montar el procesamiento en unas cloud functions de Firebase (durante la fase MVP), ya que es fácil montar una API con autenticación, almacenamiento, base de datos, etc., y todo out of the box con capa de uso gratuito. Aunque hace tiempo que le tengo ganas a Supabase. Escucho opiniones.
Más adelante, la idea es desplegar una API con NestJS en Railway (tengo muchas ganas de probarlo también jeje). Como base de datos usaremos un combo de PostgreSQL en PlanetScale o puede que un Redis en Upstash. Como ven, me gustan mucho el PaaS y el SaaS, pero no sin razón. Para proyectos de este tipo ni me plantearía otra cosa. De hecho, para casi ningún proyecto en fase inicial me plantearía otra cosa. Para uso personal, los costos no serán un problema y ya he pasado por tener que gestionar toda la infraestructura en AWS o GCP.
Próximos pasos
Nuestro primer objetivo será hacer un MVP que incluya al menos uno de los caminos críticos del ciclo completo de ingesta, procesamiento y almacenamiento. Una vez logrado, podremos empezar a mejorar y expandir funcionalidades.
Por otro lado, más investigación (nunca se termina). He estado probando distintos SaaS de transcripción de reuniones (comentaré más sobre esto esta semana). Y otras herramientas de segundo cerebro y demás para sacar ideas, ver qué se puede replicar y qué no.
El próximo día, y en contra de toda lógica, empezaremos por el final del ciclo con la codificación del plugin de Obsidian, de modo que tengamos una primera aproximación más profunda acerca del funcionamiento de los plugins y sus posibilidades y limitaciones.
Cabe destacar que todo esto será open source y que escuchamos opiniones, comentarios y sugerencias. Esto aún está muy verde, pero veremos a dónde puede llegar.
Si has llegado hasta aquí, sería genial que me lo hicieses saber de algún modo. Seguiré compartiendo igualmente, ¡pero me anima mucho! A su vez te recuerdo que iré subiendo contenido de este tipo y otras temáticas relacionadas con el mundo tech, desarrollo software y startups. Eso sí, no prometo ni tiempos de publicación ni nada, ¡que luego me pillo los dedos!