Skip to content

Instantly share code, notes, and snippets.

@mgaitan
Created July 19, 2026 15:14
Show Gist options
  • Select an option

  • Save mgaitan/38eef41fb079c25d39da64718cc69f26 to your computer and use it in GitHub Desktop.

Select an option

Save mgaitan/38eef41fb079c25d39da64718cc69f26 to your computer and use it in GitHub Desktop.
borges project: Prompt original

Construí un MVP de buscador para un corpus completo de y sobre Jorge Luis Borges, usando Python 3.14, FastAPI, SQLAlchemy 2 async, Alembic, PostgreSQL en Neon y despliegue en FastAPI Cloud.

Objetivo:

  • descargar libros de Borges
  • Importar libros EPUB de Borges y también textos “sobre Borges”.
  • Preservar estructura editorial y bibliográfica.
  • Permitir búsqueda textual, semántica e híbrida.
  • Mostrar fragmentos relevantes, ampliar contexto y abrir el texto completo.
  • Filtrar/facetar por autor, obra, libro/edición, año, década, tipo de texto y naturaleza del documento.
  • Sugerir fragmentos y obras relacionadas.

Fuente bibliografica:

  • Descargar todos los libros cuyo autor sea Borges o libros cuya temática central sea Borges (por ejemplo "Borges" de Bioy Casares) CSV de magnet links de libros https://github.com/0x2b3bfa0/armarius transmission-cli está disponible. Los libros no deben versionarse Podemos comenzar con algunos libros relevantes y luego ampliar .

Modelo de dominio:

  • Author
  • Work: obra intelectual canónica; título, autor, tipo, fecha/año original, idioma, is_about_borges, metadata JSONB.
  • Book: edición/importación; título, editorial, año, ISBN, archivo fuente y hash.
  • BookItem: relación ordenada entre Book y Work.
  • Section: jerarquía interna.
  • Paragraph: unidad canónica y estable de navegación.
  • Passage: unidad regenerable de búsqueda, compuesta por párrafos completos, con solapamiento, tsvector, texto normalizado y embedding.
  • TextRelation: relación entre obras o passages, con tipo, score, procedencia y estado de revisión.

Reglas:

  • No mezclar obra con edición.
  • La fuente canónica es Paragraph; Passage puede regenerarse.
  • Los chunks deben respetar obra, sección y párrafos; objetivo 250–450 tokens, máximo 600, solapamiento de un párrafo.
  • Para poemas, respetar versos y estrofas.
  • Guardar versiones del parser, segmentación y modelo de embeddings.
  • Toda metadata inferida debe registrar source, confidence y reviewed.

PostgreSQL:

  • Extensiones vector, pg_trgm y unaccent.
  • Full-text search con índices GIN para configuraciones simple y spanish.
  • Búsqueda literal sobre texto normalizado.
  • Embeddings con pgvector e índice HNSW para cosine distance.
  • Mantener todos los filtros y facetas como columnas relacionales o metadata estructurada, no generarlos dinámicamente con un LLM.

Ingestión:

  • Usar EbookLib y lxml/BeautifulSoup.
  • Leer el EPUB según su spine.
  • Extraer HTML, títulos, secciones, párrafos e imágenes relevantes.
  • Detectar automáticamente posibles límites entre obras, pero permitir revisión/corrección.
  • Crear un importador idempotente basado en hash.
  • Incluir comandos CLI con typer para importar EPUB, regenerar passages, generar embeddings y reindexar.
  • Separar interfaces de embeddings para poder usar inicialmente un proveedor configurable y cambiarlo después.

Búsqueda:

  • lexical: frase exacta, full-text, prefijos y fuzzy matching.
  • semantic: similitud vectorial.
  • hybrid: recuperar candidatos lexicales y semánticos, fusionarlos inicialmente con Reciprocal Rank Fusion y conservar scores parciales.
  • Agrupar hits cercanos o solapados del mismo texto.
  • Excluir passages vecinos al buscar contenidos relacionados.
  • Permitir filtros combinables por autor, obra, libro, rango de fechas, década, tipo y is_about_borges.
  • Las facetas deben indicar tanto cantidad de passages como cantidad de obras distintas cuando corresponda.

API mínima:

  • POST /api/search
  • GET /api/facets
  • GET /api/works
  • GET /api/works/{id}
  • GET /api/passages/{id}
  • GET /api/passages/{id}/context
  • GET /api/passages/{id}/related
  • GET /api/works/{id}/related
  • endpoints protegidos para importación y reindexado
  • GET /health y GET /ready

Cada resultado debe devolver:

  • fragmento destacado;
  • párrafos de contexto opcionales;
  • obra, libro, autor, tipo y fecha;
  • scores lexical, semántico y combinado;
  • identificadores y URL estable para abrir el texto completo en el párrafo correspondiente.

UI y experiencia de lectura: Construí también una interfaz web responsive, integrada con FastAPI, usando Jinja2 + HTMX + Alpine.js y Tailwind CSS. Evitar una SPA salvo que resulte estrictamente necesario. La aplicación debe funcionar bien en desktop, tablet y mobile. Ver @design.md

Implementación:

  • Estructura modular: domain, db, ingestion, search, embeddings, api, cli.
  • Configuración con Pydantic Settings.
  • Dependencias con uv.
  • Tests con pytest, incluyendo ingestión de un EPUB fixture, chunking, filtros, búsqueda textual y RRF.
  • Dockerfile compatible con FastAPI Cloud.
  • Alembic completo y script de bootstrap de extensiones.
  • README con setup local, Neon, migraciones, importación, embeddings, tests y despliegue.
  • Evitar LangChain, Haystack, LlamaIndex y bases vectoriales externas.
  • No implementar todavía chatbot ni generación de respuestas: el núcleo es un buscador documental verificable.

Primero generá:

  1. estructura del proyecto;
  2. modelos y migraciones;
  3. pipeline de importación;
  4. búsqueda lexical;
  5. búsqueda vectorial e híbrida;
  6. endpoints;
  7. tests y documentación.

Tomá decisiones razonables sin detenerte a pedir confirmación. Marcá explícitamente cualquier parte que requiera credenciales, elección de modelo de embeddings o configuración específica de FastAPI Cloud.

Diseñá el dominio desde el inicio para soportar múltiples idiomas. Aunque el corpus inicial sea Borges en español, el modelo de datos, la búsqueda, los analizadores de texto, las interfaces de embeddings y la UI deben poder incorporar otros idiomas (inglés, francés, alemán, etc.) sin cambios estructurales importantes. Evitá asumir que existe un único idioma en el sistema; almacená explícitamente el idioma de obras, ediciones y fragmentos cuando corresponda.

Gestion repo: Crear en GitHub: mgaitan/borges.

Usá gh CLI para todas las operaciones sobre GitHub (crear issues, PRs). No me pidas URLs ni comandos manuales si gh puede hacerlo.

Trabajá de manera incremental y continua. Si durante el desarrollo aparecen tareas, mejoras, bugs, deuda técnica o ideas futuras, creá issues pequeños, concretos y accionables en el repositorio, con una descripción breve. Evitá crear épicos gigantes; preferí issues pragmáticos que puedan resolverse en una o pocas sesiones.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment