Skip to main content
Deploying your application is just the beginning of a continuous improvement process. After you deploy to production, you’ll want to refine your system by enhancing prompts, language models, tools, and architectures. Backtesting involves assessing new versions of your application using historical data and comparing the new outputs to the original ones. Compared to evaluations using pre-production datasets, backtesting offers a clearer indication of whether the new version of your application is an improvement over the current deployment. Here are the basic steps for backtesting:
  1. Select sample runs from your production tracing project to test against.
  2. Transform the run inputs into a dataset and record the run outputs as an initial experiment against that dataset.
  3. Execute your new system on the new dataset and compare the results of the experiments.
This process will provide you with a new dataset of representative inputs, which you can version and use for backtesting your models.
Often, you won’t have definitive “ground truth” answers available. In such cases, you can manually label the outputs or use evaluators that don’t rely on reference data. If your application allows for capturing ground-truth labels, for example by allowing users to leave feedback, we strongly recommend doing so.

Setup

Configure the environment

Install and set environment variables. This guide requires langsmith>=0.2.4.
For convenience we’ll use the LangChain OSS framework in this tutorial, but the LangSmith functionality shown is framework-agnostic.

Define the application

For this example lets create a simple Tweet-writing application that has access to some internet search tools:

Simulate production data

Now lets simulate some production data:

Convert production traces to experiment

The first step is to generate a dataset based on the production inputs. Then copy over all the traces to serve as a baseline experiment.

Select runs to backtest on

You can select the runs to backtest on using the filter argument of list_runs. The filter argument uses the LangSmith trace query syntax to select runs.

Convert runs to experiment

convert_runs_to_test is a function which takes some runs and does the following:
  1. The inputs, and optionally the outputs, are saved to a dataset as Examples.
  2. The inputs and outputs are stored as an experiment, as if you had run the evaluate function and received those outputs.
Once this step is complete, you should see a new dataset in your LangSmith project called “Tweet Writing Task-backtesting TODAYS DATE”, with a single experiment like so: Baseline experiment

Benchmark against new system

Now we can start the process of benchmarking our production runs against a new system.

Define evaluators

First let’s define the evaluators we will use to compare the two systems. Note that we have no reference outputs, so we’ll need to come up with evaluation metrics that only require the actual outputs.

Evaluate baseline

Now, let’s run our evaluators against the baseline experiment.

Define and evaluate new system

Now, let’s define and evaluate our new system. In this example our new system will be the same as the old system, but will use GPT-4o instead of GPT-3.5. Since we’ve made our model configurable we can just update the default config passed to our agent:

Comparing the results

After running both experiments, you can view them in your dataset: Dataset page The results reveal an interesting tradeoff between the two models:
  1. GPT-4o shows improved performance in following formatting rules, consistently including the requested number of emojis
  2. However, GPT-4o is less reliable at staying grounded in the provided search results
To illustrate the grounding issue: in this example run, GPT-4o included facts about Abū Bakr Muhammad ibn Zakariyyā al-Rāzī’s medical contributions that weren’t present in the search results. This demonstrates how it’s pulling from its internal knowledge rather than strictly using the provided information. This backtesting exercise revealed that while GPT-4o is generally considered a more capable model, simply upgrading to it wouldn’t improve our tweet-writer. To effectively use GPT-4o, we would need to:
  • Refine our prompts to more strongly emphasize using only provided information
  • Or modify our system architecture to better constrain the model’s outputs
This insight demonstrates the value of backtesting - it helped us identify potential issues before deployment. Tutorial comparison view