50:00
Mistral AI · Data science live case

Keeping Vibe Work users

From raw usage logs to a product decision. About 60 minutes. ⏱ ~4 min to read this page

Objective

You are given a dataset describing how users interact with Vibe Work (formerly known as Le Chat), an AI assistant. The data is synthetic but reflects patterns inspired by real-world usage. Your objective is to understand user engagement and retention, and to help the team decide where to focus.

Key areas of focus

Dataset

One row per request.

Period: 1 January to 28 February 2025
Markets: US, FR, UK
ColumnDescription
request_uuidUnique ID of each request
user_uuidUnique ID of each user
request_atTimestamp when the request was made
request_date_atDate of the request
user_countryUser's country (e.g. US, FR)
intent_categoryType of request (e.g. Coding, Search)
number_of_characters_in_answersTotal number of characters in the AI's answer
time_per_characters_msGeneration time per character of the answer, in milliseconds
has_error_during_generation1 if an error occurred while generating the answer, else 0
is_dislike1 if the user gave negative feedback (thumbs-down) on the answer, else 0
In this session you won't write code. We'll go through a series of charts and results built from this dataset. Think aloud, ask for anything you need, and feel free to do rough calculations on paper.
Mistral AI · Data scienceKeeping Vibe Work users

Data quality

You've just received this file: 258,786 rows, one per request.

Before any analysis, what data quality checks would you run? What could make you distrust this data? ⏱ ~2 min

Mistral AI · Data scienceKeeping Vibe Work users

Data quality: a first look

You load the file in a notebook and run the usual first commands.

Here is what df.info() and df.describe() return. What do you conclude? ⏱ ~2 min

df = pd.read_csv("request_data_take_home.csv") df.info()
<class 'pandas.core.frame.DataFrame'>
RangeIndex: 258786 entries, 0 to 258785
Data columns (total 10 columns):
 #   Column                           Non-Null Count   Dtype 
---  ------                           --------------   ----- 
 0   request_uuid                     258786 non-null  object
 1   user_uuid                        258786 non-null  object
 2   request_at                       258786 non-null  object
 3   request_date_at                  258786 non-null  object
 4   user_country                     258786 non-null  object
 5   intent_category                  258786 non-null  object
 6   has_error_during_generation      258786 non-null  int64 
 7   is_dislike                       258786 non-null  int64 
 8   number_of_characters_in_answers  258786 non-null  int64 
 9   time_per_characters_ms           258786 non-null  int64 
dtypes: int64(4), object(6)
memory usage: 19.7+ MB
df.describe().round(2)
       has_error_during_generation  is_dislike  number_of_characters_in_answers  time_per_characters_ms
count                    258786.00   258786.00                        258786.00               258786.00
mean                          0.02        0.02                          1261.98                    3.14
std                           0.15        0.14                           837.32                    1.63
min                           0.00        0.00                            50.00                    1.00
25%                           0.00        0.00                           795.00                    2.00
50%                           0.00        0.00                           975.00                    3.00
75%                           0.00        0.00                          1347.00                    4.00
max                           1.00        1.00                          8419.00                   47.00
df.describe(include="object")
                                request_uuid                             user_uuid           request_at request_date_at user_country intent_category
count                                 258786                                258786               258786          258786       258786          258786
unique                                258786                                 11086               247495              59            3               4
top     d08aec8e-306c-41da-8ce0-5198d6330ba1  6f37f97f-523d-47b4-8e8e-547b7b4ae79d  2025-02-12 16:24:31      2025-02-26           US         Writing
freq                                       1                                    88                    4            6264       125127           90917
Mistral AI · Data scienceKeeping Vibe Work users

General exploration

The data can be trusted. Before looking at engagement or retention, get to know each variable.

Let's get to know the variables one by one: country, intent, answer length, generation speed, errors and dislikes. What chart would you draw for each, and what would you look for? ⏱ ~3 min

Mistral AI · Data scienceKeeping Vibe Work users

General exploration: the charts

Here is one chart per variable.

What do these charts tell you? What stands out, and what would you dig into next? ⏱ ~4 min

A. Country

Share of requests and share of users, by country 0% 20% 40% 48% US: requests 50% US: users 31% FR: requests 30% FR: users 20% UK: requests 20% UK: users

B. Intent

Share of requests, by intent 0% 10% 20% 30% 35% Writing 35% Coding 16% Search 14% Image Generation

C. Answer length

Answer length (characters), 100-character bins 0 20,000 40,000 0 1,000 2,000 3,000 4,000 5,000 6,000+ Characters in the answer

Median 975 · mean 1,262 · p90 2,204 · p99 4,640

D. Generation time per character

Generation time per character (ms): share of requests per value 0.0% 10.0% 20.0% 30.0% 7.3% 1 30.6% 2 31.1% 3 17.6% 4 7.6% 5 3.0% 6 1.2% 7 0.6% 8 0.3% 9 0.2% 10 0.1% 11 0.1% 12 0.1% 13 0.1% 14 0.2% 15+ Milliseconds per character (integer values)

E. Error rate per day

Daily error rate (share of requests with an error) 0% 1% 2% 3% 4% 1 Jan 15 Jan 1 Feb 15 Feb
Additional chart (open when the interviewer asks)
14-day churn after a request, with vs without an error (95% CI) 0% 1% 2% 3% 4% 5% No error 1.8% (n=180,766) Error 3.7% (n=4,834)
Mistral AI · Data scienceKeeping Vibe Work users

Data exploration: engagement

The data looks usable. Let's start with engagement.

How would you explore how frequently and how intensively users interact with Vibe Work? Which metrics and breakdowns would you look at, and what would you watch out for? ⏱ ~3 min

Mistral AI · Data scienceKeeping Vibe Work users

Engagement: the charts

Here are the main engagement charts.

What do these charts tell you about how users engage with Vibe Work? What stands out, and what would you dig into next? ⏱ ~3 min

A. Volume over time: requests, active users, requests per active user

Requests per day 0 2,000 4,000 6,000 1 Jan 15 Jan 1 Feb 15 Feb Daily active users 0 1,000 2,000 1 Jan 15 Jan 1 Feb 15 Feb Requests per active user, per day 0.0 1.0 2.0 1 Jan 15 Jan 1 Feb 15 Feb

B. How often users come back

Days between two active days of the same user 0% 10% 20% 30% 36% 1 23% 2 15% 3 10% 4 6% 5 4% 6 3% 7 2% 8 1% 9 1% 10 0% 11 0% 12 0% 13 0% 14 0% 15+ Gap in days (1 = active again the next day)

C. Intent mix by country

Intent mix by country (share of requests) 0% 10% 20% 30% 40% 50% 40% 30% 11% 19% US 30% 40% 20% 10% FR 30% 40% 20% 10% UK Coding Writing Search Image Generation
Mistral AI · Data scienceKeeping Vibe Work users

Retention: definition and measurement

Leadership is worried about retention.

How would you define and measure retention with this data? ⏱ ~3 min

Mistral AI · Data scienceKeeping Vibe Work users

Retention: choosing the churn window

To say a user has churned, we first need to decide how long a silence is too long.

How would you choose the time to come back, i.e. how long without a request before you call a user churned? ⏱ ~2 min

Mistral AI · Data scienceKeeping Vibe Work users

Retention: picking the churn window

For each number of inactive days N, here is how often users came back afterwards.

Looking at this curve, which churn window would you choose, and why? ⏱ ~3 min

Return rate after N days of inactivity Share of inactivity periods followed by a return within the next 21 days 0% 25% 50% 75% 100% 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 N = days without a request 94% 88% 76% 57% 26% 7% 1%

One point per active day followed by more than N days of inactivity. Only active days early enough to observe the inactivity plus the following 21 days are used.

Additional chart (open when the interviewer asks)
Users first seen, per day 0 1,000 2,000 1 Jan 15 Jan 1 Feb 15 Feb Users last seen, per day 0 1,000 2,000 1 Jan 15 Jan 1 Feb 15 Feb
Mistral AI · Data scienceKeeping Vibe Work users

Retention: reading the curves

Here are the weekly retention curves by cohort, excluding the first week (pre-existing users) and the partial last week.

Here are the weekly retention curves, one per first-seen cohort. What do you take from them? What would you tell leadership? ⏱ ~3 min

First-seen week 0% 25% 50% 75% 100% 0 1 2 3 4 5 6 Weeks since first-seen week Cohort 8 Jan Cohort 15 Jan Cohort 22 Jan Cohort 29 Jan Cohort 5 Feb Cohort 12 Feb

Share of each cohort active in week N after its first-seen week. Cohorts start on 8 Jan (the first week is excluded), and the partial last week (26–28 Feb) is excluded.

Mistral AI · Data scienceKeeping Vibe Work users

Retention: what drives it

We know how to measure retention. Now, what drives it?

What charts would you want to plot to start exploring what drives retention? ⏱ ~2 min

Mistral AI · Data scienceKeeping Vibe Work users

Retention: the charts

Here are the charts of churn after a request, by experience. All use the 14-day churn definition and exclude the last 14 days of data.

What do these charts tell you about what drives retention? What would you be careful about? ⏱ ~3 min

A. Churn by intent

14-day churn after a request, by intent (95% CI) 0% 1% 2% 3% 4% Coding 1.6% (n=64,850) Writing 1.6% (n=65,157) Search 1.7% (n=28,972) Image Generation 3.2% (n=26,621)

B. Errors and dislikes

14-day churn after a request: error and dislike (95% CI) 0% 1% 2% 3% 4% 5% No error 1.8% (n=180,766) Error 3.7% (n=4,834) No dislike 1.9% (n=181,864) Dislike 1.6% (n=3,736)

C. Country, at equal intent

14-day churn after a request, by intent × country FR UK US Coding 1.4% 1.6% 1.7% Writing 1.5% 1.7% 1.7% Search 1.5% 1.9% 1.7% Image Generation 3.1% 2.8% 3.3% All intents 1.6% 1.8% 2.0% Share of image requests 10% 10% 19%
Mistral AI · Data scienceKeeping Vibe Work users

Retention: causality

The charts show associations. How do we get to causes?

What are 3+ causal methods you could use to study the impact of a given experience (e.g. an error, an image request) on churn? ⏱ ~5 min

Mistral AI · Data scienceKeeping Vibe Work users

Retention: what to prioritise

A colleague regressed churn after each request on the request experience, comparing each user with themselves (user fixed effects). Coefficients are in probability units: 0.0147 = +1.47 percentage points of churn.

model = PanelOLS.from_formula( "churn_14d ~ 1 + error + dislike + length_k + latency_ms" " + C(intent) + C(day_of_week) + EntityEffects", data=requests.set_index(["user_uuid", "request_at"]), ) model.fit(cov_type="clustered", cluster_entity=True)
                                PanelOLS Estimation Summary                                 
============================================================================================
Dep. Variable:                     churn_14d   R-squared (Within):                    0.0018
Estimator:                          PanelOLS   No. Observations:                     185,600
Entity effects:                    user_uuid   Entities:                               9,358
Mean of dep. variable:                0.0185   Cov. Estimator:            Clustered (entity)
============================================================================================
                                 Parameter  Std. Err.  T-stat  P-value  Lower CI  Upper CI
--------------------------------------------------------------------------------------------
Intercept                           0.0156     0.0011   13.66    0.000    0.0134    0.0178
error                               0.0147     0.0026    5.60    0.000    0.0095    0.0198
dislike                            -0.0024     0.0020   -1.20    0.231   -0.0064    0.0016
length_k                           -0.0001     0.0004   -0.34    0.732   -0.0008    0.0006
latency_ms                         -0.0001     0.0002   -0.56    0.575   -0.0005    0.0003
C(intent)[T.Image_Generation]       0.0136     0.0012   11.74    0.000    0.0113    0.0159
C(intent)[T.Search]                 0.0011     0.0009    1.20    0.228   -0.0007    0.0028
C(intent)[T.Writing]                0.0008     0.0007    1.08    0.280   -0.0006    0.0021
============================================================================================
C(day_of_week) coefficients not shown. Intent baseline: Coding.
churn_14d = 1 if the user makes no further request within 14 days after the request.
Sample: requests at least 14 days before the end of the data.

Leadership can fund one retention project next quarter. Based on these results, what would you prioritise, and why? ⏱ ~5 min

Mistral AI · Data scienceKeeping Vibe Work users

A/B test: design

Following the retention analysis, the team built a new image generation model, "Imagine v2". Before rolling it out, they want to A/B test it.

Facts you can use
Image usersAbout 6,300 distinct users make an image request over 4 weeks (and growing)
"Any request within 14 days" after a first image request97%
"Active between day 8 and day 14" after a first image request82.5%
Smallest effect worth shipping+2 pp of retention

Design the test: who is in it, what do you randomise, what is your primary metric, what are your guardrails, how many users do you need, and how long does it run? ⏱ ~5 min

Mistral AI · Data scienceKeeping Vibe Work users

A/B test: first readout Optional

The test ran for 8 weeks. Here is the dashboard the product team shared.

Experiment: Imagine v2
ChangeNew image generation model ("Imagine v2") vs the current one
PopulationUsers who make at least one image request during the test (US, FR, UK)
RandomisationPer user, 50/50
Who is countedUsers are randomised on their first image request, and counted in the results once their first image has been successfully generated and displayed
Primary metricWeek-2 retention: share of users active between day 8 and day 14 after their first exposure
GuardrailsGeneration time (p95), timeout error rate
Duration8 weeks
MetricControlImagine v2Differencep-value
Users in the test6,2405,520
Week-2 retention (primary)82.4%84.9%+2.5 pp< 0.001
Image requests per user5.46.4+18%< 0.001
Timeout error rate2.0%3.2%+1.2 pp< 0.001
Generation time, p959.8 s13.2 s+35%< 0.001

The PM says: "Retention +2.5 pp, engagement +18%. Let's ship." What do you check before agreeing? ⏱ ~4 min

Mistral AI · Data scienceKeeping Vibe Work users

A/B test: the rerun Optional

The logging was fixed (users are now logged when randomised) and the test was rerun for 8 weeks. The split is now balanced: 5,931 vs 5,902 users.

Experiment: Imagine v2
ChangeNew image generation model ("Imagine v2") vs the current one
PopulationUsers who make at least one image request during the test (US, FR, UK)
RandomisationPer user, 50/50
Who is countedUsers are now counted as soon as they are randomised, whether or not an image is displayed
Primary metricWeek-2 retention: share of users active between day 8 and day 14 after their first exposure
GuardrailsGeneration time (p95), timeout error rate
Duration8 weeks (rerun, logging fixed)
Primary resultWeek-2 retention 82.6% → 84.1%: +1.5 pp [+0.1; +2.9], p = 0.04

Effect by week since first exposure

Difference in active users between Imagine v2 and control, by week since first exposure Each point: % of Imagine v2 users active that week minus % of control users active that week (95% CI) -2 pp -1 pp 0 pp +1 pp +2 pp +3 pp +4 pp +5 pp +3.0 pp Week 1 +1.5 pp Week 2 +0.4 pp Week 3 +0.2 pp Week 4 Weeks since the user’s first exposure to the test

The primary metric is significant (+1.5 pp, p = 0.04). What effect would you report to leadership, and why? ⏱ ~3 min

Mistral AI · Data scienceKeeping Vibe Work users

Thank you!

Thanks for thinking aloud with us. There was no single right path through this case: what we were looking for was how you reason.

What we covered

1Data qualityCan we trust the logs?
2ExplorationHow do users engage?
3RetentionWho leaves, and why?
4A/B testDoes the fix really work?

Your turn

What questions do you have for us, about the team, the role, or how we work with data at Mistral? ⏱ ~5 min