Volver al Blog
Publicado el

Google acaba de borrar tu roadmap: lo que el cierre de Assistant nos enseña sobre alquilar tus cimientos

Auditoría y RecuperaciónArquitectura de SoftwareEstrategia de IALiderazgo de IngenieríaCloud e Infraestructura
Google acaba de borrar tu roadmap: lo que el cierre de Assistant nos enseña sobre alquilar tus cimientos

En algún lugar, ahora mismo, hay un responsable de ingeniería leyendo un aviso de discontinuación y haciendo cuentas mentalmente. Google Assistant está siendo retirado de los teléfonos y tablets Android en favor de Gemini. Para la mayoría de la gente es una noticia de consumo. Para un pequeño número de equipos de producto es una migración forzada con fecha límite, que aterriza en medio de un trimestre que ya estaba completamente comprometido.

La parte dolorosa no es la migración en sí. Es el proceso de descubrimiento. Alguien tiene que abrir el código y responder a una pregunta que nadie ha formulado en tres años: ¿dónde tocamos exactamente esta cosa? No "¿usamos Assistant?" - por supuesto que sí, ha estado en tu superficie de integración durante años. Sino ¿qué flujos? ¿Es solo la App Action que abre una pantalla? ¿O es la ruta de accesibilidad por voz de la que depende un subconjunto de tus usuarios y que nunca aparece en tus analíticas porque no dispara los mismos eventos? ¿Es la vinculación con el hogar inteligente que tu socio de hardware revende como una funcionalidad? ¿Está en las capturas de la App Store?

Enumerar esos puntos de contacto flujo por flujo - la arqueología, no la lista de proveedores - suele llevar una semana si se hace bien. Y esa semana sale de la misma capacidad de sprint que habías presupuestado para el arreglo real.

La discontinuación no es una traición. Es meteorología.

Quitemos de en medio lo obvio. Google no perjudicó a nadie aquí. Según nuestra lectura, Assistant llevaba tiempo estratégicamente despriorizado y una consolidación en torno a Gemini parecía probable, y una empresa que mantiene todos sus productos vivos para siempre acaba con un portafolio que nadie puede mantener. Retirar productos es señal de una organización de ingeniería sana, no hostil.

El error no es confiar en un proveedor. El error es tratar una plataforma externa como si tuviera las mismas garantías de ciclo de vida que tu propio código. Tu código cambia cuando tú lo decides. Una plataforma cambia cuando cambian los OKR de otra persona. Son dos perfiles de riesgo completamente distintos, y la mayoría de las arquitecturas no los distinguen en absoluto.

Aquí está la versión incómoda: si la retirada de un tercero puede borrar un trimestre de tu roadmap, esa dependencia era estructural y no estaba declarada. El anuncio del proveedor no creó la fragilidad. Solo la reveló, en su calendario y no en el tuyo.

El coste real es la arqueología, no la reescritura

Cuando los equipos estiman una migración forzada, estiman la nueva integración. Conectar el nuevo SDK, adaptar los payloads, desplegar. Dos semanas, quizá tres.

Lo que realmente consume el tiempo:

Encontrar cada punto de contacto. Las integraciones se extienden. Lo que empieza como un módulo acaba referenciado en una app móvil, un manejador de webhooks en el backend, un runbook de operaciones, una página de marketing, un contrato con un socio y un fichero de Terraform. Rara vez hay una única frontera por la que cortar.

Reconstruir la intención. La persona que construyó la integración probablemente ya no está. El comportamiento está documentado en el código, no las decisiones. ¿Por qué la ruta de voz se salta el paso de confirmación? ¿Fue una decisión deliberada de UX o un workaround para una limitación de la plataforma que ya no existe? Nadie lo sabe, así que o preservas fielmente un bug o arriesgas romper algo que no entiendes.

Renegociar expectativas. Alguien vendió esta funcionalidad. Está en una presentación, en una renovación, en una declaración de cumplimiento de accesibilidad. La migración técnica es la conversación fácil comparada con decirle a un cliente que una capacidad que se le prometió está cambiando de forma.

Superficie de regresión. Según nuestra experiencia, las superficies de voz y asistente son difíciles de probar automáticamente. Heredas una carga de QA manual que compite con todo lo demás en la release.

Por eso, según nuestra experiencia, una migración "de tres semanas" se convierte de forma fiable en un trimestre. Y por eso la discontinuación de plataformas pertenece a la misma lista que las señales clásicas que justifican una auditoría: bugs recurrentes, releases que dan miedo, roadmaps bloqueados, opacidad de proveedores. El síntoma parece externo, pero la condición subyacente es interna: no tienes un mapa de tu propio sistema.

El mapa de dependencias es el artefacto más barato que producirás jamás

Según nuestra experiencia, la mayoría de las empresas no pueden responder a "¿qué plataformas de terceros nos romperían si desaparecieran mañana?". No por descuido, sino porque nadie es dueño de la pregunta. Compras es dueña de los contratos. Ingeniería es dueña del código. El hueco entre ambas es donde viven, sin documentar, las dependencias estructurales.

Puedes cerrar la parte de ese hueco a nivel de proveedor en unos 90 minutos con una pizarra y un grep: de qué plataformas dependes y, aproximadamente, qué superficies tocan. Ese es un trabajo distinto de la semana de arqueología de puntos de contacto por flujo descrita arriba - el mapa no elimina la arqueología, la acorta, porque empiezas desde una lista de superficies en lugar de una página en blanco. Hazlo antes de que el comunicado de prensa de otro te obligue.

Empieza con un inventario plano. Cada plataforma externa que tu producto toca en tiempo de ejecución, en tiempo de compilación o en tu narrativa de cumplimiento. Después clasifica cada una en tres ejes: cuánto de tu producto se rompe si desaparece (radio de impacto), cuánto trabajo supondría un reemplazo (coste de sustitución) y qué tan buena es la frontera a su alrededor (abstracción).

# dependency-map.yaml — keep it in the repo, review it quarterly # status: RED | AMBER | GREEN | ACCEPTED — derived from the three axes below # RED = serious blast radius + weak or absent abstraction # AMBER = serious blast radius + partial abstraction, or minor radius + none # GREEN = clean boundary, swap is a diff # ACCEPTED = deliberately unabstracted, written down, owner on record dependencies: - name: Payment processor surface: [checkout, payouts, refunds] blast_radius: revenue-stops swap_cost: high # regulated, custom flows, stored tokens abstraction: partial # domain service exists, webhooks are not abstracted status: AMBER # revenue-stops + partial abstraction - name: LLM provider (chat + summarisation) surface: [assistant-panel, digest-emails] blast_radius: feature-degraded swap_cost: low abstraction: full # single adapter, prompts versioned, evals in CI status: GREEN - name: Voice / assistant platform surface: [android-app-actions, accessibility-path] blast_radius: feature-gone compliance_risk: accessibility-claim swap_cost: medium abstraction: none # SDK types leak into view models status: RED # feature-gone + no abstraction - name: Managed database (cloud provider) surface: [all-persistence] blast_radius: revenue-stops swap_cost: high abstraction: none # deliberate: we use provider-specific features status: ACCEPTED accepted: true rationale: >- A generic persistence layer buys portability we will never exercise and costs performance, features, and clarity. Reviewed 2026-Q3, platform team.

Rojo no significa "crítico". Rojo significa radio de impacto serio y una frontera débil. Un procesador de pagos incrustado en tu ruta de ingresos puede ser verde si has mantenido una costura limpia a su alrededor. Una funcionalidad cosmética puede ser roja si los tipos de su SDK están embadurnados por cuarenta ficheros. La forma de la frontera determina tus opciones; el radio de impacto determina lo que está en juego; el coste de sustitución te dice lo que costará ejercer esas opciones.

De esto salen tres decisiones, y solo tres:

Abstraerla. Merece el esfuerzo cuando la dependencia es reemplazable y la frontera es delgada. Introduce una costura, apropiate del modelo de dominio, trata al proveedor como un detalle de implementación.

Aceptarla. Algunas dependencias no merecen ser abstraídas. Si estás totalmente comprometido con la base de datos gestionada de un proveedor cloud, una capa de persistencia genérica te cuesta rendimiento, funcionalidades y claridad a cambio de una portabilidad que nunca ejercerás. Deja escrito que aceptaste el riesgo y por qué - para eso están el estado ACCEPTED y su rationale, para que la entrada se lea como una decisión y no como un descuido. Esa frase vale más que una abstracción falsa.

Arrancarla de raíz. Si una dependencia sostiene una funcionalidad que nadie usa, la discontinuación es un regalo. Elimina la funcionalidad. Es la opción a la que los equipos recurren en último lugar y a la que deberían recurrir primero.

La parte a contracorriente: abstraerlo todo es peor que no abstraer nada. Un wrapper genérico alrededor de un proveedor que nunca vas a cambiar añade indirección, oculta comportamiento y crea una segunda cosa que mantener. La portabilidad tiene un precio. Págalo deliberadamente, allí donde las probabilidades lo justifiquen.

Cómo se ve una costura real

Dado que los proveedores de IA son donde esta presión es hoy más alta, úsalos como ejemplo trabajado. Nosotros mismos desplegamos sobre OpenAI y Claude. La cuestión no es evitar a los proveedores de modelos, sino hacer que cambiar de uno sea un trabajo de dos días en lugar de una reconstrucción de dos trimestres.

Una costura no es wrapper.callTheApi(). Una costura es una frontera expresada en tu lenguaje de dominio, donde el vocabulario del proveedor deja de existir.

// Your domain. No vendor nouns. No SDK types. No 'messages' array. export interface TranscriptSegment { speaker: string; startMs: number; text: string; } export interface Decision { id: string; statement: string; owner: string | null; } export interface ActionItem { id: string; description: string; owner: string | null; dueDate: string | null; } export interface SummariseInput { transcript: TranscriptSegment[]; audience: "exec" | "engineering"; } export interface MeetingSummary { headline: string; decisions: Decision[]; actions: ActionItem[]; confidence: "high" | "low"; } export interface MeetingSummariser { summarise(input: SummariseInput): Promise<MeetingSummary>; } // Domain failure modes. Vendor errors never escape the adapter. export class SummariserUnavailable extends Error {} export class SummariserInvalidOutput extends Error {}

Todo lo específico del proveedor vive al otro lado: construcción de prompts, contabilidad de tokens, reintentos, esquemas de herramientas, reparación de JSON, peculiaridades de cada modelo. Los fallos del proveedor también se detienen ahí - salen como SummariserUnavailable o SummariserInvalidOutput, nunca como un 429 o un ZodError.

export class ClaudeSummariser implements MeetingSummariser { constructor(private client: Anthropic, private prompts: PromptRegistry) {} async summarise(input: SummariseInput): Promise<MeetingSummary> { const prompt = this.prompts.get("meeting.summary.v7"); let lastError: unknown; for (let attempt = 0; attempt < 3; attempt++) { try { const raw = await withTimeout( this.client.messages.create({ model: "claude-sonnet-4-5", max_tokens: 2000, system: prompt.system, messages: [{ role: "user", content: render(prompt.user, input) }], }), 20_000, ); // Vendor shape dies here. Nothing above sees this structure. return MeetingSummarySchema.parse(repairJson(extractJson(raw))); } catch (err) { lastError = err; // 429s, 5xx, 'overloaded', timeouts, and malformed JSON are all worth another go. if (attempt < 2 && isRetryable(err)) { await backoff(attempt); continue; } if (err instanceof ZodError) { throw new SummariserInvalidOutput("summary did not match the domain schema"); } throw new SummariserUnavailable("summariser call failed"); } } throw new SummariserUnavailable(`summariser exhausted retries: ${classify(lastError)}`); } }

Dos detalles hacen que esto sea real y no teatro.

Los prompts son artefactos versionados, no literales de cadena. meeting.summary.v7 es una entrada de registro con un hash, un responsable y un changelog. Según nuestra experiencia, los prompts son el código con mayor rotación y menor revisión de un producto de IA. Si son cadenas en línea, tu migración consiste en buscar párrafos entrecomillados por todo el código.

Las evals se ejecutan en CI contra la interfaz, no contra el proveedor. Esta es la parte que los equipos se saltan, y es la parte que convierte un cambio de proveedor de una apuesta en un diff. La salida de un modelo es no determinista, así que una única aserción no te dice nada útil: puntúa un conjunto de fixtures a lo largo de ejecuciones repetidas y pon la puerta en una tasa de acierto.

const providers = [ ["claude", makeClaude], ["openai", makeOpenAI], ] as const; const RUNS = 20; const PASS_RATE_THRESHOLD = 0.9; describe.each(providers)("MeetingSummariser: %s", (_name, make) => { it.each(fixtures.decisionCases)("extracts decisions: $id", async (fixture) => { const summariser = make(); let passes = 0; for (let run = 0; run < RUNS; run++) { const result = await summariser.summarise(fixture.input); const ids = result.decisions.map(d => d.id); const ok = fixture.expectedDecisionIds.every(id => ids.includes(id)) && result.confidence === fixture.expectedConfidence; if (ok) passes++; } expect(passes / RUNS).toBeGreaterThanOrEqual(PASS_RATE_THRESHOLD); }); });

Ejecuta la misma suite contra cada proveedor candidato. Ahora "¿deberíamos abandonar este modelo?" tiene una respuesta con números en lugar de intuiciones: tasas de acierto por fixture, por proveedor, en el log de CI. Sin evals puedes construir una abstracción perfecta y seguir siendo incapaz de cambiar, porque nadie puede demostrar que el nuevo proveedor es tan bueno como el anterior. Esa es la trampa: la interfaz está limpia, y la decisión sigue atascada. Cualquiera que haya visto a un gran asistente de voz encallar a mitad de reconstrucción ha visto este patrón desde fuera.

Y mantén un interruptor de emergencia. A nivel de configuración, no de código. La raíz de composición es el único lugar del sistema donde se permite que existan nombres de proveedores - el código de aplicación por debajo nunca los conoce.

// Resolved per call, so a config change doesn't need a code change. // The id is just a registered string ("claude", "openai", "local"); nothing // outside this function and the registry's boot-time wiring sees it. function getSummariser(): MeetingSummariser { return providerRegistry.resolve(config.current().providers.summariser); }

Si un proveedor se degrada un viernes por la tarde, cambias una variable de entorno y reinicias el servicio. Si tu fuente de configuración soporta recarga en caliente, la siguiente llamada recoge el cambio directamente. En cualquier caso, no despliegas un hotfix.

La regla: asume una fecha de caducidad que no controlas

Toda dependencia externa tiene un final. No sabes la fecha, y no tienes voto. Eso no es cinismo, es simplemente cómo funciona el roadmap de otra persona.

La respuesta arquitectónica no es la paranoia ni internalizar todo. Es humildad, escrita en el diseño. Sé dueño de tu modelo de dominio. Deja que los proveedores sean implementaciones. Mantén un mapa de dependencias que una persona no técnica pueda leer. Deja escrito qué riesgos has aceptado, para que la siguiente persona no confunda una decisión con un descuido. Y construye las pruebas que te permitan demostrar que un cambio de proveedor es seguro, porque una portabilidad que no puedes verificar no es portabilidad.

Esa es la tesis, y esta discontinuación la ilustra con precisión. El coste de una migración forzada lo determinan tres cosas: si la dependencia estaba en un mapa, cuánto del vocabulario del proveedor se filtró en tu modelo de dominio, y si puedes demostrar que un reemplazo se comporta igual. Un código perfectamente estable con tipos de Assistant embadurnados por sus view models paga dos veces: una por la integración original y otra por reconstruirla. Un código más desordenado con una costura limpia y una suite de evals en verde paga una sola vez.

Si ahora mismo no puedes responder a "¿qué plataformas de terceros nos romperían si desaparecieran?" - ese es el hallazgo. No una crisis, solo un hueco con un coste conocido. Es más barato cerrarlo un martes tranquilo que durante la ventana de migración de otro.

La discontinuación de plataformas es la quinta señal de alarma, junto a los bugs recurrentes, las releases que dan miedo, los roadmaps bloqueados y la opacidad de los proveedores. Si acabas de darte cuenta de que no puedes responder a la pregunta de las dependencias, dediquémosle treinta minutos.

Reserva una Auditoría Gratuita

Artículos relacionados

Tu agente de IA no leyó el manual: por qué la gobernanza debe ser código, no prosa
Estrategia de IA

Tu agente de IA no leyó el manual: por qué la gobernanza debe ser código, no prosa

Los prompts extensos no gobiernan de forma fiable a los agentes de IA. La gobernanza real vive en permisos, validadores y máquinas de estados, no en prosa.

Por qué el 'AI Slop' es la señal de alerta que tu recuperación de software necesita ahora
Estrategia de IA

Por qué el 'AI Slop' es la señal de alerta que tu recuperación de software necesita ahora

La economía de creadores se está ahogando en basura generada por IA. Si tu plataforma se apresura a agregar funciones de IA sobre cimientos inestables, no estás innovando: estás acumulando deuda técnica que te costará el doble arreglar.

El Problema de la Ventana de Contexto de la IA: Por Qué Tu Sistema Empresarial Es Demasiado Complejo para los LLMs (Y Lo Que Silicon Valley No Te Está Contando)
Realidad de la IA

El Problema de la Ventana de Contexto de la IA: Por Qué Tu Sistema Empresarial Es Demasiado Complejo para los LLMs (Y Lo Que Silicon Valley No Te Está Contando)

Silicon Valley promete que la IA reemplazará a tus ingenieros. Las matemáticas dicen lo contrario. Aquí está por qué la limitación de la ventana de contexto significa que la IA solo puede ver el 0.67% de tu base de código-y lo que la reversión de contrataciones de Big Tech nos dice sobre el secreto sucio de la automatización.