Un flujo de trabajo diario de GitHub a LLM local que escribe mis tarjetas de proyecto
La sección de Proyectos de este sitio no se mantiene manualmente. Una vez al día un trabajo revisa mis repositorios de GitHub, detecta lo que ha cambiado, pide a un modelo de lenguaje local que escriba una breve descripción de cada proyecto modificado y guarda el resultado. Publico los que merecen ser vistos; el resto quedan como borradores.
Así es como está conectado — y, más importante aún, las tres reglas que evitan que haga nada estúpido.
El flujo
cron (03:30)
→ GET /api/internal/repos (lo que ya sé: repo → último SHA)
→ GET api.github.com/user/repos (token de solo lectura, granular)
→ diff by default-branch SHA (solo los repositorios cambiados continúan)
→ fetch README + languages
→ POST {OLLAMA}/api/chat (gemma, formato: json, think: false)
→ POST /api/internal/projects (fusionar en SQLite)
El LLM es local: una instancia de Ollama ejecutando Gemma en la LAN. Ningún código, README ni metadatos del repositorio salen nunca de la red. Se le pide al modelo, en un system prompt estricto, que se comporte como un "redactor técnico preciso" y que devuelva solo un objeto JSON:
{ "title": "…", "blurb": "…", "tags": ["…"], "highlight": true }
format: "json" de Ollama garantiza una salida analizable, y think: false deshabilita el rastro de razonamiento del modelo: más rápido (~5–6 s/repo) y más limpio.
Regla 1 — solo tocar lo que ha cambiado
Cada repositorio que he visto está registrado en una tabla repo_state con su último SHA de la rama por defecto. Cada ejecución compara el SHA en vivo con el almacenado; los repositorios sin cambios se saltan antes de llamar al modelo. El LLM es el paso costoso, por lo que solo se ejecuta para los repositorios que realmente han cambiado. Una segunda ejecución minutos después no hace nada y llama al modelo cero veces.
Regla 2 — nunca sobrescribir mis ediciones
La salida del modelo es un dato automático. En SQLite, cada proyecto tiene dos conjuntos paralelos de campos: los valores automáticos (de GitHub/LLM) y los valores de sobrescritura (lo que escribí en el administrador). El sitio público muestra la sobrescritura si existe, de lo contrario, el valor automático.
El endpoint de fusión lo garantiza. Cuando un repositorio cambia y el pipeline publica datos nuevos, actualiza las columnas automáticas y deja *_override, published y sort_order intactos. Así puedo reescribir un texto manualmente, y la ejecución de mañana actualizará los metadatos de GitHub debajo sin tocar mis palabras.
El LLM es un motor de sugerencias, no la fuente de verdad.
Regla 3 — privado se queda privado
Todos mis repositorios fuente son privados, y un README privado puede contener contexto de cliente o interno que nunca querría en una página pública. Por lo tanto, la importación es confidencial por defecto: un repositorio recién descubierto se inserta como un borrador no publicado (published = 0). Nada lo que cree el pipeline es visible en el sitio hasta que yo active explícitamente el interruptor en el administrador. El token en sí es de solo lectura (Contenido + Metadatos, sin ámbitos de escritura): puede mirar, no puede enviar.
Cuando el modelo está caído
Debido a que el LLM reside en esta ruta por lotes offline y no en la ruta de solicitud, una interrupción no es un evento para los visitantes: el sitio sigue sirviendo desde SQLite. El pipeline también lo maneja con gracia: si Ollama es inalcanzable, ese repositorio se omite (su SHA no avanza, por lo que se reintenta en la siguiente ejecución) y recibo una única alerta de Telegram enumerando lo que se omitió. Sin fallos, sin datos a medias, sin huecos silenciosos.
¿Por qué molestarse?
Lanzar herramientas pequeñas constantemente. Mantener un portafolio sincronizado manualmente es exactamente el tipo de tarea tediosa que se pudre en silencio. Esto traslada la parte aburrida —"qué construí y cuál es una descripción de una línea"— a una máquina que se ejecuta cada noche, manteniendo todas las decisiones editoriales y de privacidad firmemente conmigo.
La automatización interesante nunca está entre tú y esta página. Ese es todo el diseño.
Transparencia: la mayoría de las entradas se redactan con ayuda de IA, y las versiones que no están en inglés se traducen automáticamente con un LLM local y luego se revisan. ¿Has visto un error? Avísame, por favor.