A/B testing de campagnes
A/B-tester dans Trackily = combiner 3 ingrédients : (1) plusieurs landings dans
schema.landings[]avec poids égaux, (2) un visitor bindingcookieouip+ua, (3) une règle automizer qui kill la variante perdante. Voici le workflow end-to-end avec un cas réel.
Concept
Un A/B test honnête doit garantir :
- Random assignment : chaque visiteur a la même chance de tomber sur A ou B.
- Sticky exposure : le même visiteur voit TOUJOURS la même variante (sinon il y a contamination).
- Suffisant de volume : statistiquement, il faut souvent 500-2000 conversions par bras pour détecter une différence de 10 %.
- Kill switch automatique : la variante manifestement perdante doit être tuée avant qu'elle bouffe le budget.
Trackily couvre les 4 via le quartet : flows.schema (random pondéré) + binding=cookie (sticky) + reporting (volume) + automizer rules (kill).
Architecture d'un A/B test
┌──────────────┐
│ Campaign │
│ (id=8) │
└──────┬───────┘
│
▼
┌──────────────┐
│ Flow │
│ default, 1 │
│ binding=cookie│
│ 168h sticky │
└──────┬───────┘
│
┌────────────┼────────────┐
│ │ │
weight=50 weight=50 (peut être plus)
│ │
▼ ▼
┌─────────┐ ┌─────────┐
│Landing A│ │Landing B│
│ (#17) │ │ (#18) │
└─────────┘ └─────────┘
+
┌──────────────┐
│ Automizer │
│ Rule (kill │
│ loser bras) │
└──────────────┘
Étape 1 — Préparer les variantes
Crée tes 2 (ou N) landings AVANT de toucher au flow. Tu peux :
- Cloner une landing existante (UI → Landings → ⋯ → Duplicate).
- Générer N variantes IA via
generate_landing_variants(voir ai-builder). - Créer manuellement via
create_landing.
{
"name": "generate_landing_variants",
"arguments": { "ai_landing_id": 17, "count": 2 }
}
Tu obtiens 2 nouvelles landings sœurs (même variant_group_id).
Étape 2 — Créer le flow A/B
Tool : create_flow.
{
"name": "create_flow",
"arguments": {
"campaign_id": 8,
"type": "default",
"binding": "cookie",
"binding_hours": 168,
"schema": {
"landings": [
{ "id": 17, "weight": 50 },
{ "id": 18, "weight": 50 }
],
"offers": [{ "id": 12, "weight": 100 }]
}
}
}
Clés :
binding: cookie— un cookie HTTP est posé sur le visiteur la première fois qu'il atterrit. Il garantit que les revisites voient la même variante.binding_hours: 168— 7 jours. Pour les funnels avec abandons puis retours (email retargeting), monte plus haut.- Poids 50/50 — split pari, pas de biais.
Étape 3 — Lancer le trafic
Aucune action spéciale. La campagne est déjà active, le flow nouveau remplace l'ancien (ou tu l'as ajouté en default si elle n'en avait pas). Le trafic est splitté à partir du prochain clic.
Étape 4 — Quand déclarer un winner
Trackily n'inclut PAS de calculateur de significativité statistique baked-in. Tu décides selon ces seuils empiriques :
| Volume par bras | Seuil "raisonnable" pour un winner | Note |
|---|---|---|
| < 100 conv | NE PAS DÉCLARER | Trop de variance random |
| 100-300 conv | Écart > 30 % en CR ou EPC | Significatif si stable sur 48 h |
| 300-1000 conv | Écart > 15 % | OK |
| > 1000 conv | Écart > 5 % | Solide |
Pour aller plus loin, exporte les clicks + conversions via reports CSV → calculator externe (Optimizely chi-square, R, Python scipy.stats.proportions_ztest).
Étape 5 — Kill switch automizer
Une fois 24h-72h passées, automatise le kill du loser :
{
"name": "create_automizer_rule",
"arguments": {
"name": "B-killswitch — variante perdante",
"campaign_id": 8,
"conditions": [
{ "metric": "clicks", "operator": ">=", "value": 1000, "window": "72h" },
{ "metric": "cr", "operator": "<", "value": 1.5, "window": "72h" }
],
"actions": [
{ "type": "pause_landing", "landing_id": 18 }
],
"check_interval_minutes": 60
}
}
⚠️ La règle ci-dessus mesure le cr agrégé de la campagne, pas par landing. Pour cibler une landing précise, il faut filtrer côté actions (le moteur évalue côté campagne mais l'action peut cibler landing_id). Vérifie automizer/conditions pour les métriques par-landing si disponibles.
Étape 6 — Promouvoir le winner
Une fois landing #18 paused (ou supprimée du flow), landing #17 reçoit 100 % du trafic. Tu peux :
- Lancer un nouveau test en remplaçant
#18par une variante C :update_landingdu flow viacreate_flowen remplacement (les flows sont versionnés par insert, pas par update — crée un nouveau et désactive l'ancien). - Garder en single variant indéfiniment.
- Promouvoir le winner en cross-campagne : cloner la landing #17 sur d'autres campagnes (UI → Duplicate to campaign).
Cas réel : MemoMind 4-tier price test (campaign #8)
Sur l'instance prod trackily.online, la campagne #8 ("MemoMind") teste 4 prix différents en simultané :
landing #31— MemoMind à $24.99 (tier 1)landing #32— MemoMind à $34.99 (tier 2)landing #33— MemoMind à $44.99 (tier 3)landing #34— MemoMind à $54.99 (tier 4)
Chaque landing utilise le MÊME HTML AI-générée (archetype wellness) avec price_overrides pointant le bon prix sur les native_product_variants.id. Voir ab-price-testing pour les détails.
Le flow associé :
{
"name": "create_flow",
"arguments": {
"campaign_id": 8,
"type": "default",
"binding": "cookie",
"binding_hours": 168,
"schema": {
"landings": [
{ "id": 31, "weight": 25 },
{ "id": 32, "weight": 25 },
{ "id": 33, "weight": 25 },
{ "id": 34, "weight": 25 }
],
"offers": []
}
}
}
Note l'absence d'offers — la conversion est gérée par le checkout natif Trackily (commerce natif), pas un postback affiliate.
Après 30 jours, l'objectif est de mesurer non pas la CR par tier (qui décroît mécaniquement avec le prix), mais la revenue par 1000 clics — c'est ça qui décide du tier optimal.
Une règle automizer kill les tiers manifestement non-rentables :
{
"name": "create_automizer_rule",
"arguments": {
"name": "MemoMind tier-killer",
"campaign_id": 8,
"conditions": [
{ "metric": "clicks", "operator": ">=", "value": 500, "window": "7d" },
{ "metric": "revenue", "operator": "<", "value": 50, "window": "7d" }
],
"actions": [{ "type": "pause_campaign" }],
"check_interval_minutes": 60
}
}
(En vraie prod tu raffines la règle pour cibler la landing spécifique, mais cette version est le filet anti-disaster.)
Workflow complet récapitulatif
1. generate_landing_variants (ou clone manuel) → N landings prêtes
2. create_flow (binding=cookie, weights égaux) → split traffic
3. ~ laisser tourner 24-72h ~ → collecter volume
4. lire reports (CR + EPC + revenue par landing) → identifier loser
5. create_automizer_rule (kill threshold) → automatiser
6. (optionnel) promote winner cross-campagne → scale
Erreurs courantes
binding: none: ton test est pollué — chaque revisite est un nouveau coup de dé. Toujourscookieouip+ua.- Trop peu de volume : tirer une conclusion à 50 conv/bras = pile/face. Attendre min 200-300 conv par bras.
- Variables multiples : tu changes le titre ET l'image ET le CTA en même temps — impossible de savoir QUI a déclenché la différence. Un changement à la fois.
- Pas de variant_group_id : si tu crées tes variantes à la main avec
create_landing, elles n'ont pas devariant_group_id. Pas critique mais le reporting "siblings" perd en lisibilité. - Kill trop tôt : une règle qui pause après 50 clics peut tuer un winner qui aurait gagné au-delà. Mets toujours un seuil
clicks >= 500minimum. - Test pendant un peak / promo : un weekend Black Friday biaise les données. Préfère les tests sur fenêtre week-day stable.
- Stat sig calculée à l'oeil : 23 conv vs 19 conv n'est pas significatif. Use un calculator (par ex.
https://abtestguide.com/calc/).
Voir aussi
- Flows — rotation pondérée + binding
- A/B price testing — la version "même landing, prix différent"
- Automizer scopé campagne — kill switches
- Landings — ai-builder — générer N variantes en parallèle
- MCP — tools reference —
generate_landing_variants,create_flow