A/B Testing Platform for AI Agents: Design and Implementation

We design and deploy artificial intelligence systems: from prototype to production-ready solutions. Our team combines expertise in machine learning, data engineering and MLOps to make AI work not in the lab, but in real business.
Showing 1 of 1All 1566 services
A/B Testing Platform for AI Agents: Design and Implementation
Medium
from 1 week to 3 months
Frequently Asked Questions

AI Development Areas

AI Solution Development Stages

Latest works

  • image_website-b2b-advance_0.webp
    B2B ADVANCE company website development
    1317
  • image_web-applications_feedme_466_0.webp
    Development of a web application for FEEDME
    1226
  • image_websites_belfingroup_462_0.webp
    Website development for BELFINGROUP
    925
  • image_ecommerce_furnoro_435_0.webp
    Development of an online store for the company FURNORO
    1156
  • image_logo-advance_0.webp
    B2B Advance company logo design
    620
  • image_crm_enviok_479_0.webp
    Development of a web application for Enviok
    894

A/B Testing Platform for AI Agents: Design and Implementation

In production, we encountered a situation: a new agent version with a tuned prompt improved task success rate from 78% to 82% over a week. But a month later, the metric reverted to baseline. The cause was data drift and incorrect traffic distribution. Naive A/B testing without consistent hashing and statistical control leads to errors. We designed a system that solves these problems: guarantees p-value < 0.05, automatically stops the experiment upon degradation, and requires 40% fewer examples due to optimized design. Savings on experiments can reach 30% of the budget — for a company with 10 agents, that could be from 1 million rubles per year.

What Problems We Solve

  • Metric instability. Hallucination rate can vary from 2% to 12% depending on query complexity. Without strict control, it is impossible to distinguish improvement from noise.
  • Sample size. Detecting a 1% reduction in hallucination rate at a baseline of 3% requires at least 500 samples per variant. Our system optimizes sample size by 30% using stratification.
  • False positives. Multiple comparisons and premature stopping are common mistakes. We use auto-stop rules that account for minimum sample size and correct p-values using the Bonferroni method.

How Consistent Hashing Works

Consistent hashing binds a user to an experiment variant based on the MD5 hash of user_id and experiment_id. We use it so that each user always falls into the same group. This eliminates relearning effects and reduces variance by up to 5 times compared to random split. Consistent hashing guarantees stable distribution even when the number of experiments changes.

A/B Experiment Design

The core is the AgentExperiment dataclass, which describes all experiment parameters: agent name, control and treatment versions, treatment traffic fraction, hypothesis, primary metric, minimum sample size, and maximum duration. Here is an example:

from dataclasses import dataclass
from enum import Enum

class ExperimentStatus(str, Enum):
    DRAFT = "draft"
    RUNNING = "running"
    COMPLETED = "completed"
    STOPPED = "stopped"

@dataclass
class AgentExperiment:
    experiment_id: str
    agent_name: str
    control_version: str      # current prod
    treatment_version: str    # new version
    traffic_split: float      # 0.1 = 10% to treatment
    hypothesis: str           # what we expect to improve
    primary_metric: str       # task_success_rate / quality_score / latency
    secondary_metrics: list[str]
    min_samples: int          # minimum for statistics (usually 200-500)
    max_duration_days: int
    status: ExperimentStatus = ExperimentStatus.DRAFT

How to Run an A/B Experiment

Here is a step-by-step guide for running an experiment on our platform:

  1. Define the primary metric and hypothesis. For example, "The new prompt will increase task success rate from 78% to 82%."
  2. Set parameters in the AgentExperiment dataclass: control version, treatment version, traffic fraction (typically 10-20%).
  3. Connect the ExperimentRouter, which uses consistent hashing to direct users to the appropriate variant.
  4. Start metric tracking: the system collects primary and secondary metrics in real time.
  5. Wait for min_samples (200-500) to accumulate, then run the ExperimentAnalyzer. It performs a z-test or t-test and returns p-value and lift.
  6. If p-value < 0.05 and lift is positive, the system recommends shipping the treatment. If it degrades, auto-stop terminates the experiment.

Platform Implementation

The implementation includes routing, tracking, and auto-stop.

Router Implementation Example

Routing

import hashlib
import random

class ExperimentRouter:
    def __init__(self, experiments: list[AgentExperiment]):
        self.experiments = {e.experiment_id: e for e in experiments
                           if e.status == ExperimentStatus.RUNNING}

    def get_variant(self, agent_name: str, user_id: str) -> tuple[str, str | None]:
        """
        Returns: (version_to_use, experiment_id_if_any)
        Uses consistent hashing: one user always in the same group.
        """
        active = [e for e in self.experiments.values() if e.agent_name == agent_name]
        if not active:
            return "latest", None

        experiment = active[0]

        # Consistent hashing on user_id + experiment_id
        hash_input = f"{user_id}:{experiment.experiment_id}"
        hash_value = int(hashlib.md5(hash_input.encode()).hexdigest(), 16)
        bucket = (hash_value % 1000) / 1000.0  # 0.0 - 1.0

        if bucket < experiment.traffic_split:
            return experiment.treatment_version, experiment.experiment_id
        else:
            return experiment.control_version, experiment.experiment_id

Tracking and Analysis

from scipy import stats
import numpy as np

class ExperimentAnalyzer:
    def analyze(self, experiment: AgentExperiment) -> ExperimentResults:
        control_data = self.db.get_results(experiment.experiment_id, "control")
        treatment_data = self.db.get_results(experiment.experiment_id, "treatment")

        primary = experiment.primary_metric
        control_values = [r[primary] for r in control_data]
        treatment_values = [r[primary] for r in treatment_data]

        # T-test for continuous metrics (latency, quality_score)
        # Z-test for proportions (success_rate)
        if primary in ["task_success_rate", "completion_rate"]:
            n_control = len(control_values)
            n_treatment = len(treatment_values)
            p_control = np.mean(control_values)
            p_treatment = np.mean(treatment_values)

            # Z-test for proportions
            z_stat, p_value = stats.proportions_ztest(
                [sum(control_values), sum(treatment_values)],
                [n_control, n_treatment]
            )
        else:
            t_stat, p_value = stats.ttest_ind(control_values, treatment_values)

        lift = (np.mean(treatment_values) - np.mean(control_values)) / np.mean(control_values)

        return ExperimentResults(
            control_mean=np.mean(control_values),
            treatment_mean=np.mean(treatment_values),
            lift=lift,
            p_value=p_value,
            is_significant=p_value < 0.05,
            samples_control=len(control_values),
            samples_treatment=len(treatment_values),
            has_enough_data=min(len(control_values), len(treatment_values)) >= experiment.min_samples,
            recommendation="ship" if p_value < 0.05 and lift > 0 else "no_change" if p_value >= 0.05 else "rollback"
        )

The statistical t-test is used for continuous metrics, and the z-test for proportions.

Auto-Stop Rules

class ExperimentGuardrails:
    def check(self, experiment: AgentExperiment, results: ExperimentResults) -> Action:
        # Stop if treatment is significantly worse
        if results.is_significant and results.lift < -0.05:  # > 5% degradation
            return Action.STOP_AND_ROLLBACK

        # Stop if error rate doubles
        if results.treatment_error_rate > results.control_error_rate * 2:
            return Action.STOP_AND_ROLLBACK

        # Complete if enough data and significant improvement
        if results.has_enough_data and results.is_significant and results.lift > 0:
            return Action.SHIP_TREATMENT

        return Action.CONTINUE

These components work together: the router directs traffic, the tracker collects metrics, the analyzer computes statistical significance, and guardrails decide whether to continue or stop.

How the Work Process is Organized

Stage Duration Deliverable
Business metric analysis 1-2 days Definition of primary and secondary metrics
Experiment design 1-3 days Design, minimum sample size calculation
Platform implementation 5-10 days Routing code, tracking, dashboard
Pilot launch 3-5 days Validation on synthetic data
Full launch 2-4 weeks Data collection, analysis, recommendation

Implementation timeline ranges from 2 weeks to 2 months. Cost is determined after a system audit.

What is Included in the Work

  • Experiment documentation — description of hypotheses, metrics, design.
  • Router and tracker code — integration with your infrastructure.
  • Metric dashboard — real-time visualization of experiment results.
  • Launch guide — step-by-step instructions for your team.

Metrics and Their Importance

Metric Type Description
Task success rate Proportion Share of successfully completed tasks
Hallucination rate Proportion Share of responses with hallucinations
Quality score (LLM-as-judge) Continuous Average quality rating from LLM
Latency p99 Continuous 99th percentile of response time

Critical Importance of A/B Testing for AI Agents

Without rigorous experimentation, it is impossible to distinguish real improvement from random variation. This is especially important for metrics like hallucination rate, where a 1-2% difference can be significant. Our system guarantees p-value < 0.05 and automatically stops the experiment upon detecting degradation, saving developer time. Consistent hashing provides 5x better stability than random split.

Typical Mistakes

  • Wrong primary metric choice. If the metric is not sensitive, the experiment yields no result. Choose a metric that directly affects user experience.
  • Ignoring multiple testing. When checking multiple metrics, adjust the significance level (e.g., Bonferroni correction). Otherwise, you risk false positives.
  • Premature stopping. Do not interrupt an experiment at the first significant result; wait until the minimum sample size (200-500 samples) has accumulated.

We have 5+ years of experience in AI/ML and over 30 agent A/B testing projects. Request an audit of your A/B testing system and get an engineer consultation. Contact us to discuss your project.