Saltar al contenido

Por qué estoy aprendiendo Python para IA sin abandonar TypeScript

Después de años con JavaScript y Node.js, añadí Python y FastAPI a mi stack de IA. No por moda, sino para elegir la mejor frontera para cada ecosistema.

Por Yago Lagrotti Bracco6 min de lectura
  • python
  • fastapi
  • typescript
  • inteligencia artificial
  • arquitectura

Por qué añadí Python a mi stack

Después de años trabajando principalmente con JavaScript y TypeScript, llegué muy cerca de una conclusión cómoda: puedo construir prácticamente todo lo que necesito con este ecosistema.

Node/Nest en backend, React/Next en frontend, workers, colas, integraciones, streaming y APIs de LLM. Y sigo prefiriendo la sintaxis para muchas cosas del día a día.

Si me das estas dos líneas:

ts
const activeUsers = users.filter(user => user.active)
py
active_users = [user for user in users if user.active]

mi cerebro todavía elige la primera sin convocar una reunión.

Aun así, decidí aprender Python de verdad para IA y usar FastAPI en esa frontera.

No porque "Python sea obligatorio". Sino porque empecé a separar dos preguntas que estaba tratando como si fueran una sola:

  1. ¿qué lenguaje prefiero?
  2. ¿qué ecosistema elimina más trabajo en este problema concreto?

JavaScript no se volvió peor de repente

Esto fue lo primero que tuve que aclarar.

Añadir Python a la stack no significa admitir que Node.js sea inadecuado para IA.

Para una enorme cantidad de productos, TypeScript sigue siendo excelente para:

  • llamar OpenAI, Anthropic, Gemini, Kimi o Groq;
  • streaming de respuestas;
  • tool calling;
  • RAG sencillo;
  • integraciones SaaS;
  • orquestación web;
  • colas y workers;
  • APIs de producto;
  • autenticación y billing;
  • aplicaciones con AI SDK;
  • agentes cuyo trabajo principal es integrar herramientas web.

Si el valor principal del sistema está en las reglas de negocio y la IA es una dependencia más, no veo motivo para abandonar el ecosistema que ya entrega bien el resto del producto.

Dónde Python empezó a ganar para mí

La diferencia apareció cuando el proyecto dejó de limitarse a consumir modelos y empezó a hacer más ingeniería de IA.

Algunos ejemplos:

  • notebooks para experimentación;
  • evaluación de embeddings;
  • datasets;
  • pipelines de ML;
  • librerías académicas;
  • herramientas de visión y audio;
  • inferencia local;
  • Hugging Face;
  • PyTorch;
  • experimentos que nacen en papers y llegan primero a Python.

Parte de esto se puede usar desde JavaScript. La mejor pregunta es: ¿por qué añadiría fricción justo en el área donde estoy intentando aprender más rápido?

La arquitectura que tiene más sentido para mí

En lugar de pensar "voy a migrar a Python", empecé a pensar en fronteras.

txt
┌───────────────────────────────────────────┐
│ Producto                                  │
│ Next.js / TypeScript                     │
│ auth, UI, billing, workflows, webhooks   │
└─────────────────┬─────────────────────────┘
                  │ HTTP / queue / events
┌─────────────────▼─────────────────────────┐
│ Servicio de IA                            │
│ FastAPI / Python                          │
│ models, evals, RAG, ML, local inference  │
└───────────────────────────────────────────┘

No todo proyecto necesita esto. Un servicio extra sin necesidad es solo un impuesto operativo.

Pero cuando la frontera existe de verdad, queda clara: el producto sigue en TypeScript; el componente donde Python tiene una ventaja real de ecosistema pasa a Python.

Por qué FastAPI

Consideré varias opciones, pero FastAPI encaja bien con la forma en que ya pienso backend.

Una ruta sencilla es predecible:

py
from fastapi import FastAPI
from pydantic import BaseModel

app = FastAPI()

class AnalyzeRequest(BaseModel):
    text: str

class AnalyzeResponse(BaseModel):
    category: str
    confidence: float

@app.post('/analyze', response_model=AnalyzeResponse)
async def analyze(payload: AnalyzeRequest) -> AnalyzeResponse:
    result = await classifier.classify(payload.text)

    return AnalyzeResponse(
        category=result.category,
        confidence=result.confidence,
    )

Quien viene de NestJS reconoce los conceptos de inmediato:

  • contrato de entrada;
  • validación;
  • contrato de salida;
  • inyección de dependencias cuando hace falta;
  • OpenAPI;
  • separación por capas.

No necesito convertirme en coleccionista de frameworks para aplicar buena arquitectura en Python.

El peligro: escribir Node.js con sintaxis de Python

Es un error que intento evitar conscientemente.

Aprender un lenguaje no consiste solo en descubrir cómo escribe for, class y async. También significa aprender las convenciones que hacen legible el código de ese ecosistema.

Por eso mi ruta práctica está enfocada en:

  1. Python moderno y typing;
  2. uv para entornos y dependencias;
  3. Pydantic;
  4. FastAPI;
  5. pytest;
  6. async/await y concurrencia;
  7. notebooks cuando realmente ayudan;
  8. ecosistema de datos/IA;
  9. packaging y deploy.

El objetivo no es memorizar todo el lenguaje. Es llegar al punto en que pueda juzgar código Python sin traducir mentalmente cada línea a TypeScript.

Interfaces tipadas reducen fricción entre stacks

Cuando conviven dos lenguajes, los contratos importan aún más.

Prefiero fronteras explícitas:

json
{
  "documentId": "doc_123",
  "analysis": {
    "category": "quality-complaint",
    "confidence": 0.94,
    "evidence": ["line 12", "line 48"]
  }
}

OpenAPI ayuda bastante aquí.

Un servicio FastAPI puede publicar su schema y el lado TypeScript puede generar o validar el cliente. Cambia el lenguaje; el contrato no se vuelve implícito.

Para trabajo asíncrono, la frontera también puede ser una cola:

txt
Node publica job → worker Python procesa → evento de resultado → Node actualiza producto

Lo importante es evitar un híbrido fuertemente acoplado donde cada lado conozca detalles internos del otro.

Qué se queda en TypeScript

Mi heurística actual es simple.

Empiezo con TypeScript cuando el problema es principalmente:

  • producto web;
  • integraciones;
  • reglas de negocio;
  • APIs tradicionales;
  • automatización SaaS;
  • agentes con muchas herramientas web;
  • realtime.

Traigo Python cuando entran con fuerza:

  • ML;
  • experimentación científica;
  • modelos locales;
  • pipelines de datos orientados a IA;
  • librerías que tratan Python como first-class;
  • evaluación muy ligada al ecosistema de investigación.

No es una ley. Es una heurística para que la elección de lenguaje no se convierta en identidad.

Un ejemplo realista: análisis de reclamaciones de calidad

Imagina un sistema interno que recibe hojas de cálculo complejas, normaliza reclamaciones, agrupa causas probables y alimenta un dashboard.

Podría organizarlo así:

txt
Desktop / Web UI
      ↓
API de aplicación
      ↓
parser y normalización
      ↓
clasificación / embeddings / clustering
      ↓
reglas verificables
      ↓
base analítica
      ↓
Power BI

La parte de producto puede quedarse en una stack conocida. Clustering, embeddings, parsing experimental y evaluación de modelos probablemente me den más opciones en Python.

Cada ecosistema hace lo que mejor sabe hacer.

El insight más importante no fue sobre Python

El insight real fue notar que estaba optimizando demasiado pronto para una única stack.

Una stack consistente es excelente. Una stack dogmática no.

Demasiados servicios son malos. Demasiados lenguajes también. Pero insistir en una herramienta solo porque es familiar puede crear otro tipo de complejidad: adapters, bindings, librerías menos maduras y tiempo perdido luchando con el ecosistema.

Hoy prefiero preguntar:

¿cuál es la menor cantidad de tecnologías que le da a este producto acceso a las mejores herramientas para el problema?

A veces la respuesta sigue siendo full TypeScript.

En sistemas de IA más profundos, cada vez me resulta más natural que la respuesta sea TypeScript y Python.

Y está bien.

Mi objetivo con FastAPI

No quiero convertirme en alguien que conoce veinte frameworks Python de forma superficial.

Quiero suficiente profundidad para construir un servicio de IA de producción con:

  • contratos claros;
  • tests;
  • observabilidad;
  • colas cuando haga falta;
  • procesamiento asíncrono;
  • aislamiento de dominio;
  • deploy reproducible;
  • evaluación de modelos separada de opiniones.

Es decir: las mismas preocupaciones de ingeniería que tenía antes de que Python entrara en la historia.

Cambia el lenguaje. La ingeniería sigue siendo ingeniería.

Referencias