evolutia 0.1.0__py3-none-any.whl → 0.1.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- evolutia/__init__.py +1 -1
- evolutia/config_manager.py +11 -5
- evolutia/llm_providers.py +2 -0
- evolutia/variation_generator.py +202 -12
- evolutia-0.1.1.dist-info/METADATA +221 -0
- {evolutia-0.1.0.dist-info → evolutia-0.1.1.dist-info}/RECORD +11 -11
- {evolutia-0.1.0.dist-info → evolutia-0.1.1.dist-info}/WHEEL +1 -1
- {evolutia-0.1.0.dist-info → evolutia-0.1.1.dist-info}/licenses/LICENSE +1 -1
- evolutia_cli.py +10 -0
- evolutia-0.1.0.dist-info/METADATA +0 -723
- {evolutia-0.1.0.dist-info → evolutia-0.1.1.dist-info}/entry_points.txt +0 -0
- {evolutia-0.1.0.dist-info → evolutia-0.1.1.dist-info}/top_level.txt +0 -0
evolutia/__init__.py
CHANGED
evolutia/config_manager.py
CHANGED
|
@@ -51,12 +51,14 @@ class ConfigManager:
|
|
|
51
51
|
if root_config.exists():
|
|
52
52
|
self.config_path = root_config
|
|
53
53
|
else:
|
|
54
|
-
# Default interno:
|
|
55
|
-
#
|
|
56
|
-
|
|
57
|
-
self.config_path = self.base_path / 'evolutia' / 'config' / 'config.yaml'
|
|
54
|
+
# Default interno: ubicado en el paquete instalado
|
|
55
|
+
# Obtenemos la ruta de este archivo (config_manager.py) -> parent (evolutia/) -> config -> config.yaml
|
|
56
|
+
self.config_path = Path(__file__).parent / 'config' / 'config.yaml'
|
|
58
57
|
|
|
59
|
-
|
|
58
|
+
if self.config_path.exists():
|
|
59
|
+
logger.info(f"Usando archivo de configuración: {self.config_path}")
|
|
60
|
+
else:
|
|
61
|
+
logger.info(f"Archivo de configuración no encontrado en {self.config_path}. Usando configuración por defecto.")
|
|
60
62
|
|
|
61
63
|
def validate_config(self, config_data: Dict[str, Any]) -> bool:
|
|
62
64
|
"""Valida la configuración contra el esquema JSON."""
|
|
@@ -187,6 +189,10 @@ class ConfigManager:
|
|
|
187
189
|
|
|
188
190
|
logger.info(f"Configuración actualizada en {self.config_path}")
|
|
189
191
|
|
|
192
|
+
def update_config_from_structure(self):
|
|
193
|
+
"""Alias para update_config, usado por compatibilidad."""
|
|
194
|
+
return self.update_config()
|
|
195
|
+
|
|
190
196
|
def main():
|
|
191
197
|
import argparse
|
|
192
198
|
parser = argparse.ArgumentParser(description='Gestor de configuración automática de Evolutia')
|
evolutia/llm_providers.py
CHANGED
evolutia/variation_generator.py
CHANGED
|
@@ -58,7 +58,201 @@ class VariationGenerator:
|
|
|
58
58
|
return None
|
|
59
59
|
|
|
60
60
|
return self._provider_instance
|
|
61
|
-
|
|
61
|
+
|
|
62
|
+
def _create_prompt(self, exercise: Dict, analysis: Dict) -> str:
|
|
63
|
+
"""Crea el prompt para generar una variación."""
|
|
64
|
+
|
|
65
|
+
content = exercise.get('content', '')
|
|
66
|
+
complexity = analysis.get('total_complexity', 0)
|
|
67
|
+
concepts = ", ".join(analysis.get('concepts', []))
|
|
68
|
+
|
|
69
|
+
prompt = f"""Actúa como un profesor experto de física y matemáticas universitarias.
|
|
70
|
+
Tu tarea es crear una VARIACIÓN de un ejercicio existente.
|
|
71
|
+
|
|
72
|
+
EJERCICIO ORIGINAL:
|
|
73
|
+
{content}
|
|
74
|
+
|
|
75
|
+
ANÁLISIS DE COMPLEJIDAD ORIGINAL:
|
|
76
|
+
- Complejidad: {complexity:.2f}
|
|
77
|
+
- Conceptos: {concepts}
|
|
78
|
+
|
|
79
|
+
OBJETIVO:
|
|
80
|
+
Generar una nueva versión del ejercicio que sea MÁS COMPLEJA y DESAFIANTE, pero evaluando los mismos principios fundamentales.
|
|
81
|
+
|
|
82
|
+
ESTRATEGIAS PARA AUMENTAR COMPLEJIDAD:
|
|
83
|
+
1. Cambia las variables numéricas por parámetros simbólicos (a, b, R, etc.)
|
|
84
|
+
2. Introduce sistemas de coordenadas diferentes (cilíndricas/esféricas) si aplica
|
|
85
|
+
3. Combina múltiples conceptos en un solo problema
|
|
86
|
+
4. Agrega una restricción o condición de borde adicional
|
|
87
|
+
5. Pide una generalización del resultado
|
|
88
|
+
|
|
89
|
+
REGLAS DE FORMATO:
|
|
90
|
+
1. Usa Markdown estándar
|
|
91
|
+
2. Usa LaTeX para matemáticas (bloques :::math o $$...$$)
|
|
92
|
+
3. La salida debe contener DOS PARTES separadas por "SOLUCIÓN REQUERIDA:"
|
|
93
|
+
- Parte 1: El enunciado del nuevo ejercicio (encabezado con "EJERCICIO VARIADO:")
|
|
94
|
+
- Parte 2: La solución paso a paso
|
|
95
|
+
|
|
96
|
+
Genera solo el contenido solicitado."""
|
|
97
|
+
return prompt
|
|
98
|
+
|
|
99
|
+
def _create_quiz_prompt(self, context_info: Dict) -> str:
|
|
100
|
+
"""Crea prompt para ejercicios de selección única."""
|
|
101
|
+
content = context_info.get('content', '')
|
|
102
|
+
|
|
103
|
+
prompt = f"""Actúa como un profesor experto. Genera una pregunta de examen de tipo SELECCIÓN ÚNICA (Quiz) basada en el siguiente material:
|
|
104
|
+
|
|
105
|
+
MATERIAL BASE:
|
|
106
|
+
{content}
|
|
107
|
+
|
|
108
|
+
REQUISITOS:
|
|
109
|
+
1. La pregunta debe ser conceptual y desafiante.
|
|
110
|
+
2. Genera 4 opciones (A, B, C, D).
|
|
111
|
+
3. Solo una opción debe ser correcta, las otras deben ser distractores plausibles.
|
|
112
|
+
4. Devuelve la respuesta EXCLUSIVAMENTE en formato JSON válido:
|
|
113
|
+
{{
|
|
114
|
+
"question": "Enunciado de la pregunta en Markdown...",
|
|
115
|
+
"options": {{
|
|
116
|
+
"A": "Texto opción A",
|
|
117
|
+
"B": "Texto opción B",
|
|
118
|
+
"C": "Texto opción C",
|
|
119
|
+
"D": "Texto opción D"
|
|
120
|
+
}},
|
|
121
|
+
"correct_option": "A",
|
|
122
|
+
"explanation": "Explicación detallada de por qué es la correcta..."
|
|
123
|
+
}}
|
|
124
|
+
"""
|
|
125
|
+
return prompt
|
|
126
|
+
|
|
127
|
+
def generate_variation(self, exercise: Dict, analysis: Dict, exercise_type: str = "development") -> Optional[Dict]:
|
|
128
|
+
"""
|
|
129
|
+
Genera una variación de un ejercicio existente.
|
|
130
|
+
"""
|
|
131
|
+
# 1. Crear prompt según tipo
|
|
132
|
+
if exercise_type == 'multiple_choice':
|
|
133
|
+
context_info = {
|
|
134
|
+
'content': f"Ejercicio Original:\n{exercise.get('content')}"
|
|
135
|
+
}
|
|
136
|
+
prompt = self._create_quiz_prompt(context_info)
|
|
137
|
+
else:
|
|
138
|
+
prompt = self._create_prompt(exercise, analysis)
|
|
139
|
+
|
|
140
|
+
# 2. Get Provider
|
|
141
|
+
provider = self._get_provider()
|
|
142
|
+
if not provider: return None
|
|
143
|
+
|
|
144
|
+
# 3. Generar
|
|
145
|
+
content = provider.generate_content(prompt, system_prompt="Eres un experto en diseño de exámenes de ingeniería.")
|
|
146
|
+
|
|
147
|
+
if not content:
|
|
148
|
+
return None
|
|
149
|
+
|
|
150
|
+
# 4. Parsear respuesta
|
|
151
|
+
variation_content = ""
|
|
152
|
+
variation_solution = ""
|
|
153
|
+
|
|
154
|
+
if exercise_type == 'multiple_choice':
|
|
155
|
+
data = extract_and_parse_json(content)
|
|
156
|
+
if data and 'question' in data:
|
|
157
|
+
variation_content = f"{data['question']}\n\n"
|
|
158
|
+
for opt, text in data.get('options', {}).items():
|
|
159
|
+
variation_content += f"- **{opt})** {text}\n"
|
|
160
|
+
variation_solution = f"**Respuesta Correcta: {data.get('correct_option', '?')}**\n\n{data.get('explanation', '')}"
|
|
161
|
+
else:
|
|
162
|
+
variation_content = content
|
|
163
|
+
variation_solution = "Error parseando JSON de quiz."
|
|
164
|
+
else:
|
|
165
|
+
# Parseo texto plano
|
|
166
|
+
parts = content.split("SOLUCIÓN REQUERIDA:")
|
|
167
|
+
if len(parts) == 2:
|
|
168
|
+
variation_content = parts[0].replace("EJERCICIO VARIADO:", "").strip()
|
|
169
|
+
variation_solution = parts[1].strip()
|
|
170
|
+
else:
|
|
171
|
+
variation_content = content
|
|
172
|
+
variation_solution = ""
|
|
173
|
+
|
|
174
|
+
return {
|
|
175
|
+
'variation_content': variation_content,
|
|
176
|
+
'variation_solution': variation_solution,
|
|
177
|
+
'original_frontmatter': exercise.get('frontmatter', {}),
|
|
178
|
+
'original_label': exercise.get('label'),
|
|
179
|
+
'type': exercise_type
|
|
180
|
+
}
|
|
181
|
+
|
|
182
|
+
def _create_new_exercise_prompt(self, topic: str, tags: list, context: Dict, difficulty: str) -> str:
|
|
183
|
+
"""Crea prompt para ejercicio nuevo desde cero."""
|
|
184
|
+
tags_str = ", ".join(tags)
|
|
185
|
+
|
|
186
|
+
prompt = f"""Diseña un NUEVO ejercicio de examen universitario para:
|
|
187
|
+
Asignatura/Tema: {topic}
|
|
188
|
+
Conceptos Clave (Tags): {tags_str}
|
|
189
|
+
Nivel de Dificultad: {difficulty.upper()} (donde ALTA implica demostraciones o conexiones no triviales).
|
|
190
|
+
|
|
191
|
+
INSTRUCCIONES:
|
|
192
|
+
1. Crea un problema original que evalúe comprensión profunda.
|
|
193
|
+
2. No copies ejercicios de libros de texto.
|
|
194
|
+
3. Formato de salida:
|
|
195
|
+
EJERCICIO NUEVO:
|
|
196
|
+
[Enunciado en Markdown con LaTeX]
|
|
197
|
+
|
|
198
|
+
SOLUCIÓN REQUERIDA:
|
|
199
|
+
[Solución paso a paso]
|
|
200
|
+
"""
|
|
201
|
+
return prompt
|
|
202
|
+
|
|
203
|
+
def generate_new_exercise_from_topic(self, topic: str, tags: list = None, difficulty: str = "alta", exercise_type: str = "development") -> Optional[Dict]:
|
|
204
|
+
"""
|
|
205
|
+
Genera un ejercicio nuevo desde cero.
|
|
206
|
+
"""
|
|
207
|
+
tags = tags or []
|
|
208
|
+
context = {} # Base implementations doesn't use context
|
|
209
|
+
|
|
210
|
+
# 1. Crear prompt
|
|
211
|
+
if exercise_type == 'multiple_choice':
|
|
212
|
+
context_info = {
|
|
213
|
+
'content': f"Tema: {topic}\nTags: {', '.join(tags)}\nDificultad: {difficulty}"
|
|
214
|
+
}
|
|
215
|
+
prompt = self._create_quiz_prompt(context_info)
|
|
216
|
+
else:
|
|
217
|
+
prompt = self._create_new_exercise_prompt(topic, tags, context, difficulty)
|
|
218
|
+
|
|
219
|
+
# 2. Get Provider
|
|
220
|
+
provider = self._get_provider()
|
|
221
|
+
if not provider: return None
|
|
222
|
+
|
|
223
|
+
# 3. Generar
|
|
224
|
+
content = provider.generate_content(prompt)
|
|
225
|
+
if not content: return None
|
|
226
|
+
|
|
227
|
+
# 4. Parsear
|
|
228
|
+
# Reutilizamos lógica simple de parseo
|
|
229
|
+
if exercise_type == 'multiple_choice':
|
|
230
|
+
data = extract_and_parse_json(content)
|
|
231
|
+
if data and 'question' in data:
|
|
232
|
+
var_content = f"{data['question']}\n\n"
|
|
233
|
+
# ... (simplificado, igual que arriba)
|
|
234
|
+
for k, v in data.get('options',{}).items():
|
|
235
|
+
var_content += f"- **{k})** {v}\n"
|
|
236
|
+
var_sol = f"R: {data.get('correct_option')}. {data.get('explanation')}"
|
|
237
|
+
else:
|
|
238
|
+
var_content = content
|
|
239
|
+
var_sol = ""
|
|
240
|
+
else:
|
|
241
|
+
parts = content.split("SOLUCIÓN REQUERIDA:")
|
|
242
|
+
if len(parts) == 2:
|
|
243
|
+
var_content = parts[0].replace("EJERCICIO NUEVO:", "").strip()
|
|
244
|
+
var_sol = parts[1].strip()
|
|
245
|
+
else:
|
|
246
|
+
var_content = content
|
|
247
|
+
var_sol = ""
|
|
248
|
+
|
|
249
|
+
return {
|
|
250
|
+
'variation_content': var_content,
|
|
251
|
+
'variation_solution': var_sol,
|
|
252
|
+
'original_frontmatter': {'topic': topic, 'tags': tags},
|
|
253
|
+
'type': exercise_type
|
|
254
|
+
}
|
|
255
|
+
|
|
62
256
|
def generate_variation_with_solution(self, exercise: Dict, analysis: Dict) -> Optional[Dict]:
|
|
63
257
|
"""
|
|
64
258
|
Genera una variación con su solución.
|
|
@@ -69,23 +263,19 @@ class VariationGenerator:
|
|
|
69
263
|
if not variation:
|
|
70
264
|
return None
|
|
71
265
|
|
|
266
|
+
# Si ya tiene solución (porque el prompt único la pidió), retornarla
|
|
267
|
+
if variation.get('variation_solution'):
|
|
268
|
+
return variation
|
|
269
|
+
|
|
72
270
|
provider = self._get_provider()
|
|
73
271
|
if not provider: return None
|
|
74
272
|
|
|
75
|
-
#
|
|
76
|
-
solution_prompt = f"""Eres un experto en métodos matemáticos
|
|
77
|
-
|
|
273
|
+
# Si no, generar la solución por separado (fallback legacy)
|
|
274
|
+
solution_prompt = f"""Eres un experto en métodos matemáticos. Resuelve el siguiente ejercicio paso a paso:
|
|
275
|
+
|
|
78
276
|
EJERCICIO:
|
|
79
277
|
{variation['variation_content']}
|
|
80
278
|
|
|
81
|
-
INSTRUCCIONES:
|
|
82
|
-
1. Resuelve el ejercicio de forma completa y detallada
|
|
83
|
-
2. Muestra todos los pasos intermedios
|
|
84
|
-
3. Usa notación matemática LaTeX correcta
|
|
85
|
-
4. Explica el razonamiento cuando sea necesario
|
|
86
|
-
5. Usa bloques :::{{math}} para ecuaciones display y $...$ para inline
|
|
87
|
-
6. Escribe en español
|
|
88
|
-
|
|
89
279
|
GENERA LA SOLUCIÓN COMPLETA:"""
|
|
90
280
|
|
|
91
281
|
solution_content = provider.generate_content(solution_prompt)
|
|
@@ -0,0 +1,221 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: evolutia
|
|
3
|
+
Version: 0.1.1
|
|
4
|
+
Summary: Sistema automatizado para generar preguntas de examen desafiantes basadas en materiales didácticos existentes
|
|
5
|
+
Home-page: https://github.com/glacy/evolutIA
|
|
6
|
+
Author: Gerardo Lacy-Mora
|
|
7
|
+
Author-email: gerardolacymora@gmail.com
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
+
Classifier: Operating System :: OS Independent
|
|
11
|
+
Requires-Python: >=3.8
|
|
12
|
+
Description-Content-Type: text/markdown
|
|
13
|
+
License-File: LICENSE
|
|
14
|
+
Requires-Dist: PyYAML
|
|
15
|
+
Requires-Dist: requests
|
|
16
|
+
Requires-Dist: python-dotenv
|
|
17
|
+
Requires-Dist: openai
|
|
18
|
+
Requires-Dist: anthropic
|
|
19
|
+
Requires-Dist: google-generativeai
|
|
20
|
+
Requires-Dist: tqdm
|
|
21
|
+
Dynamic: author
|
|
22
|
+
Dynamic: author-email
|
|
23
|
+
Dynamic: classifier
|
|
24
|
+
Dynamic: description
|
|
25
|
+
Dynamic: description-content-type
|
|
26
|
+
Dynamic: home-page
|
|
27
|
+
Dynamic: license-file
|
|
28
|
+
Dynamic: requires-dist
|
|
29
|
+
Dynamic: requires-python
|
|
30
|
+
Dynamic: summary
|
|
31
|
+
|
|
32
|
+
# EvolutIA: Generador de preguntas de examen
|
|
33
|
+
|
|
34
|
+
Sistema automatizado para generar preguntas de examen desafiantes basadas en materiales didácticos existentes (lecturas, prácticas, tareas). El sistema aumenta la complejidad matemática de los ejercicios mientras mantiene el formato y estructura familiar.
|
|
35
|
+
|
|
36
|
+
## Características Principales
|
|
37
|
+
|
|
38
|
+
- **Multi-Modo**:
|
|
39
|
+
- **Variación**: Incrementa la complejidad de ejercicios existentes.
|
|
40
|
+
- **Creación**: Genera ejercicios nuevos desde cero basados en temas y tags.
|
|
41
|
+
- **RAG (Retrieval-Augmented Generation)**: Usa tus propios apuntes y ejercicios previos como contexto para generar contenido más alineado al curso.
|
|
42
|
+
- **Multi-Proveedor**: Soporte nativo para OpenAI (GPT-4), Anthropic (Claude 3), Google (Gemini 1.5) y Modelos Locales (via Ollama/LM Studio).
|
|
43
|
+
- **Análisis de Complejidad**: Valida automáticamente que las nuevas preguntas sean matemáticamente más exigentes.
|
|
44
|
+
- **Formato MyST**: Salida compatible con Curvenote y Jupyter Book.
|
|
45
|
+
|
|
46
|
+
---
|
|
47
|
+
|
|
48
|
+
## Instalación
|
|
49
|
+
|
|
50
|
+
### Requisitos Previos
|
|
51
|
+
- Python 3.8 o superior
|
|
52
|
+
- API Key de tu proveedor preferido (OpenAI, Anthropic, Google) o un servidor local (Ollama).
|
|
53
|
+
|
|
54
|
+
### Opción 1: Instalación desde PyPI (Recomendada)
|
|
55
|
+
Para uso general, instala directamente el paquete:
|
|
56
|
+
|
|
57
|
+
```bash
|
|
58
|
+
# Crear entorno virtual (Recomendado)
|
|
59
|
+
python -m venv venv
|
|
60
|
+
source venv/bin/activate # Windows: venv\Scripts\activate
|
|
61
|
+
|
|
62
|
+
# Instalar
|
|
63
|
+
pip install evolutia
|
|
64
|
+
```
|
|
65
|
+
|
|
66
|
+
### Opción 2: Instalación desde Fuente (Desarrollo)
|
|
67
|
+
Si deseas modificar el código o contribuir:
|
|
68
|
+
|
|
69
|
+
```bash
|
|
70
|
+
git clone https://github.com/glacy/evolutIA.git
|
|
71
|
+
cd evolutia
|
|
72
|
+
pip install -e .
|
|
73
|
+
```
|
|
74
|
+
|
|
75
|
+
### Configuración Inicial
|
|
76
|
+
Crea un archivo `.env` en la raíz de tu proyecto con tus credenciales:
|
|
77
|
+
|
|
78
|
+
```bash
|
|
79
|
+
OPENAI_API_KEY=sk-...
|
|
80
|
+
ANTHROPIC_API_KEY=sk-ant-...
|
|
81
|
+
GOOGLE_API_KEY=...
|
|
82
|
+
```
|
|
83
|
+
|
|
84
|
+
---
|
|
85
|
+
|
|
86
|
+
## Guía de Uso Rápido
|
|
87
|
+
|
|
88
|
+
El comando principal es `evolutia`. Aquí tienes los casos de uso más comunes:
|
|
89
|
+
|
|
90
|
+
### 1. Generar Variaciones (Modo Clásico)
|
|
91
|
+
Toma ejercicios existentes de un tema y crea versiones más complejas.
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
# Generar 3 variaciones del tema 'analisis_vectorial'
|
|
95
|
+
evolutia --tema analisis_vectorial --num_ejercicios 3 --output examenes/parcial1
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
O variar ejercicios específicos por su etiqueta (Label):
|
|
99
|
+
```bash
|
|
100
|
+
evolutia --tema analisis_vectorial --label ex1-s1 ex2-s1 --output examenes/recuperacion
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 2. Crear Nuevos Ejercicios (Modo Creación)
|
|
104
|
+
Genera ejercicios desde cero sin necesitar un "ejercicio semilla".
|
|
105
|
+
|
|
106
|
+
```bash
|
|
107
|
+
# Crear 3 ejercicios nuevos sobre 'numeros_complejos'
|
|
108
|
+
evolutia --mode creation --tema numeros_complejos --num_ejercicios 3 --output examenes/quiz1
|
|
109
|
+
```
|
|
110
|
+
|
|
111
|
+
### 3. Usar RAG (Contexto del Curso)
|
|
112
|
+
Enriquece la generación indexando tus lecturas y prácticas.
|
|
113
|
+
|
|
114
|
+
```bash
|
|
115
|
+
# La primera vez, usa --reindex para leer tus materiales
|
|
116
|
+
evolutia --tema matrices --num_ejercicios 3 --use_rag --reindex --output examenes/final
|
|
117
|
+
|
|
118
|
+
# Consultas posteriores (usa el índice ya creado)
|
|
119
|
+
evolutia --tema matrices --num_ejercicios 3 --use_rag --output examenes/final
|
|
120
|
+
```
|
|
121
|
+
|
|
122
|
+
### 4. Consultar tu Base de Conocimiento
|
|
123
|
+
Pregúntale al sistema qué sabe sobre un concepto (útil para verificar RAG):
|
|
124
|
+
```bash
|
|
125
|
+
evolutia --query "Teorema de Stokes"
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
---
|
|
129
|
+
|
|
130
|
+
## Configuración Avanzada
|
|
131
|
+
|
|
132
|
+
EvolutIA es altamente configurable a través del archivo `evolutia_config.yaml` o argumentos CLI.
|
|
133
|
+
|
|
134
|
+
### Archivo de Configuración
|
|
135
|
+
Puedes colocar un `evolutia_config.yaml` en la raíz de tu carpeta de curso. Si no existe, puedes generarlo o ver el estado actual con:
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# Analiza tu estructura de carpetas y genera/actualiza la config
|
|
139
|
+
evolutia --analyze
|
|
140
|
+
# O explícitamente usando el script auxiliar
|
|
141
|
+
python evolutia/config_manager.py
|
|
142
|
+
```
|
|
143
|
+
|
|
144
|
+
### Argumentos CLI Disponibles
|
|
145
|
+
|
|
146
|
+
| Argumento | Descripción | Default |
|
|
147
|
+
|-----------|-------------|---------|
|
|
148
|
+
| `--tema` | Identificador del tema (carpeta) | **Requerido** |
|
|
149
|
+
| `--output` | Carpeta de salida | **Requerido** |
|
|
150
|
+
| `--num_ejercicios` | Cantidad a generar | 1 |
|
|
151
|
+
| `--complejidad` | Nivel objetivo (`media`, `alta`, `muy_alta`) | `alta` |
|
|
152
|
+
| `--api` | Proveedor (`openai`, `anthropic`, `gemini`, `local`) | `openai` |
|
|
153
|
+
| `--type` | Tipo de pregunta (`problem`, `multiple_choice`) | `problem` |
|
|
154
|
+
| `--no_generar_soluciones` | Omite la creación de archivos de solución | False |
|
|
155
|
+
|
|
156
|
+
### Uso con Modelos Locales (Offline)
|
|
157
|
+
Para usar modelos como Llama 3 o Mistral sin costo de API:
|
|
158
|
+
|
|
159
|
+
1. Ejecuta tu servidor (ej. `ollama serve`).
|
|
160
|
+
2. Configura `evolutia_config.yaml` (opcional, si usas defaults de Ollama no es necesario):
|
|
161
|
+
```yaml
|
|
162
|
+
local:
|
|
163
|
+
base_url: "http://localhost:11434/v1"
|
|
164
|
+
model: "llama3"
|
|
165
|
+
```
|
|
166
|
+
3. Ejecuta con el flag local:
|
|
167
|
+
```bash
|
|
168
|
+
evolutia --tema basicos --api local --output prueba_local
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
---
|
|
172
|
+
|
|
173
|
+
## Gestión de Materiales (Cómo "ve" los ejercicios EvolutIA)
|
|
174
|
+
|
|
175
|
+
Para que el sistema encuentre tus ejercicios y lecturas, utiliza una estrategia de descubrimiento basada en carpetas y metadatos.
|
|
176
|
+
|
|
177
|
+
1. **Escaneo de Carpetas**: Busca archivos `.md` dentro de la carpeta del tema (ej: `./analisis_vectorial/`).
|
|
178
|
+
2. **Tags y Metadatos**: Para archivos fuera de esa carpeta (ej. en `tareas/`), el sistema lee el *frontmatter* YAML. Incluye el tag del tema para hacerlo visible:
|
|
179
|
+
|
|
180
|
+
```yaml
|
|
181
|
+
---
|
|
182
|
+
title: Tarea 1
|
|
183
|
+
tags:
|
|
184
|
+
- analisis_vectorial # <--- Este tag permite que evolutia encuentre el archivo
|
|
185
|
+
- stokes
|
|
186
|
+
---
|
|
187
|
+
```
|
|
188
|
+
|
|
189
|
+
### Trazabilidad
|
|
190
|
+
Los ejercicios generados heredan los tags de sus "padres". El archivo final del examen (`examenX.md`) resume todos los temas cubiertos.
|
|
191
|
+
|
|
192
|
+
---
|
|
193
|
+
|
|
194
|
+
## Estructura del Proyecto
|
|
195
|
+
|
|
196
|
+
Se recomienda la siguiente estructura para tus cursos:
|
|
197
|
+
|
|
198
|
+
```
|
|
199
|
+
MiCurso/
|
|
200
|
+
├── evolutia_config.yaml # Configuración específica del curso
|
|
201
|
+
├── analisis_vectorial/ # Materiales del tema 1
|
|
202
|
+
│ ├── lectura.md
|
|
203
|
+
│ └── practica.md
|
|
204
|
+
├── matrices/ # Materiales del tema 2
|
|
205
|
+
├── examenes/ # Salida generada por EvolutIA
|
|
206
|
+
└── .env # API Keys (no subir a git)
|
|
207
|
+
```
|
|
208
|
+
|
|
209
|
+
> **Nota para usuarios antiguos**: Anteriormente se recomendaba usar Git Submodules. Ese método ha sido archivado. Si lo necesitas, consulta [docs/legacy/GUIDE_SUBMODULES.md](docs/legacy/GUIDE_SUBMODULES.md).
|
|
210
|
+
|
|
211
|
+
## Contribuciones y Desarrollo
|
|
212
|
+
|
|
213
|
+
El código fuente está organizado modularmente en `evolutia/`:
|
|
214
|
+
- `evolutia_engine.py`: Orquestador principal.
|
|
215
|
+
- `variation_generator.py`: Lógica de prompts y llamadas a LLMs.
|
|
216
|
+
- `rag/`: Subsistema de indexación y recuperación.
|
|
217
|
+
|
|
218
|
+
Para reportar bugs o mejoras, por favor visita el repositorio en GitHub.
|
|
219
|
+
|
|
220
|
+
## Licencia
|
|
221
|
+
Apache 2.0
|
|
@@ -1,13 +1,13 @@
|
|
|
1
|
-
evolutia_cli.py,sha256=
|
|
2
|
-
evolutia/__init__.py,sha256=
|
|
1
|
+
evolutia_cli.py,sha256=suMvTD2v7075-pQmyji2jCTOHuxZWENJM8Se0ynIl-k,7784
|
|
2
|
+
evolutia/__init__.py,sha256=BydLq-f4ekW6SKFPKFA-W5QJLizRbNhqscAiLQGgeVI,172
|
|
3
3
|
evolutia/complexity_validator.py,sha256=7LL7X9mfEb6S8o_Nj3U7gBpKRBUd49IKIvMGk0e6G6M,7258
|
|
4
|
-
evolutia/config_manager.py,sha256=
|
|
4
|
+
evolutia/config_manager.py,sha256=gmaRb1tKD7G5OW61rO01cYu3O6o8ATS7JMxrRy0hoVI,8492
|
|
5
5
|
evolutia/evolutia_engine.py,sha256=ZJOox50c7PiBuiqDnwx49P0vN0_Gu5_l0SG0K9UPVSQ,11969
|
|
6
6
|
evolutia/exam_generator.py,sha256=bLMbSg4LV9boMjv3KUiOR4K2Auw90mOk60gjTY8Tymk,13670
|
|
7
7
|
evolutia/exercise_analyzer.py,sha256=4g7LJv4oY0BagSZCm_iqodpKjoVcGCJn90y2Nz2f6ro,8784
|
|
8
|
-
evolutia/llm_providers.py,sha256=
|
|
8
|
+
evolutia/llm_providers.py,sha256=9sKu3x9ffZhomTR72R3rGBQUVUvO3U3un2VqxkLRBYk,7790
|
|
9
9
|
evolutia/material_extractor.py,sha256=d2wnApRfWdc-1f5tibX5tmNr0yPBmNDN3aO9TsYQjj4,9732
|
|
10
|
-
evolutia/variation_generator.py,sha256=
|
|
10
|
+
evolutia/variation_generator.py,sha256=F6dQUwsljtAT5hO_1NyQA_uQ8YBr9Gep5tU3Ypcbc3M,10807
|
|
11
11
|
evolutia/rag/__init__.py,sha256=c4tpP4b-C6BruvO1G865ta-RvZewqECy94QDN2fFRJA,112
|
|
12
12
|
evolutia/rag/consistency_validator.py,sha256=jsPPCIjiMQ8oCkffvww142kGWfBUl70Bq4YiTwe8eqk,8337
|
|
13
13
|
evolutia/rag/context_enricher.py,sha256=WnOVLOWByiX9_XZayaVsExbzldIWzl9AGwf5rAuSv4c,11723
|
|
@@ -19,9 +19,9 @@ evolutia/utils/__init__.py,sha256=rD3hl92fM5L3_7QCRrCjyR91bx_bOsw0baVQrCjy6vg,56
|
|
|
19
19
|
evolutia/utils/json_parser.py,sha256=jZModUbVhR4MvzbD7qZOCtUricx9j_Tomc_M-zfuGIM,2872
|
|
20
20
|
evolutia/utils/markdown_parser.py,sha256=7m1oqfe4eSkX1yi_VteEM2Q784UczOZ6YNngf8UWedc,4872
|
|
21
21
|
evolutia/utils/math_extractor.py,sha256=pBscN0aDk9CFV-vKbk43e-lHI_vo2RyhxLMmwx3dgEQ,4832
|
|
22
|
-
evolutia-0.1.
|
|
23
|
-
evolutia-0.1.
|
|
24
|
-
evolutia-0.1.
|
|
25
|
-
evolutia-0.1.
|
|
26
|
-
evolutia-0.1.
|
|
27
|
-
evolutia-0.1.
|
|
22
|
+
evolutia-0.1.1.dist-info/licenses/LICENSE,sha256=jyOI5zt59oNBGE33KX2L1py7ZwWKqVFNcgEePR6o6YA,11564
|
|
23
|
+
evolutia-0.1.1.dist-info/METADATA,sha256=bvapXA__5RRN2-OVqIkmX5iuI1PlrtPq1dK-UM-B0R8,7412
|
|
24
|
+
evolutia-0.1.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
25
|
+
evolutia-0.1.1.dist-info/entry_points.txt,sha256=BMYhya9XcbrfsjGfp4lMVQF0TK3Bd_Kj6mZtFhVJ7zo,47
|
|
26
|
+
evolutia-0.1.1.dist-info/top_level.txt,sha256=GrIvEW8qAI8CIW5XTPnCqC7o06qJIL8p9CGwVhCEC4s,22
|
|
27
|
+
evolutia-0.1.1.dist-info/RECORD,,
|
|
@@ -186,7 +186,7 @@
|
|
|
186
186
|
same "printed page" as the copyright notice for easier
|
|
187
187
|
identification within third-party archives.
|
|
188
188
|
|
|
189
|
-
Copyright
|
|
189
|
+
Copyright 2026 glacy (gerardolacymora@gmail.com)
|
|
190
190
|
|
|
191
191
|
Licensed under the Apache License, Version 2.0 (the "License");
|
|
192
192
|
you may not use this file except in compliance with the License.
|
evolutia_cli.py
CHANGED
|
@@ -7,6 +7,10 @@ import argparse
|
|
|
7
7
|
import logging
|
|
8
8
|
import sys
|
|
9
9
|
from pathlib import Path
|
|
10
|
+
from dotenv import load_dotenv
|
|
11
|
+
|
|
12
|
+
# Cargar variables de entorno desde el directorio actual (donde el usuario ejecuta el comando)
|
|
13
|
+
load_dotenv()
|
|
10
14
|
|
|
11
15
|
# Add current directory to path so we can import 'evolutia' package if running locally without install
|
|
12
16
|
sys.path.insert(0, str(Path(__file__).parent))
|
|
@@ -56,9 +60,15 @@ Ejemplos:
|
|
|
56
60
|
parser.add_argument('--list', action='store_true', help='Listar ejercicios')
|
|
57
61
|
parser.add_argument('--query', type=str, help='Consulta RAG')
|
|
58
62
|
parser.add_argument('--workers', type=int, default=5, help='Número de hilos para generación paralela')
|
|
63
|
+
parser.add_argument('--analyze', action='store_true', help='Analizar estructura y generar config.yaml')
|
|
59
64
|
|
|
60
65
|
args = parser.parse_args()
|
|
61
66
|
|
|
67
|
+
if args.analyze:
|
|
68
|
+
print("Analizando estructura del proyecto...")
|
|
69
|
+
ConfigManager(str(Path.cwd())).update_config_from_structure()
|
|
70
|
+
return 0
|
|
71
|
+
|
|
62
72
|
# Validaciones básicas de argumentos
|
|
63
73
|
if not args.reindex and not args.list and not args.query:
|
|
64
74
|
if not args.tema and not args.label:
|
|
@@ -1,723 +0,0 @@
|
|
|
1
|
-
Metadata-Version: 2.4
|
|
2
|
-
Name: evolutia
|
|
3
|
-
Version: 0.1.0
|
|
4
|
-
Summary: Sistema automatizado para generar preguntas de examen desafiantes basadas en materiales didácticos existentes
|
|
5
|
-
Home-page: https://github.com/glacy/evolutIA
|
|
6
|
-
Author: Gerardo Lacy-Mora
|
|
7
|
-
Author-email: glacycr@gmail.com
|
|
8
|
-
Classifier: Programming Language :: Python :: 3
|
|
9
|
-
Classifier: License :: OSI Approved :: Apache Software License
|
|
10
|
-
Classifier: Operating System :: OS Independent
|
|
11
|
-
Requires-Python: >=3.8
|
|
12
|
-
Description-Content-Type: text/markdown
|
|
13
|
-
License-File: LICENSE
|
|
14
|
-
Requires-Dist: PyYAML
|
|
15
|
-
Requires-Dist: requests
|
|
16
|
-
Requires-Dist: python-dotenv
|
|
17
|
-
Requires-Dist: openai
|
|
18
|
-
Requires-Dist: anthropic
|
|
19
|
-
Requires-Dist: google-generativeai
|
|
20
|
-
Requires-Dist: tqdm
|
|
21
|
-
Dynamic: author
|
|
22
|
-
Dynamic: author-email
|
|
23
|
-
Dynamic: classifier
|
|
24
|
-
Dynamic: description
|
|
25
|
-
Dynamic: description-content-type
|
|
26
|
-
Dynamic: home-page
|
|
27
|
-
Dynamic: license-file
|
|
28
|
-
Dynamic: requires-dist
|
|
29
|
-
Dynamic: requires-python
|
|
30
|
-
Dynamic: summary
|
|
31
|
-
|
|
32
|
-
# EvolutIA: Generador de preguntas de examen
|
|
33
|
-
|
|
34
|
-
Sistema automatizado para generar preguntas de examen desafiantes basadas en materiales didácticos existentes (lecturas, prácticas, tareas). El sistema aumenta la complejidad matemática de los ejercicios mientras mantiene el formato y estructura familiar.
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
## Características
|
|
38
|
-
|
|
39
|
-
- **Extracción automática**: Lee y procesa materiales didácticos en formato Markdown/MyST
|
|
40
|
-
- **Análisis de complejidad**: Identifica tipo, pasos, variables y conceptos de cada ejercicio
|
|
41
|
-
- **Generación inteligente**: Usa IA (OpenAI GPT-4 o Claude) para crear variaciones más complejas
|
|
42
|
-
- **Validación automática**: Verifica que las variaciones sean más desafiantes que los originales
|
|
43
|
-
- **Formato consistente**: Genera archivos en formato MyST/Markdown compatible con Curvenote
|
|
44
|
-
- **Multi-proveedor**: Soporte para OpenAI (GPT-4), Anthropic (Claude 3) y Google (Gemini 1.5).
|
|
45
|
-
- **RAG (Retrieval-Augmented Generation)**: Utiliza apuntes de clase y ejercicios existentes para dar contexto.
|
|
46
|
-
- **Modo Creación**: Genera ejercicios nuevos desde cero basados en temas y tags del curso.
|
|
47
|
-
- **Generación Paralela**: Utiliza concurrencia para acelerar drásticamente la generación de múltiples ejercicios.
|
|
48
|
-
- **Parseo Robusto**: Sistema avanzado para manejar y limpiar JSON con alta densidad de LaTeX.
|
|
49
|
-
|
|
50
|
-
```mermaid
|
|
51
|
-
flowchart LR
|
|
52
|
-
A[📚 Materiales Didácticos<br>Lecturas, Tareas, Prácticas] --> B(🔍 Extracción y Análisis<br>Identifica ejercicios y conceptos)
|
|
53
|
-
B --> C{⚙️ Motor de Generación}
|
|
54
|
-
subgraph C [ ]
|
|
55
|
-
direction LR
|
|
56
|
-
D[Modo Variación<br>Incrementa complejidad]
|
|
57
|
-
E[Modo Creación<br>Nuevos ejercicios desde cero]
|
|
58
|
-
end
|
|
59
|
-
C --> F(🧠 Inteligencia Artificial<br>LLM + RAG opcional)
|
|
60
|
-
F --> G(✅ Validación<br>Verifica aumento de dificultad)
|
|
61
|
-
G --> H[📝 Generación de Archivos<br>Examen y Soluciones en MyST/Markdown]
|
|
62
|
-
H --> I(🎯 Evaluación Coherente y Desafiante)
|
|
63
|
-
I --> J(🚀 Generación Paralela<br>Concurrencia para acelerar)
|
|
64
|
-
```
|
|
65
|
-
|
|
66
|
-
## Requisitos
|
|
67
|
-
|
|
68
|
-
- Python 3.8 o superior
|
|
69
|
-
- API key de OpenAI o Anthropic (Claude)
|
|
70
|
-
- Opcional: Servidor LLM local (Ollama, LM Studio) para generación offline
|
|
71
|
-
|
|
72
|
-
### Instalación
|
|
73
|
-
|
|
74
|
-
1. Clona el repositorio:
|
|
75
|
-
```bash
|
|
76
|
-
git clone https://github.com/glacy/evolutIA.git
|
|
77
|
-
cd evolutia
|
|
78
|
-
```
|
|
79
|
-
|
|
80
|
-
2. Crea y activa un entorno virtual:
|
|
81
|
-
```bash
|
|
82
|
-
python -m venv venv
|
|
83
|
-
source venv/bin/activate # En Windows: venv\Scripts\activate
|
|
84
|
-
```
|
|
85
|
-
|
|
86
|
-
3. Instala el paquete en modo editable (esto instalará también las dependencias):
|
|
87
|
-
```bash
|
|
88
|
-
pip install -e .
|
|
89
|
-
```
|
|
90
|
-
|
|
91
|
-
4. Configura las variables de entorno:
|
|
92
|
-
```bash
|
|
93
|
-
cp .env.example .env
|
|
94
|
-
# Edita .env con tus API keys
|
|
95
|
-
```
|
|
96
|
-
Y edita `.env` con tus claves reales:
|
|
97
|
-
```
|
|
98
|
-
OPENAI_API_KEY=sk-tu-api-key-aqui
|
|
99
|
-
ANTHROPIC_API_KEY=sk-ant-tu-api-key-aqui
|
|
100
|
-
GOOGLE_API_KEY=tu-api-key-aqui
|
|
101
|
-
```
|
|
102
|
-
|
|
103
|
-
**Obtener API keys**:
|
|
104
|
-
- OpenAI: https://platform.openai.com/api-keys
|
|
105
|
-
- Anthropic: https://console.anthropic.com/
|
|
106
|
-
- Google: https://console.cloud.google.com/ai/generative-ai/credentials
|
|
107
|
-
|
|
108
|
-
## Uso
|
|
109
|
-
|
|
110
|
-
### Uso básico
|
|
111
|
-
|
|
112
|
-
```bash
|
|
113
|
-
python evolutia.py \
|
|
114
|
-
--tema analisis_vectorial \
|
|
115
|
-
--num_ejercicios 4 \
|
|
116
|
-
--output examenes/examen3
|
|
117
|
-
```
|
|
118
|
-
|
|
119
|
-
### Variación de ejercicios específicos
|
|
120
|
-
|
|
121
|
-
```bash
|
|
122
|
-
python evolutia.py \
|
|
123
|
-
--tema analisis_vectorial \
|
|
124
|
-
--label ex1-s1 ex2-s1 \
|
|
125
|
-
--output variacion_especifica
|
|
126
|
-
```
|
|
127
|
-
|
|
128
|
-
### Listar ejercicios disponibles
|
|
129
|
-
|
|
130
|
-
```bash
|
|
131
|
-
python evolutia.py --tema analisis_vectorial --list
|
|
132
|
-
```
|
|
133
|
-
|
|
134
|
-
Si no se indica un tema, el sistema buscará en todos los archivos disponibles.
|
|
135
|
-
|
|
136
|
-
### Opciones disponibles
|
|
137
|
-
|
|
138
|
-
- `--tema`: Tema del examen (requerido)
|
|
139
|
-
- Ejemplos: `analisis_vectorial`, `matrices`, `edps`, `espacios_vectoriales`, `numeros_complejos`
|
|
140
|
-
|
|
141
|
-
- `--num_ejercicios`: Número de ejercicios a generar (default: 1)
|
|
142
|
-
|
|
143
|
-
- `--output`: Directorio de salida (requerido)
|
|
144
|
-
- Se creará automáticamente si no existe
|
|
145
|
-
|
|
146
|
-
- `--complejidad`: Nivel de complejidad objetivo
|
|
147
|
-
- Opciones: `media`, `alta` (default), `muy_alta`
|
|
148
|
-
|
|
149
|
-
- `--api`: Proveedor de API de IA
|
|
150
|
-
- Opciones: `openai` (default), `anthropic`, `local`, `gemini`
|
|
151
|
-
|
|
152
|
-
- `--label`: ID(s) específico(s) del ejercicio a variar (ej: `ex1-s1` o múltiples: `ex1-s1 ex2-s1`).
|
|
153
|
-
- Si se usa, ignora `--num_ejercicios` y genera variaciones **solo** para los ejercicios indicados.
|
|
154
|
-
|
|
155
|
-
- `--config`: Ruta a un archivo de configuración externo (ej: `./mi_curso_config.yaml`). (default: busca `evolutia_config.yaml` en la raíz, o usa el interno).
|
|
156
|
-
|
|
157
|
-
- `--base_path`: Ruta base del proyecto (default: directorio actual)
|
|
158
|
-
|
|
159
|
-
- `--examen_num`: Número del examen (se infiere del nombre del directorio si no se especifica)
|
|
160
|
-
|
|
161
|
-
- `--no_generar_soluciones`: NO genera las soluciones (por defecto siempre se generan)
|
|
162
|
-
|
|
163
|
-
- `--subject`: Asignatura del examen (default: "IF3602 - II semestre 2025")
|
|
164
|
-
|
|
165
|
-
- `--keywords`: Palabras clave para el examen (múltiples valores)
|
|
166
|
-
|
|
167
|
-
- `--use_rag`: Usa RAG para enriquecer generación con contexto del curso (requiere indexación inicial)
|
|
168
|
-
|
|
169
|
-
- `--reindex`: Fuerza re-indexación de materiales (solo con `--use_rag`)
|
|
170
|
-
|
|
171
|
-
- `--list`: Lista todos los ejercicios encontrados en los temas seleccionados y muestra sus etiquetas, archivo origen y preview.
|
|
172
|
-
|
|
173
|
-
- `--query`: Realiza una búsqueda semántica en la base de datos RAG y muestra los fragmentos de texto más relevantes encontrados. Útil para verificar qué "sabe" el sistema sobre un tema.
|
|
174
|
-
|
|
175
|
-
- `--workers`: Número de hilos simultáneos para la generación paralela (default: 5). Útil para ajustar el rendimiento o evitar límites de rate.
|
|
176
|
-
|
|
177
|
-
### Ejemplos
|
|
178
|
-
|
|
179
|
-
**Generar examen de análisis vectorial con 4 ejercicios:**
|
|
180
|
-
```bash
|
|
181
|
-
python evolutia.py \
|
|
182
|
-
--tema analisis_vectorial \
|
|
183
|
-
--num_ejercicios 4 \
|
|
184
|
-
--output examenes/examen3
|
|
185
|
-
```
|
|
186
|
-
|
|
187
|
-
**Generar examen usando Claude (las soluciones se generan automáticamente):**
|
|
188
|
-
```bash
|
|
189
|
-
python evolutia.py \
|
|
190
|
-
--tema matrices \
|
|
191
|
-
--num_ejercicios 3 \
|
|
192
|
-
--api anthropic \
|
|
193
|
-
--output examenes/examen4
|
|
194
|
-
```
|
|
195
|
-
|
|
196
|
-
### Uso Básico
|
|
197
|
-
|
|
198
|
-
Una vez instalado, puedes usar el comando `evolutia` (o ejecutar el wrapper `python evolutia_cli.py`):
|
|
199
|
-
|
|
200
|
-
1. **Analizar el repositorio y entender la estructura:**
|
|
201
|
-
```bash
|
|
202
|
-
evolutia --analyze
|
|
203
|
-
```
|
|
204
|
-
*(Esto generará `config.yaml` si no existe)*
|
|
205
|
-
|
|
206
|
-
2. **Generar examen con variaciones de ejercicios existentes:**
|
|
207
|
-
```bash
|
|
208
|
-
evolutia --exam-number 1 --num-ejercicios 3 --tema "Derivadas" --complejidad "media"
|
|
209
|
-
```
|
|
210
|
-
**Generar examen SIN soluciones:**
|
|
211
|
-
```bash
|
|
212
|
-
python evolutia.py \
|
|
213
|
-
--tema matrices \
|
|
214
|
-
--num_ejercicios 3 \
|
|
215
|
-
--no_generar_soluciones \
|
|
216
|
-
--output examenes/examen5
|
|
217
|
-
```
|
|
218
|
-
|
|
219
|
-
**Generar examen con complejidad muy alta:**
|
|
220
|
-
```bash
|
|
221
|
-
python evolutia.py \
|
|
222
|
-
--tema edps \
|
|
223
|
-
--num_ejercicios 5 \
|
|
224
|
-
--complejidad muy_alta \
|
|
225
|
-
--output examenes/examen5
|
|
226
|
-
```
|
|
227
|
-
|
|
228
|
-
**Generar examen usando RAG (recomendado para mejor calidad):**
|
|
229
|
-
```bash
|
|
230
|
-
python evolutia.py \
|
|
231
|
-
--tema analisis_vectorial \
|
|
232
|
-
--num_ejercicios 4 \
|
|
233
|
-
--use_rag \
|
|
234
|
-
--output examenes/examen3
|
|
235
|
-
```
|
|
236
|
-
|
|
237
|
-
### Herramienta de Consulta RAG
|
|
238
|
-
Puedes "preguntarle" al sistema qué información tiene sobre un concepto específico sin generar nada:
|
|
239
|
-
|
|
240
|
-
```bash
|
|
241
|
-
python evolutia.py --query "Teorema de Stokes"
|
|
242
|
-
```
|
|
243
|
-
|
|
244
|
-
Esto mostrará una lista de ejercicios y lecturas relevantes con su puntuación de similitud.
|
|
245
|
-
|
|
246
|
-
### Modo Creación (Nuevo)
|
|
247
|
-
Genera ejercicios totalmente nuevos desde cero, basándose en un tema y tags opcionales, en lugar de variar ejercicios existentes.
|
|
248
|
-
|
|
249
|
-
**Generar 3 ejercicios nuevos de variable compleja:**
|
|
250
|
-
```bash
|
|
251
|
-
python evolutia.py \
|
|
252
|
-
--mode creation \
|
|
253
|
-
--tema numeros_complejos \
|
|
254
|
-
--num_ejercicios 3 \
|
|
255
|
-
--output examenes/parcial1
|
|
256
|
-
```
|
|
257
|
-
|
|
258
|
-
**Generar con tags específicos y usar Gemini:**
|
|
259
|
-
```bash
|
|
260
|
-
python evolutia.py \
|
|
261
|
-
--mode creation \
|
|
262
|
-
--tema analisis_vectorial \
|
|
263
|
-
--tags stokes divergencia \
|
|
264
|
-
--api gemini \
|
|
265
|
-
--output examenes/quiz3
|
|
266
|
-
```
|
|
267
|
-
|
|
268
|
-
### Tipos de Ejercicio
|
|
269
|
-
Ahora puedes elegir entre ejercicios de desarrollo (default) o selección única (quiz).
|
|
270
|
-
|
|
271
|
-
**Generar pregunta de Selección Única (Conceptual):**
|
|
272
|
-
```bash
|
|
273
|
-
python evolutia.py \
|
|
274
|
-
--mode creation \
|
|
275
|
-
--tema matrices \
|
|
276
|
-
--type multiple_choice \
|
|
277
|
-
--api anthropic \
|
|
278
|
-
--output examenes/quiz_rapido
|
|
279
|
-
```
|
|
280
|
-
|
|
281
|
-
## Uso de LLM local (offline)
|
|
282
|
-
|
|
283
|
-
EvolutIA soporta la generación de exámenes usando modelos locales como Llama 3, Mistral, o Qwen, ejecutándose en tu propia máquina a través de herramientas como [Ollama](https://ollama.com/) o [LM Studio](https://lmstudio.ai/).
|
|
284
|
-
|
|
285
|
-
**Requisitos:**
|
|
286
|
-
1. Tener corriendo un servidor local compatible con OpenAI API.
|
|
287
|
-
- **Ollama**: Ejecuta `ollama serve` (por defecto en puerto 11434).
|
|
288
|
-
- **LM Studio**: Inicia el servidor local desde la interfaz.
|
|
289
|
-
|
|
290
|
-
2. **Ejemplo de ejecución:**
|
|
291
|
-
```bash
|
|
292
|
-
python evolutia.py \
|
|
293
|
-
--tema matrices \
|
|
294
|
-
--num_ejercicios 3 \
|
|
295
|
-
--api local \
|
|
296
|
-
--output examenes/examen_local
|
|
297
|
-
```
|
|
298
|
-
|
|
299
|
-
3. **Configuración avanzada (opcional):**
|
|
300
|
-
Si tu servidor no usa el puerto por defecto o quieres cambiar el modelo, edita `evolutia/config/config.yaml`:
|
|
301
|
-
```yaml
|
|
302
|
-
local:
|
|
303
|
-
base_url: "http://localhost:11434/v1" # URL de tu servidor
|
|
304
|
-
model: "llama3" # Modelo a utilizar
|
|
305
|
-
api_key: "not-needed"
|
|
306
|
-
```
|
|
307
|
-
|
|
308
|
-
## Sistema RAG (Retrieval-Augmented Generation)
|
|
309
|
-
|
|
310
|
-
El sistema incluye un módulo RAG opcional que mejora significativamente la calidad de las variaciones generadas.
|
|
311
|
-
|
|
312
|
-
### ¿Qué es RAG?
|
|
313
|
-
|
|
314
|
-
RAG (Retrieval-Augmented Generation) es un sistema que:
|
|
315
|
-
- **Indexa** todos tus materiales didácticos (ejercicios, soluciones y **lecturas/teoría**)
|
|
316
|
-
- **Busca** ejercicios similares y conceptos teóricos relevantes cuando generas variaciones
|
|
317
|
-
- **Enriquece** los prompts con información del curso para generar variaciones más coherentes
|
|
318
|
-
- **Valida** consistencia comparando con ejercicios y teoría reales del curso
|
|
319
|
-
|
|
320
|
-
### Ventajas de usar RAG
|
|
321
|
-
|
|
322
|
-
1. **Mejor contexto**: Las variaciones son más coherentes con el estilo y nivel del curso
|
|
323
|
-
2. **Consistencia**: Los ejercicios generados se alinean mejor con materiales existentes
|
|
324
|
-
3. **Relevancia**: Selección inteligente de ejercicios base por similitud semántica
|
|
325
|
-
4. **Validación mejorada**: Compara con ejercicios reales del curso
|
|
326
|
-
|
|
327
|
-
### Cómo usar RAG
|
|
328
|
-
|
|
329
|
-
**Primera vez (indexación inicial):**
|
|
330
|
-
```bash
|
|
331
|
-
python evolutia.py \
|
|
332
|
-
--tema analisis_vectorial \
|
|
333
|
-
--num_ejercicios 4 \
|
|
334
|
-
--use_rag \
|
|
335
|
-
--reindex \
|
|
336
|
-
--output examenes/examen3
|
|
337
|
-
```
|
|
338
|
-
|
|
339
|
-
La primera vez con `--use_rag` indexará automáticamente todos los materiales. Esto puede tardar unos minutos.
|
|
340
|
-
|
|
341
|
-
**Uso posterior:**
|
|
342
|
-
```bash
|
|
343
|
-
python evolutia.py \
|
|
344
|
-
--tema analisis_vectorial \
|
|
345
|
-
--num_ejercicios 4 \
|
|
346
|
-
--use_rag \
|
|
347
|
-
--output examenes/examen4
|
|
348
|
-
```
|
|
349
|
-
|
|
350
|
-
El índice se reutiliza automáticamente. Solo usa `--reindex` si cambias materiales y quieres actualizar el índice.
|
|
351
|
-
|
|
352
|
-
### Configuración de RAG
|
|
353
|
-
|
|
354
|
-
Edita `config/config.yaml` para personalizar RAG:
|
|
355
|
-
```yaml
|
|
356
|
-
rag:
|
|
357
|
-
vector_store:
|
|
358
|
-
# Base de datos vectorial persistente
|
|
359
|
-
persist_directory: "./storage/vector_store"
|
|
360
|
-
collection_name: "mi_curso_coleccion"
|
|
361
|
-
embeddings:
|
|
362
|
-
provider: openai
|
|
363
|
-
model: text-embedding-3-small
|
|
364
|
-
retrieval:
|
|
365
|
-
top_k: 5
|
|
366
|
-
similarity_threshold: 0.7
|
|
367
|
-
```
|
|
368
|
-
|
|
369
|
-
**Opciones de embeddings:**
|
|
370
|
-
- `openai`: Más rápido y preciso, pero tiene costo (~$0.02 por 1M tokens)
|
|
371
|
-
- `sentence-transformers`: Gratis y local, pero más lento
|
|
372
|
-
|
|
373
|
-
### Costos de RAG
|
|
374
|
-
|
|
375
|
-
- **Indexación inicial**: ~$1-5 dependiendo del volumen de materiales
|
|
376
|
-
- **Búsquedas**: Mínimas, solo cuando generas variaciones
|
|
377
|
-
- **Alternativa gratuita**: Usa `sentence-transformers` en lugar de OpenAI
|
|
378
|
-
|
|
379
|
-
### Cuándo usar RAG
|
|
380
|
-
|
|
381
|
-
**Usa RAG si:**
|
|
382
|
-
- Tienes muchos materiales (50+ ejercicios)
|
|
383
|
-
- Quieres máxima consistencia con el curso
|
|
384
|
-
- Tienes presupuesto para embeddings de OpenAI
|
|
385
|
-
|
|
386
|
-
**No uses RAG si:**
|
|
387
|
-
- Tienes pocos materiales (<20 ejercicios)
|
|
388
|
-
- Prefieres simplicidad y rapidez
|
|
389
|
-
- El costo es una preocupación
|
|
390
|
-
|
|
391
|
-
## Gestión de metadatos y descubrimiento
|
|
392
|
-
|
|
393
|
-
### Organización y visibilidad de ejercicios
|
|
394
|
-
|
|
395
|
-
Para que `evolutia` encuentre ejercicios ubicados en carpetas generales como `examenes/` o `tareas/` cuando filtras por un tema (ej: `--tema analisis_vectorial`), es fundamental que los archivos fuente incluyan los metadatos correctos.
|
|
396
|
-
|
|
397
|
-
El sistema utiliza la siguiente lógica de "descubrimiento":
|
|
398
|
-
|
|
399
|
-
1. **Escaneo directo**: Todos los archivos dentro de la carpeta del tema (ej: `analisis_vectorial/`) son incluidos automáticamente.
|
|
400
|
-
2. **Escaneo de exámenes y tareas**: Para archivos fuera de la carpeta del tema, el sistema revisa el *frontmatter* y los incluye **SOLO SI** encuentra coincidencias con el tema en:
|
|
401
|
-
- **`tags`**: (Recomendado) Incluye el código del tema (ej: `analisis_vectorial`) en la lista.
|
|
402
|
-
- **`subject`**: El nombre de la asignatura o tema.
|
|
403
|
-
- **`keywords`**: Palabras clave relacionadas.
|
|
404
|
-
|
|
405
|
-
**Ejemplo de Frontmatter para que un examen sea "visible":**
|
|
406
|
-
```yaml
|
|
407
|
-
---
|
|
408
|
-
title: Examen Parcial 1
|
|
409
|
-
tags:
|
|
410
|
-
- analisis_vectorial # <--- CRÍTICO: Permite que el extractor lo encuentre
|
|
411
|
-
- stokes
|
|
412
|
-
subject: Cálculo Superior
|
|
413
|
-
---
|
|
414
|
-
```
|
|
415
|
-
|
|
416
|
-
> **Nota**: Si usas `--label` para seleccionar un ejercicio específico, el filtro de tema se ignora y el sistema buscará el ID en todos los archivos disponibles.
|
|
417
|
-
|
|
418
|
-
### Propagación de tags (trazabilidad)
|
|
419
|
-
|
|
420
|
-
`EvolutIA` asegura que los metadatos de los ejercicios originales se conserven en las variaciones generadas. Esto es crucial para mantener un registro de qué conceptos se están evaluando.
|
|
421
|
-
|
|
422
|
-
**¿Cómo funciona?**
|
|
423
|
-
1. **Lectura**: El sistema lee los tags del archivo fuente (`.md`) donde reside el ejercicio original.
|
|
424
|
-
2. **Transferencia**: Al generar la variación, estos tags se copian al nuevo archivo generado.
|
|
425
|
-
3. **Agregación**: El archivo final del examen (`examenX.md`) recopila automáticamente los tags de *todos* los ejercicios incluidos, generando un resumen temático del examen.
|
|
426
|
-
|
|
427
|
-
#### Ejemplo práctico
|
|
428
|
-
|
|
429
|
-
**1. Archivo fuente (ej: `matrices/semana11_practica.md`)**
|
|
430
|
-
Este archivo contiene los ejercicios originales ("semilla") y define el contexto temático:
|
|
431
|
-
|
|
432
|
-
```yaml
|
|
433
|
-
---
|
|
434
|
-
title: Ejercicios Semana 11
|
|
435
|
-
tags:
|
|
436
|
-
- autovalores # Concepto clave
|
|
437
|
-
- diagonalizacion # Concepto clave
|
|
438
|
-
- procedimental # Tipo de competencia
|
|
439
|
-
- intermedio # Nivel de dificultad
|
|
440
|
-
subject: Matrices y Algebra Lineal
|
|
441
|
-
---
|
|
442
|
-
```
|
|
443
|
-
|
|
444
|
-
**2. Archivo generado (ej: `examenes/examen1/ex1_e1.md`)**
|
|
445
|
-
La variación generada hereda estos metadatos y agrega los suyos propios:
|
|
446
|
-
|
|
447
|
-
```yaml
|
|
448
|
-
---
|
|
449
|
-
generator: evolutia
|
|
450
|
-
source: ai_variation
|
|
451
|
-
tags: [autovalores, diagonalizacion, procedimental, intermedio] # <--- Tags heredados
|
|
452
|
-
original_subject: Matrices y Algebra Lineal
|
|
453
|
-
complexity: media
|
|
454
|
-
mode: variation # <--- Nuevo: Modo de generación
|
|
455
|
-
target_difficulty: alta # <--- Nuevo: Dificultad objetivo
|
|
456
|
-
based_on: ex1-e1 # <--- Nuevo: ID del ejercicio semilla
|
|
457
|
-
rag_references: # <--- Nuevo: Contexto usado (con --use_rag)
|
|
458
|
-
- ex5-e2
|
|
459
|
-
- semana3_lectura.md
|
|
460
|
-
---
|
|
461
|
-
```
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
## Estructura de archivos generados
|
|
465
|
-
|
|
466
|
-
El script genera la siguiente estructura:
|
|
467
|
-
|
|
468
|
-
```
|
|
469
|
-
examenes/examen3/
|
|
470
|
-
├── examen3.md # Archivo principal del examen
|
|
471
|
-
├── ex1_e3.md # Ejercicio 1
|
|
472
|
-
├── ex2_e3.md # Ejercicio 2
|
|
473
|
-
├── ex3_e3.md # Ejercicio 3
|
|
474
|
-
├── ex4_e3.md # Ejercicio 4
|
|
475
|
-
├── solucion_ex1_e3.md # Solución ejercicio 1
|
|
476
|
-
├── solucion_ex2_e3.md # Solución ejercicio 2
|
|
477
|
-
├── solucion_ex3_e3.md # Solución ejercicio 3
|
|
478
|
-
└── solucion_ex4_e3.md # Solución ejercicio 4
|
|
479
|
-
```
|
|
480
|
-
|
|
481
|
-
## ¿Cómo funciona?
|
|
482
|
-
|
|
483
|
-
1. **Extracción**: El sistema busca y lee materiales didácticos del tema especificado
|
|
484
|
-
- Busca en directorios del tema (ej: `analisis_vectorial/`)
|
|
485
|
-
- Lee archivos de prácticas (`*practica*.md`)
|
|
486
|
-
- Lee archivos de tareas (`tareas/tarea*/tarea*.md`)
|
|
487
|
-
|
|
488
|
-
2. **Análisis**: Analiza cada ejercicio encontrado
|
|
489
|
-
- Identifica tipo (demostración, cálculo, aplicación)
|
|
490
|
-
- Cuenta pasos en soluciones
|
|
491
|
-
- Extrae variables y conceptos matemáticos
|
|
492
|
-
- Calcula complejidad matemática
|
|
493
|
-
|
|
494
|
-
3. **Generación**: Crea variaciones más complejas usando IA
|
|
495
|
-
- Aumenta número de variables
|
|
496
|
-
- Combina múltiples conceptos
|
|
497
|
-
- Agrega pasos intermedios
|
|
498
|
-
- Modifica sistemas de coordenadas
|
|
499
|
-
|
|
500
|
-
4. **Validación**: Verifica que las variaciones sean más complejas
|
|
501
|
-
- Compara complejidad total
|
|
502
|
-
- Verifica aumento en pasos, variables, conceptos
|
|
503
|
-
- Valida operaciones matemáticas
|
|
504
|
-
|
|
505
|
-
5. **Generación de archivos**: Crea archivos en formato MyST/Markdown
|
|
506
|
-
- Frontmatter YAML apropiado
|
|
507
|
-
- Estructura de ejercicios con labels
|
|
508
|
-
- Bloques de solución
|
|
509
|
-
|
|
510
|
-
## Configuración
|
|
511
|
-
|
|
512
|
-
Puedes personalizar el comportamiento editando `config/config.yaml`:
|
|
513
|
-
|
|
514
|
-
- **APIs**: Configurar modelos y parámetros
|
|
515
|
-
- **Rutas**: Especificar directorios de materiales (dentro de `materials_directories`)
|
|
516
|
-
- **Complejidad**: Ajustar umbrales de validación
|
|
517
|
-
- **Exámenes**: Configurar valores por defecto y **keywords** por tema
|
|
518
|
-
- **RAG**: Definir persistencia (local vs nube) y nombres de colección
|
|
519
|
-
|
|
520
|
-
### Cambiar Proveedor por Defecto
|
|
521
|
-
Puedes definir qué IA usar si no se especifica el argumento `--api`:
|
|
522
|
-
|
|
523
|
-
```yaml
|
|
524
|
-
api:
|
|
525
|
-
default_provider: gemini # openai, anthropic, gemini, local
|
|
526
|
-
gemini:
|
|
527
|
-
model: gemini-1.5-pro # Cambiar modelo específico
|
|
528
|
-
```
|
|
529
|
-
|
|
530
|
-
### Nota Importante sobre Configuración
|
|
531
|
-
Para evitar errores de validación, asegúrate de que tu `evolutia_config.yaml` incluya la sección `api`. El sistema usa esto para determinar los modelos por defecto.
|
|
532
|
-
|
|
533
|
-
### Configuración Avanzada / Multi-Curso
|
|
534
|
-
|
|
535
|
-
Para usar `evolutia` en múltiples cursos o sin modificar el código fuente:
|
|
536
|
-
|
|
537
|
-
1. **Archivo de Configuración Externo**: Crea un archivo `evolutia_config.yaml` en la raíz de tu proyecto (junto a la carpeta `evolutia/`). El sistema lo detectará automáticamente.
|
|
538
|
-
2. **Argumento CLI**: Usa `--config ruta/a/mi_config.yaml` para especificar un archivo arbitrario.
|
|
539
|
-
|
|
540
|
-
**Ejemplo de estructura recomendada para un nuevo curso:**
|
|
541
|
-
```
|
|
542
|
-
NuevoCurso/
|
|
543
|
-
├── evolutia/ # Carpeta copiada o submódulo git
|
|
544
|
-
├── evolutia_config.yaml # Configuración específica de este curso
|
|
545
|
-
└── temas/ # Carpetas de contenido
|
|
546
|
-
```
|
|
547
|
-
|
|
548
|
-
> **IMPORTANTE**: No edites `evolutia/config/config.yaml` para datos de un curso específico. Ese archivo es una plantilla del motor. Crea un `evolutia_config.yaml` en la raíz de tu proyecto para tus ajustes personales.
|
|
549
|
-
|
|
550
|
-
> **Guía Detallada**: Para instrucciones paso a paso sobre cómo usar Git Submodules, consulta [GUIDE_SUBMODULES.md](GUIDE_SUBMODULES.md).
|
|
551
|
-
|
|
552
|
-
## Estrategias de aumento de complejidad
|
|
553
|
-
|
|
554
|
-
El sistema aplica las siguientes estrategias para aumentar la complejidad:
|
|
555
|
-
|
|
556
|
-
1. **Más variables independientes**: Introduce parámetros adicionales
|
|
557
|
-
2. **Combinación de conceptos**: Integra múltiples teoremas en un ejercicio
|
|
558
|
-
3. **Pasos intermedios**: Agrega cálculos adicionales
|
|
559
|
-
4. **Casos límite**: Introduce condiciones especiales
|
|
560
|
-
5. **Sistemas de coordenadas**: Cambia de cartesianas a cilíndricas/esféricas
|
|
561
|
-
6. **Dimensiones adicionales**: Aumenta la dimensionalidad del problema
|
|
562
|
-
|
|
563
|
-
## Solución de Problemas
|
|
564
|
-
|
|
565
|
-
### Error: "No se encontraron materiales"
|
|
566
|
-
- Verifica que el tema especificado existe como directorio
|
|
567
|
-
- Asegúrate de que hay archivos `.md` con ejercicios en ese directorio
|
|
568
|
-
- Usa `--base_path` para especificar la ruta correcta
|
|
569
|
-
|
|
570
|
-
### Error: "API key no configurada"
|
|
571
|
-
- Verifica que el archivo `.env` existe y contiene la API key
|
|
572
|
-
- Asegúrate de que el archivo está en el directorio `evolutia/`
|
|
573
|
-
- Revisa que la variable se llama correctamente (`OPENAI_API_KEY` o `ANTHROPIC_API_KEY`)
|
|
574
|
-
|
|
575
|
-
### Error: "No se generaron variaciones válidas"
|
|
576
|
-
- Intenta aumentar el número de ejercicios candidatos
|
|
577
|
-
- Verifica que los ejercicios originales tienen suficiente complejidad
|
|
578
|
-
- Considera usar `--complejidad media` para requisitos menos estrictos
|
|
579
|
-
|
|
580
|
-
### Variaciones no son suficientemente complejas
|
|
581
|
-
- Ajusta los umbrales en `config/config.yaml`
|
|
582
|
-
- Usa `--complejidad muy_alta`
|
|
583
|
-
- Revisa los prompts en `variation_generator.py` y ajústalos según necesites
|
|
584
|
-
- Considera usar `--use_rag` para mejor contexto
|
|
585
|
-
|
|
586
|
-
### Error: "RAG no disponible"
|
|
587
|
-
- Instala dependencias: `pip install chromadb sentence-transformers`
|
|
588
|
-
- Verifica que `OPENAI_API_KEY` está configurada si usas embeddings de OpenAI
|
|
589
|
-
- Si prefieres embeddings locales, cambia `provider: sentence-transformers` en `config.yaml`
|
|
590
|
-
|
|
591
|
-
## Limitaciones
|
|
592
|
-
|
|
593
|
-
- Requiere conexión a internet para usar APIs de IA
|
|
594
|
-
- Los costos de API dependen del número de ejercicios generados
|
|
595
|
-
- La calidad depende de la calidad de los materiales originales
|
|
596
|
-
- Las variaciones requieren revisión manual antes de usar
|
|
597
|
-
|
|
598
|
-
## Mejores prácticas
|
|
599
|
-
|
|
600
|
-
1. **Revisar siempre**: Las variaciones generadas deben revisarse manualmente
|
|
601
|
-
2. **Ajustar según necesidad**: Modifica los ejercicios generados según tu criterio
|
|
602
|
-
3. **Probar primero**: Genera un examen de prueba antes de usar en evaluación real
|
|
603
|
-
4. **Mantener materiales actualizados**: Asegúrate de que los materiales fuente están completos
|
|
604
|
-
5. **Documentar cambios**: Si modificas ejercicios, documenta los cambios realizados
|
|
605
|
-
|
|
606
|
-
## Configuración automática
|
|
607
|
-
|
|
608
|
-
El proyecto incluye una herramienta para sincronizar automáticamente el archivo de configuración con la estructura de carpetas y los metadatos de los archivos de lectura.
|
|
609
|
-
|
|
610
|
-
### config_manager.py
|
|
611
|
-
|
|
612
|
-
Este script escanea el directorio del proyecto para:
|
|
613
|
-
1. Identificar carpetas de temas existentes.
|
|
614
|
-
2. Leer los archivos de lectura (`semana*_lectura.md`) y extraer las palabras clave (`keywords`) del frontmatter.
|
|
615
|
-
3. Actualizar el archivo de configuración activo (`evolutia_config.yaml` o interno).
|
|
616
|
-
|
|
617
|
-
**Uso:**
|
|
618
|
-
|
|
619
|
-
```bash
|
|
620
|
-
# Uso básico (detecta configuración automáticamente)
|
|
621
|
-
python evolutia/config_manager.py
|
|
622
|
-
|
|
623
|
-
# Uso con archivo específico
|
|
624
|
-
python evolutia/config_manager.py --config ./evolutia_config.yaml
|
|
625
|
-
```
|
|
626
|
-
|
|
627
|
-
Ejecuta este script cada vez que agregues nuevos temas o modifiques las palabras clave en los materiales de lectura.
|
|
628
|
-
|
|
629
|
-
### Validación de Configuración (Schema)
|
|
630
|
-
|
|
631
|
-
Evolutia incluye un sistema de validación estricta para el archivo de configuración (`evolutia_config.yaml`).
|
|
632
|
-
|
|
633
|
-
- **JSON Schema**: La estructura válida se define en `evolutia/schemas/config.schema.json`.
|
|
634
|
-
- **Validación Automática**: Cada vez que ejecutas `evolutia.py` o `config_manager.py`, el sistema verifica que tu archivo de configuración cumpla con el esquema.
|
|
635
|
-
- **Errores Claros**: Si tu configuración tiene errores (campos faltantes, tipos incorrectos), el sistema detendrá la ejecución y te indicará exactamente dónde está el problema.
|
|
636
|
-
|
|
637
|
-
Esto facilita la adopción de la herramienta por nuevos usuarios, reduciendo errores de configuración inicial.
|
|
638
|
-
|
|
639
|
-
## Estructura del repositorio (Contexto)
|
|
640
|
-
|
|
641
|
-
El generador está diseñado para funcionar dentro de la estructura estándar del curso. A continuación se muestra el esquema de directorios esperado:
|
|
642
|
-
|
|
643
|
-
```
|
|
644
|
-
.
|
|
645
|
-
├── tema1/ # Carpeta del primer tema (ej: analisis_vectorial)
|
|
646
|
-
├── tema2/ # Carpeta del segundo tema
|
|
647
|
-
├── ... # Otros temas
|
|
648
|
-
├── tareas/ # Tareas evaluadas (fuente de ejercicios)
|
|
649
|
-
├── proyecto/ # Enunciados de proyectos
|
|
650
|
-
├── examenes/ # Directorio de salida para exámenes generados
|
|
651
|
-
├── evolutia/ # Este sistema de generación
|
|
652
|
-
├── myst.yml # Configuración del sitio Curvenote
|
|
653
|
-
└── programa-curso.md # Información general del curso
|
|
654
|
-
```
|
|
655
|
-
|
|
656
|
-
### Estructura interna de cada tema
|
|
657
|
-
|
|
658
|
-
Cada carpeta de tema (ej: `tema1/`) debe seguir una estructura similar para que el extractor encuentre los materiales:
|
|
659
|
-
|
|
660
|
-
```
|
|
661
|
-
tema1/
|
|
662
|
-
├── semana1_lectura.md # Material teoría (puede contener ejemplos)
|
|
663
|
-
├── semana1_practica.md # Ejercicios de práctica
|
|
664
|
-
├── semana2_lectura.md
|
|
665
|
-
├── semana2_practica.md
|
|
666
|
-
└── otros_archivos.md # Otros materiales complementarios
|
|
667
|
-
```
|
|
668
|
-
|
|
669
|
-
## Estructura del código (generador)
|
|
670
|
-
|
|
671
|
-
```
|
|
672
|
-
evolutia/
|
|
673
|
-
├── evolutia.py # Script principal (CLI Wrapper)
|
|
674
|
-
├── evolutia_engine.py # Motor central de orquestación
|
|
675
|
-
├── config_manager.py # Gestor de configuración automática
|
|
676
|
-
├── material_extractor.py # Extracción de materiales
|
|
677
|
-
├── exercise_analyzer.py # Análisis de complejidad
|
|
678
|
-
├── variation_generator.py # Generación de variaciones
|
|
679
|
-
├── llm_providers.py # Proveedores de LLM (OpenAI, Anthropic, Gemini, Local)
|
|
680
|
-
├── complexity_validator.py # Validación de complejidad
|
|
681
|
-
├── exam_generator.py # Generación de archivos
|
|
682
|
-
├── rag/ # Sistema RAG (opcional)
|
|
683
|
-
│ ├── rag_indexer.py # Indexación de materiales
|
|
684
|
-
│ ├── rag_retriever.py # Búsqueda semántica
|
|
685
|
-
│ ├── context_enricher.py # Enriquecimiento de contexto
|
|
686
|
-
│ ├── enhanced_variation_generator.py # Generador con RAG
|
|
687
|
-
│ ├── consistency_validator.py # Validación de consistencia
|
|
688
|
-
│ └── rag_manager.py # Gestor principal
|
|
689
|
-
├── storage/
|
|
690
|
-
│ └── vector_store/ # Base de datos vectorial (RAG)
|
|
691
|
-
├── config/
|
|
692
|
-
│ └── config.yaml # Configuración
|
|
693
|
-
├── templates/
|
|
694
|
-
│ ├── exam_template.md # Plantilla de examen
|
|
695
|
-
│ └── exercise_template.md # Plantilla de ejercicio
|
|
696
|
-
├── utils/
|
|
697
|
-
│ ├── markdown_parser.py # Parser de Markdown
|
|
698
|
-
│ ├── math_extractor.py # Extracción de matemáticas
|
|
699
|
-
│ └── json_parser.py # Parser robusto de JSON (LaTeX friendly)
|
|
700
|
-
├── requirements.txt # Dependencias
|
|
701
|
-
└── README.md # Esta documentación
|
|
702
|
-
```
|
|
703
|
-
|
|
704
|
-
## Contribuciones
|
|
705
|
-
|
|
706
|
-
Para mejorar el sistema:
|
|
707
|
-
|
|
708
|
-
1. Ajusta los prompts en `variation_generator.py` para mejor generación
|
|
709
|
-
2. Agrega nuevos patrones de conceptos en `exercise_analyzer.py`
|
|
710
|
-
3. Mejora las métricas de complejidad en `complexity_validator.py`
|
|
711
|
-
4. Personaliza las plantillas en `templates/`
|
|
712
|
-
|
|
713
|
-
## Licencia
|
|
714
|
-
|
|
715
|
-
Este proyecto está bajo la Licencia Apache 2.0. Consulta el archivo [LICENSE](LICENSE) para más detalles.
|
|
716
|
-
|
|
717
|
-
## Reconocimientos
|
|
718
|
-
|
|
719
|
-
Este proyecto fue desarrollado utilizando asistencia de Inteligencia Artificial:
|
|
720
|
-
|
|
721
|
-
- **Cursor**: Entorno de desarrollo asistido por IA.
|
|
722
|
-
- **Antigravity** (Google DeepMind): Agente de codificación y planificación avanzado.
|
|
723
|
-
|
|
File without changes
|
|
File without changes
|