# Algo de práctica con una API de LLM

Veremos tokens, contexto y variabilidad

Como desarrollador backend que está aprendiendo un poco de esto mundo de la AI, decidí comenzar con un experimento pequeño antes de implementar una aplicación completa.

Mi objetivo a largo plazo es procesar estados de cuenta bancarios en PDF , extraer sus movimientos y algunas otras cosas que uso personal. Me gusta saber en que gasto mi dinero. Que vamos a validar aqui? Lo que ya vimos en teoría en este [articulo](https://robertonunez.dev/lecci-n-1-fundamentos-de-los-llms)

1.  ¿Qué ocurre cuando mi backend llama a un modelo de lenguaje (LLM)?
    
2.  ¿Cómo influye el tamaño de la entrada en el consumo de tokens?
    
3.  ¿Puede variar la respuesta aunque envíe exactamente la misma solicitud?
    

En este artículo comparto el código de un pequeño ejercicio, mis mediciones reales y lo que aprendí.

## Conceptos básicos

Un **LLM** procesa una entrada y genera una respuesta token por token, a partir de patrones aprendidos y del contexto recibido. Eso le permite interpretar texto y extraer información, pero no garantiza que cada dato generado sea correcto.

Para este laboratorio me concentré en cuatro conceptos:

*   **Tokens de entrada:** unidades de texto consumidas por las instrucciones y el contenido enviado.
    
*   **Tokens de salida:** unidades generadas en la respuesta.
    
*   **Ventana de contexto:** límite de información que el modelo puede considerar en una solicitud, sujeto a las restricciones del modelo.
    
*   **Variabilidad:** dos ejecuciones con una misma entrada no necesariamente generan una respuesta idéntica.
    

La meta no era optimizar prompts ni construir una extracción lista para producción, sino observar estos comportamientos directamente.

## Preparar un proyecto mínimo con TypeScript

Utilicé Node.js, TypeScript y el SDK de OpenAI:

```bash
mkdir llm-labs
cd llm-labs
npm init -y
npm install openai dotenv
npm install -D typescript tsx @types/node
mkdir src
```

En un archivo `.env` configuré la clave de la API:

```dotenv
OPENAI_API_KEY=tu_api_key
```

Es importante agregar `.env` al `.gitignore` para evitar publicar credenciales. El uso de la API puede generar cargos y se factura por separado de una suscripción a ChatGPT.

## Experimento 1: extraer cinco movimientos

Creé el archivo `src/lab1.ts`, es un código en su version mas simple posible.

```typescript
import "dotenv/config";
import OpenAI from "openai";

const client = new OpenAI();

const bankStatement = `
Estado de cuenta - Octubre 2026

01/10/2026 OXXO      -150.00
02/10/2026 NOMINA  +25000.00
03/10/2026 AMAZON    -850.00
04/10/2026 UBER      -120.00
05/10/2026 WALMART   -950.00
`;

async function main() {
  const response = await client.responses.create({
    model: "gpt-4.1-mini",
    instructions:
      "Eres un asistente que analiza movimientos bancarios.",
    input: `Identifica las transacciones del siguiente texto:\n${bankStatement}`,
  });

  console.log("Respuesta del modelo:");
  console.log(response.output_text);

  console.log("\nConsumo de tokens:");
  console.log(response.usage);
}

main().catch(console.error);
```

Para ejecutarlo:

```bash
npx tsx src/lab1.ts
```

El nombre del modelo es un ejemplo; se puede utilizar otro disponible en la cuenta de API. La respuesta incluye metadatos de consumo, entre ellos los tokens de entrada y salida.

### Resultado observado

Con cinco movimientos obtuve:

| Métrica | Tokens |
| --- | --- |
| Entrada | 116 |
| Salida | 120 |
| **Total** | **236** |

Los tokens de entrada no corresponden únicamente a las cinco filas: también cuentan las instrucciones y el texto adicional de la solicitud.

## Experimento 2: aumentar de cinco a veinte movimientos

Después amplié el estado de cuenta simulado a veinte movimientos, manteniendo el mismo modelo y la misma tarea.

Estos fueron mis resultados:

| Métrica | 5 movimientos | 20 movimientos | Incremento |
| --- | --- | --- | --- |
| Tokens de entrada | 116 | 332 | 2.86× |
| Tokens de salida | 120 | 390 | 3.25× |
| **Total** | **236** | **722** | **3.06×** |

Aunque la cantidad de movimientos aumentó **cuatro veces**, el consumo total creció aproximadamente **3.06 veces**.

¿Por qué no creció exactamente en la misma proporción? Parte de la solicitud permanece constante: las instrucciones y el texto que describe la tarea. Además, la longitud de la respuesta depende de cómo el modelo presenta los resultados.

**Conclusión:** más contenido suele implicar más tokens, pero el número de movimientos —o de páginas de un PDF— no permite calcular el consumo exacto por sí solo.

Estas cifras provienen de mis ejecuciones, no de una prueba de rendimiento exhaustiva.

## Experimento 3: repetir la misma solicitud

Finalmente volví al documento de cinco movimientos y ejecuté la misma solicitud varias veces.

Observé que **en algunas ejecuciones aumentaba el número de tokens de salida**, aunque no hubiera cambiado la entrada.

Esto es compatible con la naturaleza de la generación de los LLMs: pueden variar la redacción, el formato o el nivel de detalle. También pueden devolver respuestas idénticas; la variabilidad no está garantizada en cada ejecución.

Lo importante es que **consumir más tokens no significa responder mejor**.

Una respuesta larga podría incluir todos los movimientos y una explicación adicional. Una respuesta corta podría ser completamente correcta o podría omitir información. El número de tokens no permite determinarlo.

## Qué aprendí

### 1\. Ventana de contexto no significa exactitud

Que un documento quepa dentro de la ventana de contexto no garantiza que el modelo extraiga toda su información. Poder recibir cincuenta movimientos es distinto de identificar correctamente los cincuenta.

### 2\. Los tokens influyen en el costo, no miden la calidad

El consumo de tokens importa para la facturación y puede influir en la latencia. Pero no es una métrica de precisión.

### 3\. La respuesta de un LLM no debe tratarse como una fuente de verdad

Si un estado de cuenta contiene cincuenta movimientos y el modelo devuelve cuarenta y ocho, mi aplicación no debería asumir silenciosamente que la extracción está completa.

Este primer laboratorio **no implementó esas validaciones**. Su propósito fue entender por qué serán necesarias cuando construya el procesador de estados de cuenta.

## Reproduce el laboratorio

Si quieres probarlo por tu cuenta:

1.  Ejecuta el ejemplo con cinco movimientos simulados y registra los tokens de entrada y salida.
    
2.  Amplía el texto a veinte movimientos sin modificar las instrucciones.
    
3.  Compara el consumo y calcula cuánto aumentó.
    
4.  Ejecuta tres veces la solicitud original y compara el contenido y los tokens de salida.
    
5.  Pregúntate si alguna de esas mediciones demuestra que la extracción es correcta.
    

Para publicar ejemplos, utiliza movimientos sintéticos en lugar de información financiera real.

Este fue un ejercicio intencionalmente pequeño.

Me quedo con una idea fundamental: **un LLM es un componente probabilístico útil dentro de una aplicación, lo que nos response no es verdad o garantía al 100%**. Para garantizar lo que nos responde hay que implementar otras técnicas y patrones que veremos más adelante.

Entender esa diferencia es el primer paso para integrar modelos de lenguaje con criterio de ingeniería backend.

* * *

*El consumo de tokens corresponde a mis pruebas y pueden variar según el modelo, las instrucciones y la versión de la API.*
