Appearance
Experimentos A/B de campaña
English: Campaign A/B experiments.
Un experimento compara de dos a cinco variantes de una misma campaña. Corre en campañas de voz, SMS y correo (ver Campañas de SMS y correo). Créalo como borrador, inícialo cuando las variantes estén listas y deténlo para dejarlo terminal. Las rutas, los cuerpos de petición, los envoltorios de respuesta y los códigos de estado de abajo están copiados de los esquemas Experiment y de las operaciones listCampaignExperiments, createCampaignExperiment, getCampaignExperiment, updateCampaignExperiment, deleteCampaignExperiment, startCampaignExperiment y stopCampaignExperiment del openapi/dialer-v1.yaml vendorizado.
Crear un borrador
POST /v1/campaigns/{id}/experiments acepta name, primary_metric y variants. primary_metric es contact_rate o promise_rate. El arreglo de variantes tiene de 2 a 5 entradas, cada una con un name, un weight de 1 a 1,000 y exactamente una entrada con is_control: true.
bash
curl -sS -X POST "$API/v1/campaigns/$CAMPAIGN_ID/experiments" \
-H "Authorization: Bearer $TOKEN" \
-H 'Content-Type: application/json' \
-d '{
"name": "Window test",
"primary_metric": "contact_rate",
"variants": [
{"name": "Control", "weight": 50, "is_control": true, "overrides": {}},
{"name": "Afternoon window", "weight": 50, "overrides": {
"window": {"start": "10:00", "end": "16:00"}
}}
]
}'La respuesta es 201 con { "experiment": ... }. Un cuerpo mal formado es 400; un experimento inválido es 422 con error.details, una entrada por cada campo rechazado. window y min_gap_seconds solo aplican a una campaña de voz, y una campaña de SMS o de correo no puede elegir promise_rate (una promesa apunta a una llamada, no a un mensaje): las tres cosas se rechazan con 422 (createCampaignExperiment). Una ventana debe ser un subconjunto de la ventana de la campaña, y un guion de SMS debe cumplir los validadores de la propia campaña, incluido el requisito de STOP.
Qué puede cambiar una variante
El objeto overrides es una lista cerrada. Solo se aceptan estas claves:
script:{ "field": "tts_prompt" | "voicemail_message" | "sms_body", "text": "..." };window:{ "start": "HH:MM", "end": "HH:MM" }, nunca más ancha que la ventana de la campaña;min_gap_seconds: un entero de 1 a 2,592,000 (solo campañas de voz, ver más abajo);email_template_id: un UUID de una plantilla aprobada que pertenezca al tenant.
Claves como optout_digit, abandonment_threshold y max_dial_ratio no son controles de un experimento. Se rechazan en lugar de ignorarse. Esta lista cerrada y las restricciones de los campos vienen de ExperimentVariantOverrides en la spec vendorizada; el límite de cumplimiento también está registrado en el ADR #242 de core.
Consultar, editar y borrar
GET /v1/campaigns/{id}/experimentslista todos los estados, del más nuevo al más antiguo, con las variantes en orden deposition.GET /v1/campaigns/{id}/experiments/{experiment_id}devuelve un experimento.PATCH /v1/campaigns/{id}/experiments/{experiment_id}aceptanamey/ovariants; reemplazarvariantsreemplaza el conjunto completo.primary_metricsolo puede repetirse, no cambiarse.DELETE /v1/campaigns/{id}/experiments/{experiment_id}borra únicamente un borrador y devuelve204.
Cuando un experimento está en curso o terminado, sus variantes quedan congeladas. Editarlo o borrarlo devuelve 409. Los recursos de otro tenant y los identificadores desconocidos devuelven 404.
Iniciar y detener
Inicia un borrador con:
bash
curl -sS -X POST \
"$API/v1/campaigns/$CAMPAIGN_ID/experiments/$EXPERIMENT_ID/start" \
-H "Authorization: Bearer $TOKEN"POST .../start pasa de draft a running y vuelve a validar las variantes contra la campaña actual. Devuelve 422 si las restricciones ya no se cumplen y 409 si ya hay otro experimento en curso o el experimento no es un borrador. Los experimentos corren en campañas de voz, SMS y correo cuyos mensajes o llamadas envía la propia plataforma. Iniciar uno en una campaña de vista previa o manual es 422 (details[].path = "campaign"), aunque la creación del borrador se haya aceptado (startCampaignExperiment).
Detén un experimento en curso con:
bash
curl -sS -X POST \
"$API/v1/campaigns/$CAMPAIGN_ID/experiments/$EXPERIMENT_ID/stop" \
-H "Authorization: Bearer $TOKEN"POST .../stop pasa de running al estado terminal ended; cualquier otro estado actual devuelve 409.
Campañas de SMS y correo
En una campaña de SMS o de correo, el experimento lee el libro de mensajes de la campaña en lugar del libro de llamadas (getCampaignExperimentResults):
- Los intentos son los mensajes salientes originales y sus transiciones de estado. Un mensaje que el proveedor nunca tomó es
not_placed, y un contacto es un mensajedelivered. promisesyabandonedson siempre 0, así quepromise_rateyabandon_ratesonnull. Usaprimary_metric: contact_rate;promise_ratese rechaza al crear.- En una campaña de SMS, una variante puede sustituir
scriptconfield: "sms_body"; el texto debe seguir cumpliendo los validadores de la propia campaña, incluidoSTOP. Para elemail_template_idde una variante, la plantilla debe ser una aprobada del tenant (ExperimentVariantOverrides). - La lista cerrada de
overrides, la asignación y las reglas del veredicto son las mismas que en voz.
El release v0.105.0 de core incluye los commits de experimentos de SMS y correo etiquetados core#2057 (los libros de mensajes estampan la variante, los ejecutores la aplican, y los resultados y el inicio aceptan el canal). La spec vendorizada de ese release es la fuente de las líneas de arriba.
La lectura aparte GET /v1/campaigns/{id}/email-skips (campaignEmailSkips) explica por qué una campaña de correo no envió a un lead; es un diagnóstico del ejecutor de correo y no recibe ningún parámetro de experimento, así que no forma parte del contrato de experimentos.
Asignación estable e invariantes de cumplimiento
Core asigna una deuda de forma determinista a partir de sha256(experiment_id <> debt_id), usando los primeros 64 bits y los pesos de las variantes en orden de position. Por eso el mismo par experimento/deuda recibe la misma variante entre reintentos; el identificador del experimento forma parte de la entrada, así que experimentos distintos no comparten asignación. Este comportamiento lo define la implementación Dialer.Campaigns.Experiments.Assignment de core y sus pruebas.
El experimento no crea un carril de cumplimiento aparte. Todas las variantes pasan por las mismas puertas de cumplimiento, y la divulgación legal no cambia entre variantes. La lista cerrada de overrides es deliberada: los controles de opt-out, abandono y ratio de marcación no pueden variarse en un experimento. El ADR #242 de core documenta este límite y el ejecutor de campañas conserva la ruta de cumplimiento completa en la originación.
Resultados y veredicto
GET /v1/campaigns/{id}/experiments/{experiment_id}/results devuelve { "results": ... }. Se recalcula desde el libro de llamadas en cada lectura (sin contadores), y un draft responde con ceros e insufficient_data. Los errores son 401, 404 y 429.
bash
curl -sS \
"$API/v1/campaigns/$CAMPAIGN_ID/experiments/$EXPERIMENT_ID/results" \
-H "Authorization: Bearer $TOKEN"variants[]: por varianteassigned_debts,attempts,not_placed,placed,contacts,promises,abandoned,successes, y las tasascontact_rate,promise_rateyabandon_rate(cada unanullcuando su denominador es cero). Los intentos que nunca salieron (not_placed) quedan fuera de todos los denominadores.verdict.statusesinsufficient_data,no_significant_differenceowinner. Unwinnertraevariant_id,versus_variant_id,p_value,difference,ci_lowyci_high;comparisons[]tiene una entrada por retador ysample_floorindica la muestra mínima.allocation_warningestruecuando el reparto observado de las deudas asignadas se desvía de los pesos (chi-cuadrado, alfa 0.001); entonces no se emite ningúnwinner.verdict.withheld_byesallocation_warningsolo cuando se retuvo un ganador que habría existido (el estado es entoncesno_significant_difference); en cualquier otro caso esnull, incluso conallocation_warning: true.unattributed_attemptses distinto de cero cuando el sello de experimento de un intento y el experimento no coinciden.
Las definiciones de los campos son ExperimentResults, ExperimentVariantResults y ExperimentVerdict en la spec vendorizada (core v0.105.0); las reglas de recálculo y de veredicto están registradas en el ADR #249 de core.