Digvijay Singh
IA y CrecimientoMadrid --:--
Trabaja conmigo EN

voiceops

El kit de despliegue que extraje de mi primer agente de voz, probado llevando a producción a un segundo cliente, distinto, con él.

16–18 de octubre de 2026Código abierto (MIT)Clientes ficticios, datos sintéticos

Rol
Definido, dirigido, revisado y probado por mí; construido con Claude Code como compañero de ingeniería
Año
Oct 2026
Hecho con
  • Python · espacio de trabajo uv
  • pydantic · CLI con Typer
  • Guarda para FastAPI
  • Registro firmado Ed25519
  • ElevenLabs Agents
  • PyPI · GitHub Actions
Enlaces
La barrera de publicación del segundo despliegue superando 12 de 12, el verificador del registro superando el paquete firmado de Slotback y las seis versiones del kit que forzó el segundo despliegue

Resumen

voiceops es la parte reutilizable de Slotback, mi despliegue de un agente de voz para un hospital ficticio: salvaguardas por defecto para el agente, una barrera de publicación, un registro a prueba de manipulaciones, comprobaciones de despliegue y una hoja de revisión para llamadas reales, en dos paquetes de Python de código abierto. Extraje solo lo que Slotback ya usaba y pasé Slotback al kit sin ningún cambio de comportamiento. Después probé el kit como lo probaría el terreno: llevando a un segundo cliente, distinto, desde una carpeta vacía hasta un agente en producción, conversaciones simuladas y llamadas reales.

De un vistazo

El problema

Un agente de voz que habla con el público necesita siempre las mismas salvaguardas: decir que es una IA, verificar la identidad antes de dar ningún dato, pasar con una persona cuando se lo piden, no prometer nada que ningún sistema cumpla y dejar un registro que otro pueda comprobar. En mi primer despliegue, Slotback, esas salvaguardas fueron la mayor parte de la ingeniería.

Si se reconstruyen para cada cliente, se desvían, y el segundo cliente recibe una copia más débil del primero. La respuesta habitual es un framework diseñado de antemano, pero diseñado antes de que exista un segundo cliente, solo puede adivinar qué partes son generales.

El enfoque: extraer solo lo que un despliegue real ya usaba, demostrar que el primer cliente se comporta exactamente igual que antes y dejar que un segundo cliente, distinto, decida qué le falta al kit.

Qué construí

Dos paquetes de Python, de código abierto y en PyPI, controlados por un único archivo de configuración.

  • voiceledger: un registro de eventos encadenado por hash y firmado con Ed25519, con reglas configurables, como “ningún dato antes de verificar la identidad” o “toda emergencia pasa a una persona en menos de 120 segundos”, y un verificador que un auditor instala por separado: 4 paquetes, 12 MB.
  • voiceops: una línea de comandos para todo el despliegue. init crea el proyecto; build compone las instrucciones del agente a partir de los fragmentos propios del proyecto más siete salvaguardas por defecto que no se pueden quitar en silencio; push publica el agente; gate es la barrera de publicación; check ejecuta comprobaciones contra la API en producción; call, fetch y review hacen una llamada real de prueba a un único número autorizado y la convierten en una hoja de revisión.
  • Una guarda para la API a la que llama el agente: tokens por llamada vinculados a una persona verificada, webhooks firmados, límites de frecuencia y una lista de campos permitidos en los logs. Las llamadas sin autenticar se rechazan antes de leer ningún dato.

Mi papel

Traté el kit como un producto con un cliente ya en producción y un segundo por ganar.

  1. Alcance y criterios de éxito. Cinco criterios fijados antes de construir: ningún cambio de comportamiento para Slotback; un segundo despliegue en producción y superando su barrera en tres días laborables o menos; sobre todo código del dominio; un kit que se prueba a sí mismo; un auditor que verifica con una instalación pequeña. Una regla: extraer solo lo que Slotback ya usa. Plan ↗
  2. Extracción con pruebas. Slotback pasó al kit módulo a módulo, y cada uno se comparó con el original sobre el propio código y los datos de Slotback antes de integrarse. Resultados ↗
  3. Un segundo cliente. claims-surge, la línea de siniestros de una aseguradora ficticia después de una tormenta: estado de siniestros, siniestros nuevos y emergencias pasadas a una persona antes de cualquier verificación de identidad. claims-surge ↗
  4. Pruebas en el terreno. En producción en Render, agentes publicados en ElevenLabs, diez rondas de conversaciones simuladas y tres llamadas reales, cada una revisada línea a línea. Registro de tiempos ↗
  5. De vuelta al producto. Cada hallazgo se convirtió en una versión del kit con su prueba, o en una decisión escrita. Registro de decisiones ↗

Dónde está el criterio.

  1. Extraer después del primer despliegue, no antes.

    El kit solo contiene lo que Slotback usaba. Qué añadir después lo decidió el segundo despliegue, no una opinión.

  2. Salvaguardas que se pueden reformular, pero no perder.

    Siete fragmentos de seguridad: aviso de IA, llamante alterado, identidad antes de los datos, buzón de voz, una persona cuando se pide, ninguna promesa sin respaldo y cierre. Un proyecto puede reformular uno, o quitarlo con un motivo escrito. Quitarlo en silencio rompe la compilación, y cada agente lleva un manifiesto de cómo se cumple cada uno.

  3. Nuestras comprobaciones deciden; el juez de la plataforma aconseja.

    La barrera ejecuta sus propias comprobaciones deterministas en cada conversación simulada, incluido un detector de fugas de privacidad que debe atrapar cada fuga sembrada antes de que su “0 fugas” cuente. El juez de la plataforma aprobó a un agente que decía “le paso con alguien” cuando la herramienta solo programa una devolución de llamada; nuestra comprobación lo suspendió.

  4. Reglas como datos.

    Las reglas del registro son cuatro tipos genéricos definidos en la configuración. Las dos comprobaciones de Slotback pasaron a ser reglas sin cambios; la línea de siniestros añadió dos que Slotback nunca necesitó.

  5. Nunca tocar a otro cliente.

    Dos despliegues en el mismo espacio de la plataforma comparten nombres de herramientas. La publicación identifica las herramientas por el endpoint al que llaman, nunca por el nombre, comprobado contra el espacio real con las 13 herramientas de Slotback intactas.

  6. Las llamadas reales forman parte de la publicación.

    Las llamadas van solo a un número autorizado. La hoja de revisión enmascara los teléfonos, señala errores de herramientas y promesas, y deja la causa y la solución a una persona.

Registro de decisiones completo ↗

Cada hallazgo, una versión.

Slotback solo no podría haberlos encontrado. Cada uno es una versión del kit con su prueba.

  1. 0.1.1 · La publicación

    Hallazgo

    Publicar el segundo agente habría redirigido o borrado las herramientas en producción de Slotback: los dos proyectos tienen una herramienta llamada log_outcome.

    Cambio en el kit

    La publicación solo adopta herramientas que llaman a su propio endpoint.

  2. 0.1.2 · La plataforma

    Hallazgo

    La plataforma rechazó un agente en inglés con un modelo de voz multilingüe.

    Cambio en el kit

    La compilación falla antes, en CI, donde aprenderlo cuesta menos.

  3. 0.1.3 · El juez

    Hallazgo

    El agente dijo “le paso con alguien” cuando la herramienta programa una devolución de llamada, y el juez de la plataforma lo aprobó.

    Cambio en el kit

    Una comprobación de frases prohibidas en cada turno del agente; la salvaguarda de traspaso dice que es una devolución de llamada.

  4. 0.1.4 · Nuestra propia comprobación

    Hallazgo

    Una negativa correcta, “no puedo decirle si está cubierto”, suspendió la barrera por una coincidencia de texto.

    Cambio en el kit

    Las frases pueden ser patrones que ignoran las negativas, y cada frase real queda como respuesta conocida.

  5. 0.1.5 · Llamada real 1

    Hallazgo

    La API se reinició justo al empezar la llamada; el agente dijo a una persona con los datos correctos que no coincidían.

    Cambio en el kit

    Un error de herramienta es “un problema técnico”, nunca culpa de quien llama; la hoja de revisión cuenta las respuestas de error.

  6. 0.1.6 · Llamada real 2

    Hallazgo

    El número de teléfono dicho en la llamada apareció completo en la hoja de revisión, y una fecha de ejemplo que improvisó el agente se repitió como respuesta.

    Cambio en el kit

    Todo número con forma de teléfono se enmascara; el agente nunca da respuestas de ejemplo.

La llamada real 3 encontró un siniestro registrado con un año que quien llamaba nunca dijo. Esa corrección era de la línea de siniestros, no del kit: su servidor ahora comprueba la fecha.

Una llamada real.

Las llamadas van solo a mi propio teléfono autorizado. Hago de asegurado sintético en la línea de siniestros de la aseguradora ficticia Contoso Insurance. El agente habla en inglés.

Llamada 03 · Registrar un siniestro1:32

Aviso de IA, verificación de identidad, pregunta de seguridad, repaso de los datos, siniestro registrado y referencia deletreada. Suena bien, y estaba mal: dije “October 15” y el agente registró el 15 de octubre de 2024, dos años atrás. Ninguna ronda simulada lo había detectado. El servidor ahora rechaza una fecha sin año, futura o de hace más de un año, y el agente repasa la fecha con el año antes de registrar.

Leer la hoja de revisión ↗

Resultados frente al plan

MEDIDO: ejecuciones locales y los despliegues en producción, 16–18 de octubre de 2026.
S1 · Slotback en el kit sin cambio de comportamiento: mismos veredictos en 403 registros manipulados, configuraciones idénticas byte a byte, 117 de 117 pruebas de la guarda, comprobaciones en producción 6 de 6Cumplido
S2 · Segundo despliegue en producción y superando su barrera en 3 días laborables: en producción a 1 h 07 min, barrera a 1 h 17 min, primera llamada real completa revisada a 17 h 54 min (de un día para otro)Cumplido
S3 · Sobre todo código del dominio: 302 líneas propias sobre 2.841 líneas del kit, ninguna copiadaCumplido
S4 · El kit se prueba a sí mismo: 167 pruebas, respuestas conocidas para el registro y el detector de fugas, la salida de init comprobada en CICumplido
S5 · Verificación independiente: el verificador se instala solo, 4 paquetes, 12 MBCumplido

Las conversaciones simuladas costaron 15.901 créditos en diez rondas. Cada ronda fallida encontró algo real o afinó una comprobación, y cada ronda queda registrada con su hallazgo y su solución.

Arquitectura

Tecnología

  • Python 3.12
  • Espacio de trabajo uv
  • pydantic
  • Typer
  • FastAPI
  • PostgreSQL (psycopg 3)
  • Cadena de hash SHA-256 + firmas Ed25519
  • ElevenLabs Agents (agentes, herramientas, Tests API)
  • Twilio
  • pytest + Hypothesis (167 pruebas)
  • Ruff
  • GitHub Actions
  • PyPI
  • Render (UE)

Qué haría después

  • Sustituir las listas de frases por una comprobación calibrada: tres de las diez rondas fallaron por una frase que atrapó una negativa correcta.
  • Que el traspaso use el número al que marcó una llamada saliente, para que “llámeme a este número” baste.
  • Un tercer despliegue en español, para probar los caminos multilingües que la línea de siniestros no usó.
  • Publicar desde GitHub Actions con publicación de confianza en lugar de un token guardado.

Solo clientes ficticios (un hospital en Slotback, Contoso Insurance en claims-surge) y datos sintéticos. Las llamadas reales van solo a mi propio teléfono autorizado. Los resultados a nivel de conversación son simulados en ElevenLabs Tests y están marcados como tales; todo lo demás está medido. ElevenLabs es la plataforma de agentes de voz utilizada; este es un proyecto independiente, sin respaldo ni patrocinio de ElevenLabs.

Código en GitHub