Primera fase: se construyen las funciones para las primeras 12 preguntas

This commit is contained in:
Mongar28
2025-10-30 11:05:14 -05:00
parent e2b027026d
commit 878ff1e9f3
16 changed files with 1953 additions and 0 deletions

207
.gitignore vendored Normal file
View File

@@ -0,0 +1,207 @@
# Byte-compiled / optimized / DLL files
__pycache__/
*.py[codz]
*$py.class
# C extensions
*.so
# Distribution / packaging
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
share/python-wheels/
*.egg-info/
.installed.cfg
*.egg
MANIFEST
# PyInstaller
# Usually these files are written by a python script from a template
# before PyInstaller builds the exe, so as to inject date/other infos into it.
*.manifest
*.spec
# Installer logs
pip-log.txt
pip-delete-this-directory.txt
# Unit test / coverage reports
htmlcov/
.tox/
.nox/
.coverage
.coverage.*
.cache
nosetests.xml
coverage.xml
*.cover
*.py.cover
.hypothesis/
.pytest_cache/
cover/
# Translations
*.mo
*.pot
# Django stuff:
*.log
local_settings.py
db.sqlite3
db.sqlite3-journal
# Flask stuff:
instance/
.webassets-cache
# Scrapy stuff:
.scrapy
# Sphinx documentation
docs/_build/
# PyBuilder
.pybuilder/
target/
# Jupyter Notebook
.ipynb_checkpoints
# IPython
profile_default/
ipython_config.py
# pyenv
# For a library or package, you might want to ignore these files since the code is
# intended to run in multiple environments; otherwise, check them in:
# .python-version
# pipenv
# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control.
# However, in case of collaboration, if having platform-specific dependencies or dependencies
# having no cross-platform support, pipenv may install dependencies that don't work, or not
# install all needed dependencies.
#Pipfile.lock
# UV
# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
#uv.lock
# poetry
# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control.
# This is especially recommended for binary packages to ensure reproducibility, and is more
# commonly ignored for libraries.
# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control
#poetry.lock
#poetry.toml
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
# pdm recommends including project-wide configuration in pdm.toml, but excluding .pdm-python.
# https://pdm-project.org/en/latest/usage/project/#working-with-version-control
#pdm.lock
#pdm.toml
.pdm-python
.pdm-build/
# pixi
# Similar to Pipfile.lock, it is generally recommended to include pixi.lock in version control.
#pixi.lock
# Pixi creates a virtual environment in the .pixi directory, just like venv module creates one
# in the .venv directory. It is recommended not to include this directory in version control.
.pixi
# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
__pypackages__/
# Celery stuff
celerybeat-schedule
celerybeat.pid
# SageMath parsed files
*.sage.py
# Environments
.env
.envrc
.venv
env/
venv/
ENV/
env.bak/
venv.bak/
# Spyder project settings
.spyderproject
.spyproject
# Rope project settings
.ropeproject
# mkdocs documentation
/site
# mypy
.mypy_cache/
.dmypy.json
dmypy.json
# Pyre type checker
.pyre/
# pytype static type analyzer
.pytype/
# Cython debug symbols
cython_debug/
# PyCharm
# JetBrains specific template is maintained in a separate JetBrains.gitignore that can
# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore
# and can be added to the global gitignore or merged into this file. For a more nuclear
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
#.idea/
# Abstra
# Abstra is an AI-powered process automation framework.
# Ignore directories containing user credentials, local state, and settings.
# Learn more at https://abstra.io/docs
.abstra/
# Visual Studio Code
# Visual Studio Code specific template is maintained in a separate VisualStudioCode.gitignore
# that can be found at https://github.com/github/gitignore/blob/main/Global/VisualStudioCode.gitignore
# and can be added to the global gitignore or merged into this file. However, if you prefer,
# you could uncomment the following to ignore the entire vscode folder
# .vscode/
# Ruff stuff:
.ruff_cache/
# PyPI configuration file
.pypirc
# Cursor
# Cursor is an AI-powered code editor. `.cursorignore` specifies files/directories to
# exclude from AI features like autocomplete and code analysis. Recommended for sensitive data
# refer to https://docs.cursor.com/context/ignore-files
.cursorignore
.cursorindexingignore
# Marimo
marimo/_static/
marimo/_lsp/
__marimo__/

1
.python-version Normal file
View File

@@ -0,0 +1 @@
3.12.7

View File

@@ -0,0 +1 @@
,mongar,mongar,28.10.2025 15:08,file:///home/mongar/.config/libreoffice/4;

BIN
entrada_base.ods Normal file

Binary file not shown.

0
extraccion/__init__.py Normal file
View File

View File

@@ -0,0 +1,298 @@
from llm.context import LLMContext
from llm.config import LLMConfig
from extraccion.schemas_entidades import (
Acciones,
Temas,
Estrategias,
Factores,
Entidades,
Competencias,
Herramientas,
Mecanismos,
)
import yaml
# Cargar la configración de prompts desde el archivo .yaml
def load_prompts_config(file_path):
with open(file_path, "r") as file:
prompts_config = yaml.safe_load(file)
return prompts_config
path_prompts = "extraccion/prompts.yaml"
prompts_config = load_prompts_config(path_prompts)
context = LLMContext()
def extractor_pre_1(respuesta: str) -> Acciones:
prompt = prompts_config["prompts"]["pregunta_1"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Acciones)
acciones: list = llm_so.invoke(prompt)
lista_acciones = acciones.acciones
for accion in lista_acciones:
print("-" * 100)
print(accion.accion)
print("-" * 100)
return acciones
def extractor_pre_2(respuesta: str) -> Acciones:
prompt = prompts_config["prompts"]["pregunta_2"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Acciones)
acciones: list = llm_so.invoke(prompt)
lista_acciones = acciones.acciones
for accion in lista_acciones:
print("-" * 100)
print(accion.accion)
print("-" * 100)
return acciones
# El caso de este agente debe analizar se bien posteriormente para afinar bien el schema de datos
def extractor_pre_3(respuesta: str) -> Temas:
prompt = prompts_config["prompts"]["pregunta_3"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Temas)
temas: list = llm_so.invoke(prompt)
lista_temas = temas.temas
for tema in lista_temas:
print("-" * 100)
print(tema.tema)
print("-" * 100)
return temas
def extractor_pre_4(respuesta: str) -> Temas:
prompt = prompts_config["prompts"]["pregunta_4"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Temas)
temas: list = llm_so.invoke(prompt)
lista_temas = temas.temas
for tema in lista_temas:
print("-" * 100)
print(tema.tema)
print("-" * 100)
return temas
def extractor_pre_5(respuesta: str) -> Estrategias:
prompt = prompts_config["prompts"]["pregunta_5"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Estrategias)
estrategias: list = llm_so.invoke(prompt)
lista_estrategias = estrategias.estrategias
for estrategia in lista_estrategias:
print("-" * 100)
print(estrategia.estrategia)
print("-" * 100)
return estrategias
def extractor_pre_6(respuesta: str) -> Mecanismos:
prompt = prompts_config["prompts"]["pregunta_6"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Mecanismos)
mecanismos: list = llm_so.invoke(prompt)
lista_mecanismos = mecanismos.mecanismos
for mecanismo in lista_mecanismos:
print("-" * 100)
print(mecanismo.mecanismo)
print("-" * 100)
return mecanismos
def extractor_pre_7(respuesta: str) -> Estrategias:
prompt = prompts_config["prompts"]["pregunta_7"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Estrategias)
estrategias: list = llm_so.invoke(prompt)
lista_estrategias = estrategias.estrategias
for estrategia in lista_estrategias:
print("-" * 100)
print(estrategia.estrategia)
print("-" * 100)
return estrategias
def extractor_pre_8(respuesta: str) -> Factores:
prompt = prompts_config["prompts"]["pregunta_8"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-sonnet-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Factores)
factores: list = llm_so.invoke(prompt)
lista_factores = factores.factores
for factor in lista_factores:
print("-" * 100)
print(factor.factor)
print("-" * 100)
return factores
def extractor_pre_9(respuesta: str) -> Entidades:
prompt = prompts_config["prompts"]["pregunta_9"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Entidades)
entidades: list = llm_so.invoke(prompt)
lista_entidades = entidades.entidades
for entidad in lista_entidades:
print("-" * 100)
print(entidad.entidad)
print("-" * 100)
return entidades
def extractor_pre_10(respuesta: str) -> Competencias:
prompt = prompts_config["prompts"]["pregunta_10"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Competencias)
competencias: Competencias = llm_so.invoke(prompt)
print("\n Competencias extraídas:")
print(f"Básicas: {competencias.basicas}")
print(f"Socioemocionales: {competencias.socioemocionales}")
print(f"Ciudadanas: {competencias.ciudadanas}")
print(f"Siglo XXI: {competencias.siglo_xxi}")
return competencias
def extractor_pre_11(respuesta: str) -> Herramientas:
prompt = prompts_config["prompts"]["pregunta_11"]["prompt"].format(
respuesta=respuesta
)
config = LLMConfig(provider="anthropic", model_name="claude-haiku-4-5")
context.set_strategy(config)
llm = context.get_llm()
llm_so = llm.with_structured_output(Herramientas)
herramientas: list = llm_so.invoke(prompt)
lista_herramientas = herramientas.herramientas
for herramienta in lista_herramientas:
print("-" * 100)
print(herramienta.herramienta)
print("-" * 100)
return herramientas
respuesta = """
Cada semestre en nuestra programación están estipuladas dos capacitaciones según
las necesidades que los profesores expresen. Cuando algunos profesores participan
en fotos o seminarios deben de comprometerse a compartir lo aprendido sacando para
ello un espacio en la reunión de profesores, también deben de enviar un correo con
el certificado
"""
extractor_pre_6(respuesta)

698
extraccion/prompts.yaml Normal file
View File

@@ -0,0 +1,698 @@
prompts:
pregunta_1:
prompt: |
Ayudarás a estructurar y extraer acciones específicas de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
las acciones distintas mencionadas en la respuesta, luego reescribirlas en un formato claro y
estructurado.
Aquí está la pregunta:
<pregunta>
¿Qué acciones implementa su establecimiento educativo para garantizar el acceso de
los estudiantes a la educación media? 
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las acciones, estrategias o medidas mencionadas.
2. Extraer cada acción como un elemento separado.
3. Reescribir cada acción para que sea clara, completa y bien estructurada, preservando su significado original.
4. Asegurarte de que cada acción tenga sentido por sí sola y esté directamente relacionada con la pregunta.
Por ejemplo, si la pregunta fuera:
"¿Qué acciones implementa su establecimiento educativo para garantizar el acceso de los estudiantes a la educación?"
y la respuesta fuera:
"Realizamos voz a voz con la comunidad, anunciando antes de finalizar el año que se disponen de cupos. También se anuncia por la página web con frases motivadoras",
deberías extraer y estructurar la información así:
1. Realizan comunicación directa con la comunidad para anunciar la disponibilidad de cupos antes de finalizar el año escolar.
2. Publican anuncios en la página web institucional con mensajes motivadores para promover el acceso educativo.
Pautas para estructurar las acciones:
* Cada acción debe ser una afirmación completa y clara.
* Utiliza la tercera persona cuando sea apropiado para mantener la coherencia.
* Conserva el significado esencial mientras mejoras la claridad.
* Combina fragmentos relacionados que describan la misma acción.
* Asegúrate de que cada acción responda directamente a la pregunta planteada.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"acciones": [
{{
"accion": "string", // texto de la acción extraida de la respuesta.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_2:
prompt: |
Ayudarás a estructurar y extraer acciones específicas de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
las acciones distintas mencionadas en la respuesta, luego reescribirlas en un formato claro y
estructurado.
Aquí está la pregunta:
<pregunta>
¿Qué acciones implementa su establecimiento educativo para favorecer la permanencia de
los estudiantes? 
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las acciones, estrategias o medidas mencionadas.
2. Extraer cada acción como un elemento separado.
3. Reescribir cada acción para que sea clara, completa y bien estructurada, preservando su significado original.
4. Asegurarte de que cada acción tenga sentido por sí sola y esté directamente relacionada con la pregunta.
Por ejemplo, si la pregunta fuera:
"¿Qué acciones implementa su establecimiento educativo para favorecer la permanencia de los estudiantes?"
y la respuesta fuera:
"Destacamos el clima escolar en el colegio, la comunidad nos reconoce como un espacio acogedor , con claras normas de convivencia... Consideramos sumamente importante para lograr la permanencia el reconocimiento y valoración de todas las acciones educativas de nuestros profesores y estudiantes ya que esto aumenta la autoestima y además crea un sentido de pertenencia...",
deberías extraer y estructurar la información así:
1. Fomentan un clima escolar positivo y acogedor.
2. Establecen y mantienen normas de convivencia claras.
3. Implementan el reconocimiento y la valoración de las acciones educativas de profesores y estudiantes.
4. Desarrollan estrategias para fortalecer el sentido de pertenencia y la autoestima de los estudiantes.
Pautas para estructurar las acciones:
* Cada acción debe ser una afirmación completa y clara.
* Utiliza la tercera persona cuando sea apropiado para mantener la coherencia.
* Conserva el significado esencial mientras mejoras la claridad.
* Combina fragmentos relacionados que describan la misma acción.
* Asegúrate de que cada acción responda directamente a la pregunta planteada.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"acciones": [
{{
"accion": "string", // texto de la acción extraida de la respuesta.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_3:
prompt: |
Ayudarás a estructurar y extraer información clave sobre transformaciones curriculares de respuestas
abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
el tema central de la transformación y cualquier área, asignatura o proyecto específico mencionado.
Aquí está la pregunta:
<pregunta>
¿Cuál fue el tema central de la última transformación curricular? Si fue a nivel
microcurricular, indique también qué áreas o asignaturas se incluyeron.
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar el **tema central** de la transformación curricular.
2. Identificar todas las **áreas, asignaturas o proyectos** específicos que se mencionan como incluidos o modificados.
3. Extraer cada uno de estos elementos (el tema central y cada área/proyecto) como un ítem separado.
4. Reescribir cada ítem para que sea claro, conciso y capture la esencia del componente curricular, preservando su significado original.
5. Asegurarte de que cada ítem responda directamente a la pregunta (ya sea al "tema central" o a las "áreas/asignaturas").
Por ejemplo, si la pregunta fuera:
"¿Cuál fue el tema central de la última transformación curricular? Si fue a nivel microcurricular, indique también qué áreas o asignaturas se incluyeron."
y la respuesta fuera:
"Se actualizo el PEI con el apoyo de la UdeA y la gobernación. Además se incorporaron dos proyectos pedagógicos nuevos: Huertas comunitarias y emprendimiento",
deberías extraer y estructurar la información así:
1. Tema central: Actualización del Proyecto Educativo Institucional (PEI) (con apoyo de UdeA y Gobernación).
2. Incorporación del proyecto pedagógico: Huertas comunitarias.
3. Incorporación del proyecto pedagógico: Emprendimiento.
Pautas para estructurar los ítems:
* Cada ítem debe ser una afirmación clara que identifique el componente.
* Conserva el significado esencial mientras mejoras la claridad.
* Separa el tema central de las áreas/proyectos en ítems distintos.
* Asegúrate de que cada ítem responda directamente a la pregunta planteada.
Escribe tu lista estructurada de ítems dentro de las etiquetas <structured_actions>, numerando cada ítem en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"acciones": [
{{
"accion": "string", // texto del tema central, área o proyecto extraído.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_4:
prompt: |
Ayudarás a estructurar y extraer los temas o ejes principales de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
los temas o ejes de formación docente mencionados en la respuesta.
Aquí está la pregunta:
<pregunta>
En los últimos dos años, ¿cuáles han sido los temas o ejes de interés en los
procesos de formación del equipo docente de la educación media?
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todos los **temas o ejes de formación** docente mencionados.
2. Extraer cada tema como un elemento separado.
3. Reescribir cada tema para que sea claro, conciso y capture la esencia del eje de formación, preservando su significado original.
4. Asegurarte de que cada tema responda directamente a la pregunta planteada.
Por ejemplo, si la pregunta fuera:
"En los últimos dos años, ¿cuáles han sido los temas o ejes de interés en los procesos de formación del equipo docente de la educación media?"
y la respuesta fuera:
"Todo lo que tiene que ver con los procesos de inclusión, especialmente la elaboración de PIAR ya que estos han sido muy complicado ya que no tenemos maestra de apoyo que nos ayude.",
deberías extraer y estructurar la información así:
1. Procesos de inclusión.
2. Elaboración de PIAR (Planes Individualizados de Ajustes Razonables).
Pautas para estructurar los ítems:
* Cada ítem debe ser una afirmación clara y concisa que identifique el tema.
* Conserva el significado esencial mientras mejoras la claridad.
* Separa temas distintos en ítems diferentes (p.ej., un tema general y uno específico pueden ir separados si la respuesta los distingue).
* **Importante**: Céntrate únicamente en el "qué" (el tema de formación) e ignora las justificaciones, opiniones o problemas asociados (p.ej., "porque fue difícil", "porque no tenemos apoyo").
Escribe tu lista estructurada de ítems dentro de las etiquetas <structured_actions>, numerando cada ítem en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"acciones": [
{{
"accion": "string", // texto del tema o eje de formación extraído.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_5:
prompt: |
Ayudarás a estructurar y extraer estrategias específicas de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
las estrategias o métodos mencionados en la respuesta que se utilizan para identificar necesidades.
Aquí está la pregunta:
<pregunta>
¿Qué estrategias utiliza su establecimiento para identificar las necesidades de
formación del equipo docente de la educación media?
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las **estrategias, métodos o acciones** utilizados para *identificar* necesidades de formación.
2. Extraer cada estrategia como un elemento separado.
3. Reescribir cada estrategia para que sea clara, completa y bien estructurada, preservando su significado original.
4. Asegurarte de que cada estrategia responda directamente a la pregunta (es decir, que sea un método de identificación).
Por ejemplo, si la pregunta fuera:
"¿Qué estrategias utiliza su establecimiento para identificar las necesidades de formación del equipo docente de la educación media?"
y la respuesta fuera:
"Generalmente hacemos encuestas internas para saber que quieren aprender o profundizar . También cuando hay oferta de formación por ejemplo por las caja de compensación nos damos cuenta cuales son en los que más se inscriben y asi vamos ofreciendo otras alternativas complementarias",
deberías extraer y estructurar la información así:
1. Realizar encuestas internas para consultar a los docentes sobre sus intereses de aprendizaje o profundización.
2. Analizar las tendencias de inscripción del personal docente en ofertas de formación externas (p.ej., cajas de compensación) para identificar temas de alta demanda.
Pautas para estructurar las estrategias:
* Cada estrategia debe ser una afirmación completa y clara que describa el método.
* Escribe cada estrategia comenzando con un verbo en infinitivo (p.g., "Realizar", "Analizar") para mantener la coherencia.
* Conserva el significado esencial mientras mejoras la claridad.
* **Importante**: Céntrate únicamente en *cómo identifican* las necesidades (el método de diagnóstico). Ignora las acciones que toman *después* de identificarlas (p.ej., "ofrecer alternativas complementarias").
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"estrategias": [
{{
"estrategia": "string", // texto de la estrategia de identificación extraída (en infinitivo).
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_6:
prompt: |
Ayudarás a estructurar y extraer mecanismos de seguimiento de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
los mecanismos o procesos de seguimiento mencionados en la respuesta.
Aquí está el enunciado (pregunta):
<pregunta>
¿El establecimiento educativo tiene mecanismos de seguimiento a los procesos de WELCOME.
actualización y/o capacitación del equipo docente de la media? Si la respuesta
anterior fue si, comunique cómo se realiza dicho proceso.
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todos los **mecanismos o procesos** utilizados para *realizar el seguimiento* a la formación docente.
2. Extraer cada mecanismo como un elemento separado.
3. Reescribir cada mecanismo para que sea claro, completo y describa el proceso de seguimiento.
4. Asegurarte de que cada mecanismo responda directamente a la segunda parte de la pregunta ("cómo se realiza dicho proceso").
Por ejemplo, si la pregunta fuera:
"¿El establecimiento educativo tiene mecanismos de seguimiento...? Si la respuesta anterior fue si, comunique cómo se realiza dicho proceso."
y la respuesta fuera:
"Cada semestre en nuestra programación están estipuladas dos capacitaciones según las necesidades que los profesores expresen. Cuando algunos profesores participan en fotos o seminarios deben de comprometerse a compartir lo aprendido sacando para ello un espacio en la reunión de profesores, también deben de enviar un correo con el certificado",
deberías extraer y estructurar la información así:
1. Exigir a los docentes que participan en foros o seminarios que compartan lo aprendido en la reunión de profesores.
2. Solicitar a los docentes el envío de un correo con el certificado de la formación recibida.
Pautas para estructurar los mecanismos:
* Cada mecanismo debe ser una afirmación completa y clara que describa el proceso.
* Escribe cada mecanismo comenzando con un verbo en infinitivo (p.g., "Exigir", "Solicitar", "Realizar").
* **Importante**: Céntrate únicamente en el *seguimiento*, *socialización* o *verificación* posterior a la formación. Ignora la descripción de la programación o la capacitación en sí misma (p.ej., "Cada semestre... dos capacitaciones").
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"mecanismos": [
{{
"mecanismo": "string", // texto del mecanismo de seguimiento extraído (en infinitivo).
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_7:
prompt: |
Ayudarás a estructurar y extraer estrategias específicas de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea será identificar
las estrategias o acciones mencionadas en la respuesta que se utilizan para apoyar el tránsito
de estudiantes.
Aquí está la pregunta:
<pregunta>
¿Qué estrategias son implementadas en el establecimiento educativo para garantizar
el tránsito efectivo de la educación básica a la media?
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las **estrategias, métodos o acciones** utilizados para *garantizar el tránsito* de la básica a la media.
2. Extraer cada estrategia como un elemento separado.
3. Reescribir cada estrategia para que sea clara, completa y bien estructurada, preservando su significado original.
4. Asegurarte de que cada estrategia responda directamente a la pregunta.
Por ejemplo, si la pregunta fuera:
"¿Qué estrategias son implementadas en el establecimiento educativo para garantizar el tránsito efectivo de la educación básica a la media?"
y la respuesta fuera:
"Tenemos charlas con los estudiantes mediados del tercer trimestre y ya finalizando el cuarto, allí les explicamos las ventajas
de continuar en el proceso formativo. También el la última reunión se cita a los padres de familia y a egresados para que los
motiven a continuar con el proceso educativo. Es importante anotar que hace 4 años se realizó un proyectos educativo donde se
involucro a toda la básica secundaria para que conocieran y aprendiera que era la educación media, esto fue producto de un trabajo
de maestría de una de las profesoras de la IE.",
deberías extraer y estructurar la información así:
1. Realizar charlas con los estudiantes (entre el tercer y cuarto trimestre) para explicar las ventajas de continuar el proceso formativo.
2. Citar a padres de familia y egresados a la última reunión para motivar la continuidad en el proceso educativo.
3. Desarrollar un proyecto educativo para involucrar a toda la básica secundaria en el conocimiento de la educación media.
Pautas para estructurar las estrategias:
* Cada estrategia debe ser una afirmación completa y clara que describa la acción.
* Escribe cada estrategia comenzando con un verbo en infinitivo (p.g., "Realizar", "Citar", "Desarrollar").
* Conserva el significado esencial mientras mejoras la claridad.
* Extrae todas las estrategias mencionadas, independientemente del tiempo al que se refiera la respuesta (p.ej., "hace 4 años se realizó..."), ya que son parte de la respuesta del encuestado.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"estrategias": [
{{
"estrategia": "string", // texto de la estrategia de tránsito extraída (en infinitivo).
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_8:
prompt: |
Ayudarás a estructurar y extraer factores clave de respuestas abiertas de encuestas.
Se te proporcionará una pregunta y una respuesta correspondiente, y tu tarea es identificar
los factores sociales, culturales o económicos (las CAUSAS) mencionados en la respuesta que afectan
a los estudiantes.
Aquí está la pregunta:
<pregunta>
¿Cuáles son los principales factores sociales, culturales o económicos que afectan
el tránsito y permanencia de los estudiantes en la educación media en su institución?
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todos los **factores (CAUSAS)** sociales, culturales o económicos mencionados.
2. Extraer cada factor (CAUSA) como un elemento separado.
3. Reescribir el factor para que sea claro y completo.
4. Asegurarte de que cada ítem sea una **CAUSA** (un factor que origina el problema), y no un **EFECTO** (una consecuencia).
Por ejemplo, si la pregunta fuera:
"¿Cuáles son los principales factores sociales, culturales o económicos que afectan el tránsito y permanencia de los estudiantes en la educación media en su institución?"
y la respuesta fuera:
"El más marcado en los últimos 4 años han sido el surgimiento de los creadores de contenido, muchos estudiantes ya ven esta acción como una alternativa económica. Pese a que hay cupos, se les motiva y se les muestran ejemplos de egresados , deciden trabajar en esta modalidad y si algunos empiezan su permanencia es corta.",
deberías extraer y estructurar la información así:
1. El surgimiento de los "creadores de contenido" (influencers) como una alternativa económica percibida por los estudiantes.
Pautas para estructurar los factores:
* **REGLA DE ORO: Extraer la CAUSA, no el EFECTO.**
* **CAUSA (SÍ extraer):** "El surgimiento de los creadores de contenido".
* **EFECTO (NO extraer):** "La permanencia es corta" o "los estudiantes deciden trabajar". La pregunta es sobre *qué* afecta, no sobre *cuál es el resultado* de esa afectación.
* **Combinar en un solo ítem:** Si el texto describe el factor (p.ej., "surgimiento de creadores") y su percepción (p.ej., "los estudiantes lo ven como alternativa"), combínalos en un solo ítem. No los extraigas como dos factores separados.
* **Ignorar estrategias de mitigación:** Ignora cualquier acción que el establecimiento mencione para mitigar el factor (p.ej., "se les motiva", "se les muestran ejemplos").
* **Evitar interpretaciones:** No generes interpretaciones abstractas o generalizaciones que no estén explícitamente en el texto.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"factores": [
{{
"factor": "string", // texto del factor (CAUSA) social, cultural o económico extraído.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_9:
prompt: |
Ayudarás a estructurar y extraer una lista de programas o alianzas de respuestas abiertas de encuestas.
Se te proporcionará un enunciado y una respuesta correspondiente, y tu tarea será identificar
los programas, alianzas, convenios o vínculos específicos mencionados en la respuesta.
Aquí está el enunciado (pregunta):
<pregunta>
Indique cuáles programas de articulación o alianzas, convenios o vínculos para
fortalecer la educación media
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todos los **programas, alianzas, convenios o vínculos** específicos mencionados.
2. Extraer cada programa o alianza como un elemento separado.
3. Reescribir cada ítem para que describa claramente el programa o vínculo, preservando su significado original.
4. Asegurarte de que cada ítem responda directamente a la pregunta (es decir, que sea un programa o alianza).
Por ejemplo, si la pregunta fuera:
"Indique cuáles programas de articulación o alianzas, convenios o vínculos para fortalecer la educación media"
y la respuesta fuera:
"Actualmente se cuenta con la presencia de prácticas de la Licenciatura de Lengua Castellana del Tecnológico de Antioquia. También la casa de la cultura ha realizado talleres de artes y oficios en alianza con el SENA y la secretaria de educación organizo hace 2 años la feria de oferta academica para educación superior con la Universidad Cooperativa",
deberías extraer y estructurar la información así:
1. Prácticas de la Licenciatura de Lengua Castellana del Tecnológico de Antioquia.
2. Talleres de artes y oficios realizados por la Casa de la Cultura en alianza con el SENA.
3. Feria de oferta académica para educación superior con la Universidad Cooperativa (organizada por la Secretaría de Educación).
Pautas para estructurar los ítems:
* Cada ítem debe ser una descripción clara y concisa del programa o alianza.
* Incluye las entidades externas involucradas (p.ej., SENA, Tecnológico de Antioquia) si el texto las menciona como parte de la alianza.
* Separa cada programa, convenio o alianza distinta en un ítem nuevo.
* No es necesario usar verbos en infinitivo; el objetivo es listar los programas.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"entidades": [
{{
"entidad": "string", // texto del programa, alianza o convenio extraído.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_10:
prompt: |
Ayudarás a estructurar y extraer una lista de competencias específicas de respuestas abiertas de encuestas.
Se te proporcionará un enunciado y una respuesta correspondiente, y tu tarea será identificar
cada competencia mencionada y la categoría a la que pertenece.
Aquí está el enunciado (pregunta):
<pregunta>
Describa cuáles competencias básicas, socioemocionales, ciudadanas y del siglo XXI
se fortalecen en el establecimiento educativo
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las **competencias específicas** mencionadas.
2. Identificar la **categoría** a la que pertenece cada competencia (Básicas, Socioemocionales, Ciudadanas, o Siglo XXI), basándote en el contexto de la respuesta.
3. Extraer cada competencia individual como un elemento separado, incluso si se mencionan juntas (p.ej., "matemáticas y lenguaje").
4. Reescribir cada ítem para que indique claramente la categoría y la competencia.
Por ejemplo, si la pregunta fuera:
"Describa cuáles competencias básicas, socioemocionales, ciudadanas y del siglo XXI se fortalecen en el establecimiento educativo"
y la respuesta fuera:
"Como respondimos anteriormente en las competencias básicas dedicamos un ben tiempo a trabajar las matemáticas y lenguaje. En lo que se refiere a las socio emocionales le damos muy fuerte a lo que se refiere la toma de decisiones y autoconocimiento, ya que como personas no puedo proponer algo productivo si yo no me conozco como persona. Y en lo que se refiere a las del S.XXI fortalecemos pensamiento critico y resolución de problemas principalmente, ya que se articula con todas las anteriores.",
deberías extraer y estructurar la información así:
1. Competencias básicas: Matemáticas.
2. Competencias básicas: Lenguaje.
3. Competencias socioemocionales: Toma de decisiones.
4. Competencias socioemocionales: Autoconocimiento.
5. Competencias del Siglo XXI: Pensamiento crítico.
6. Competencias del Siglo XXI: Resolución de problemas.
Pautas para estructurar los ítems:
* Cada ítem debe seguir el formato: **[Categoría]: [Competencia]**.
* Separa cada competencia en un ítem nuevo. Si la respuesta dice "matemáticas y lenguaje", debes crear dos ítems.
* **Importante**: Céntrate únicamente en *cuáles* son las competencias. Ignora todo el texto de relleno, justificaciones u opiniones (p.ej., "dedicamos un ben tiempo a", "le damos muy fuerte a", "ya que como personas...", "ya que se articula con...").
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"competencias": [
{{
"básicas": [lista de stings"], // Lista de competencias básicas
"socioemocionales": [lista de stings"], // Lista de competencias sociemocionales
"ciudadanas": [lista de stings"], // Lista de competencias ciudadanas
"siglo_xxi": [lista de stings"], // Lista de competencias siglo_xxi
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_11:
prompt: |
Ayudarás a estructurar y extraer una lista de herramientas específicas de respuestas abiertas de encuestas.
Se te proporcionará un enunciado y una respuesta correspondiente, y tu tarea será identificar
las herramientas evaluativas mencionadas en la respuesta.
Aquí está el enunciado (pregunta):
<pregunta>
Mencione cuáles herramientas evaluativas se utilizan (ej. pruebas internas, rúbricas,
portafolios, observación en aula, otros)
</pregunta>
Aquí está la respuesta a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la respuesta e identificar todas las **herramientas evaluativas** específicas mencionadas.
2. Extraer cada herramienta como un elemento separado.
3. Reescribir cada ítem para que sea claro, conciso y nombre la herramienta.
4. Asegurarte de que cada ítem responda directamente a la pregunta.
Por ejemplo, si la pregunta fuera:
"Mencione cuáles herramientas evaluativas se utilizan (ej. pruebas internas, rúbricas, portafolios, observación en aula, otros)"
y la respuesta fuera:
"Por ahora solo usamos la observación en el aula y esta se refleja en los diarios de campo que solicitamos a los maestros cada dos meses",
deberías extraer y estructurar la información así:
1. Observación en el aula.
2. Diarios de campo.
Pautas para estructurar los ítems:
* Cada ítem debe ser el nombre claro y conciso de la herramienta evaluativa.
* Separa cada herramienta en un ítem nuevo.
* **Importante**: Céntrate únicamente en *cuál* es la herramienta. Ignora cualquier texto de relleno, contexto, frecuencia o detalles de implementación (p.ej., "Por ahora solo usamos", "esta se refleja en", "que solicitamos... cada dos meses").
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"herramientas": [
{{
"herramienta": "string", // texto de la herramienta evaluativa extraída.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional
pregunta_12:
prompt: |
Ayudarás a estructurar y extraer los puntos clave, razones o ejemplos de una respuesta abierta de explicación.
Se te proporcionará una instrucción (la pregunta a la que responde el texto) y una respuesta
correspondiente (la explicación), y tu tarea será identificar los puntos clave de esa explicación.
Aquí está la instrucción (pregunta) a la que responde el texto:
<pregunta>
Explique brevemente su respuesta anterior [sobre la pertinencia del currículo],
señale ejemplos.
</pregunta>
Aquí está la respuesta (la explicación) a analizar:
<respuesta>
{respuesta}
</respuesta>
Tu tarea es:
1. Leer cuidadosamente la explicación e identificar las **razones, justificaciones o ejemplos** clave que la persona da.
2. Extraer cada razón, fortaleza, debilidad o ejemplo clave como un elemento separado.
3. Reescribir cada ítem para que sea claro, conciso y capture la esencia del punto de la explicación.
4. Asegurarte de que cada ítem responda directamente a la instrucción ("Explique...").
Por ejemplo, si la instrucción fuera:
"Explique brevemente su respuesta anterior [sobre la pertinencia del currículo], señale ejemplos."
y la respuesta (explicación) fuera:
"Responde bien a las aspiraciones de los estudiantes porque incluimos una media técnica en software que es lo que ellos piden. Pero falla en responder al contexto regional, ya que nuestra región es agrícola y no tenemos proyectos en ese frente.",
deberías extraer y estructurar la información así:
1. El currículo responde a las aspiraciones de los estudiantes al incluir una media técnica en software.
2. El currículo falla en responder al contexto regional (agrícola) al no tener proyectos en ese frente.
Pautas para estructurar los ítems:
* Cada ítem debe ser una afirmación clara que resuma una razón, un ejemplo, una fortaleza o una debilidad mencionada en la explicación.
* Céntrate en el "por qué" (la explicación y los ejemplos).
* Separa las ideas distintas (p.ej., una fortaleza y una debilidad) en ítems diferentes.
Escribe tu lista estructurada de acciones dentro de las etiquetas <structured_actions>, numerando cada acción en una línea separada.
# ESTRUCTURA DE SALIDA
{{
"percepcioones": [
{{
"accion": "string", // texto del punto clave, razón o ejemplo extraído de la explicación.
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las acciones
- No incluir texto explicativo adicional

View File

@@ -0,0 +1,101 @@
from pydantic import BaseModel, Field
from typing import Optional
class Accion(BaseModel):
accion: str = Field(..., description="Texto de la accion extraida de la respuesta.")
class Acciones(BaseModel):
acciones: list[Accion] = Field(
..., description="Lista de acciones extraidas de la respuesta."
)
class Tema(BaseModel):
tema: str = Field(..., description="Texto del tema extraido de la respuesta.")
class Temas(BaseModel):
temas: list[Tema] = Field(
..., description="Lista de temas extraidos de la respuesta."
)
class Estrategia(BaseModel):
estrategia: str = Field(
..., description="Texto de la estrategia extraida de la respuesta."
)
class Estrategias(BaseModel):
estrategias: list[Estrategia] = Field(
..., description="Lista de estrategias extraidas de la respuesta."
)
class Factor(BaseModel):
factor: str = Field(..., description="Texto del factor extraido de la respuesta.")
class Factores(BaseModel):
factores: list[Factor] = Field(
..., description="Lista de factores extraidos de la respuesta."
)
class Entidad(BaseModel):
entidad: str = Field(
...,
description="Texto del programa, alianza o convenio extraido de la respuesta.",
)
class Entidades(BaseModel):
entidades: list[Entidad] = Field(
...,
description="Lista de entidades ( programa, alianza o convenio) extraidas de la respuesta.",
)
class Competencias(BaseModel):
basicas: Optional[list[str]] = Field(
default_factory=list, description="Lista de competencias básicas"
)
socioemocionales: Optional[list[str]] = Field(
default_factory=list, description="Lista de competencias socioemocionales"
)
ciudadanas: Optional[list[str]] = Field(
default_factory=list, description="Lista de competencias ciudadanas"
)
siglo_xxi: Optional[list[str]] = Field(
default_factory=list, description="Lista de competencias siglo_xxi"
)
class Herramienta(BaseModel):
herramienta: str = Field(
...,
description="Texto de la herramienta extraida de la respuesta.",
)
class Herramientas(BaseModel):
herramientas: list[Herramienta] = Field(
...,
description="Lista de herramientas extraidas de la respuesta.",
)
class Mecanismo(BaseModel):
mecanismo: str = Field(
...,
description="Texto del mecanismo extraido de la respuesta.",
)
class Mecanismos(BaseModel):
mecanismos: list[Mecanismo] = Field(
...,
description="Lista de mecanismos extraidas de la respuesta.",
)

3
llm/__init__.py Normal file
View File

@@ -0,0 +1,3 @@
"""
Archivo __init__.py para marcar el directorio como un paquete Python.
"""

78
llm/config.py Normal file
View File

@@ -0,0 +1,78 @@
"""
Módulo para la configuración de modelos de lenguaje.
Este módulo proporciona clases para manejar la configuración
de diferentes modelos de lenguaje de manera estructurada.
"""
from typing import Dict, Any, Optional
class LLMConfig:
"""
Clase para manejar la configuración de los modelos de lenguaje.
Esta clase encapsula todos los parámetros necesarios para crear
un modelo de lenguaje, facilitando su gestión y reutilización.
"""
def __init__(
self,
provider: str,
model_name: Optional[str] = None,
temperature: float = 0.0,
**kwargs
):
"""
Inicializa una configuración para un modelo de lenguaje.
Args:
provider: Proveedor del modelo (openai, anthropic)
model_name: Nombre del modelo específico (opcional)
temperature: Temperatura para la generación (default: 0.0)
**kwargs: Parámetros adicionales específicos del modelo
"""
self.provider = provider
self.model_name = model_name
self.temperature = temperature
self.extra_params = kwargs
def as_dict(self) -> Dict[str, Any]:
"""
Convierte la configuración a un diccionario.
Returns:
Diccionario con todos los parámetros de configuración
"""
config = {
"temperature": self.temperature,
}
# Añadir el nombre del modelo si está definido
if self.model_name:
config["model_name"] = self.model_name
# Añadir parámetros adicionales
config.update(self.extra_params)
return config
@classmethod
def default_openai(cls) -> 'LLMConfig':
"""
Crea una configuración predeterminada para OpenAI.
Returns:
Configuración predeterminada para OpenAI
"""
return cls(provider="openai", model_name="o4-mini")
@classmethod
def default_anthropic(cls) -> 'LLMConfig':
"""
Crea una configuración predeterminada para Anthropic.
Returns:
Configuración predeterminada para Anthropic
"""
return cls(provider="anthropic", model_name="claude-3-5-haiku-20241022")

110
llm/context.py Normal file
View File

@@ -0,0 +1,110 @@
"""
Módulo que implementa el contexto del patrón Strategy para modelos de lenguaje.
Este módulo contiene la clase LLMContext que mantiene una referencia a la
estrategia actual y delega en ella la creación del modelo de lenguaje.
"""
from typing import Dict, Any, Optional
from .strategies import (
LLMStrategy,
OpenAIO4MiniStrategy,
OpenAIGPT41MiniStrategy,
AnthropicHaikuStrategy,
AnthropicSonnet37Strategy,
AnthropicHaiku45Strategy,
)
from .config import LLMConfig
class LLMContext:
"""
Contexto que utiliza diferentes estrategias para crear modelos de lenguaje.
Esta clase es el punto central de interacción con el sistema de modelos.
Mantiene una referencia a la estrategia actual y delega la creación
del modelo a dicha estrategia.
"""
def __init__(self):
"""
Inicializa el contexto con las estrategias disponibles.
"""
# Mapeo de proveedores y modelos a estrategias
self._strategies = {
"openai": {
"o4-mini": OpenAIO4MiniStrategy(),
"gpt-4.1-mini": OpenAIGPT41MiniStrategy(),
},
"anthropic": {
"claude-3-5-haiku-20241022": AnthropicHaikuStrategy(),
"claude-sonnet-4-5": AnthropicSonnet37Strategy(),
"claude-haiku-4-5": AnthropicHaiku45Strategy(),
},
}
self._current_strategy: Optional[LLMStrategy] = None
self._config: Optional[Dict[str, Any]] = None
def set_strategy(self, config: LLMConfig) -> None:
"""
Establece la estrategia actual basada en la configuración.
Args:
config: Configuración del modelo
Raises:
ValueError: Si el proveedor o modelo no están soportados
"""
provider = config.provider.lower()
# Verificar que el proveedor es válido
if provider not in self._strategies:
raise ValueError(f"Proveedor no soportado: {provider}")
# Si se especificó un modelo, usarlo
if config.model_name:
model_name = config.model_name
if model_name not in self._strategies[provider]:
raise ValueError(f"Modelo no soportado para {provider}: {model_name}")
self._current_strategy = self._strategies[provider][model_name]
else:
# Si no se especificó un modelo, usar el primero disponible
self._current_strategy = next(iter(self._strategies[provider].values()))
# Guardar la configuración
self._config = config.as_dict()
def get_llm(self):
"""
Crea y devuelve un modelo de lenguaje usando la estrategia actual.
Returns:
Instancia del modelo de lenguaje
Raises:
ValueError: Si no se ha establecido una estrategia
"""
if not self._current_strategy:
raise ValueError("No se ha establecido una estrategia")
return self._current_strategy.create_llm(self._config)
def register_strategy(
self, provider: str, model_name: str, strategy: LLMStrategy
) -> None:
"""
Registra una nueva estrategia.
Args:
provider: Nombre del proveedor (openai, anthropic)
model_name: Nombre del modelo
strategy: Instancia de la estrategia a registrar
"""
provider = provider.lower()
# Crear el diccionario del proveedor si no existe
if provider not in self._strategies:
self._strategies[provider] = {}
# Registrar la estrategia
self._strategies[provider][model_name] = strategy

131
llm/strategies.py Normal file
View File

@@ -0,0 +1,131 @@
"""
Módulo que define la interfaz de estrategia y las implementaciones concretas
para diferentes modelos de lenguaje (LLM).
"""
from abc import ABC, abstractmethod
from langchain_openai import ChatOpenAI
from langchain_anthropic import ChatAnthropic
from typing import Any, Dict, Optional
from dotenv import load_dotenv
load_dotenv()
# 1.Interfaz de la estrategia
class LLMStrategy(ABC):
"""Interfaz para todas las estrategias de modelos de lenguaje.
Esta clase define la interfaz commún que todas las estrategias
concretas deben implementar.
"""
@abstractmethod
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> Any:
"""Crea una instancia de modelo de lenguaje según la configuración.
Args:
config: Diccionario con la configuración del modelo.
Returns:
Instancia del modelo de lenguaje.
"""
pass
class OpenAIO4MiniStrategy(LLMStrategy):
"""Estrategia para el modelo OpenAI o4-mini"""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatOpenAI:
"""
Implementación concreta para crear un modelo OpenAI o4-mini
Args:
config: Configuración opcional para el modelo (no utilizada)
Returns:
ChatOpenAI: Instancia del modelo o4-mini
"""
# Para o4-mini solo pasamos el nombre del modelo sin parámetros adicionales
return ChatOpenAI(model="o4-mini")
class OpenAIGPT41MiniStrategy(LLMStrategy):
"""Estrategia para el modelo OpenAI GPT-4.1-mini."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatOpenAI:
"""
Implementación concreta para crear un modelo OpenAI GPT-4.1-mini.
Args:
config: Configuración opcional para el modelo
Returns:
ChatOpenAI: Una instancia del modelo gpt-4.1-mini
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatOpenAI(
model="gpt-4.1-mini",
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)
class AnthropicHaikuStrategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude 3.5 Haiku."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude 3.5 Haiku.
Args:
config: Configuración opcional para el modelo
Returns:
ChatAnthropic: Una instancia del modelo claude-3-5-haiku
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatAnthropic(
model="claude-3-5-haiku-20241022",
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)
class AnthropicSonnet37Strategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude 4.5 Sonnet."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude 4.5 Sonnet.
Args:
config: Configuración opcional para el modelo (no utilizada)
Returns:
ChatAnthropic: Una instancia del modelo claude-sonnet-4-5
"""
return ChatAnthropic(model="claude-sonnet-4-5")
class AnthropicHaiku45Strategy(LLMStrategy):
"""Estrategia para el modelo Anthropic Claude Haiku 4-5."""
def create_llm(self, config: Optional[Dict[str, Any]] = None) -> ChatAnthropic:
"""
Implementación concreta para crear un modelo Anthropic Claude Haiku 4-5.
Args:
config: Configuración opcional para el modelo
Returns:
ChatAnthropic: Una instancia del modelo claude-haiku-4-5
"""
config = config or {}
temperature = config.get("temperature", 0.0)
return ChatAnthropic(
model="claude-haiku-4-5", # <-- Nombre exacto del modelo
temperature=temperature,
**{k: v for k, v in config.items() if k != "temperature"},
)

BIN
preguntas_abiertas.ods Normal file

Binary file not shown.

298
prompts.yaml Normal file
View File

@@ -0,0 +1,298 @@
prompts:
categorizador:
prompt: |
# CONTEXTO Y OBJETIVO
Actúa como un experto en análisis cualitativo. Tu tarea es analizar un conjunto de aproximadamente 60 verbatims para
identificar y categorizar patrones significativos, considerando el contexto específico del proyecto de investigación
proporcionado.
# ENTRADAS
- Verbatims:
{grupo_verbatims}
- Contexto del Proyecto:
{info_proyecto}
# INSTRUCCIONES DE CATEGORIZACIÓN
1. Analiza detenidamente la información del proyecto.
2. Examina cuidadosamente cada verbatim.
3. Identifica ideas, patrones y temas recurrentes.
4. Agrupar los verbatims en función estas ideas, patrones y temas.
5. Construir nombres para cada uno de los grupos, y deben ser:
- Sean relevantes para los objetivos del proyecto
- Capturen las ideas, patrones y dimensiones principales de los verbatims
- Sean mutuamente excluyentes
- Tengan nombres concisos pero descriptivos
# CRITERIOS DE CALIDAD
- Relevancia: Cada categoría debe aportar valor al análisis según los objetivos del proyecto
- Claridad: Usar nombres inequívocos y descripciones precisas
- Completitud: Asegurar que cada verbatim pueda ser asociado a una categoría
- Coherencia: Mantener un nivel consistente de especificidad entre categorías
# ESTRUCTURA DE SALIDA
{{
"categorias": [
{{
"nombre": "string", // Nombre conciso y descriptivo
"descripcion": "string", // Explicación clara del tipo de verbatims que incluye
"observables": "string" // Indicadores específicos para identificar la categoría en verbatims)
}}
]
}}
# RESTRICCIONES
- Entregar únicamente el JSON con las categorías
- No incluir texto explicativo adicional
- No hacer referencia a verbatims específicos en las descripciones
- Mantener consistencia en el nivel de abstracción entre categorías
conciliador:
prompt: |
# CONTEXTO Y OBJETIVO
Actúa como un experto en análisis cualitativo especializado en la armonización de categorías.
Tu tarea es identificar y unificar ÚNICAMENTE categorías que se refieren al mismo fenómeno pero con
denominaciones diferentes, manteniendo la especificidad y riqueza conceptual original.
IMPORTANTE: Las categorías que no requieran armonización DEBEN mantenerse exactamente igual que en el input.
# ENTRADAS
- Categorías a armonizar:
{categorias_generales}
- Contexto del Proyecto:
{info_proyecto}
# PROCESO DE ANÁLISIS Y ARMONIZACIÓN
1. Análisis preliminar:
- Examina detenidamente cada categoría en relación con los objetivos del proyecto
- Identifica categorías que describen el mismo fenómeno con diferentes términos o enfoques
- Detecta posibles redundancias genuinas (copias exactas) vs. variaciones significativas
- CONSERVA INTACTAS las categorías que ya son únicas y no requieren armonización
2. Evaluación sistemática de cada categoría:
- Unicidad conceptual: ¿Representa un fenómeno verdaderamente diferente o es una variación terminológica?
- Especificidad: ¿Qué nivel de detalle aporta que deba preservarse?
- Valor analítico: ¿Qué matices únicos contribuye a los objetivos de investigación?
- Operatividad: ¿Cómo se identifica en los datos cualitativos de forma distintiva?
3. Toma de decisiones estratégicas:
a) Preservación: Mantén EXACTAMENTE IGUAL cualquier categoría que ya sea única y específica
b) Armonización terminológica: SOLO para categorías que representan el mismo fenómeno pero con términos
diferentes, unifícalas bajo la denominación más precisa y descriptiva, preservando los matices
relevantes de cada variante en la descripción
c) Diferenciación: Mantén separadas las categorías que, aunque similares, capturan aspectos o
dimensiones distintas del fenómeno estudiado
d) Eliminación: Descarta únicamente categorías que sean exactamente duplicadas sin aportar matices nuevos
4. Criterios para decisiones:
- REGLA PRIORITARIA: No modificar categorías que ya sean únicas y específicas
- Mantener la especificidad y nivel de detalle original de las categorías
- La capacidad de cada categoría para capturar matices únicos del fenómeno estudiado
- La claridad terminológica que facilite la identificación en verbatims
- El balance entre eliminar redundancias exactas mientras se preservan variaciones significativas
# REQUISITOS DE CALIDAD
- Presunción de validez: Asumir que cada categoría original es válida a menos que sea claramente redundante
- Preservación por defecto: Mantener sin cambios toda categoría que no requiera armonización
- Precisión conceptual: Definiciones claras que preserven los matices específicos de las categorías originales
- Distinción apropiada: Mantener separadas categorías que reflejen dimensiones distintas aunque relacionadas
- Exhaustividad matizada: Preservar la riqueza de detalles del conjunto original
- Armonización sin sobresimplificación: Unificar términos sin crear categorías excesivamente abstractas
- Aplicabilidad: Categorías que mantengan el nivel de especificidad necesario para identificar fenómenos concretos
# ESTRUCTURA DE SALIDA
{{
"categorias": [
{{
"nombre": "string", // Nombre preciso que preserve la especificidad original
"descripcion": "string", // Descripción comprehensiva que integre los matices de las categorías armonizadas
"observables": "string", // Indicadores específicos para identificar la categoría en verbatims
"justificacion": "string", // Fundamentación clara: para categorías preservadas o explicación detallada para las armonizadas
"categorias_originales": "string" // Lista de las categorías originales que se han armonizado, o "Original preservada" si no se modificó
}}
]
}}
# RESTRICCIONES
- CRÍTICO: Si una categoría no necesita armonización, debe pasar al resultado final SIN NINGÚN CAMBIO
- Evitar la creación de categorías excesivamente abstractas o generales
- No perder matices importantes al unificar categorías similares
- Entregar únicamente el JSON con las categorías armonizadas y preservadas
- Todos los campos son obligatorios para cada categoría
- No incluir texto explicativo adicional fuera del JSON
- Mantener un equilibrio entre la unificación de términos y la preservación de la especificidad
verificador:
prompt: |
# CONTEXTO Y OBJETIVO
Actúa como un experto verificador de categorías cualitativas. Tu función es evaluar críticamente
el trabajo realizado, adaptando tu proceso según estés verificando el trabajo del agente refinador
o del agente corrector en la fase 1 del análisis.
# ENTRADAS
- Información del proyecto:
{info_proyecto}
- Categorías generales originales:
{categorias_generales}
- Categorías a verificar:
{categorias_a_verificar}
- Origen del resultado // "refinador" o "corrector":
{origen}
- Verificación previa (solo si origen="corrector"):
{verificacion_previa}
# PROCESO DE VERIFICACIÓN DUAL
## SI ORIGEN = "refinador"
1. Evaluación completa de categorías refinadas:
- Analiza sistemáticamente cada categoría refinada contra las categorías originales
- Evalúa cada categoría según los cinco criterios definidos abajo
- Identifica fortalezas y debilidades específicas
- Formula recomendaciones precisas para las categorías que requieran mejoras o eliminación
- Determina qué categorías necesitan corrección o deben ser eliminadas
2. Criterios de verificación para trabajo del refinador:
a) Precisión conceptual:
- ¿El nombre refleja con exactitud el contenido de la categoría?
- ¿La descripción es clara, completa y sin ambigüedades?
b) Coherencia con el proyecto:
- ¿La categoría contribuye directamente a los objetivos de investigación?
- ¿Está alineada con el contexto del proyecto?
c) Unicidad y diferenciación:
- ¿La categoría representa un concepto realmente distintivo?
- ¿Existe solapamiento o redundancia con otras categorías?
d) Operatividad metodológica:
- ¿Los observables son específicos y permiten identificar claramente la categoría en los datos?
- ¿La categoría es aplicable en la codificación de verbatims?
e) Justificación del refinamiento:
- ¿La justificación explica adecuadamente las decisiones tomadas?
- ¿Se fundamenta en los criterios establecidos para el refinamiento?
## SI ORIGEN = "corrector"
1. Verificación de implementación de correcciones:
- Compara cada categoría del resultado con la verificación previa
- Verifica si el corrector:
a) Implementó todas las correcciones solicitadas
b) Eliminó todas las categorías marcadas para eliminación
c) Mantuvo intactas las categorías que no requerían cambios
- Determina si las correcciones resolvieron adecuadamente los problemas identificados
2. Criterios de verificación para trabajo del corrector:
a) Precisión de la implementación:
- ¿Se implementaron exactamente las correcciones solicitadas?
- ¿Se mantuvieron intactas las categorías que no requerían cambios?
b) Resolución de problemas:
- ¿Las correcciones resolvieron los problemas identificados en la verificación previa?
- ¿Persiste algún problema que no fue adecuadamente corregido?
c) Cumplimiento de eliminaciones:
- ¿Se eliminaron todas las categorías marcadas para eliminación?
# REGLAS DE DECISIÓN
- Cada categoría se evalúa de forma independiente
- Una categoría requiere corrección si presenta deficiencias en cualquiera de los criterios aplicables
- Una categoría debe ser eliminada si no aporta valor único o es irrelevante para el proyecto
- La decisión global es "False" si al menos una categoría requiere corrección o eliminación
- La decisión global es "True" solo si todas las categorías cumplen satisfactoriamente con los criterios
# FORMATO DE SALIDA REQUERIDO
La salida debe ser un objeto JSON con la siguiente estructura:
{{
"verificacion": {{
"categorias": [
{{
"categoria": "Nombre de la categoría",
"evaluacion": "Evaluación detallada según los criterios correspondientes al origen",
"recomendacion": "Recomendación específica para mejorar o indicación explícita de eliminarla",
"requiere_correccion": true/false, // Indica si la categoría necesita ser corregida
"eliminar": true/false // Indica si la categoría debe ser eliminada completamente
}}
],
"decision": true/false, // true si todas las categorías son adecuadas, false si al menos una necesita corrección o eliminación
"origen_verificado": "refinador" // o "corrector", para referencia
}}
}}
# RESTRICCIONES
- Adapta rigurosamente tu proceso según el origen del resultado (refinador o corrector)
- Si verificas el trabajo del corrector, compara explícitamente con las recomendaciones previas
- Proporciona recomendaciones solo para categorías que lo requieran
- Sé específico y concreto en las recomendaciones (qué cambiar y cómo)
- Fundamenta tus evaluaciones en evidencia objetiva
- Mantén consistencia en el nivel de detalle para todas las categorías
- La salida debe seguir estrictamente el formato JSON especificado
- No incluyas texto explicativo adicional fuera del JSON
corrector:
prompt: |
# CONTEXTO Y OBJETIVO
Actúa como un experto corrector de categorías cualitativas. Tu tarea es implementar las correcciones
específicas recomendadas por el agente verificador, ajustando o eliminando las categorías marcadas
según las recomendaciones precisas proporcionadas.
# ENTRADAS
- Información del proyecto:
{info_proyecto}
- Categorías generales originales:
{categorias_generales}
- Categorías refinadas:
{categorias_destiladas}
- Verificación y recomendaciones:
{verificacion}
# CRITERIOS DE REFINAMIENTO
Al corregir las categorías, debes aplicar los mismos criterios utilizados durante el refinamiento inicial:
1. Unicidad: Cada categoría debe representar un concepto distintivo
2. Precisión: Nombres y descripciones deben ser inequívocos
3. Relevancia: Cada categoría debe aportar valor al análisis
4. Coherencia: Mantener consistencia en el nivel de abstracción
5. Operatividad: Los observables deben permitir identificar claramente la categoría en los datos
# PROCESO DE CORRECCIÓN
1. Identificación de categorías a procesar:
- Identifica las categorías marcadas con "requiere_correccion": true para corregirlas
- Identifica las categorías marcadas con "eliminar": true para eliminarlas
- Mantén sin cambios las categorías no marcadas para corrección o eliminación
2. Implementación de correcciones:
- Para cada categoría que requiere corrección:
a) Consulta la "recomendacion" específica proporcionada por el verificador
b) Implementa cuidadosamente los cambios sugeridos siguiendo los criterios de refinamiento
c) Asegúrate de que las correcciones resuelvan completamente los problemas identificados
3. Gestión de categorías a eliminar:
- Excluye completamente del resultado final cualquier categoría marcada con "eliminar": true
4. Validación de las correcciones:
- Comprueba que cada categoría corregida cumpla ahora con los criterios de calidad
- Verifica que las categorías corregidas sean coherentes con el resto del sistema categorial
5. Preparación de la salida completa:
- Integra las categorías corregidas con las que no requerían corrección
- Excluye las categorías marcadas para eliminación
- Mantén el orden original de las categorías restantes
- Formatea la salida exactamente según la estructura requerida
# ESTRUCTURA DE SALIDA
{{
"categorias": [
{{
"nombre": "string", // Nombre refinado y preciso
"descripcion": "string", // Descripción comprehensiva y clara
"observables": "string", // Indicadores específicos para identificar la categoría
"justificacion": "string" // Fundamentación del refinamiento/corrección
}}
]
}}
# RESTRICCIONES
- Modifica ÚNICAMENTE las categorías marcadas con "requiere_correccion": true
- Elimina completamente las categorías marcadas con "eliminar": true
- Implementa EXACTAMENTE las correcciones recomendadas por el verificador
- Mantén INTACTAS todas las categorías que no requieren corrección ni eliminación
- Conserva el mismo formato de salida que el refinador
- No agregues campos adicionales ni alteres la estructura del JSON
- No incluyas explicaciones o texto fuera del formato especificado
- No cuestiones ni ignores ninguna recomendación del verificador
- Asegúrate de entregar todas las categorías finales en la salida (corregidas + no corregidas - eliminadas)

17
prueba_llm.py Normal file
View File

@@ -0,0 +1,17 @@
# from Extraction.llm.context import LLMContext
# from Extraction.llm.config import LLMConfig
from llm.context import LLMContext
from llm.config import LLMConfig
# Opción 1: Usando el método factory
context = LLMContext()
config = LLMConfig(
provider="anthropic", model_name="claude-haiku-4-5"
) # Ya viene con o4-mini
context.set_strategy(config)
llm = context.get_llm()
pregunta = "¿Cuál es el mejor modelo de lenguaje?"
respuesta = llm.invoke(pregunta)
print(respuesta)

10
requirements.txt Normal file
View File

@@ -0,0 +1,10 @@
annotated-types
anthropic
langchain
langchain-anthropic
langchain-openai
langgraph
openai
pandas
pydantic
python-dotenv