Este trabajo estudia un sistema de IA autoevolutiva para generación y mejora de código, tomando como base OpenEvolve y complementándolo con OptiLLM para poder usar modelos locales o remotos a través de una API compatible con OpenAI.
La idea central trata de analizar un ciclo completo de investigación: generación, evaluación, retroalimentación, selección, mutación, checkpointing y comparación entre configuraciones. Eso permite estudiar qué decisiones de diseño funcionan mejor según el problema, el modelo y los hiperparámetros.
openevolve-main/: motor principal de evolución, evaluadores, ejemplos y configuración del sistema.optillm-main/: proxy OpenAI-compatible para modelos locales o para usar técnicas de inferencia más avanzadas.runner.py: orquesta una ejecución completa, levantandoOptiLLM, lanzandoOpenEvolvey notificando por Telegram.recover_benchmark_logs.py: recupera logs de ejecuciones de benchmark y genera comandos SFTP o un fichero de reparación de configuración.extract_metrics.py: resume métricas a partir de logs de ejecución.resultados/: resultados consolidados de las campañas experimentales del TFG.
La arquitectura combina varios componentes que colaboran en bucle:
OpenEvolvecarga un programa inicial y un evaluador.- Un
PromptSamplerconstruye el prompt con programas top, programas diversos y artefactos de ejecuciones previas. - Un
LLMEnsemblegenera candidatos con uno o varios modelos ponderados. - El
Evaluatorejecuta el programa, impone timeouts y devuelve métricas y artefactos. ProgramDatabasealmacena programas, puntuaciones, linaje, islas, archivo de élite y el mejor programa global.- El controlador paralelo coordina la evaluación y el guardado de checkpoints.
El sistema hace una búsqueda iterativa guiada por resultados reales de ejecución. Eso es lo que lo acerca a la línea de trabajo de sistemas como AlphaEvolve.
controller.py: orquesta la evolución completa.database.py: almacén de programas, selección, archivo y soporte de islas.evaluator.py: interfaz de evaluación de programas.config.py: carga y valida configuración desde YAML.iteration.py: lógica asociada a cada iteración evolutiva.llm/: clientes y ensambles de modelos.prompt/: generación de prompts y plantillas.threaded_parallel.py: ejecución paralela y coordinación.utils/: utilidades de código, formato y métricas.
Contiene problemas de referencia y benchmarks reales, entre ellos:
function_minimizationcircle_packingalphaevolve_math_problems/sums_diffs_finite_setsalphaevolve_math_problems/heilbronn_trianglealphaevolve_math_problems/minimizing_max_min_dist/2alphaevolve_math_problems/minimizing_max_min_dist/3alphaevolve_math_problems/erdos_min_overlapalphaevolve_math_problems/second_autocorr_ineq
Aquí se almacenan las campañas del TFG, separadas por ejecución y por problema/modelo. Dentro de cada ejecución aparecen:
logs: trazas completas de la ejecución.iteraciones.csv: recultado de procesar los logs para extraer distintas metricas.
El flujo de una ejecución es este:
- Se define un programa inicial con una zona evolucionable marcada por comentarios
# EVOLVE-BLOCK-STARTy# EVOLVE-BLOCK-END. - Se implementa un evaluador que ejecuta ese programa y devuelve métricas objetivas.
OpenEvolvecrea la población inicial y evalúa el programa base.- El sistema selecciona padres e inspiraciones a partir de la base de datos interna.
- El LLM propone una variante del código.
- El evaluador la ejecuta y devuelve puntuaciones, errores y artefactos.
- El sistema actualiza la base de datos, conserva el mejor programa y genera checkpoints.
- Se comparan resultados entre iteraciones, configuraciones y modelos.
Cada decisión de diseño puede medirse en términos de rendimiento, robustez, estabilidad y coste computacional.
Para trabajar con el proyecto conviene tener:
- Python 3.9 o superior.
- Un entorno virtual dedicado.
- Acceso a una API compatible con OpenAI, ya sea remota o local.
- Opcionalmente, un servidor
OptiLLMsi se quiere usar modelos locales o combinar técnicas de inferencia.
Una forma de preparar el entorno es:
python3 -m venv .venv
source .venv/bin/activate
pip install -r openevolve-main/requirements.txt
pip install -r optillm-main/requirements.txtSi prefieres instalar cada subproyecto en modo editable, puedes hacerlo desde cada carpeta:
cd openevolve-main
pip install -e .
cd ../optillm-main
pip install -e .Un ejemplo reproducible y fácil de entender es function_minimization:
cd openevolve-main
source ../.venv/bin/activate
export OPENAI_API_KEY="sk-no-key"
python openevolve-run.py \
examples/function_minimization/initial_program.py \
examples/function_minimization/evaluator.py \
--config examples/function_minimization/config.yaml \
--iterations 10Si estás usando un proxy local con OptiLLM, la configuración del problema debe apuntar a la API del proxy:
llm:
api_key: "sk-no-key"
api_base: "http://127.0.0.1:8000/v1"El mismo patrón se aplica a otros benchmarks: cambias initial_program.py, evaluator.py y el config.yaml del problema.
OptiLLM actúa como proxy compatible con OpenAI. En este TFG es importante porque permite que OpenEvolve trabaje con modelos locales o con estrategias de inferencia más sofisticadas sin tener que modificar el núcleo evolutivo.
Ejemplo con un backend local tipo Ollama:
cd optillm-main
source ../.venv/bin/activate
python optillm.py --base_url http://localhost:11434/v1El punto de entrada principal es openevolve-run.py, que llama a la CLI del paquete openevolve.
Opciones relevantes:
--config: archivo YAML con hiperparámetros y modelos.--iterations: número máximo de iteraciones.--checkpoint: reanudación desde un checkpoint previo.--api-base,--primary-model,--secondary-model: sobrescrituras rápidas desde línea de comandos.
También existe soporte para reanudar una ejecución guardada:
python openevolve-run.py \
examples/function_minimization/initial_program.py \
examples/function_minimization/evaluator.py \
--checkpoint examples/function_minimization/openevolve_output/checkpoints/checkpoint_50 \
--iterations 50runner.py automatiza la campaña experimental completa:
- lanza
OptiLLMen segundo plano; - arranca
OpenEvolvecon la configuración elegida; - controla PIDs y procesos auxiliares;
- registra logs separados por ejecución;
- envía notificaciones por Telegram;
- permite consultar estado, logs, errores, mejor solución y checkpoints desde Telegram.
Entre los comandos soportados en el bot están /status, /log, /errores, /best, /checkpoint, /code, /optillm y /stop.
Este script está pensado para consolidar campañas largas desde una máquina remota o un servidor de experimentación.
Hace varias cosas útiles:
- detecta logs válidos de
OpenEvolvedentro deexamples/; - infiere qué problema y qué combinación de modelos hay detrás de cada log;
- valida que la ejecución tenga un inicio y un cierre coherentes;
- genera un comando
sftppara descargar automáticamente los ficheros; - puede crear una versión de configuración reparada para ejecutar de nuevo sólo lo problemático.
Resume logs por modelo y problema, calculando métricas como:
- tiempo total acumulado;
- número de mejores soluciones encontradas;
- número de errores;
- número de iteraciones completadas;
- tiempo medio por iteración;
- mejor puntuación observada.
Es útil para comparar ejecuiones y construir tablas para memoria, defensa o capítulo de resultados.
Este script toma logs de OpenEvolve desde la entrada estándar y los transforma en un CSV de iteraciones y métricas.
Su utilidad principal es convertir la salida textual de las ejecuciones en un formato más cómodo para análisis posterior.
Hace lo siguiente:
- detecta la iteración actual a partir de líneas que contienen
Iteration; - extrae el bloque
Metrics:de cada iteración; - separa pares clave-valor como
score=...oerror=...; - añade campos auxiliares como
has_erroryerror_msg; - genera un CSV ordenado por iteración.
Uso:
cd openevolve-main
cat logs/openevolve_YYYYMMDD_HHMMSS.log | python parser.py --outdir resultados --outfile iteraciones.csvEs especialmente útil cuando se quiere comparar muchas ejecuciones.
Este script automatiza la ejecución de parser.py sobre todos los logs contenidos en una carpeta de resultados (por ejemplo, dentro de resultados/Segunda ejecución).
Recorre recursivamente el directorio indicado, encuentra todos los subdirectorios que contengan archivos .log, los ordena por nombre y genera los CSVs correspondientes junto a cada log, siguiendo la convención de nombres utilizada en el repositorio.
Además, realiza una validación ligera tras generar cada CSV: cuenta el número de líneas del fichero y muestra una advertencia si el CSV contiene una o cero líneas (es decir, solo cabecera o vacío). Esto suele indicar que el log original no contenía métricas de iteración parseables (por ejemplo, porque la ejecución falló o hubo errores en las llamadas al LLM).
Uso:
python run_parser_on_results.py "resultados/Segunda ejecución"Opciones disponibles:
--dry-run: muestra qué archivos se generarían sin ejecutar realmente el parser.--parser-script: ruta alternativa al script parser.py de OpenEvolve.
Convención de nombres de salida:
El script distingue según el nombre del problema:
- Para
circle_packing→primera_fase.csv,segunda_fase.csv - Para
minimazing_max_min_dist_2yminimazing_max_min_dist_3→primera_mitad.csv,segunda_mitad.csv - Para el resto de problemas →
iteraciones.csv
Si hay más logs de los que hay nombres predefinidos, genera automáticamente nombres como iteraciones_2.csv, iteraciones_3.csv, etc.
Ejemplo de salida:
[OK] resultados/Segunda ejecución/circle_packing/qwen-coder/logs/openevolve_20250320_120000.log -> resultados/Segunda ejecución/circle_packing/qwen-coder/primera_fase.csv (42 lines)
[WARN] El CSV resultados/Segunda ejecución/function_minimization/llama3/iteraciones.csv contiene 1 líneas. El log puede no contener iteraciones parseables.
[DONE] Procesados 12 logs en resultados/Segunda ejecución
Este script actúa como un filtro de líneas sobre la salida de ejecuciones o logs, extrayendo únicamente las filas de métricas con formato tabular y transformándolas a un formato más sencillo y consistente.
Está pensado para procesar directamente la salida de extract_metrics.
Funcionamiento: El script lee desde la entrada estándar línea por línea y:
- Detecta líneas que contienen el carácter
|(separador de tablas). - Descarta líneas de separadores (
---,===) y cabeceras (líneas conPROBLEMoTIME). - Valida que la línea tenga al menos 7 columnas.
- Comprueba que el campo de tiempo tenga formato
hh:mm:ss. - Extrae: tiempo, mejor puntuación, mejores soluciones encontradas, errores, iteraciones y tiempo medio.
- Convierte los puntos decimales a comas (formato europeo).
- Añade la letra
sal tiempo medio si no está presente. - Imprime las líneas resultantes separadas por tabuladores (
\t).
Uso:
# Desde la salida de un analisis
python extract_metrics.py ... | python parse_metrics.py
# Redirigir a un fichero
python extract_metrics.py ... | python parse_metrics.py > metricas_resumidas.txtFormato de entrada esperado:
| PROBLEM | TIME | BEST SCORE | #BETTER SOLS | #ERRORS | ITERS | AVG TIME |
|----------------------|----------|------------|--------------|---------|-------|----------|
| circle_packing | 00:05:23 | 0.8742 | 12 | 3 | 50 | 6.47s |
Formato de salida generado:
00:05:23 0,8742 12 3 50 6,47s
Cada campo está separado por tabulador, lo que facilita su importación en hojas de cálculo o su procesamiento posterior con herramientas como awk, cut o scripts de análisis.
El proyecto trabaja con varios modelos y combinaciones:
qwen-coderllama3mistral-smalldeepseek-coderqwen-math
Y también ensambles como:
qwen-coder + qwen-mathqwen-coder + deepseek-coderdeepseek-coder + mistral-small
La parte importante no es sólo qué modelo se usa, sino cómo se combinan las decisiones: temperatura, pesos del ensamble, tamaño de población, intervalos de checkpoint, tolerancia a fallos y selección de programas de referencia.
Las opciones globales se concentran en openevolve-main/configs/default_config.yaml y en archivos específicos de cada problema.
Algunos parámetros relevantes:
max_iterations: número máximo de iteraciones.checkpoint_interval: frecuencia de guardado.random_seed: reproducibilidad.llm.models: modelos usados para evolución.database.num_islands: particionado de la población.database.feature_dimensions: dimensiones del esquema tipo MAP-Elites.evaluator.timeout: límite de tiempo por evaluación.evaluator.cascade_evaluation: evaluación por etapas.
Para crear un nuevo benchmark o adaptar uno existente:
- Define un
initial_program.pycon la parte evolucionable delimitada. - Implementa un
evaluator.pyque expongaevaluate(program_path). - Crea un
config.yamlcon el modelo, los timeouts y los hiperparámetros. - Lanza
OpenEvolvesobre ese directorio. - Analiza checkpoints, logs y métricas para comparar variantes.
OpenEvolve: https://github.com/algorithmicsuperintelligence/openevolveOptiLLM: https://github.com/codelion/optillmAlphaEvolve: Novikov et al., 2025, Alphaevolve: A coding agent for scientific and algorithmic discovery.