DEV Community

Cover image for Show HN: Needle distilled Gemini tool calling en 26M parámetros — lectura técnica sin hype
Juan Torchia
Juan Torchia Subscriber

Posted on • Originally published at juanchi.dev

Show HN: Needle distilled Gemini tool calling en 26M parámetros — lectura técnica sin hype

Show HN: Needle distilled Gemini tool calling en 26M parámetros — lectura técnica sin hype

Estaba revisando mi pipeline de Ollama cuando apareció el post en HN: Needle, un modelo de 26M de parámetros destilado desde Gemini específicamente para tool calling. Mi primera reacción fue escéptica. 26M suena a juguete. Después leí con más calma y entendí que el punto interesante no es el tamaño: es el problema que están atacando.

Acá va mi lectura técnica, sin euforia y sin descarte fácil.


El problema real detrás de Needle y la destilación de Gemini para tool calling

Mi tesis es esta: el cuello de botella en sistemas con herramientas externas no es el razonamiento general del LLM, sino la parsabilidad del output. Si el modelo produce JSON mal formado, llama funciones con argumentos incorrectos o alucina nombres de tools que no existen, el sistema entero se rompe — no importa qué tan "inteligente" sea el modelo en otras tareas.

Esto lo experimenté directamente mientras armaba loops de agentes con Claude Code. La parte más frágil nunca fue el razonamiento; fue la confiabilidad del contrato de datos. Me acordé de cuando me resistí a TypeScript durante años pensando que los tipos eran burocracia. Después entendí que muchas fallas evitables empiezan como contratos de datos mal expresados. Con tool calling pasa exactamente lo mismo: un modelo puede ser brillante en prosa y pésimo para respetar un esquema JSON estricto bajo presión de latencia.

Needle ataca ese punto específico: toma el comportamiento de tool calling de Gemini — que es consistente y bien estructurado — y lo destila en un modelo pequeño y especializado. La hipótesis es que para esta tarea concreta, 26M entrenados con el comportamiento correcto pueden superar a modelos gigantes generalistas que no fueron ajustados para respetar esquemas de función con precisión.

¿Es verdad? En benchmarks propios, según el repositorio del proyecto, sí. En producción real propia, no lo sé todavía — y esa diferencia importa.


Qué es la destilación de conocimiento y por qué importa aquí

La destilación de conocimiento (knowledge distillation) es una técnica donde un modelo grande — el teacher — genera outputs que después se usan para entrenar un modelo pequeño — el student. El student no aprende de datos crudos: aprende a imitar el comportamiento del teacher en las distribuciones que más importan.

# Concepto simplificado del pipeline de destilación para tool calling:
# 1. Teacher (Gemini) genera miles de ejemplos de tool calling correcto
# 2. Student (Needle, 26M) entrena sobre esos ejemplos
# 3. El student aprende la distribución de outputs del teacher, no reglas escritas a mano
Enter fullscreen mode Exit fullscreen mode

Para tool calling, esto tiene sentido particular. No necesitás que el modelo sepa historia universal. Necesitás que cuando le pasés este schema:

// Definición de herramienta — el modelo tiene que respetar esto al 100%
const tools = [
  {
    name: "buscar_producto",
    description: "Busca un producto por ID en el catálogo",
    parameters: {
      type: "object",
      properties: {
        producto_id: { type: "string" },
        incluir_stock: { type: "boolean" }
      },
      required: ["producto_id"]
    }
  }
]
Enter fullscreen mode Exit fullscreen mode

El output sea exactamente:

{
  "name": "buscar_producto",
  "arguments": {
    "producto_id": "SKU-4821",
    "incluir_stock": true
  }
}
Enter fullscreen mode Exit fullscreen mode

Y no alguna variación creativa con claves renombradas, tipos erróneos o campos inventados. En eso los modelos pequeños generalistas fallan bastante. Si Needle lo resuelve de forma confiable, el caso de uso existe.


Cómo probarlo en Ollama: checklist reproducible

Si querés validar si un modelo como Needle tiene lugar en tu stack, el criterio no debería ser un benchmark ajeno. Debería ser tu propio conjunto de herramientas bajo las condiciones reales de tu sistema.

# Paso 1: Instalar Ollama si no lo tenés
curl -fsSL https://ollama.com/install.sh | sh

# Paso 2: Cuando el modelo esté disponible en Ollama registry, pull directo
# (verificar disponibilidad en https://ollama.com/search)
ollama pull needle  # nombre tentativo — verificar el registry oficial

# Paso 3: Preparar un set de pruebas de tool calling propio
# No uses los ejemplos del README del modelo; usá TUS herramientas reales
Enter fullscreen mode Exit fullscreen mode
// prueba-tool-calling.ts
// Criterios de validación que yo usaría para evaluar cualquier modelo pequeño

interface ResultadoPrueba {
  caso: string;
  esperado: object;
  obtenido: string;
  jsonValido: boolean;
  schemaRespetado: boolean;
  latenciaMs: number;
}

async function evaluarModeloToolCalling(
  modelo: string,
  casos: Array<{ prompt: string; schemaEsperado: object }>
): Promise<ResultadoPrueba[]> {
  const resultados: ResultadoPrueba[] = [];

  for (const caso of casos) {
    const inicio = Date.now();

    // Llamada al modelo vía API de Ollama
    const respuesta = await fetch("http://localhost:11434/api/chat", {
      method: "POST",
      headers: { "Content-Type": "application/json" },
      body: JSON.stringify({
        model: modelo,
        messages: [{ role: "user", content: caso.prompt }],
        // Pasar las herramientas como parte del request
        tools: [caso.schemaEsperado],
        stream: false,
      }),
    });

    const data = await respuesta.json();
    const latencia = Date.now() - inicio;

    // Validar si el JSON es parseable y si respeta el schema
    let jsonValido = false;
    let schemaRespetado = false;
    let obtenido = "";

    try {
      // El tool_call debería estar en message.tool_calls[0]
      const toolCall = data.message?.tool_calls?.[0];
      obtenido = JSON.stringify(toolCall ?? data.message?.content ?? "");
      jsonValido = !!toolCall;
      // Validación básica de schema: las claves required tienen que estar presentes
      if (toolCall?.function?.arguments) {
        const args = toolCall.function.arguments;
        const requiredKeys = Object.keys(caso.schemaEsperado);
        schemaRespetado = requiredKeys.every((k) => k in args);
      }
    } catch {
      obtenido = "parse error";
    }

    resultados.push({
      caso: caso.prompt.slice(0, 50),
      esperado: caso.schemaEsperado,
      obtenido,
      jsonValido,
      schemaRespetado,
      latenciaMs: latencia,
    });
  }

  return resultados;
}
Enter fullscreen mode Exit fullscreen mode

Mi criterio mínimo de aceptación para cualquier modelo de tool calling en un sistema real:

Métrica Mínimo aceptable Por qué
JSON válido 99%+ Un parse error en producción rompe el flujo entero
Schema respetado 95%+ Argumentos incorrectos son silenciosamente peligrosos
Latencia p95 < 500ms local Si tarda más que una API externa, perdiste el punto
Hallucination de tool names 0% Un nombre inventado es un error no recuperable

Los límites que el hype no menciona

Hay tres limitaciones que no aparecen en los titulares y que me parecen centrales antes de apostar por un modelo destilado en un sistema real.

Primero, la distribución del teacher define el techo. Si Gemini tiene sesgos en cómo genera tool calls — ciertos patrones de argumentos, ciertas convenciones de nombrado — el student los hereda sin filtro. Esto importa si tu API tiene convenciones que se alejan del estilo de Gemini.

Segundo, la generalización a schemas no vistos es una pregunta abierta. Un modelo destilado puede ser excelente en los patrones que aprendió y frágil frente a schemas complejos con anyOf, $ref anidados o validaciones condicionales. Hay que probarlo explícitamente con los schemas propios, no asumir que el benchmark general aplica.

Tercero, el tamaño de 26M parámetros implica capacidad de contexto limitada. En sistemas donde el prompt incluye muchas herramientas al mismo tiempo — algo común en backends con docenas de endpoints expuestos como tools — la degradación puede ser significativa. Es una hipótesis que hay que validar, no asumir.

Esto no invalida el proyecto. Lo ubica. La misma disciplina que apliqué al revisar problemas de caché en CI con pnpm workspaces aplica acá: primero entender el límite, después decidir si encaja.


Dónde Needle sí tiene sentido y dónde no

Escenarios donde tiene sentido probar Needle:

  • Pipelines de agentes locales donde la latencia de red hacia APIs externas es el cuello de botella
  • Edge devices o entornos con recursos limitados donde un modelo de 26M entra en memoria cómodamente
  • Sistemas con un conjunto acotado y estable de herramientas — no docenas de schemas cambiantes
  • Como fallback local cuando las APIs externas no están disponibles

Escenarios donde probablemente no alcanza:

  • Sistemas donde el razonamiento entre pasos de tool calling es complejo — decidir cuándo llamar qué tool, no solo cómo llamarla
  • APIs con schemas profundamente anidados o polimórficos
  • Flujos donde el contexto conversacional largo importa — el límite de contexto de 26M va a doler
  • Entornos que necesitan garantías de seguridad auditables — un modelo destilado privado es una caja más opaca

La tensión que señaló el post de Spring Boot Actuator en producción aplica de otra manera acá: la comodidad de "funciona en el demo" puede esconder riesgos de superficie que solo aparecen bajo carga o con inputs inesperados.


Lo que esto anticipa para el ecosistema de modelos pequeños

Lo incómodo de Needle no es el modelo en sí. Es lo que confirma: la especialización funcional va a presionar la hegemonía de los modelos grandes generales en tareas estructuradas.

Tool calling, clasificación de intents, extracción de entidades con schema fijo — son tareas donde un modelo destilado bien entrenado puede ganarle a GPT-4 o Claude en costo y latencia sin sacrificar confiabilidad. Eso cambia el cálculo de arquitectura.

En mi stack actual con Claude Code para razonamiento complejo y Ollama para tareas locales, hay un hueco exactamente donde Needle apuntaría: el router de herramientas que decide qué función llamar y con qué argumentos, sin necesitar el overhead de un modelo de 70B para eso. No digo que lo vaya a adoptar mañana. Digo que la categoría tiene sentido y que el experimento merece seguimiento.

Al igual que cuando evalué tradeoffs de Jakarta EE vs Spring Boot o comparé gestores de paquetes en monorepos reales, la respuesta honesta no es "adoptalo ya" ni "ignoralo": es "probalo con tus propios criterios antes de comprometerte".


FAQ: Needle, destilación y tool calling en modelos pequeños

¿Qué es exactamente la destilación de modelos en el contexto de LLMs?
Es un proceso donde un modelo grande (teacher) genera un dataset de comportamiento correcto — en este caso, ejemplos de tool calling bien formados — que se usa para entrenar un modelo pequeño (student). El student aprende a imitar la distribución de outputs del teacher en las tareas específicas para las que fue destilado, sin necesitar la arquitectura completa del teacher.

¿26M parámetros es suficiente para tool calling confiable?
Depende del scope. Para un conjunto acotado de herramientas con schemas simples, probablemente sí. Para sistemas con docenas de herramientas complejas, contextos largos o razonamiento multi-paso, es una hipótesis abierta. El benchmark del proyecto es optimista; la validación con schemas propios es obligatoria antes de apostar.

¿Cómo lo pruebo localmente sin comprometer un sistema en producción?
Con Ollama, si el modelo está disponible en el registry, es tan simple como ollama pull [nombre] y después evaluar con un script propio contra los schemas que ya usás. El checklist de validación de este post es un punto de partida. Siempre contra tus herramientas reales, nunca contra los ejemplos del README.

¿Cuál es la diferencia práctica entre Needle y usar function calling de OpenAI o Anthropic?
Latencia, costo y privacidad. Un modelo local no tiene RTT de red, no tiene costo por token y no manda los schemas de tus herramientas a una API externa. La contrapartida es que la confiabilidad depende enteramente de la calidad del entrenamiento del modelo local, sin el respaldo de un proveedor con SLA.

¿Vale la pena para un stack individual o solo para empresas con infraestructura?
Un modelo de 26M entra en una MacBook con 8GB de RAM sin drama. No es infraestructura de empresa. Si ya usás Ollama para otras tareas — como yo — agregar un modelo especializado es operativamente trivial. El costo real es el tiempo de evaluación, no el hardware.

¿Qué pasa si el modelo alucina un nombre de herramienta que no existe en mi sistema?
Es el peor caso y hay que diseñarlo como falla esperada. La capa de routing que consume el output del modelo tiene que validar que el name de la tool call corresponda a una herramienta registrada antes de ejecutar. Si no existe, el error tiene que ser explícito y no silencioso. Esto es diseño defensivo básico, independiente del modelo que uses.


Conclusión: probalo con los ojos abiertos

No voy a decir que Needle es el futuro ni que es ruido. Mi postura es más específica: la destilación funcional de comportamiento de modelos grandes en modelos pequeños especializados es una dirección legítima, y tool calling es un caso de uso donde tiene sentido técnico genuino.

Lo que no compro es el entusiasmo sin fricción. Un modelo de 26M tiene límites reales de contexto, de generalización y de confiabilidad bajo schemas no vistos. Esos límites no aparecen en el post de HN y aparecerán en producción.

Mi recomendación concreta: si tenés un pipeline de agentes con un conjunto estable de herramientas y latencia es un problema, armá un harness de prueba con los schemas propios, correlo contra los criterios de aceptación del post y medí. Si pasa el umbral de 99% de JSON válido y 95% de schema respetado en tus propios casos, tenés algo útil. Si no, sabés exactamente por qué.

Eso es más útil que cualquier benchmark ajeno.

¿Estás usando modelos locales para tool calling? Contame en juanchi.dev qué stack armaste y dónde encontraste los límites.


Este artículo fue publicado originalmente en juanchi.dev

Top comments (0)