Skip to contents

English version: vignette("text-analysis", package = "ellmercodex").

Los modelos de lenguaje son útiles en investigación cuando devuelven algo con lo que R puede trabajar, no solo prosa. Este artículo usa intervenciones de un debate parlamentario uruguayo sobre la regulación del cannabis para mostrar dos funciones de ellmer que funcionan con ellmercodex: los datos estructurados y las llamadas a herramientas. Los ejemplos están inspirados en el artículo sobre ellmercodex en el blog.

Las salidas que se muestran provienen de una sesión real con gpt-6-luna.

library(ellmercodex)

chat <- chat_codex(model = "gpt-6-luna", effort = "low")

Clasifica un fragmento

Con $chat_structured() describes el resultado que quieres con el sistema de tipos de ellmer, y el modelo tiene que responder con esa forma. Aquí pedimos una orientación sobre política de drogas, a partir de un conjunto fijo de códigos, junto con una breve justificación:

# Fragmento real del debate
fragmento <- paste(
  "seguimos pensando que además de la represión y del combate al",
  "narcotráfico que debe seguir con firmeza y decisión como sociedad",
  "debemos apostar a dos o tres pilares fundamentales la educación",
  "la prevención y la rehabilitación"
)

resultado <- chat$chat_structured(
  paste(
    "Clasifica el fragmento como PREVENTIVA, PUNITIVA, MIXTA o",
    "SIN_ORIENTACIÓN_ATRIBUIBLE.",
    "Usa MIXTA cuando se defiendan simultáneamente respuestas",
    "preventivas y punitivas.",
    "\n\nFragmento:",
    fragmento
  ),
  type = ellmer::type_object(
    codigo = ellmer::type_enum(c(
      "PREVENTIVA",
      "PUNITIVA",
      "MIXTA",
      "SIN_ORIENTACIÓN_ATRIBUIBLE"
    )),
    justificacion = ellmer::type_string()
  )
)

resultado
#> $codigo
#> [1] "MIXTA"
#>
#> $justificacion
#> [1] "El fragmento defiende explícitamente la represión y el combate al
#> narcotráfico, que son respuestas punitivas, y simultáneamente propone la
#> educación, la prevención y la rehabilitación, de carácter preventivo o
#> rehabilitador."

El resultado es una lista de R, así que puedes ponerlo en un data.frame, validarlo o analizarlo junto a los códigos de codificadores humanos. El artículo de ellmer sobre datos estructurados (en inglés) explica el sistema de tipos en detalle, incluido cómo extraer varias filas a la vez.

Deja que el modelo llame a tus funciones de R

Supongamos que ya clasificaste muchas intervenciones:

intervenciones <- data.frame(
  partido = c("FA", "FA", "PN", "PN", "PN"),
  orientacion = c("PREVENTIVA", "MIXTA", "PUNITIVA", "PUNITIVA", "MIXTA")
)

En vez de pegar los datos en el prompt, puedes darle al modelo una herramienta: una función de R que puede llamar cuando necesita información. Esta cuenta las orientaciones de un partido y devuelve JSON, que es lo que ellmer espera de una herramienta:

resumir_partido <- function(partido_buscado) {
  intervenciones |>
    dplyr::filter(partido == partido_buscado) |>
    dplyr::count(orientacion) |>
    jsonlite::toJSON()
}

resumen_tool <- ellmer::tool(
  resumir_partido,
  name = "resumir_partido",
  description = "Cuenta las orientaciones discursivas de un partido.",
  arguments = list(partido_buscado = ellmer::type_string())
)

chat$register_tool(resumen_tool)

chat$chat(
  paste(
    "Compara las orientaciones discursivas de FA y PN.",
    "Usa la herramienta disponible."
  )
)
#> FA presenta una orientación **mixta** y una **preventiva** (una observación
#> de cada tipo). PN presenta una orientación **mixta** y dos **punitivas**.
#> En común, ambos tienen una orientación mixta; la diferencia es que FA
#> incluye una preventiva, mientras que PN se inclina más hacia lo punitivo.

El modelo decidió llamar a resumir_partido() para cada partido, recibió los resultados calculados por R y los usó en su respuesta. Una herramienta también podría consultar una base de datos, buscar en un corpus o llamar a una API.

R siempre ejecuta las funciones: el modelo solo puede usar las herramientas que registres, y decide cuándo llamarlas y con qué argumentos. El artículo de ellmer sobre llamadas a herramientas (en inglés) explica cómo diseñar buenas herramientas.

Combina las dos cosas

Como en ellmer, $chat_structured() no usa las herramientas registradas. Cuando necesites ambas cosas, reúne primero el contexto con $chat() y después extrae el resultado con $chat_structured() en la misma conversación:

chat$chat("Usa la herramienta para obtener las orientaciones de FA y PN.")

conteos <- chat$chat_structured(
  "Devuelve los conteos que acabas de obtener.",
  type = ellmer::type_array(
    ellmer::type_object(
      partido = ellmer::type_string(),
      orientacion = ellmer::type_string(),
      n = ellmer::type_integer()
    )
  )
)

conteos
#> # A tibble: 4 x 3
#>   partido orientacion     n
#>   <chr>   <chr>       <int>
#> 1 FA      MIXTA           1
#> 2 FA      PREVENTIVA      1
#> 3 PN      MIXTA           1
#> 4 PN      PUNITIVA        2