Sesión 4.2: LLMs como herramientas de investigación
El mecanismo (lo que vimos)
La consecuencia (donde quedamos)
Nota
Ahora: lo que el mecanismo nos pide. Aprender cuatro defensas para usar LLMs con responsabilidad en investigación
El problema y las defensas
Aplicación y herramientas
El problema:
Por un lado, los LLMs nos permiten hacer en minutos lo que antes llevaba semanas (anotar miles de textos, extraer entidades, sintetizar literatura)
Por otro, confiar en su salida sin defensas produce errores que se ven exactamente igual que los aciertos
Esta clase es sobre cómo aprovechar lo primero sin caer en lo segundo 😅
Varghese v. China Southern Airlines)Nota
Las cuatro defensas que veremos atacan distintas alucinaciones. Ninguna defensa por sí sola las elimina todas. Es un problema estructural del mecanismo, no un bug
Una cita falsa
Bertoni, L. y Salgado, M. (2021). “Participación electoral y transferencias condicionadas en el Cono Sur”. Latin American Politics and Society, 63(2), 88-114. doi:10.1017/lap.2021.14
Para investigación, “bajo” no es “aceptable”: una cita inventada en un paper es una cita inventada
Mala práctica común
Prompt: “Analiza este texto.”
Problema: ¿analizar qué? ¿sentimiento? ¿tema? El modelo elige por ustedes
Buena práctica
Prompt: “Sos un analista político con experiencia en discurso latinoamericano. Clasificá el sentimiento del siguiente texto como positivo, negativo o neutro. Responde en JSON con campos sentimiento y justificacion.”
Mismo modelo, output mucho más útil
Ejemplo para anotación sistemática
Sos un asistente de codificación para
investigación en ciencias sociales en
América Latina.
Reglas:
- Respondé siempre en español
- Si no estás seguro, decilo explícitamente
- No inventes datos ni estadísticas
- No agregues comentarios fuera del JSON
- Formato: JSON estricto, sin texto antes o después
Fuente: GitHub - System Prompts and Models of AI Tools
Nota
El system prompt es invisible para el modelo en el sentido de que no lo cita, pero condiciona todas las respuestas. Es la forma más limpia de fijar el comportamiento
Zero-shot: sin ejemplos
Clasificá el sentimiento de
este texto como positivo,
negativo o neutro:
"La economía creció un 5%
pero el desempleo subió."
Funciona para tareas simples y bien definidas. Lo que vimos en la Sesión 4.1 como emergencia hace esto posible
Bueno para empezar y baseline
Nota
Pista: few-shot funciona porque el modelo aprende del patrón del prompt mismo. Es la capacidad emergente que vimos en la sesión anterior (in-context learning)
Few-shot: con ejemplos
Ejemplos:
- "La inflación es alta" → negativo
- "El empleo mejoró" → positivo
- "Los datos son de 2023" → neutro
- "Cayó la pobreza pero subió
la deuda" → mixto
Clasificá:
"El crecimiento fue moderado" →
Mejora la precisión al mostrar el formato y los matices (Brown et al., 2020; Min et al., 2022)
Tres a cinco ejemplos suelen ser óptimos
Ojo: ejemplos mal elegidos o sesgados pueden empeorar el resultado. La calidad importa más que la cantidad
La técnica
Pedir al modelo que razone explícitamente antes de responder
Antes de clasificar, razoná paso a paso:
Texto: "A pesar de la crisis, el
gobierno logró reducir la pobreza."
Razonamiento:
1. "crisis" es contexto negativo
2. "logró reducir la pobreza" es resultado positivo
3. "a pesar de" indica contraste
4. El resultado supera al contexto
Clasificación: POSITIVO
Modelos de razonamiento (o-series, DeepSeek R1, extended thinking) ya hacen CoT internamente: a veces conviene elegir uno en vez de escribir los pasos a mano
Por qué funciona
Cuándo usarlo
Costo: respuestas más largas → más tokens → más caro. Vale la pena para tareas complejas
Recomendaciones rápidas
| Tarea | Temperatura |
|---|---|
| Clasificación | 0,0 - 0,1 |
| Extracción de datos | 0,0 - 0,2 |
| Resumen | 0,2 - 0,4 |
| Análisis abierto | 0,3 - 0,5 |
| Escritura creativa | 0,7 - 1,0 |
| Brainstorming | 0,8 - 1,0 |
Para investigación reproducible: temperatura 0 siempre que se pueda
jsonliteNota
Incluir un ejemplo de la estructura esperada en el prompt reduce drásticamente los errores de formato
Ejemplo: extracción de entidades
Extraé las entidades del texto en JSON:
{
"personas": [...],
"organizaciones": [...],
"lugares": [...],
"fechas": [...]
}
Texto: "El presidente Lacalle Pou se reunió
con el FMI en Montevideo el 15 de marzo
de 2024."
Respuesta esperada
ellmer y quallmer)Adelanto: tipos en ellmer
Resultado: una lista R lista para usar, sin parsear texto. Más información en https://ellmer.tidyverse.org/articles/structured-data.html
Ejemplo típico
Preguntar a un LLM sobre un artículo académico que el usuario tiene como PDF:
La solución
Sí usar RAG cuando
No necesitás RAG cuando
Nota
A veces “RAG” es exagerado. Si su PDF entra en el contexto, pueden pegarlo directamente.
¿Qué es “aceptable”?
Depende de la tarea. Algunos benchmarks:
Ejemplo de tabla de validación
Dataset: 100 textos políticos
Gold standard: 2 investigadores
| Accuracy | F1
---------|----------|------
LLM | 0,87 | 0,85
Dicción. | 0,72 | 0,68
LDA+sup. | 0,79 | 0,76
Humano | 0,91 | 0,89
Conclusión: LLM cerca de humanos,
supera métodos clásicos.
Sin esta tabla, es difícil defender el uso del LLM en una publicación
Documentación mínima
Sin esto, el análisis no es replicable
Ejemplo de prompt completo
System: Sos un analista político. Clasificá
textos según el tema principal. Temas
posibles: economia, educacion, seguridad,
salud, medio ambiente.
Respondé SOLO con el tema, sin explicación.
User: "La inflación sigue siendo un problema
grave que afecta a las familias más
vulnerables."
Respuesta: economia
En un lab veremos cómo procesar mil textos así, con ellmer y quallmer
Ejemplo de prompt
Generá 10 respuestas simuladas a
una encuesta sobre confianza en
instituciones en Uruguay.
Cada respuesta debe incluir:
- edad (18-80)
- género (M/F)
- confianza_gobierno (1-4)
- confianza_justicia (1-4)
- comentario (1 oración)
Formato: CSV con encabezados. Las
respuestas deben reflejar la
diversidad demográfica real.
Útiles como complemento, no como sustituto
| Criterio | Diccionarios | TF-IDF + clasificador | LLM (zero-shot) | LLM (few-shot) |
|---|---|---|---|---|
| Precisión | Baja | Moderada | Alta | Muy alta |
| Velocidad | Muy rápida | Rápida | Lenta | Lenta |
| Costo | Gratis | Gratis | USD/1000 textos | USD/1000 textos |
| Datos etiquetados | No | Sí (cientos) | No | 3-10 ejemplos |
| Reproducibilidad | Alta | Alta | Difícil | Difícil |
| Transparencia | Total | Moderada | Caja negra | Caja negra |
| Idiomas | Uno por uno | Uno por uno | Multilingüe | Multilingüe |
| Negación/ironía | Pobre | Pobre | Buena | Muy buena |
Recomendación: para volúmenes grandes y tareas comunes, considerar híbridos. Usar el LLM para etiquetar un subconjunto y entrenar un clasificador clásico con esas etiquetas. Mejor calidad que diccionarios, mucho más barato que LLM en todo el corpus
| Opción | Ventajas | Limitaciones | Cuándo usarla |
|---|---|---|---|
| OpenRouter | Una API key para docenas de modelos; tier gratuito; sin tarjeta para empezar | Rate limits en modelos :free; depende de un agregador externo |
Empezar, prototipos, volúmenes pequeños |
| Ollama (local) | Cero costo; los datos no salen de su máquina; versión exacta queda fija | Necesita 8+ GB de RAM; modelos chicos son menos potentes | Privacidad, reproducibilidad, corpus grande |
| APIs comerciales (OpenAI, Anthropic) | Mejor calidad disponible; respuestas rápidas | Tarjeta de crédito; pago por uso; caja negra | Cuando la institución cubre el costo o el proyecto lo justifica |
Con ellmer pueden cambiar de proveedor sin reescribir su código. En los labs lo vemos paso a paso
ellmer: interfaz unificada para Rchat_openrouter(), chat_ollama(), chat_openai(), chat_anthropic(), chat_google_gemini()chat$chat(): enviar un mensajechat$chat_structured(): extraer datos con tipos validados (las defensas 1 y 2 en una sola llamada)chat$tokens(): contar tokens usadospurrr::map() para procesar muchos textos en pipelineMás detalles en los Laboratorios 7 y 8
El patrón mínimo
library(ellmer)
chat <- chat_openrouter(
model = "nvidia/nemotron-3-super-120b-a12b:free",
system_prompt = "Sos un analista político..."
)
# Texto libre
chat$chat("Resumí este texto...")
# Extracción tipada (defensa 2)
chat$chat_structured(
"La economía está en crisis.",
type = type_object(
tema = type_string(),
sentimiento = type_string(),
confianza = type_number()
)
)Cambiar chat_openrouter por chat_ollama y el resto del código sigue igual
granite4.1:3b ocupa ~2,1 GB y corre con 8 GB de RAMHáganlo antes de la clase
La descarga puede tardar varios minutos según la conexión. Si la dejan para el laboratorio, pierden tiempo de práctica
Nota
Pista: granite4.1:3b es el modelo más chico de su familia. Si su laptop no puede correrlo, no hay problema: el laboratorio también puede seguirse con OpenRouter, como en los labs 7 y 8
Lo mismo que hoy hacemos con ellmer en la nube, mañana lo haremos en local
Lo que aprendimos hoy
Herramientas
Regla de oro
Nota
Nunca confiar en la salida de un LLM sin verificación. Los LLMs son herramientas de borrador, no fuentes de verdad
Ninguna defensa por sí sola es suficiente. Las cuatro juntas hacen el trabajo más confiable
ellmer
ellmer con OpenRouterquallmer
Mañana cerramos con modelos locales, ética y regulación