Un único agente de voz white-label que se reconfigura por mandante y campaña en runtime. Stack 100% managed: ElevenLabs Conversational AI + Cloudflare (Workers + Pages). Sin telefonía propia: widget web (extensible a SIP nativo).
La consola elige mandante, campaña y contacto, y al lanzar la llamada inyecta la identidad (nombre, voz, tono, idioma), la etapa de mora y los datos del cliente como dynamic variables + override de voz. El agente ejecuta las gestiones contra el Worker, que también sirve la bandeja y la elegibilidad a la consola.
flowchart LR U["Operador / Cliente"] --> C["Consola Émerix
(Cloudflare Pages)"] C -. "GET /api: clientes, campañas,
bandeja, elegibilidad, ficha" .-> W C == "dynamic vars +
override de voz" ==> A["Agente único
ElevenLabs"] A == "14 webhook tools" ==> W["Worker poc-emerix-tools
(Hono)"] W --> M[("Datos mock
clientes · campañas · cuentas")] W --> P["Motor de elegibilidad
+ prioridad"] W --> S[("Store de outcomes
promesas · pagos · opt-out")]
No hay un agente por cliente ni un workflow de cinco nodos: hay un solo prompt seccionado.
La variable management_stage selecciona la sección activa; la voz se pisa por mandante con un override por llamada.
Cambiar de mandante o campaña es configuración, no entrenar operadores.
flowchart TB DV["Dynamic variables
agent_name · client_display_name · tone · language
management_stage · account_id · allowed_actions · datos cliente"] --> PR["Prompt único seccionado
(gemini-2.5-flash · eleven_turbo_v2_5)"] VO["Override de voz
tts.voice_id por mandante"] --> PR PR --> A["preventive"] PR --> B["early_delinquency"] PR --> D["late_delinquency"] PR --> E["self_service / inbound"] A1["Claudia · Banco Andino (es-CL)"]:::id A2["Mariana · Financiera Sur (es-CL)"]:::id A3["Patricia · Tienda Norte (es-PE)"]:::id A1 --> DV A2 --> DV A3 --> DV classDef id fill:#18254c,stroke:#2a60e6,color:#e9eefb;
El agente nunca expone deuda antes de validar identidad. Como el Worker es stateless
(cada tool call puede caer en otro isolate), el estado "validado" no vive en memoria: validate_identity
lo escribe en una dynamic variable id_verified (vía assignment) que viaja en la conversación y llega
bindeada como parámetro a las tools que exponen datos.
sequenceDiagram
participant C as Consola
participant Ag as Agente
participant W as Worker
C->>Ag: dynamic vars (account_id, id_verified=false)
Ag->>W: validate_identity(account_id, últimos 2 dígitos)
W-->>Ag: { verified: true }
Note over Ag: assignment → id_verified = true
Ag->>W: register_promise_to_pay(account_id, identity_verified=true)
W-->>Ag: { ok: true, registered }
Note over Ag,W: sin identity_verified → { identity_required:true }
En modalidad saliente, el Worker no devuelve una lista plana: aplica las reglas de contacto y una fórmula de prioridad sobre el estado de la cuenta combinado con el store en vivo (una promesa o un opt-out registrados durante la demo cambian la elegibilidad al instante).
sin consentimiento · solicitud vigente de no contacto · superó intentos de la semana · promesa de pago vigente · pago reportado en validación · reclamo abierto · teléfono inválido · fuera del horario permitido.
días de atraso ×3 + peso de monto + canal preferido + ventana óptima activa + promesa anterior incumplida − promesa vigente − restricción de contacto − reclamo abierto. Se explica en lenguaje natural en la ficha.
account_id viaja bindeado en todas (el LLM no lo maneja). Las que exponen datos exigen
identity_verified; las irreversibles usan doble paso (recap → confirmado=true).
| Grupo | Tools |
|---|---|
| Identidad / datos | validate_identity · account_balance · available_actions |
| Acciones de pago | generate_payment_link · register_promise_to_pay · register_payment_reported · create_callback |
| Mora tardía | get_eligible_offers · create_offer_review_request · create_dispute_case |
| Preferencias / cierre | update_contact_preference · register_do_not_contact · save_interaction_outcome · transfer_to_human |
agent_2501kwakkzsvf71bnskk0nmkzr5y
LLM gemini-2.5-flash · temp 0.3
TTS eleven_turbo_v2_5 · latency 3
ASR elevenlabs · es
Worker Hono · Cloudflare
Consola · Cloudflare Pages
3 voces (es-CL ×2, es-PE)
Overrides: voz · saludo · idioma