• Updated:
  • Featured post

How LLMs generate the next token

(este post es una explicación de la teoría. dejo aquí otro post con el detalle práctico de como usar la temperature, top_k y top_p a efectos prácticos)

Explicación más en detalle de cómo obtienen los LLMs las probabilidades para generar el siguiente token

Sampling

En cada posición el modelo tiene una bolsa con miles de tokens posibles. Sampling es el proceso de no coger siempre el token más probable, si no de orientarlo a coger respuestas con determinadas características.

Si el modelo escogiera siempre el token con más probabilidades, obtendríamos respuestas aburridas y repetitivas.

Logits

Para generar el siguiente token, una red neuronal calcula primero los vectores de logits, donde cada logit corresponde a un valor posible. El tamaño de estos vectores de logits es tan grande como el vocabulario completo del modelo.

(representación de vectores de logits)

flowchart LR
	N1["What's your favorite color?"]:::note --> Z
	Z --> A1 --> A
	Z --> B1 --> B
	Z --> C1 --> C
	Z --> D1 --> D
	
	Z["Neural network"]
    A["a"]
    A1["(-0.5)"]
    B["green"]
    B1["(0.7)"]
    C["red"]
    C1["(0.5)"]
    D["the"]
    D1["(-1.2)"]
    
    classDef note fill:none,stroke:none,color:#777;    

Los logits NO representan probabilidades ya que no suman 1 y pueden incluso ser negativos (la probabilidades no pueden). Para convertir logits a probabilidades se usa una Softmax layer

Temperature

La temperatura es una constante que se aplica a los logits antes de la transformación de la Softmax layer. Se usa para ajustar la creatividad del modelo y redistribuir la probabilidad de los valores. Una temperatura más alta hace que el modelo sea más creativo ya que aumenta las posibilidades de elegir tokens menos probables.

xychart-beta
  title "Temperatura vs Probabilidad"
  x-axis "Temperatura (T)" [0.1, 0.2, 0.5, 1, 2, 5]
  y-axis "Probabilidad" 0 --> 1
  line "P(token1)" [0.9999546, 0.9933071, 0.8807971, 0.7310586, 0.6224593, 0.5498340]
  line "P(token2)" [0.0000454, 0.0066929, 0.1192029, 0.2689414, 0.3775407, 0.4501660]

Ejemplos de temperaturas:

  • Low (0.2-0.3): El modelo es cauto y elige las palabras más probables. Output factual y predecible.
  • Medium (0.5-0.7): Un mix de confiabilidad y engagement
  • High (0.9-1.0): Toma riesgos y es impredecible

Read More

  • Updated:

Chunking techniques

Chunking es el proceso de partir la información que contienen nuestros documentos en pedazos digestibles. Estos chunks los usaremos después para hacer queries contra ellos.

A veces si parece que no obtenemos los resultados que queremos de nuestras queries no es por falta de información, si no por un chunking mal hecho. Si hacemos una query y por cómo hemos partido nuestros documentos tenemos la pregunta en un chunk y partes de la respuesta divididas entre múltiples chunks sin solapamiento, no obtendremos buenas respuestas.

La idea es simple, el proceso no tanto. Hay varias técnicas según lo que nos queramos complicar y los resultados que obtenemos varían entre ellas.

Chunking estático

El más simple. Tenemos un documento y partimos cada chunk en grupos de (por ejemplo) 500 tokens con 100 tokens de solapamiento entre chunks.

Tenemos la siguiente frase de prueba

La casa grande es bonita aunque cara, pero tiene un buen garaje. En el futuro quiero comprarme un coche

Visualizando los tokens a nivel de subpalabra con test-multilingual-embedding me salen 28 tokens aprox.

Si establecemos un limite de 10 tokens por chunk, con 3 de solapamiento, cada chunk se podría ver así:

La casa grande es bonita aunque cara
aunque cara, pero tiene un buen garaje
buen garaje. En el futuro quiero comprar
quiero comprarme un coche

El problema es que puede cortar frases a media palabra según como coincida ya que la palabra comprarme son dos tokens comprar y me

Esto se puede aliviar un poco con librerías de chunking inteligente que existen que parten usando separadores como espacios o saltos de línea, pero el contexto se puede perder mucho si cae entre varios chunks.

Chunking semántico

Una técnica que solventa esto es hacer el chunking mediante un modelo de embedding, el cual parte los chunks por contenido semántico cuando detecta que el tema principal cambia. Es más caro porque un modelo tiene que analizar los documentos, pero da mejores resultados.

De esta manera el mismo texto nos quedaría en dos chunks que aunque tienen distinto tamaño, están mucho más contenidos, por lo que a la hora de buscar con una query nos dará mejores resultados.

La casa grande es bonita aunque cara, pero tiene un buen garaje.
En el futuro quiero comprarme un coche

Limpieza

Limpiar los chunks es tan importante como el dónde partir. En mis primeras pruebas se metía mucho ruido en cosmos por como \n o \t o chunks que solo contenían un número sin contexto ninguno.

Para sistemas grandes o genéricos puede ser importante meter metadatos junto a los chunks para filtrar luego al buscar. Cosas como el nombre del documento al que pertenece un chunk o la fecha de creación del documento ayudan a filtrar luego y favorecer documentación reciente o saber de dónde viene algún dato erróneo o con menor calidad.

  • Updated:

Embeddings y Vector Search

Un ordenador no puede entender texto ni relaciones semánticas o significados entre palabras. Solo puede entender números. Este problema lo resolvemos mediante el uso de embeddings.

Un embedding es la representación de texto (en forma de números) en un espacio vectorial. Esto permite a los modelos de IA comparar y operar sobre el significado de las palabras.

flowchart TD
    A["perro"] --> B{{Modelo de embedding}}
    B --> C["[-0.003, 0.043, ..., -0.01]"]
    
    N1["(texto que queremos convertir)"]:::note --> A
    N2["(vectores con contenido semántico)"]:::note --> C
    
    classDef note fill:none,stroke:none,color:#777;    

Los vectores de cada palabra o documento capturan el significado semántico del texto.

  • perro estará cerca de mascota
  • contrato estará lejos de playa

Vector vs SQL databases

El problema con las bases de datos típicas es que solo buscan matches exactos. Si yo busco por coche solo me sacará las entradas que contengan coche.

En cambio las BBDD vectoriales pueden interpretar la semántica de las palabras mediante vectores. Si busco por coche puede sacarme valores como sedán, SUV, Land Rover, etc.

Las BBDD vectoriales son muy buenas cuando necesitamos buscar items similares por proximidad uno respecto al otro.

Algunos ejemplos de uso son:

  • buscar películas parecidas (Netflix)
  • Recomendadores de items parecidos en tiendas online (Amazon)
  • buscar canciones parecidas (Spotify)

Read More

  • Updated:

Python 101 (env, tools and Poetry)

TL;DR

Stack a usar:

  • python -> lenguaje e intérprete
  • py -> python launcher para windows
  • pipx -> instalar tools python globales
  • .env -> variables de entorno local; UAT y PROD usar config de donde se despliegue
  • pyenv -> gestor de versiones de Python
  • poetry -> gestor de proyecto. Abstrae pip y sustituye venv y requeriments.txt. Detalles de como usar poetry aquí

No usar pero si conocer (están explicados debajo):

  • pip -> gestor de paquetes - incluye uso de requirements.txt (sustituir por poetry)
  • pip3 -> No usarlo. Leftover histórico de cuando python2 y python3 convivian hasta el 2020
  • venv -> entornos virtuales para aislamiento (sustituir por poetry)
  • conda -> package y environment manager para data science & ML

Investigar de cara a futuro si uso python de manera más regular:

  • uv -> gestor ultrarrápido de dependencies y entornos Python. Reemplaza a pip, venv, pip-tools y poetry. Soluciona la lentitud del stack clásico. Es reciente y está ganando tracción.

    Stack a usar

    Python (lenguaje/intérprete)

    Python como tal es el lenguaje y el intérprete. Es un lenguaje interpretado (no compilado) sobre una MV propia. Python por sí mismo no gestiona dependencias ni aislamiento.

Python. Solo. Ejecuta. Código.

(py) python en Windows

Python no es un único ejecutable, puedes tener varios intérpretes instalados a la vez. El caos general de python viene normalmente a que cada uno es una versión distinta, con librerías distintas y sus propios paths.

python.exe
python3.exe
py.exe

Si usas python, lo que hace el sistema es buscar python en $PATH y usar el primero que encuentre

python main.py

En windows usar siempre py. Está diseñado para gestionar múltiples versiones de Python (sólo en windows)

py # lanza la version por defecto. Normalmente el último Python3 instalado
py -3.11
py -0p # muy útil para debuggear todas las instalaciones detectadas

(!) No usar python y py indistintamente (!)

No se puede usar indistintamente python y py ya que son comandos diferentes.

# DON'T DO THIS
python -m venv .venv
.venv/Scripts/activate
pip install fastapi
py main.py # puede ignorar el .venv activado y lanzar un python global distinto

Read More

  • Updated:

MCP vs Skills vs Instructions

(Awesomes github copilot - buena página para encontrar skills e instructions reutilizables)

MCP (Model Context Protocol)

Un MCP Server es un componente que implemente el protocolo MCP, un estándar abierto diseñado para conectar LLMs y agentes de IA con datos y herramientas externas de forma segura y estándar.

El MCP server expone el contexto que necesita e indica las acciones que el agente puede usar a demanda.

Dotan a los LLMs de capacidades adicionales permitiendo:

  • Acceso a datos en tiempo real: conectar la IA a APIs, BBDD, archivos locales…
  • Automatizaciones: permiten conectar un componente a tools externas para ejecutar acciones (ejecutar flujos, crear registros, aprobar procesos)

Sin esto, los LLMs por sí solos están limitados a sus datos de entrenamiento.

(ejemplo de consumo real de MCP de Github desde Cursor. Gracias a él Cursor puede modificar issues o crear/cerrar PRs)

{
  "mcpServers": {
    "github": {
      "url": "https://api.githubcopilot.com/mcp/",
      "headers": {
        "Authorization": "Bearer github_pat_"
      }
    }
  }
}

Componentes

MCP se compone de 3 partes:

  • Host: es tu aplicación de IA. Claude Desktop, Cursor, etc. Es aquello que necesita conectarse a algo.
  • Client: está dentro del host y administra conexiones MCP. Gestiona autenticación, hacer routing de requests al servidor correcto y administrar el ciclo de vida de la sesión.
  • Server: expone una herramienta o data source a través de 3 primitivos
    • Tools: Acciones que el modelo puede hacer "Crea un ticket de JIRA"
    • Resources: Datos que el modelo puede leer "Los últimos 50 mensajes de #IA"
    • Prompts: Templates reusables que combinan ambas para workflows comunes "Resume la actividad de JIRA de hoy y crea un reporte"

Skills

Las skills son un estandar abierto que extiende lo que un agente es capaz de hacer con conocimiento y workflows especializados y reutilizables. Estas se cargan dinámicamente, generalmente en un SKILL.md y el propio agente decide cuando es necesario utilizarlas en base a la tarea que tiene entre manos.

Una vez declaradas el LLM puede decidir usarlas automáticamente o se pueden usar mediante /{nombre-skill} {opt-params}

(ejemplo de SKILL.md con Caveman, el cual reduce el número de tokens consumidos manteniendo la calidad de la respuesta)

SKILL.md in Caveman github reop

Read More

  • Updated:

(pipx) Install Python tool globally

(ver otras herramientas de Python y como se integran con pipx)

Install

# install
py -m pip install --user pipx

# only the first time we install something 
pipx ensurepath
# close and open terminal again

Usage

# build, install and run with poetry to make sure everything works
poetry build
poetry install
poetry run

# install localy with pipx
pipx install .

# now we're able to run it from anywhere
file-enlarger

in this case we invoke it as file-enlarger as the .toml declares it as such

[tool.poetry.scripts]
file-enlarger = "file_enlarger.enlarge_file:main"

Read More

  • Updated:

K8s install Minikube

(Oficial Doc)

Technology to quickly set up a Kubernetes cluster locally to learn how to use Kubernetes.

Installation

Install Docker Desktop for windows and start it.
Then install minikube through CLI or download here the exe

winget install Kubernetes.minikube

Now run

minikube start

Read More

  • Updated:

Poetry (Python)

(ver definición de Poetry y como se integra con otras herramientas Python)

Prerequisites

First of all install pip and use pip to install pipx. From then on, use only pipx

install pip tools

py -m pip install --user pip-tools

# upgrade pip
py -m pip install --upgrade pip

install pipx

py -m pip install --user pipx

# adds executables to global path so you can call them without py -m ...
py -m pipx ensurepath
# close and reopen console

install poetry through pipx

py -m pipx install --user poetry

Read More

Razor Pages - Prevent Overposting

Si las clases contienen secretos, aunque estos no se muestren en la web, hay maneras de introducir datos en un Creation aunque el form no tenga un campo para ello.

Ejemplo de clase con secretos Student.cs

public class Student
{
	public int ID { get; set; }
	public string LastName { get; set; }
	public string FirstMidName { get; set; }
	public DateTime EnrollmentDate { get; set; }
	
	// an atacker may set a Secret on creation ...
	public string Secret { get; set; }
	// ... or he may enroll the Student in Courses he shouldn't
	public ICollection<Enrollment> Enrollments { get; set; } = [];
}

Hay varias alternativas para evitar esto:

  • Usar ViewModels
  • Usar TryUpdateModelAsync

ViewModels

Una buena práctica es usar ViewModels (se puede meter en la misma Student.cs)

public class StudentVM
{
	public int ID { get; set; }
	public string LastName { get; set; }
	public string FirstMidName { get; set; }
	public DateTime EnrollmentDate { get; set; }
}

Y operamos a través del ViewModel en las vistas para crear un nuevo Student, por lo que no pueden meter un secreto ni otras relaciones.

[BindProperty]
public StudentVM StudentVM { get; set; }

public async Task<IActionResult> OnPostAsync()
{
	if (!ModelState.IsValid)
	{
		return Page();
	}
	
	var entry = _context.Add(new Student());
	entry.CurrentValues.SetValues(StudentVM);
	await _context.SaveChangesAsync();
	return RedirectToPage("./Index");
}

Para que esto funcione las clases no tienen porque estar relacionadas, pero sus properties si que tienen que ser iguales.

Read More

Microsoft Agent Framework (MAF)

Microsoft Agent Framework es un SDK y runtime para construir, orquestar y desplegar agentes de IA y workflows multi-agente en .NET y Python.

Antes de entrar en detalle es importante recalcar los avisos que dan en la documentación oficial

Si puedes hacer algo con una función determinista, hazlo. No lo hagas con un agente de IA ni con MAF
Si solo necesitas prompt-in / text-out, hazlo. Con MAF te estás complicando sin necesidad

Dicho esto, ventajas de usar MAF:

  • Proporciona una capa de abstracción para agentes
  • Soporte multi-proveedor (soporta Microsoft Foundry, Anthropic, Azure OpenAI, OpenAI, Ollama y más)
  • Interoperatibilidad de herramientas mediante MCP (Model Context Protocol) y A2A (Agent to Agent)

Agentes vs workflows

Agentes de IA - programas que usan modelos de IA generativa para procesar inputs, llamar herramientas y generar respuestas

Workflows - grafos que conectan agentes y funciones para tareas con múltiples pasos, type-safe, checkpoints y soporte human-in-the-loop

Debemos usar un agente cuando:

  • sea una tarea abierta o conversacional
  • necesitas una herramienta y planning autónomos
  • Una sola petición a un LLM (con tools) sea suficiente

En cambio, debemos usar un workflow cuando:

  • tengamos un proceso con pasos bien definidos
  • necesitamos control explícito sobre el orden de ejecución
  • debamos coordinar multiples agentes o funciones

Reference(s)

Microsoft Agent Framework Overview | Microsoft Learn Step 1: Your First Agent | Microsoft Learn

Azure Naming Strategy

(gráfico obtenido de la referencia para visualizar como se organizan los recursos en azure)

Cursor overview

Los resource groups son como directorios. Se les puede asignar múltiples a cada recurso.

Naming Strategy

La estrategia para los nombres que yo utilizo que y mejor me sirve a la hora de buscar y entender recursos es:

resource type - app name - region - env - counter

ejemplo:

azurefunction-spotiguard-spainwest-dev-01

Reference(s)

Organize Azure resources using management group, tags, naming convention – AzureDays