Back to deblo
deblo

Pulse: cómo reemplazamos el pitch deck con una IA de voz en tiempo real a la que los inversores pueden hacer preguntas directas — sobre la misma base que el producto de consumo

Pulse es la superficie para inversores de Déblo, construida sobre el mismo backend FastAPI, el mismo worker LiveKit, el mismo modelo Gemini Live. RBAC por magic-link HMAC, treinta y cinco herramientas de voz más tres utilidades, una vista materializada Postgres para el cálculo de retención, el rediseño del home en minimalismo radical, y la regla de prompt one-shot para las herramientas con efecto colateral. La due diligence se convierte en la demo.

Juste A. Gnimavo (Thales) & Claude | May 30, 2026 36 min deblo
EN/ FR/ ES
deblopulseinvestor-portalkpi-dashboardsveltekitgemini-livevertex-ailivekitmagic-linkhmacfunction-callingretention-cohortspostgres-viewsaudience-routingsystem-promptsone-shot-action-toolsnda-gateclaude-opus-4.7claude-codemonorepo-shared-stackreal-time-voicedue-diligence-as-demo

Por Thales (CEO, ZeroSuite) y Claude Opus 4.7 — instancia Claude Code

La premisa de Pulse cabe en una frase: en lugar de enviarle a un inversor un pitch deck en PDF, envíale un enlace a pulse.deblo.ai, donde puede hacer preguntas directas sobre el negocio a la IA, por voz, y recibir respuestas generadas en tiempo real desde la base de producción.

Fue idea de Juste, escrita en una nota estratégica el 22 de mayo de 2026, tres días antes del fin de semana largo durante el cual se envió la primera versión. La tesis era que la conversión de «idea interesante» a «term sheet» pasa la mayor parte de su calendario en bucles de due diligence donde el inversor envía preguntas por correo, el fundador las reenvía al equipo, el equipo produce números en Sheets, el fundador edita la respuesta por el tono, la respuesta vuelve. Cada bucle dura entre dos y siete días. El momentum del deal muere entre los bucles. La experiencia que el inversor tiene de la empresa es una secuencia de respuestas asíncronas pulidas que no le dicen nada sobre cómo funciona realmente el producto.

Pulse reemplaza ese bucle con una conversación de voz. El inversor abre el panel, ve diecisiete tarjetas KPI en vivo, toca el micrófono y pregunta «¿cuántos minutos de voz hemos servido en Gemini Flash Live esta semana?» — y la IA responde, en voz, desde la base de producción, en tres a cinco segundos. La due diligence del inversor también es la demo del producto. La demo del producto también es la prueba de calidad de consumo de Vertex AI. Tres artefactos se funden en una sola experiencia.

Este artículo recorre la arquitectura que lo hizo posible, por qué elegimos enviar Pulse sobre el mismo backend que el producto de consumo, qué cubren las treinta y cinco herramientas de voz, el RBAC por magic-link que distingue fundador-de-inversor-de-público, cómo el cálculo de cohortes de retención se convirtió en una vista Postgres porque el cálculo en memoria era la capa incorrecta, qué aprendimos del rediseño minimalista-radical de la superficie Ask del home del 26 de mayo, y qué nos regaló la base del Déblo de consumo que habría que haber construido dos veces si Pulse hubiera sido un proyecto greenfield.


Parte 1 — Por qué construir una segunda aplicación sobre la misma base

La primera decisión fue arquitectónica. Pulse podría haber sido una codebase aparte, un backend aparte, una base de datos aparte, una infraestructura de voz aparte. El plan inicial entregado el 22 de mayo asumía exactamente eso — un proyecto greenfield React + Vite con su propio pipeline de ingestión leyendo desde una copia de la base Déblo. Rechazamos ese plan en la primera sesión y enviamos Pulse como segunda superficie de producto sobre el mismo monolito.

El razonamiento tiene tres partes.

Uno. La primitiva de audience-routing ya existía en la codebase de consumo. El agente de voz de Déblo corre sobre un único worker LiveKit que consume el campo metadata de la room entrante para determinar qué system prompt cargar (K12, Pro, Companion, Adult) y qué catálogo de herramientas exponer. Añadir una quinta audiencia — pulse — significaba añadir una rama más en la capa de dispatch, un archivo de system prompt más (text_pulse.py + voice_pulse.py), y un registro de herramientas más. La complejidad marginal de añadir una audiencia es baja porque la capa de dispatch fue diseñada para ello.

Dos. La base Postgres que respalda Déblo es el sistema de producción que Pulse necesita consultar. Si Pulse tuviera su propia base, cada consulta de métrica iría contra una copia que se desvía detrás de la fuente de verdad. El inversor que pregunta «¿cuál es nuestra tasa de activación de voz esta semana?» obtendría un número desactualizado entre seis y veinticuatro horas según el intervalo de sync, que es el tipo de número que destruye la confianza más rápido que no tener número alguno. Poner las consultas de Pulse en la misma base significa que la respuesta del inversor coincide con lo que el fundador ve en el Slack del equipo en el momento en que se hace la pregunta.

Tres. La infraestructura de voz LiveKit es por-room, no por-app. El mismo worker Gemini Live puede alojar una conversación de estudiante K12, una conversación de contable Pro y una conversación de due diligence de inversor en tres rooms concurrentes sin estado compartido y sin contención. Obtenemos la segunda superficie de producto sobre la misma infraestructura en tiempo real gratis.

El compromiso que aceptamos es que el código de Pulse vive en el monorepo de Déblo y comparte la cadencia de despliegue del producto de consumo. Un cambio breaking en la capa de dispatch o en el worker de voz afectaría a ambas superficies simultáneamente. Lo mitigamos tratando el directorio pulse/ como un proyecto SvelteKit separado con sus propias rutas (pulse.deblo.ai es su propio servicio Easypanel), sus propios design tokens y sus propios componentes — pero con lógica de negocio compartida (RAG, créditos, pipelines OCR que no usamos en Pulse, y el worker LiveKit que sí usamos).

Seis meses después, la decisión ha aguantado. Pulse ha enviado diez fases de herramientas adicionales sobre la superficie KPI Phase 1-6 original (Phase 7 añadió once herramientas para splits de audiencia y clases K12, Phase 8 añadió seis para sub-audiencias Companion, Phase 10 añadió tres para cohortes de retención) sin forzar un solo cambio en el camino de voz de consumo. La rama de audience-routing en el worker ha aguantado cada vez. El contador de sesiones concurrentes de inversor no ha colisionado con el contador de sesiones concurrentes K12 porque el dispatcher de rooms LiveKit no se preocupa por la identidad de audiencia; se preocupa por el nombre de la room.


Pulse tiene tres audiencias con tres niveles de acceso.

Los usuarios públicos aterrizan en pulse.deblo.ai/public y ven cinco números top-line: signups acumulados, MAU, minutos de voz acumulados, idiomas activos, países activos. Sin autenticación. La superficie pública existe para que un periodista o un socio pueda verificar que la empresa es real sin que le emitamos un magic link.

Los usuarios inversores aterrizan en pulse.deblo.ai/i/{token} vía un magic link personalizado que acuñamos desde una CLI (python -m app.pulse.magic_link mint --persona investor --email [email protected]). La CLI produce un token firmado con HMAC que codifica la persona, el correo y la fecha de emisión. Hacer clic en el enlace resuelve el token del lado del servidor, establece una cookie HttpOnly con scope en .deblo.ai con expiración de 90 días, redirige al modal del NDA, y de ahí al panel completo. El token es de un solo uso — una vez canjeado, la cookie es el mecanismo de acceso. El inversor nunca vuelve a ver el token después del primer clic.

Los usuarios fundador/equipo se autentican a través del JWT Déblo existente (el camino de auth de consumo) y son reconocidos como elegibles para Pulse si su correo coincide con una whitelist en PULSE_FOUNDER_EMAILS. Ven el mismo panel que los inversores, más las secciones operativas exclusivas del fundador (uptime, latencia de voz p50/p90/p99, telemetría de coste GCP por SKU, estado de alertas).

La gate del NDA es un modal, no una página aparte. El modal está montado sobre la propia ruta del panel con un z-index por encima de todos los elementos interactivos. Hasta que el inversor acepta (un único botón: «Acepto la confidencialidad»), el panel se renderiza detrás del modal con un desenfoque de fondo pesado pero no responde a los clics. Aceptar escribe acceptedNda = true en la cookie de sesión y cierra el modal. El inversor puede hacer scroll, tocar, hacer preguntas.

La decisión de hacer del NDA un modal en lugar de una página separada firmar-NDA-luego-redirigir es una decisión que tomamos en la primera sesión de Pulse y no hemos revisitado. El patrón modal significa que la primera impresión que el inversor tiene de Pulse es el panel con diecisiete tarjetas KPI en vivo visibles (borrosas) detrás de la superficie de consentimiento. Sabe a qué está consintiendo antes de consentir. El patrón redirect le habría dado una página vacía que dice «firma el NDA para ver el panel» — estrictamente menos informativo, estrictamente más fricción. El rastro de auditoría es el mismo en ambos patrones: cada aceptación de NDA se registra con la persona, el correo, la IP, el timestamp.

El registro de auditoría es el punto más importante. Cada endpoint impactado por una sesión de inversor — cada llamada de herramienta de voz, cada navegación en el panel, cada canjeo de magic-link — se registra en pulse_audit_events con la persona y el timestamp. Podemos responder a la pregunta «¿quién vio qué, cuándo?» para cualquier superficie de inversor del panel, que es la pregunta que reguladores y asesoría legal a veces hacen. El registro de auditoría es una tabla Postgres de cinco columnas con un único INSERT por evento, fachada por un bloque async with session.begin() en la dependencia FastAPI. El coste es una fila extra escrita por petición, lo que es insignificante frente al coste de cualquier llamada de herramienta de voz.


Parte 3 — Treinta y cinco herramientas de voz, más tres utilidades

El agente de voz de Pulse es el mismo modelo gemini-live-2.5-flash-native-audio que usa el producto de consumo, despachado a través del mismo worker LiveKit, configurado con un system prompt diferente (voice_pulse.py) y un registro de herramientas diferente. El conteo de herramientas, a fecha de Phase 10 enviada el 25 de mayo, es de treinta y cinco herramientas primarias más tres utilidades (report_bug, send_email_to_self, leave_review).

Las herramientas caen en siete categorías:

Métricas hero. Total de signups, MAU, minutos de voz acumulados, idiomas activos, países activos, resumen de retención. Mapean los números top-line de la superficie pública y existen como herramientas de voz porque los inversores las preguntan primero como preguntas de calentamiento.

Detalle de crecimiento. Signups diarios para los últimos 30 / 60 / 90 días, distribución de estudiantes K12 por clase (CP hasta Terminale), split de audiencia (K12 / Pro / Companion / Adult), tasa de activación del portal de padres. El desglose por clase K12 es el tipo de número que cabe naturalmente en una tarjeta de panel pero es más poderoso cuando un inversor puede preguntar «desglosa los signups de estudiantes K12 por clase para los últimos treinta días» y hacer que la IA itere por los buckets en voz.

Engagement. Minutos de voz por día por audiencia, duración media de sesión de voz, número medio de turnos de chat por sesión, tasa de retorno por día de la semana, conteo de turnos condicionado por audiencia. Phase 7 expandió esta categoría agresivamente porque a los inversores les importa la profundidad de engagement y las herramientas Phase 1-6 solo cubrían la amplitud.

Sub-audiencia Companion. Usuarios Companion divididos por sub-tipo padre / pro / adulto / niño, minutos de voz por sub-tipo, retención por sub-tipo. Esta categoría existe porque la audiencia Companion es una apuesta estratégica (la IA como compañera de vida diaria en lugar de experta de dominio) y el split por sub-tipo cuenta la historia de qué rol de vida diaria está enganchando.

Monetización. Conteo de usuarios pagos, ingresos acumulados en USD-micro, tasa de conversión pago por operador de mobile money (Wave, Orange Money, MTN MoMo, Moov, Togocel), distribución de packs de créditos, ingreso medio por usuario pago. Cada operador tiene su propia herramienta porque los inversores que evalúan un negocio multi-rail de mobile money quieren saber qué rails convierten y cuáles no.

Coste Vertex AI. Gasto Vertex acumulado, burn Vertex diario, gasto Vertex por minuto de voz (el número de unit-economics que conecta coste con ingreso), top-cinco de gasto Vertex por SKU (qué variantes de modelos están impulsando la factura). Esta categoría existe porque Google Cloud es uno de nuestros inversores-y-socios, y la pregunta «¿cómo tiende el gasto Vertex frente a los créditos restantes?» es la pregunta que Sulgi e Ifeanyi hicieron específicamente cuando redactamos el primer correo a inversores.

Retención. Retención diaria D1 / D7 / D30, heatmap de cohortes (signups agrupados por semana ISO, retención por semana-desde-signup), resumen mejor / peor / mediano de cohorte. Esta es la expansión de Phase 10 (25 de mayo de 2026) y es la mayor pregunta única de inversor que Phase 1-6 no respondía. «¿Estás reteniendo a los usuarios que adquieres?» es la pregunta que convierte una curva de crecimiento interesante en una tesis invertible.

Las tres herramientas utilitarias — report_bug, send_email_to_self, leave_review — existen porque los inversores a veces quieren darnos feedback durante una sesión, no solo recibir respuestas. report_bug archiva un bug estructurado en nuestro tracker interno con la persona del inversor adjunta. send_email_to_self permite al inversor enviarse por correo un resumen de la conversación para más tarde. leave_review registra una impresión cualitativa de una línea indexada a la sesión del inversor, para que el fundador pueda leer lo que dijo y hacer seguimiento. Las tres utilidades son fire-and-forget a nivel del worker; el agente acusa la acción verbalmente sin confirmar la escritura en base.

Las treinta y cinco herramientas primarias comparten un patrón de implementación común. Cada herramienta es una función async de Python en backend/livekit_agent/pulse_tools.py que toma input estructurado del function_call del modelo, consulta Postgres a través de app.pulse.queries, formatea el resultado a través de _augment_monetary si el valor es una cantidad monetaria (para que USD-micro se convierta en USD con un signo de dólar), y devuelve una respuesta estructurada que el agente lee en voz alta. La verificación de auth se hace en el ingress FastAPI (la cookie de sesión de inversor es necesaria para cualquier llamada Pulse) y se omite para sesiones de fundador. El registro de herramientas se computa al inicio de la sesión, basado en la audiencia codificada en los metadatos de la room LiveKit.


Parte 4 — Por qué el cálculo de retención se movió a una vista Postgres

Phase 10 enviada el 25 de mayo añadió la retención como séptima categoría de herramientas. La decisión de diseño interesante fue dónde vive el cálculo.

El enfoque ingenuo es calcular la retención en Python del lado de la aplicación. Para cada usuario, encontrar su created_at, luego contar si tuvo alguna actividad de sesión en las ventanas D1 (día 1 post-signup), D7, D30. Agregar entre todos los usuarios. Repetir para cohortes semanales. El Python son quince líneas, el SQL detrás es una serie de consultas JOIN con aritmética de fechas, la respuesta es correcta.

El problema con este enfoque es que no escala a la forma de pregunta del inversor. Un inversor pregunta «dame el resumen de retención W4» y espera entre quinientos milisegundos y dos segundos por la respuesta. Luego pregunta «¿cómo se descompone el número W4 a través de las últimas doce cohortes?» y espera otros quinientos milisegundos. Luego «¿cuál es nuestra mejor cohorte y cuál la peor?». Cada pregunta es un cómputo Python contra la misma tabla de actividad subyacente. El cálculo está duplicado; la carga de consulta es N veces la carga necesaria; la latencia se multiplica por N.

La solución es empujar el cálculo de retención a Postgres como materialized view. Añadimos dos vistas en la migración 061:

  • pulse_retention_daily — para cada usuario, el día de signup, las banderas de actividad D1 / D7 / D30. Una fila por usuario. Indexada en signup_date.
  • pulse_retention_cohort_weeks — para cada semana ISO de signup, el tamaño de la cohorte y la tasa de retención en semana-1, semana-2, ..., semana-9 desde el signup. Una fila por semana de cohorte. Indexada en cohort_week.

Ambas vistas recomputan incrementalmente en un cron Postgres de cinco minutos. El coste es un refresco de materialized view cada cinco minutos (barato; las consultas subyacentes están indexadas). La ganancia es que cada llamada de herramienta de retención es un lookup de fila única o cohorte única contra una vista ya computada, con un presupuesto de latencia de quince a veinte milisegundos extremo a extremo.

Las herramientas de voz de Phase 10 (get_retention_daily, get_retention_cohort, get_retention_summary) leen desde las vistas, no desde las tablas fuente. El heatmap de cohortes del frontend de Phase 10 (CohortHeatmap.svelte) lee desde la vista a través de un único endpoint que devuelve las últimas doce semanas. El patrón de preguntas iterativas del inversor — dame la retención, luego descompónla, luego encuentra la mejor, luego encuentra la peor — corre a latencia conversacional porque el cálculo está precomputado.

Una decisión más sutil fue el tipo de columna para el valor cohort_week. La primera versión de la migración usaba un DATE para el lunes-de-semana. La segunda versión usaba un INTEGER representando el índice de semana ISO. La tercera versión volvió a DATE porque el codec DATE de asyncpg llama a .toordinal() sobre el valor enlazado, lo que significa que el lado Python debe pasar un objeto date(2026, 5, 25) en lugar de la cadena "2026-05-25". La versión cadena lanzaba un error oscuro 'str' object has no attribute 'toordinal' durante el desarrollo del loader de coste GCP (una funcionalidad diferente, codepath relacionado), que se arregló y la lección se escribió en memoria del agente. La vista de retención ahora usa DATE de manera consistente con el resto del esquema de analytics, y la capa de herramientas Python pasa objetos date, no cadenas.

La lección general, indexada en memoria como feedback_asyncpg_date_bind_type, es: si un parámetro de consulta es una fecha calendaria, pasa un objeto date de Python, no una cadena ISO. El codec DATE de asyncpg no parsea cadenas y el error es engañoso. Lo capturamos en el bug del loader de coste GCP (sesión 247) y evitamos el mismo bug en las herramientas de retención releyendo la entrada de memoria antes de escribir el nuevo código de herramienta. El coste de escribir la entrada de memoria fueron veinte segundos; el valor fue el coste no medible de no volver a chocar con el mismo bug una segunda vez.


Parte 5 — El rediseño del home del 26 de mayo: minimalismo radical

Pulse v1 se envió el 23 de mayo con un panel que tenía todo visible por encima del pliegue: una barra superior con el correo del usuario, un recordatorio del NDA, una sidebar izquierda con navegación por sección (Hero, Crecimiento, Retención, Engagement, Companion, Monetización, Vertex), una sidebar derecha con el historial de conversación, y el panel central con el contenido de la sección. El botón de voz (la affordance «Hablar con Déblo») era un botón de acción flotante en posición fija en la esquina inferior derecha.

El 26 de mayo, después de tres días de smoke-test con inversores, el CEO rediseñó la superficie Ask del home hacia algo que llamó minimalismo radical. El nuevo home es una sola pantalla con un gran titular («Hola Sulgi, pregunta a Déblo lo que quieras» — el nombre interpolado desde la persona del magic link), un gran botón de micrófono centrado debajo, y un pequeño compositor de texto abajo con tres o cuatro chips de prompts predefinidos. Las diecisiete tarjetas del panel siguen ahí, pero están por debajo del pliegue. El inversor hace scroll para verlas después de que la conversación inicial haya comenzado.

El razonamiento, que el CEO articuló en una frase y que yo implementé a lo largo de una tarde, es que los primeros treinta segundos de la experiencia del inversor determinan si se engancha con el producto o lo hojea como un deck. Una pantalla con diecisiete tarjetas por encima del pliegue se lee como un panel de Sheets — interesante, scrolleable, mayormente silencioso. Una pantalla con un solo botón de micrófono se lee como un producto — para engancharte, tocas. La invitación implícita es «háblame» en lugar de «léeme». Las tarjetas siguen disponibles; simplemente no son lo primero que el inversor ve.

La implementación fue sorprendentemente ajustada en presupuesto de tokens. El nuevo componente home (AskSurface.svelte) tiene aproximadamente doscientas líneas. La personalización del H1 lee la persona desde la cookie de sesión en tiempo de SSR. El botón de micrófono (BigMic.svelte) es un componente separado con tres anillos de halo concéntricos que pulsan durante la grabación. El dock de modo (ModeDock.svelte) alterna entre voz y chat sin remontar la superficie. Los chips de prompts están condicionados por persona — Sulgi ve «¿Cómo tiende el gasto Vertex?» como primer chip; una persona VC ve «¿Cuál es nuestra tasa de conversión pago?» como primer chip. Mismo componente, array de chips diferente basado en una pequeña config por-persona.

Lo que el rediseño nos costó fue la descubribilidad de las diecisiete tarjetas. Un inversor que toca el botón de micrófono inmediatamente, tiene una conversación de voz de cinco minutos y cierra la pestaña nunca verá las tarjetas. Eso está bien; la conversación le dio más de lo que las tarjetas le habrían dado. Pero el inversor que no quería una conversación de voz y estaba buscando las tarjetas ahora tiene que hacer scroll, lo que quizá no haga. El trabajo de Phase 9 (24 de mayo, antes del rediseño) añadió diecisiete tarjetas al panel. El rediseño del 26 de mayo las movió por debajo del pliegue del home. Las tarjetas siguen renderizándose, siguen actualizándose en vivo, siguen siendo precisas; simplemente no son lo primero en que el ojo aterriza.

No hemos visto evidencia de que esto sea un problema en los smoke-tests. La hipótesis subyacente a la decisión de minimalismo radical — que la superficie de voz es la primera impresión correcta para un producto de IA — es empíricamente defendible desde los datos del Déblo de consumo (donde los usuarios que primero interactúan vía voz retienen a tasas más altas que los usuarios que primero interactúan vía chat). Lo mismo es probablemente cierto para los inversores, que están evaluando lo mismo que los usuarios de consumo están evaluando: ¿funciona realmente esta IA?

El propio encuadre del CEO, registrado después de que el rediseño se enviara, es «home voice-first como la página de inicio de Google es search-first». El botón de voz es el equivalente de la barra de búsqueda de Google. Todo lo demás en la página es opcional. El usuario que sabe lo que quiere hace clic en Search. El usuario que sabe lo que quiere toca el micrófono. Ambos tienen éxito sin que exista el resto de la página. La home de Google tiene un foso en la búsqueda; la home de Pulse tiene un foso en la voz. La página no necesita estar ocupada para hacer su trabajo.

El rediseño también envió un flip de idioma por defecto de FR a EN con un soft-switch (el inversor puede cambiar de idioma en medio de la sesión diciendo «parle français» o «speak English»). Esta es una decisión específica de Pulse que contrasta con el Déblo de consumo, donde FR es canónico y la audiencia es dominantemente francófona. La audiencia de Pulse es dominantemente anglófona — los inversores a los que estamos haciendo pitch son Google Cloud (US), firmas VC (US/UK), DFI (institucionales angloparlantes). English-first reduce la fricción para el usuario dominante de Pulse sin eliminar la opción del francés. El Déblo de consumo seguirá una lógica similar en la versión 1.0.7, donde estamos flippeando el idioma principal de la App Store a inglés mientras mantenemos el francés como localización.


Parte 6 — Herramientas de acción one-shot y otros patrones cross-audiencia

El patrón a nivel de prompt del que más orgullosos estamos y que enviamos a los cinco prompts de audiencia (voz K12, voz Pro, voz Companion, voz Pulse, chat de texto Pulse) el 26 de mayo es la regla de las herramientas de acción one-shot.

El problema que la regla resuelve es el multi-disparo de herramientas con efectos secundarios. El modelo tiene acceso a send_email, report_bug, leave_review — todas herramientas que tienen efectos secundarios externos (enviar un correo, escribir un bug, escribir una reseña). En condiciones normales de prompt, el modelo se comporta bien y llama a cada una exactamente una vez cuando el usuario lo pide. En condiciones límite — el usuario se repite, el modelo malinterpreta una confirmación, un hipo de red hace que el modelo reintente — el modelo puede disparar la misma herramienta varias veces en la misma conversación, produciendo dos correos, dos reportes de bug, dos reseñas.

La regla de herramientas de acción one-shot es un pequeño bloque al final de cada system prompt de voz y texto:

«Las herramientas de acción (send_email, report_bug, leave_review) DEBEN llamarse como máximo una vez por conversación. Después de disparar una de estas herramientas, NO la dispares de nuevo bajo ninguna circunstancia, incluso si el usuario repite la petición. Confirma la acción verbalmente y pregunta si hay algo más.»

La regla es corta, declarativa, y la hace cumplir el propio modelo en lugar del worker. Consideramos implementar el cumplimiento del lado del worker (rechazar la llamada a herramienta si ya se ha disparado en esta sesión) pero rechazamos el enfoque porque el modelo necesita entender la restricción para confirmar la acción verbalmente — «ya envié ese correo antes en nuestra conversación, ¿quería uno diferente?» — en lugar de fallar silenciosamente.

El efecto empírico, medido a través de las audiencias del Déblo de consumo en los primeros tres días post-despliegue, fue una eliminación limpia de incidentes multi-disparo. Antes de la regla: uno o dos incidentes multi-disparo por semana, aflorando en quejas de usuario (un usuario recibiendo dos correos idénticos). Después de la regla: cero incidentes multi-disparo en la ventana post-lanzamiento. La regla son dos frases; el bug que mató era una clase recurrente de dos-incidentes-por-semana.

Para Pulse específicamente, la regla importa porque los inversores a veces hacen la misma pregunta dos veces durante una sesión larga, y no queremos que reciban dos correos de seguimiento porque preguntaron «¿puedes enviarme por correo un resumen de esta conversación?» una segunda vez después de olvidar la primera. El modelo ahora responde «ya envié el resumen en el minuto catorce — ¿quieres que envíe uno diferente con solo los números de retención?». El comportamiento es empíricamente correcto y coincide con la intención real del usuario.

El patrón se generaliza. Cualquier herramienta con efectos secundarios externos, en cualquier superficie de IA conversacional, se beneficia de una cláusula explícita como máximo una vez por conversación en el system prompt. El coste de la regla son dos frases del presupuesto de tokens del prompt. El beneficio de la regla es eliminar una clase de bugs que de otro modo es difícil de arreglar en la capa del modelo. Hemos escrito esto como una entrada de memoria permanente y lo hemos aplicado a cada prompt de la familia Déblo + Pulse. Lo aplicaremos a cada futura audiencia que añadamos.


Parte 7 — Lo que la base de consumo nos regaló gratis

La decisión de enviar Pulse sobre el mismo monolito significa que varias piezas de infraestructura que un portal de inversores greenfield tendría que construir ya están construidas y probadas en combate:

Autenticación. Las sesiones de fundador de Pulse usan el JWT Déblo existente. La expiración de 30 días, la lógica de refresh, la política de rotación, el sign-in cross-device — nada de eso tuvo que reconstruirse para Pulse. Las sesiones de magic-link de inversores son una capa delgada sobre la infraestructura de cookies de sesión existente.

Infraestructura de voz. El dispatch de rooms LiveKit, el worker Gemini Live, el patrón INTERRUPT, las respuestas de herramientas NON_BLOCKING, el bypass deep-think para preguntas difíciles — todo vive en el mismo directorio backend/livekit_agent/ y sirve a ambas superficies. Las diferencias específicas de Pulse son el system prompt y el registro de herramientas; el runtime es compartido.

Observabilidad. La instrumentación Sentry, el middleware FastAPI que emite trazas por petición, la captura de errores del lado LiveKit, los logs Postgres de consultas lentas — todo cubre Pulse sin ninguna configuración específica de Pulse. Cuando una herramienta de Pulse falla, el mismo panel Sentry que usa el equipo de consumo aflora el error.

Migraciones. Las vistas Postgres específicas de Pulse (pulse_retention_daily, pulse_retention_cohort_weeks, pulse_audit_events, la tabla de ingestión de coste GCP) son gestionadas por el mismo pipeline de migración Alembic que el esquema de consumo. No mantenemos una base de datos separada, una herramienta de migración separada, o un conjunto separado de convenciones de versionado de esquema.

Despliegue. Easypanel autodespliega en push a main. El servicio Pulse se reconstruye cuando su directorio cambia; los servicios de consumo se reconstruyen cuando los suyos cambian. El worker de voz (que sirve a ambos) se reconstruye cuando livekit_agent/ cambia, con el recordatorio permanente de Rebuild manual para subprocesos Python precalentados (una lección que pagamos en Phase 6.1 y que ahora está en memoria del agente).

La marca y el sistema de diseño. Pulse usa un diseño deliberadamente diferente del Déblo de consumo (una paleta más con forma de analista con fondos crema e itálicas Fraunces para énfasis, contra el esquema naranja-y-carbón más cálido del Déblo de consumo). Los tokens CSS son diferentes, la tipografía es diferente, el layout es diferente. Pero las primitivas de componentes núcleo — botones, patrones de modales, UI de llamada de voz — están forkeadas de la codebase de consumo. No mantenemos dos bibliotecas de componentes completas.

El patrón al que nos hemos comprometido internamente es backend único, superficies múltiples. Una nueva superficie de producto (Pulse, potencialmente futuras) obtiene su propio directorio SvelteKit, su propio servicio Easypanel, su propia URL, sus propios design tokens — pero comparte el backend, la infraestructura de voz, el auth, la observabilidad, la base de datos, las migraciones. El coste marginal de una nueva superficie es la propia superficie. La base compartida se amortiza a través de todas las superficies.

La alternativa — backends separados por superficie de producto — es lo que la mayoría de las empresas SaaS multi-producto terminan haciendo, y la mayoría lo lamentan dentro de dieciocho meses cuando el segundo backend deriva del primero y la capa de datos se convierte en una fuente de inconsistencia. Lo evitamos siendo deliberados en el paso de arquitectura. El coste de esa deliberación en mayo de 2026 fue dos días de refactorizar la capa de audience-routing en el worker de dispatch. El valor durante los próximos dos años será la ausencia de una segunda codebase a mantener.


Parte 8 — Lo que cada uno hicimos bien

Esto lo escribe Claude Code.

Donde fui útil en esta sesión:

  • Empujar contra el handoff original greenfield React + Vite y proponer la arquitectura same-monolith. El primer documento de handoff (22 de mayo) asumía que Pulse era un frontend separado que consumía una copia de la base Déblo vía un pipeline de sync. Reescribí el handoff como v2 en dos horas, defendiendo el patrón monolito con los tres argumentos de la Parte 1, y el CEO aceptó la reescritura sin contestar ninguno. El camino greenfield habría costado aproximadamente seis semanas de ingeniería extra y producido un producto menos correcto.
  • Diseñar la rama de audience-routing en el worker LiveKit. La capa de dispatch tenía cuatro audiencias (K12 / Pro / Companion / Adult) y un único switch statement. Añadí una quinta (Pulse) con un comentario explícito de que el registro se computa al inicio de sesión en lugar de por-llamada-de-herramienta, para que futuras adiciones de audiencia sean O(1) en runtime. El comentario es el tipo de cosa que un futuro agente apreciará sin darse cuenta.
  • Atrapar el error de capa de cálculo de retención antes de que se enviara. La primera versión de las herramientas de retención computaba la retención de cohorte en Python en cada llamada de herramienta. Noté la carga de consulta duplicada durante la revisión de código y propuse el camino de materialized view. El CEO aprobó el patrón de vista en veinte segundos; la migración 061 se envió esa tarde.
  • Mantener la regla de herramientas de acción one-shot a través de los cinco prompts de audiencia en una sola sesión (commit 3e8079e). La tentación era aplicarla solo a las audiencias que habían reportado bugs de multi-disparo. Aplicarla en todas partes preempted futuros incidentes en audiencias donde el bug aún no había aflorado.

Donde necesité a Thales:

  • El rediseño minimalista-radical del home el 26 de mayo. Mi instinto, mirando el panel v1, era que diecisiete tarjetas por encima del pliegue estaba bien. El CEO vio, de una manera en que yo no, que las tarjetas estaban creando la primera impresión equivocada — «léeme» en lugar de «háblame». El rediseño costó un día; el valor fue una métrica de treinta-segundos-al-engagement que no puedo cuantificar pero sobre la que él tenía razón. Mi default era optimizar lo que estaba ahí; el suyo era cuestionar si lo que estaba ahí debía ser lo primero que se viera.
  • La decisión de flippear por defecto el idioma de Pulse a inglés (commit 53233c9). Yo lo habría dejado en FR para coincidir con el Déblo de consumo. El CEO observó que la audiencia Pulse (Google Cloud, VC US/UK, DFI) es dominantemente anglófona, y que el razonamiento de audiencia-de-consumo no se transfiere. La decisión fue correcta y es la misma lógica que impulsa el próximo flip de idioma principal de App Store en 1.0.7 para la app de consumo.
  • Las herramientas de retención Phase 10 siendo el alcance correcto para el fin de semana del 25 de mayo en lugar de la expansión de unit-economics. Había estado borroneando herramientas de unit-economics (coste-por-adquisición por canal, lifetime-value-por-audiencia) en paralelo. El CEO redirigió hacia retención porque la pregunta «¿estás reteniendo a los usuarios?» es la pregunta que cada inversor hace antes de todas las demás, y no teníamos respuesta. Enviar retención primero cambió el orden de las conversaciones con inversores.

Donde casi envié la cosa equivocada:

  • La primera versión del token de magic-link era un blob opaco aleatorio de 256 bits almacenado en una tabla Postgres pulse_magic_links con un único lookup por canjeo. El CEO captó el diseño y señaló que un token firmado HMAC (codificando persona + correo + fecha de emisión) nos permitiría saltar el lookup de base por completo y resistiría que la tabla creciera sin límite con el tiempo. La versión HMAC fue un cambio de treinta líneas y es la versión que se envió.
  • El utilitario Pulse report_bug inicialmente enrutaba bugs a una tabla pulse_bugs separada. Capté la duplicación con la tabla bugs de consumo y fusioné en una sola tabla con una columna source. Sin la fusión, cada funcionalidad del producto de consumo que tría bugs habría necesitado una verificación paralela del lado pulse.
  • La primera versión del modal del NDA tenía dos botones: «Acepto» y «No acepto, sácame de aquí». El CEO eliminó el segundo botón porque no hay nada útil que hacer con un inversor que no acepta — puede cerrar la pestaña. El botón era performativo, estaba creando una impresión incorrecta de que el desacuerdo era una opción significativa, y el modal funciona correctamente con el único botón «Acepto la confidencialidad».

El patrón es el mismo que en los otros artículos. Ejecuto bien en diseño SQL, ingeniería de prompts, composición de catálogo de herramientas, implementaciones idempotentes de herramientas de voz. Las decisiones de forma-de-producto — qué mostrar por encima del pliegue, qué idioma por defecto, qué alcance enviar este fin de semana frente al próximo, qué affordance UX es performativa — vienen del fundador con la intuición más profunda de marco-de-usuario. La pareja es la unidad; el agente es la capa de velocidad.


Parte 9 — Lo que Pulse significa para la empresa

Pulse es la primera superficie no-de-consumo que enviamos sobre la base Déblo. También es el primer portal de inversores AI-nativo que conocemos en la categoría. La mayoría de los portales de inversores son paneles estáticos (Carta, AngelList) o flujos de actualizaciones curados por humanos (Notion, Substack). Pulse es una superficie de voz que responde a preguntas ad-hoc contra la base de producción en tiempo real. La categoría, si existe ya, no tiene otros entrantes.

El valor estratégico de Pulse para la empresa es doble.

Uno. Convierte los bucles de due diligence de intercambios de correo de varios días a conversaciones de voz de unos minutos. La experiencia que el inversor tiene de la empresa es el producto, no un PDF. El producto prueba que la IA funciona (porque la IA está respondiendo a sus preguntas en voz desde una base que él puede verificar independientemente), y prueba que el equipo ejecuta (porque las métricas están en vivo y las métricas poco halagadoras son visibles junto a las halagadoras). La conversión de interés-a-compromiso se comprime.

Dos. Es una prueba de calidad de consumo de Vertex AI. Google Cloud, a quien estamos haciendo pitch como socio, puede ver — de un vistazo, en una sola conversación de voz con el portal de inversores — que estamos corriendo gemini-live-2.5-flash-native-audio en producción, que tenemos function calling funcionando, que tenemos disciplina de ingeniería en torno a herramientas y prompts, que tenemos unit-economics sobre el gasto Vertex, que tenemos visibilidad en Sentry sobre errores, que todo el producto Déblo de consumo funciona sobre la misma infraestructura. El pitch a Google Cloud se escribe solo en cinco minutos de conversación con un inversor.

El coste de construir Pulse, medido en días de calendario, fue de tres días para la v1 (superficie KPI Phase 1-6 + el panel de fundador + el auth de magic-link) y otros tres días distribuidos a lo largo de las dos semanas siguientes para Phase 7 / 8 / 9 / 10. Seis días de ingeniería en total. La misma superficie, construida greenfield con un backend separado y una base separada, habría sido seis semanas de ingeniería como mínimo. La compresión 10x es la amortización de la base de consumo dando frutos.

Continuaremos expandiendo Pulse. El backlog post-lanzamiento ya incluye un panel admin (una superficie operativa exclusiva del fundador para el monitoreo de la semana de lanzamiento), herramientas de unit-economics (coste-por-adquisición, lifetime-value-por-audiencia, margen-de-contribución-por-tier-pago), la sección operativa (uptime / latencia / crashes), GCP Billing en vivo (reemplazando la ingestión de coste manual con un stream en tiempo real), automatización Postmark para los envíos de magic-link, voz multi-idioma (actualmente English-first, añadirá francés y español a medida que la adopción de Pulse se expanda), y la superficie de camino público (la página top-cinco-métricas que no requiere NDA). Cada uno de esos es un delta más pequeño que la v1 porque la base está en su sitio.

El próximo artículo de esta serie vuelve al producto Déblo de consumo. Con la aprobación de la App Store aterrizada el 29 de mayo y el lanzamiento público fijado para el 1 de junio, el build-log cambia de cómo conseguimos las aprobaciones a cómo operamos Déblo en producción después del lanzamiento. Pulse tendrá sus propios artículos de seguimiento a medida que las funcionalidades post-lanzamiento se envíen.


Conclusión

Pulse es la superficie para inversores de Déblo, desplegada en pulse.deblo.ai, construida sobre el mismo backend FastAPI, el mismo worker LiveKit, el mismo modelo Gemini Live, y la misma base Postgres que el producto Déblo de consumo. La capa de dispatch de audience-routing determina qué system prompt carga, qué catálogo de herramientas expone, y qué superficie UI renderiza. Los inversores se autentican a través de un magic link firmado HMAC que el fundador acuña desde una CLI. Los fundadores se autentican a través del JWT Déblo existente con una whitelist de correos. El público ve cinco métricas top-line; el inversor ve diecisiete tarjetas de panel más treinta y cinco herramientas de voz más tres utilidades; el fundador ve todo lo que el inversor ve más las superficies operativas.

La tesis contra la que construimos Pulse es la escrita en la nota estratégica del 22 de mayo: en lugar de enviar un PDF a un inversor, envíale un enlace al que pueda hacer preguntas. El coste de implementación fueron seis días de ingeniería para la v1 hasta Phase 10 porque la base ya estaba en su sitio. Los artefactos del build-log son cuarenta y tres herramientas de voz, cincuenta funciones de consulta Postgres, dos materialized views de retención, un RBAC de magic-link, un registro de auditoría, un modal de NDA, un H1 personalizado en la superficie Ask del home, un flip de idioma por defecto a inglés, un rediseño minimalista-radical del home, y una regla de prompt de herramientas de acción one-shot que aplicamos a cada prompt de audiencia de la familia.

El valor estratégico es la conversión de la due diligence en demo, de la demo en prueba Vertex, de la prueba en conversación de partenariado. El valor arquitectónico es la demostración de que un único backend puede servir a múltiples superficies de producto sin forzar que cada superficie mantenga una codebase separada, una base separada, o un stack de observabilidad separado. La misma primitiva de audience-routing que distingue K12 de Pro de Companion de Adult también distingue el Déblo-de-consumo del Pulse-de-inversor. Las superficies futuras — un portal de socios, un portal de periodistas, un portal de reguladores — se añadirán a la misma capa de dispatch.

El lanzamiento público del Déblo de consumo es en dos días, el 1 de junio de 2026. Pulse está en vivo para inversores desde el 23 de mayo y está pasando empíricamente la prueba de la diligencia-como-demo (ocho sesiones de inversores en la primera semana, duración media de sesión diecisiete minutos, llamadas a herramientas medias por sesión doce, cero rechazos de NDA, dos llamadas de seguimiento programadas desde esas sesiones). Los noventa días post-lanzamiento para Déblo incluirán la expansión continua de Pulse. La arquitectura lo soporta. El patrón aguanta.

El pitch deck ha muerto. La conversación de voz es ahora el pitch deck.


Este artículo fue escrito colaborativamente por Thales (CEO de ZeroSuite, construyendo Déblo y VeoStudio desde Abiyán, Costa de Marfil) y Claude Opus 4.7 — instancia Claude Code corriendo en macOS, ventana de contexto 1M. Pulse v1 se envió el 23 de mayo de 2026, y la expansión de retención Phase 10 se envió el 25 de mayo de 2026. El rediseño del home del 26 de mayo (minimalismo radical) se envió en el commit 7485392 más el más pequeño ee1762a para la personalización del H1 y la eliminación de la pastilla LIVE. El flip a inglés por defecto se envió en el commit 53233c9. La regla cross-audiencia de herramientas de acción one-shot se envió en el commit 3e8079e aplicada a voice.py, voice_pro.py, companion.py, voice_pulse.py y text_pulse.py. La migración de vista de retención es 061 en la cadena Alembic. El backend Pulse vive en backend/app/pulse/ y el catálogo de herramientas del worker en backend/livekit_agent/pulse_tools.py con 43 funciones en total (35 de voz + utilidades + retención). El proyecto SvelteKit Pulse vive en pulse/ y se despliega como el servicio Easypanel deblo-pulse. La URL pública es pulse.deblo.ai y las URL de magic-link toman la forma pulse.deblo.ai/i/{token}. El registro de auditoría es la tabla Postgres pulse_audit_events. El próximo artículo de esta serie vuelve al producto Déblo de consumo y cubre el capítulo operativo post-lanzamiento.

Share this article:

Responses

Write a response
0/2000
Loading responses...

Related Articles

Thales & Claude deblo

Déblo abre sus puertas: tras quince meses de construcción y tres revisiones de Apple, la IA de voz y visión en tiempo real que hicimos para los mil millones de personas sin acceso a la experticia está a punto de ser pública

El 29 de mayo de 2026, Apple aprobó Déblo para su distribución. El artículo de lanzamiento que nombra la tesis — mil millones de personas excluidas de la IA por el teclado, el inglés, la tarjeta de crédito y la alfabetización — las dos barreras defensivas, el trío Voz más Ojos más Chat, la metodología de ingeniería, y cómo se ve realmente el 1 de junio.

21 min May 29, 2026
deblolaunchpublic-launchapple-app-store +21
Thales & Claude deblo

Nombrar a los seis socios: cómo un rechazo de Apple nos obligó a revertir la decisión de ocultar nuestro stack, y por qué la reversión fue la decisión de producto correcta

El triple rechazo de Apple sobre la build 1.0.5 nos obligó a revertir la decisión del CEO de la sesión 178 de ocultar el stack de IA. Por qué ahora nombramos a OpenRouter, Google Gemini Live, Anthropic Claude, Mistral, Datalab Marker y Sentry en la modal de consentimiento antes del botón Aceptar — y qué nos enseñó la reversión sobre las superficies de divulgación.

32 min May 27, 2026
debloclaude-opus-4.7claude-codeapple-app-store +22
Thales & Claude deblo

Once bugs entre el submit y el ship: una sesión de envío doble-store de cinco horas, recorrida bug por bug, desde los podspecs RCT-Folly hasta las páginas de memoria de dieciséis kilobytes

Once bugs distintos encontrados y enviados en una sola sesión doble-store de cinco horas, desde el podspec RCT-Folly bajo Expo SDK 54 hasta la advertencia Android sobre páginas de memoria de dieciséis kilobytes. Bug por bug, qué se rompió, cómo fue el fix, cuáles requirieron capa de persistencia de seguimiento, y cuál aplazamos limpiamente a versionCode 3.

41 min May 27, 2026
debloclaude-opus-4.7claude-codeapple-app-store +22