הטמעת פלטפורמת בדיקות A/B מותאמת אישית לאתר שלך

אתם מריצים בדיקות A/B אך נתקלים במגבלות של כלים מוכנים: תלות בסקריפטים חיצוניים, חוסר בנתונים גולמיים ועלויות רישוי עולות. אנחנו בונים פלטפורמות A/B מותאמות אישית שמעניקות לכם שליטה מלאה בקוד, בנתונים ובתקציב. הצוות שלנו מספק את הפרויקט במפתח מלא—מאודיט וארכיטקטורה ועד הטמעה ותמיכה שוטפת—ומבטיח פתרון אמין וסקלבילי לעסק שלכם.

פיתוח ותחזוקה של כל סוגי האתרים:

אתרי מידע או יישומי אינטרנט
אתרי תדמית, דפי נחיתה, אתרי חברה, קטלוגים מקוונים, חידונים, אתרי קידום, בלוגים, מקורות חדשות, פורטלי מידע, פורומים, אגרגטורים
אתרי מסחר אלקטרוני או יישומי אינטרנט
חנויות מקוונות, פורטלי B2B, שווקים, בורסות מקוונות, אתרי קאשבק, בורסות, פלטפורמות דרופשיפינג, מנתחי מוצרים
יישומי אינטרנט לניהול תהליכים עסקיים
מערכות CRM, מערכות ERP, פורטלים ארגוניים, מערכות ניהול ייצור, מנתחי מידע
אתרי שירות אלקטרוני או יישומי אינטרנט
פלטפורמות מודעות, בתי ספר מקוונים, בתי קולנוע מקוונים, בוני אתרים, פורטלים לשירותים אלקטרוניים, פלטפורמות אירוח וידאו, פורטלים נושאיים

אלה רק חלק מהסוגים הטכניים של אתרים שאנו עובדים איתם, ולכל אחד מהם יכולים להיות מאפיינים ופונקציונליות ספציפיים משלו, וכן ניתן להתאים אותם לצרכים ולמטרות הספציפיים של הלקוח.

השירותים שאנו מציעים
מציג 1 מתוך 1כל 2062 השירותים
הטמעת פלטפורמת בדיקות A/B מותאמת אישית לאתר שלך
מורכב
~1-2 שבועות

הכישורים שלנו:

שאלות נפוצות

העבודות האחרונות

  • פיתוח אפליקציית ווב עבור FEEDME
    פיתוח אפליקציית ווב עבור FEEDME
    1359
  • פיתוח חנות מקוונת לחברת FURNORO
    פיתוח חנות מקוונת לחברת FURNORO
    1330
  • פיתוח אפליקציית ווב עבור Enviok
    פיתוח אפליקציית ווב עבור Enviok
    1077
  • פיתוח CRM עבור Chasseurs
    פיתוח CRM עבור Chasseurs
    1113
  • פיתוח אתר עבור SBH Partners
    פיתוח אתר עבור SBH Partners
    1201
  • פיתוח אתר עבור Red Pear
    פיתוח אתר עבור Red Pear
    619

תארו לעצמכם שהשקתם מבחן A/B דרך Optimizely, אבל אחרי שבוע גיליתם ש-LCP עלה ב-300 אלפיות השנייה בגלל סקריפט חיצוני. או שאינכם יכולים לקבל נתונים גולמיים — רק גרפים מצטברים. ועלות הרישיון עבור 10,000 מבקרים היא הוצאה חודשית משמעותית. פלטפורמת A/B מותאמת אישית פותרת את כל הבעיות הללו: אתם שולטים בקוד, בנתונים ובתקציב. החיסכון בעלויות הרישוי יכול להגיע עד 70%, עם תקופת החזר של 3–6 חודשים. יתרה מכך, פלטפורמה מותאמת אישית פועלת פי 2–3 מהר יותר כי אין סקריפטים חיצוניים.

צברנו ניסיון של למעלה מ-5 שנים בפיתוח מערכות כאלה עבור חנויות מקוונות עם 1M+ מבקרים חודשיים — יותר מ-50 פרויקטים. הפלטפורמה שלנו בנויה על עיקרון מודולרי ומתאימה עצמה בקלות לכל ארכיטקטורה.

יתרונות של פלטפורמת A/B מותאמת אישית

כלים מוכנים מאיצים את ההתחלה אך הופכים ליקרים ולא גמישים בקנה מידה. פלטפורמה מותאמת אישית מחזירה את ההשקעה לאחר מספר מבחנים בלבד — בפרויקט אחד, ההמרה עלתה ב-15% לאחר הניסוי הראשון. בשימוש שנתי, החיסכון ברישוי יכול לכסות את עלות הפיתוח תוך מספר חודשים.

כיצד אנו פותרים הקצאה דטרמיניסטית

הדרישה המרכזית של מבחן A/B: משתמש חייב תמיד ליפול לאותו וריאנט ניסוי. כדי להשיג זאת, אנו משתמשים ב-הקצאה מבוססת hash. hash של user_id ושם הניסוי מודולו 100% קובע את מספר הווריאנט. התוצאה נשמרת במסד הנתונים, מה שמבטיח עקביות על פני ביקורים מרובים.

הנה סכימת הטבלה לאחסון ניסויים והקצאות:

CREATE TABLE experiments (
    id SERIAL PRIMARY KEY,
    slug VARCHAR(100) UNIQUE NOT NULL,
    name VARCHAR(255) NOT NULL,
    description TEXT,
    status VARCHAR(20) DEFAULT 'draft', -- draft, running, paused, completed
    traffic SMALLINT DEFAULT 100, -- % трафика, участвующего в эксперименте
    start_at TIMESTAMPTZ,
    end_at TIMESTAMPTZ,
    created_at TIMESTAMPTZ DEFAULT NOW(),
    updated_at TIMESTAMPTZ DEFAULT NOW()
);

CREATE TABLE experiment_variants (
    id SERIAL PRIMARY KEY,
    experiment_id INTEGER REFERENCES experiments(id),
    slug VARCHAR(100) NOT NULL,
    name VARCHAR(255),
    weight SMALLINT DEFAULT 50,
    config JSONB DEFAULT '{}',
    UNIQUE(experiment_id, slug)
);

CREATE TABLE user_assignments (
    user_id BIGINT NOT NULL,
    experiment_id INTEGER REFERENCES experiments(id),
    variant_id INTEGER REFERENCES experiment_variants(id),
    assigned_at TIMESTAMPTZ DEFAULT NOW(),
    PRIMARY KEY (user_id, experiment_id)
);

שירות ה-PHP מיישם התפלגות דטרמיניסטית באמצעות crc32 ושמירה במסד נתונים:

class ExperimentAssignmentService {
    public function getVariant(int $userId, string $experimentSlug): ?string {
        $experiment = $this->getActiveExperiment($experimentSlug);
        if (!$experiment) return null;
        $existing = $this->assignmentRepo->find($userId, $experiment['id']);
        if ($existing) return $existing['variant_slug'];
        $trafficBucket = $this->hashToBucket($userId, $experimentSlug . '_traffic');
        if ($trafficBucket >= $experiment['traffic']) return null;
        $variantBucket = $this->hashToBucket($userId, $experimentSlug);
        $variant = $this->selectVariant($experiment['variants'], $variantBucket);
        $this->assignmentRepo->assign($userId, $experiment['id'], $variant['id']);
        $this->eventTracker->track($userId, 'experiment.assigned', [
            'experiment' => $experimentSlug,
            'variant' => $variant['slug'],
        ]);
        return $variant['slug'];
    }

    private function hashToBucket(int $userId, string $salt): int {
        $hash = crc32($userId . '_' . $salt);
        return abs($hash) % 100;
    }

    private function selectVariant(array $variants, int $bucket): array {
        $cumulative = 0;
        foreach ($variants as $variant) {
            $cumulative += $variant['weight'];
            if ($bucket < $cumulative) return $variant;
        }
        return end($variants);
    }
}

מעקב אירועים ב-ClickHouse

אנו שולחים את כל פעולות המשתמש המשמעותיות עם הקשר הניסוי. כדי לא להאט את חוויית המשתמש, האירועים נכתבים באופן אסינכרוני דרך תור.

class ExperimentEventTracker {
    public function track(int $userId, string $event, array $properties = []): void {
        $activeVariants = $this->assignmentRepo->getUserVariants($userId);
        $payload = [
            'event' => $event,
            'user_id' => $userId,
            'session_id' => session_id(),
            'occurred_at' => now()->toIso8601String(),
            'experiments' => $activeVariants,
            'properties' => $properties,
        ];
        $this->queue->push(new TrackExperimentEvent($payload));
    }
}

הנתונים מאוחסנים ב-ClickHouse — DBMS עמודי המותאם לשאילתות אנליטיות. זה מאפשר חישובי המרה מהירים ויצירת דוחות גם עם מיליוני אירועים.

חישוב תוצאות: מבחן Z

לאחר איסוף הנתונים, אנו משתמשים ב-מבחן Z דו-צדדי לפרופורציות (ויקיפדיה). הוא מצביע האם ההבדל בין ההמרות של קבוצת הביקורת וקבוצת הניסוי הוא מובהק סטטיסטית. האפקט המינימלי שניתן לזיהוי (MDE) מוגדר מראש — לדוגמה, 5% בעוצמה של 80%.

import numpy as np
from scipy import stats

def calculate_significance(control, treatment):
    p1 = control['conversions'] / control['users']
    p2 = treatment['conversions'] / treatment['users']
    n1, n2 = control['users'], treatment['users']
    p_pool = (control['conversions'] + treatment['conversions']) / (n1 + n2)
    se = np.sqrt(p_pool * (1 - p_pool) * (1/n1 + 1/n2))
    if se == 0:
        return {'error': 'Insufficient data'}
    z = (p2 - p1) / se
    p_value = 2 * (1 - stats.norm.cdf(abs(z)))
    diff = p2 - p1
    se_diff = np.sqrt(p1*(1-p1)/n1 + p2*(1-p2)/n2)
    ci = [diff - 1.96*se_diff, diff + 1.96*se_diff]
    return {'significant': p_value < 0.05, 'p_value': round(p_value, 6), 'lift': round((p2-p1)/p1*100,2) if p1>0 else None}

כדי להבטיח תוצאות אמינות, אנו בודקים גם אי-התאמה ביחס המדגם (SRM) — האם התפלגות המשתמשים בפועל חורגת מהצפוי. אם ערך ה-p של מבחן chi-square נמוך מ-0.01, הנתונים מסומנים כלא אמינים.

פרמטר חישוב
המרה המרות / משתמשים
Lift (p2-p1)/p1 * 100%
רווח בר-סמך p ± 1.96 * SE
שלב משך תוצאה
אנליטיקה 1–2 ימים יעדים, מדדים, ארכיטקטורה
עיצוב 2–3 ימים סכימת DB, API, חוזים
יישום 7–10 ימים קוד, בדיקות
בדיקות 2 ימים יחידה, אינטגרציה, עומס
פריסה 1–2 ימים שחרור, ניטור

כיצד דגלי תכונה עובדים במבחני A/B?

מבחני A/B ו-דגלי תכונה הם מושגים קשורים. אנו משלבים אותם כך: וריאנט ניסוי מכיל תצורת JSON המשפיעה על התנהגות התכונה. לדוגמה, וריאנט CREATE TABLE experiments ( id SERIAL PRIMARY KEY, slug VARCHAR(100) UNIQUE NOT NULL, name VARCHAR(255) NOT NULL, description TEXT, status VARCHAR(20) DEFAULT 'draft', -- draft, running, paused, completed traffic SMALLINT DEFAULT 100, -- % трафика, участвующего в эксперименте start_at TIMESTAMPTZ, end_at TIMESTAMPTZ, created_at TIMESTAMPTZ DEFAULT NOW(), updated_at TIMESTAMPTZ DEFAULT NOW() ); CREATE TABLE experiment_variants ( id SERIAL PRIMARY KEY, experiment_id INTEGER REFERENCES experiments(id), slug VARCHAR(100) NOT NULL, name VARCHAR(255), weight SMALLINT DEFAULT 50, config JSONB DEFAULT '{}', UNIQUE(experiment_id, slug) ); CREATE TABLE user_assignments ( user_id BIGINT NOT NULL, experiment_id INTEGER REFERENCES experiments(id), variant_id INTEGER REFERENCES experiment_variants(id), assigned_at TIMESTAMPTZ DEFAULT NOW(), PRIMARY KEY (user_id, experiment_id) ); מאפשר class ExperimentAssignmentService { public function getVariant(int $userId, string $experimentSlug): ?string { $experiment = $this->getActiveExperiment($experimentSlug); if (!$experiment) return null; $existing = $this->assignmentRepo->find($userId, $experiment['id']); if ($existing) return $existing['variant_slug']; $trafficBucket = $this->hashToBucket($userId, $experimentSlug . '_traffic'); if ($trafficBucket >= $experiment['traffic']) return null; $variantBucket = $this->hashToBucket($userId, $experimentSlug); $variant = $this->selectVariant($experiment['variants'], $variantBucket); $this->assignmentRepo->assign($userId, $experiment['id'], $variant['id']); $this->eventTracker->track($userId, 'experiment.assigned', [ 'experiment' => $experimentSlug, 'variant' => $variant['slug'], ]); return $variant['slug']; } private function hashToBucket(int $userId, string $salt): int { $hash = crc32($userId . '_' . $salt); return abs($hash) % 100; } private function selectVariant(array $variants, int $bucket): array { $cumulative = 0; foreach ($variants as $variant) { $cumulative += $variant['weight']; if ($bucket < $cumulative) return $variant; } return end($variants); } } . קוד הפרונטאנד או הבקאנד פשוט קורא את התצורה הזו ומשנה התנהגות.

$variant = $experimentService->getVariant($userId, 'checkout-redesign');
$config = $experimentService->getVariantConfig('checkout-redesign', $variant);
$checkoutSteps = $config['checkout_steps'] ?? 3;

מה כלול

  • פיתוח שירות הקצאה עם התפלגות מבוססת hash ובדיקות יחידה
  • מעקב אירועים עם כתיבה אסינכרונית ל-ClickHouse
  • חישוב מובהקות סטטיסטית (מבחן Z, רווחי בר-סמך)
  • פאנל ניהול להפעלה וניטור ניסויים
  • תיעוד אינטגרציה והדרכת צוות
  • תמיכה בחודש הראשון של ההשקה הפיילוטית

תהליך העבודה שלנו

  1. אנליטיקה — אנו מנתחים את היעדים, המדדים והארכיטקטורה הנוכחית שלכם (1–2 ימים)
  2. עיצוב — מכינים סכימת DB, API, חוזים (2–3 ימים)
  3. יישום — כותבים קוד, כותבים בדיקות (7–10 ימים)
  4. בדיקות — בדיקות יחידה, בדיקות אינטגרציה, עומס (2 ימים)
  5. פריסה — פריסה בסביבה שלכם, הגדרת ניטור (1–2 ימים)

לכל שאלה, צרו קשר — נעזור להעריך את היקף העבודה ולחשב חיסכון.

לוח זמנים ותקציב

זמן פיתוח משוער: 14 עד 21 ימים. העלות מחושבת באופן פרטני בהתאם למורכבות האינטגרציה ודרישות נוספות. הזמינו פלטפורמה מותאמת אישית היום — נספק הצעה תוך 2 ימי עסקים.

אנו מבטיחים איכות קוד: אנו משתמשים בסקירות קוד, כיסוי בדיקות של לפחות 80%, ומספקים אחריות לתיקון באגים ל-30 יום לאחר ההשקה. קבלו ייעוץ וגלו כיצד פלטפורמת A/B מותאמת אישית יכולה לשפר את ההמרות שלכם ללא פשרות בביצועים.