# Pipeline de Generación de Resúmenes Matemáticos (LaTeX -> PDF) Este documento contiene un script genérico en Python diseñado para integrarse en pipelines de automatización (GitHub Actions, Jenkins, GitLab CI). El script toma un archivo de texto plano, genera un resumen académico con fórmulas matemáticas usando LLMs (MiniMax, GLM, Gemini) y lo compila a PDF preservando la notación LaTeX. ## 1. Requisitos del Sistema El entorno donde se ejecute este script debe tener instalado: - **Python 3.8+** - **Pandoc** (para conversión de documentos) - **PDFLaTeX** (generalmente parte de TexLive, para renderizar fórmulas) ### Instalación en Debian/Ubuntu (Docker o CI) ```bash apt-get update && apt-get install -y pandoc texlive-latex-base texlive-fonts-recommended python3-pip pip install requests ``` ## 2. Script Genérico (`math_summary.py`) Guarda el siguiente código como `math_summary.py`. Este script es agnóstico al proveedor y se configura mediante argumentos o variables de entorno. ```python #!/usr/bin/env python3 import os import sys import argparse import subprocess import requests import json # Configuración de Modelos PROVIDERS = { "minimax": { "url": "https://api.minimax.io/anthropic/v1/messages", "model": "MiniMax-M2", "header_key": "x-api-key", "version_header": {"anthropic-version": "2023-06-01"}, "env_var": "MINIMAX_API_KEY" }, "glm": { "url": "https://api.z.ai/api/anthropic/v1/messages", "model": "glm-4.7", "header_key": "x-api-key", "version_header": {"anthropic-version": "2023-06-01"}, "env_var": "GLM_API_KEY" } } PROMPT_SYSTEM = """ Eres un asistente académico experto en matemáticas y economía. Tu tarea es resumir el texto proporcionado manteniendo el rigor científico. REGLAS DE FORMATO (CRÍTICO): 1. La salida debe ser Markdown válido. 2. TODAS las fórmulas matemáticas deben estar en formato LaTeX. 3. Usa bloques $$ ... $$ para ecuaciones centradas importantes. 4. Usa $ ... $ para ecuaciones en línea. 5. NO uses bloques de código (```latex) para las fórmulas, úsalas directamente en el texto para que Pandoc las renderice. 6. Incluye una sección de 'Conceptos Matemáticos' con las fórmulas desglosadas. """ def get_api_key(provider): env_var = PROVIDERS[provider]["env_var"] key = os.getenv(env_var) if not key: print(f"Error: La variable de entorno {env_var} no está definida.") sys.exit(1) return key def call_llm(provider, text, api_key): print(f"--- Contactando API: {provider.upper()} ---") config = PROVIDERS[provider] headers = { "Content-Type": "application/json", config["header_key"]: api_key, } if "version_header" in config: headers.update(config["version_header"]) payload = { "model": config["model"], "max_tokens": 4096, "messages": [ {"role": "user", "content": f"{PROMPT_SYSTEM}\n\nTEXTO A RESUMIR:\n{text}"} ] } try: resp = requests.post(config["url"], json=payload, headers=headers, timeout=120) resp.raise_for_status() data = resp.json() # Manejo específico para MiniMax que puede devolver bloques de "thinking" content = "" for part in data.get("content", []): if part.get("type") == "text": content += part.get("text", "") # Fallback si no hay tipo explícito (GLM estándar) if not content and data.get("content"): if isinstance(data["content"], list): content = data["content"][0].get("text", "") return content except Exception as e: print(f"Error llamando a {provider}: {e}") return None def convert_to_pdf(markdown_content, output_file): base_name = os.path.splitext(output_file)[0] md_file = f"{base_name}.md" with open(md_file, "w", encoding="utf-8") as f: f.write(markdown_content) print(f"--- Generando PDF: {output_file} ---") cmd = [ "pandoc", md_file, "-o", output_file, "--pdf-engine=pdflatex", "-V", "geometry:margin=2.5cm", "-V", "fontsize=12pt", "--highlight-style=tango" ] result = subprocess.run(cmd, capture_output=True, text=True) if result.returncode == 0: print("Éxito: PDF generado correctamente.") return True else: print("Error en Pandoc:") print(result.stderr) return False def main(): parser = argparse.ArgumentParser(description="Generador de Resúmenes Matemáticos PDF") parser.add_argument("input_file", help="Ruta al archivo de texto (.txt) fuente") parser.add_argument("--provider", choices=["minimax", "glm"], default="glm", help="Proveedor de IA a usar") parser.add_argument("--output", default="resumen_output.pdf", help="Nombre del archivo PDF de salida") args = parser.parse_args() if not os.path.exists(args.input_file): print(f"Error: No se encuentra el archivo {args.input_file}") sys.exit(1) with open(args.input_file, "r", encoding="utf-8") as f: text_content = f.read() api_key = get_api_key(args.provider) summary_md = call_llm(args.provider, text_content, api_key) if summary_md: convert_to_pdf(summary_md, args.output) else: print("Fallo en la generación del resumen.") sys.exit(1) if __name__ == "__main__": main() ``` ## 3. Ejemplo de Uso en Pipeline ### Ejecución Local ```bash export GLM_API_KEY="tu_api_key_aqui" python3 math_summary.py entrada.txt --provider glm --output reporte_final.pdf ``` ### GitHub Actions (Ejemplo .yaml) Este paso automatizaría la creación del PDF cada vez que se sube un .txt a la carpeta `docs/`. ```yaml name: Generar PDF Matemático on: push: paths: - 'docs/*.txt' jobs: build-pdf: runs-on: ubuntu-latest steps: - uses: actions/checkout@v3 - name: Instalar dependencias run: | sudo apt-get update sudo apt-get install -y pandoc texlive-latex-base texlive-fonts-recommended pip install requests - name: Generar Resumen env: GLM_API_KEY: ${{ secrets.GLM_API_KEY }} run: | python3 math_summary.py docs/archivo.txt --provider glm --output docs/resumen.pdf - name: Subir Artefacto uses: actions/upload-artifact@v3 with: name: PDF-Resumen path: docs/resumen.pdf ```