# Product updates Source: https://docs.evidentlyai.com/changelog/changelog Latest releases. ## **Evidently 0.7.11** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.11). Example notebooks: * Synthetic data generation: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/datagen.ipynb) ## **Evidently 0.7.10** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.10). NEW: automated prompt optimization. Read the release blog on [prompt optimization for LLM judges](https://www.evidentlyai.com/blog/llm-judge-prompt-optimization). Example notebooks: * Code review binary LLM judge prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_code_review_example.ipynb) * Topic multi-class LLM judge prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_bookings_example.ipynb) * Tweet generation prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_tweet_generation_example.ipynb) ## **Evidently 0.7.9** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.9). ## **Evidently 0.7.8** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.8). ## **Evidently 0.7.7** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.7). ## **Evidently 0.7.6** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.6). ## **Evidently 0.7.5** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.5). ## **Evidently 0.7.4** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.4). ## **Evidently 0.7.3** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.3). ## **Evidently 0.7.2** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.2). ## **Evidently 0.7.1** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.1). ## **Evidently 0.7** This release introduces breaking changes. Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.7.0). * The new Evidently API becomes the default. Read the [Migration guide](/faq/migration). * New Evidently Cloud version released. Read the [Evidently Cloud v2 notice](/faq/cloud_v2). ## **Evidently 0.6.7** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.7). ## **Evidently 0.6.6** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.6). ## **Evidently 0.6.5** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.5). ## **Evidently 0.6.4** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.4). ## **Evidently 0.6.3** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.3). Added new RAG descriptors: see [tutorial](/examples/LLM_rag_evals) and [release blog](https://www.evidentlyai.com/blog/open-source-rag-evaluation-tool). ## **Evidently 0.6.2** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.2). We extended support for `litellm` , so you can easily use different providers like Gemini, Anthropic, etc. for LLM-based evaluations. ## **Evidently 0.6.1** Full release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.1). ## **New API release** The new API is available when you import modules from `evidently.future`. Read more in [Migration guide](/faq/migration). Release notes on [Github](https://github.com/evidentlyai/evidently/releases/tag/v0.6.0). ## **Editable datasets** You can now hit "edit" on any existing dataset, create a copy and add / delete rows and columns. Use it while working on your evaluation datasets or to leave comments on outputs. ## **New Docs** We are creating a new Docs website in anticipation of API change. You can still access old docs for information on earlier API and examples. # Data definition Source: https://docs.evidentlyai.com/docs/library/data_definition How to map the input data. To run evaluations, you must create a `Dataset` object with a `DataDefinition`, which maps: * **Column types** (e.g., categorical, numerical, text). * **Column roles** (e.g., id, prediction, target). This allows Evidently to process the data correctly. Some evaluations need specific columns and will fail if they're missing. You can define the mapping using the Python API or by assigning columns visually when uploading data to the Evidently platform. ## Basic flow **Step 1. Imports.** Import the following modules: ```python theme={null} from evidently import Dataset from evidently import DataDefinition ``` **Step 2. Prepare your data.** Use a pandas.DataFrame. Your data can have [flexible structure](/docs/library/overview#dataset) with any mix of categorical, numerical or text columns. Check the [Reference table](/metrics/all_metrics) for data requirements in specific evaluations. **Step 3. Create a Dataset object**. Use `Dataset.from_pandas` with `data_definition`: ```python theme={null} eval_data = Dataset.from_pandas( source_df, data_definition=DataDefinition() ) ``` To map columns automatically, pass an empty `DataDefinition()` . Evidently will map columns: * By type (numerical, categorical). * By matching column names to roles (e.g., a column "target" treated as target). Automation works in many cases, but manual mapping is more accurate. It is also necessary for evaluating prediction quality or handling text columns. **How to set the data definition manually?** See the section below for available options. **Step 4. Run evals.** Once the **Dataset** object is ready, you can [add Descriptors ](/docs/library/descriptors) and[ run Reports](/docs/library/report). ### Special cases **Working directly with pandas.DataFrame**. You can sometimes pass a `pandas.DataFrame` directly to `report.run()` without creating the Dataset object. This works for checks like numerical/categorical data summaries or drift detection. However, it's best to always create a `Dataset` object explicitly for clarity and control. **Working with two datasets**. If you're working with current and reference datasets (e.g., for drift detection), create a Dataset object for each. Both must have identical data definition. ## Data definition This page shows all the different mapping options. Note that you **only need to use the relevant ones** that apply for your evaluation scenario. For example, you don’t need columns like target/prediction to run data quality or LLM checks. ### Column types Knowing the column type helps compute correct statistics, visualizations, and pick default tests. #### Text data If you run LLM evaluations, simply specify the columns with inputs/outputs as text. ```python theme={null} definition = DataDefinition( text_columns=["Latest_Review"] ) eval_data = Dataset.from_pandas( source_df, data_definition=definition ) ``` **It's optional but useful**. You can [generate text descriptors](/docs/library/descriptors) without explicit mapping. But it's a good idea to map text columns since you may later run other evals which vary by column type. #### Tabular data Map numerical, categorical or datetime columns: ```python theme={null} definition = DataDefinition( text_columns=["Latest_Review"], numerical_columns=["Age", "Salary"], categorical_columns=["Department"], datetime_columns=["Joining_Date"] ) eval_data = Dataset.from_pandas( source_df, data_definition=definition ) ``` Explicit mapping helps avoid mistakes like misclassifying numerical columns with few unique values as categorical. If you **exclude** certain columns in mapping, they’ll be ignored in all evaluations. #### Default column types If you do not pass explicit mapping, the following defaults apply: | **Column Type** | **Description** | **Automated Mapping** | | --------------------- | ------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------- | | `numerical_columns` | | All columns with numeric types (`np.number`). | | `datetime_columns` | | All columns with DateTime format (`np.datetime64`). | | `categorical_columns` | | All non-numeric/non-datetime columns. | | `text_columns` | | No automated mapping. | ### ID and timestamp If you have a timestamp or ID column, it's useful to identify them. ```python theme={null} definition = DataDefinition( id_column="Id", timestamp="Date" ) ``` | **Column role** | **Description** | **Automated mapping** | | --------------- | --------------------------------------------------------------------------------------------------------------------------- | ------------------------ | | `id_column` | | Column named "id" | | `timestamp` | | Column named "timestamp" | How is`timestamp` different from `datetime_columns`? * **DateTime** is a column type. You can have many DateTime columns in the dataset. For example, conversation start / end time or features like "date of last contact." * **Timestamp** is a role. You can have a single timestamp column. It often represents the time when a data input was recorded. Use it if you want to see it as index on the plots. ### LLM evals When you generate [text descriptors](/docs/library/descriptors) and add them to the dataset, they are automatically mapped as `descriptors` in Data Definition. This means they will be included in the `TextEvals` [preset](/metrics/preset_text_evals) or treated as descriptors when you plot them on the dashboard. However, if you computed some scores or metadata externally and want to treat them as descriptors, you can map them explicitly: ```python theme={null} definition = DataDefinition( numerical_descriptors=["chat_length", "user_rating"], categorical_descriptors=["upvotes", "model_type"] ) ``` ### Regression To run regression quality checks, you must map the columns with: * Target: actual values. * Prediction: predicted values. You can have several regression results in the dataset, for example in case of multiple regression. (Pass the mappings in a list). Example mapping: ```python theme={null} definition = DataDefinition( regression=[Regression(target="y_true", prediction="y_pred")] ) ``` Defaults: ```python theme={null} target: str = "target" prediction: str = "prediction" ``` ### Classification To run classification checks, you must map the columns with: * Target: true label. * Prediction: predicted labels/probabilities. There two different mapping options, for binary and multi-class classification. You can also have several classification results in the dataset. (Pass the mappings in a list). #### Multiclass Example mapping: ```python theme={null} from evidently import MulticlassClassification data_def = DataDefinition( classification=[MulticlassClassification( target="target", prediction_labels="prediction", prediction_probas=["0", "1", "2"], # If probabilistic classification labels={"0": "class_0", "1": "class_1", "2": "class_2"} # Optional, for display only )] ) ``` Available options and defaults: ```python theme={null} target: str = "target" prediction_labels: str = "prediction" prediction_probas: Optional[List[str]] = None #if probabilistic classification labels: Optional[Dict[Label, str]] = None ``` When you have multiclass classification with predicted probabilities in separate columns, the column names in `prediction_probas` must exactly match the class labels. For example, if your classes are 0, 1, and 2, your probability columns must be named: "0", "1", "2". Values in `target` and `prediction` columns should be strings. #### Binary Example mapping: ```python theme={null} from evidently import BinaryClassification definition = DataDefinition( classification=[BinaryClassification( target="target", prediction_labels="prediction")], categorical_columns=["target", "prediction"]) ``` Available options and defaults: ```python theme={null} target: str = "target" prediction_labels: Optional[str] = None prediction_probas: Optional[str] = "prediction" #if probabilistic classification pos_label: Label = 1 #name of the positive label labels: Optional[Dict[Label, str]] = None ``` ### Ranking #### RecSys To evaluate recommender systems performance, you must map the columns with: * Prediction: this could be predicted score or rank. * Target: relevance labels (e.g., this could be an interaction result like user click or upvote, or a true relevance label) The **target** column can contain either: * a binary label (where `1` is a positive outcome) * any scores (positive values, where a higher value corresponds to a better match or a more valuable user action). Here are the examples of the expected data inputs. If the system prediction is a **score** (expected by default): | user\_id | item\_id | prediction (score) | target (relevance) | | -------- | -------- | ------------------ | ------------------ | | user\_1 | item\_1 | 1.95 | 0 | | user\_1 | item\_2 | 0.8 | 1 | | user\_1 | item\_3 | 0.05 | 0 | If the model prediction is a **rank**: | user\_id | item\_id | prediction (rank) | target (relevance) | | -------- | -------- | ----------------- | ------------------ | | user\_1 | item\_1 | 1 | 0 | | user\_1 | item\_2 | 2 | 1 | | user\_1 | item\_3 | 3 | 0 | Example mapping: ```python theme={null} definition = DataDefinition( ranking=[Recsys()] ) ``` Available options and defaults: ```python theme={null} user_id: str = "user_id" #columns with user IDs item_id: str = "item_id" #columns with ranked items target: str = "target" prediction: str = "prediction" ``` # Descriptors Source: https://docs.evidentlyai.com/docs/library/descriptors How to run evaluations for text data. To evaluate text data, like LLM inputs and outputs, you create **Descriptors**. This is a universal interface for all evals - from text statistics to LLM judges. Each descriptor computes a score or label per row of your dataset. You can combine multiple descriptors and set optional pass/fail conditions. You can use built-in descriptors or create custom ones using LLM prompts or Python. For a general introduction, check [Core Concepts](/docs/library/overview). You can also refer to the [LLM quickstart](quickstart_llm) for a minimal example. ## Basic flow Use this code snippet to create sample data for testing: ```python theme={null} import pandas as pd data = [ ["What is the chemical symbol for gold?", "The chemical symbol for gold is Au."], ["What is the capital of Japan?", "The capital of Japan is Tokyo."], ["Tell me a joke.", "Why don't programmers like nature? It has too many bugs!"], ["What is the boiling point of water?", "The boiling point of water is 100 degrees Celsius (212 degrees Fahrenheit)."], ["Who painted the Mona Lisa?", "Leonardo da Vinci painted the Mona Lisa."], ["What’s the fastest animal on land?", "The cheetah is the fastest land animal, capable of running up to 75 miles per hour."], ["Can you help me with my math homework?", "I'm sorry, but I can't assist with homework. You might want to consult your teacher for help."], ["How many states are there in the USA?", "There are 50 states in the USA."], ["What’s the primary function of the heart?", "The primary function of the heart is to pump blood throughout the body."], ["Can you tell me the latest stock market trends?", "I'm sorry, but I can't provide real-time stock market trends. You might want to check a financial news website or consult a financial advisor."] ] # Columns columns = ["question", "answer"] # Creating the DataFrame df = pd.DataFrame(data, columns=columns) ``` **Step 1. Imports.** Import the following modules: ```python theme={null} from evidently import Dataset from evidently import DataDefinition from evidently import Report from evidently.descriptors import * from evidently.presets import TextEvals ``` **Note**. Some Descriptors (like `OOVWordsPercentage()` may require `nltk` dictionaries: ```python theme={null} nltk.download('words') nltk.download('wordnet') nltk.download('omw-1.4') nltk.download('vader_lexicon') ``` **Step 2. Add descriptors** via the Dataset object. There are two ways to do this: * **Option A.** Simultaneously create the `Dataset` object and add descriptors to the selected columns (in this case, "answer" column). ```python theme={null} eval_dataset = Dataset.from_pandas( df, data_definition=DataDefinition( text_columns=["question", "answer"]), descriptors=[ Sentiment("answer", alias="Sentiment"), TextLength("answer", alias="Length"), IncludesWords("answer", words_list=['sorry', 'apologize'], alias="Denials"), ] ) ``` Read more on how how to [create the Dataset and Data Definition](/docs/library/data_definition) * **Option B.** Add descriptors to the existing Dataset using `add_descriptors`. For example, first create the Dataset. ```python theme={null} eval_dataset = Dataset.from_pandas( df, data_definition=DataDefinition(text_columns=["question", "answer"]), ) ``` Then, add the scores to this Dataset: ```python theme={null} eval_dataset.add_descriptors(descriptors=[ Sentiment("answer", alias="Sentiment"), TextLength("answer", alias="Length"), IncludesWords("answer", words_list=['sorry', 'apologize'], alias="Denials"), ]) ``` **Step 3. (Optional). Export results**. You can preview the DataFrame with results: ```python theme={null} eval_dataset.as_dataframe() ``` **Step 4. Get the Report**. This will summarize the results, capturing stats and distributions for all descriptors. The easiest way to get the Report is through `TextEvals` Preset. To configure and run the Report for the `eval_dataset`: ```python theme={null} report = Report([ TextEvals() ]) my_eval = report.run(eval_dataset) my_eval # my_eval.json() # ws.add_report(project.id, my_eval, include_data=True) ``` You can view the Report in Python, export the outputs (HTML, JSON, Python dictionary) or upload it to the Evidently platform. Check more in [output formats](/docs/library/output_formats). ## Customizing descriptors **All descriptors and parameters**. Evidently has multiple implemented descriptors, both deterministic and LLM-based. See a [reference table](/metrics/all_descriptors) with all descriptors and parameters. **Alias**. It is best to add an `alias` to each Descriptor to make it easier to reference. This name shows up in visualizations and column headers. It’s especially handy if you’re using checks like regular expressions with word lists, where the auto-generated title could get very long. ```python theme={null} eval_dataset.add_descriptors(descriptors=[ WordCount("answer", alias="Words"), ]) ``` **Descriptor parameters**. Some Descriptors have required parameters. For example, if you’re testing for competitor mentions using the `Contains` Descriptor, add the list of `items`: ```python theme={null} eval_dataset.add_descriptors(descriptors=[ Contains("answer", items=["AcmeCorp", "YetAnotherCorp"], alias="Competitors") ]) ``` These parameters are specific to each descriptors. Check the [reference table](/metrics/all_descriptors). **Multi-column descriptors**. Some evals use more than one column. For example, to match a new answer against reference, or measure semantic similarity. Pass both columns using parameters: ```python theme={null} eval_dataset.add_descriptors(descriptors=[ SemanticSimilarity(columns=["question", "answer"], alias="Semantic_Match") ]) ``` **LLM-as-a-judge**. There are also built-in descriptors that prompt an external LLM to return an evaluation score. You can add them like any other descriptor, but you must also provide an API key to use the corresponding LLM. ```python theme={null} eval_dataset.add_descriptors(descriptors=[ DeclineLLMEval("answer", alias="Contains_Denial") ]) ``` **Using and customizing LLM judge**. Check the [in-depth LLM judge guide](/metrics/customize_llm_judge) on using built-in and custom LLM-based evaluators. **Custom evals**. Beyond custom LLM judges, you can also implement your own programmatic evals as Python functions. Check the [custom descriptor guide](/metrics/customize_descriptor). ## Adding Descriptor Tests Descriptor Tests let you define pass/fail checks for each row in your dataset. Instead of just calculating values (like “How long is this text?”), you can ask: * Is the text under 100 characters? * Is the sentiment positive? You can also combine multiple tests into a single summary result per row. **Step 1. Imports**. Run imports: ```python theme={null} from evidently.descriptors import ColumnTest, TestSummary from evidently.tests import * ``` **Step 2. Add tests to a descriptor**. When creating a descriptor (like `TextLength` or `Sentiment`), use the tests argument to set conditions. Each test adds a new column with a True/False result. ```python theme={null} eval_dataset = Dataset.from_pandas( df, data_definition=DataDefinition(text_columns=["question", "answer"]), descriptors=[ Sentiment("answer", alias="Sentiment", tests=[ gte(0, alias="Sentiment is non-negative")]), TextLength("answer", alias="Length", tests=[ lte(100, alias="Length is under 100")]), ] ) ``` Use test parameters like `gte` (greater than or equal), `lte` (less than or equal), eq (equal). Check the [full list here](docs/library/tests#test-parameters). You can preview the results with: `eval_dataset.as_dataframe()`: **Step 3. Add a Test Summary**. Use `TestSummary` to combine multiple tests into one or more summary columns. For example, the following returns True if all tests pass: ```python theme={null} eval_dataset = Dataset.from_pandas( df, data_definition=DataDefinition(text_columns=["question", "answer"]), descriptors=[ Sentiment("answer", alias="Sentiment", tests=[ gte(0, alias="Sentiment is non-negative")]), TextLength("answer", alias="Length", tests=[ lte(100, alias="Length is under 100")]), DeclineLLMEval("answer", alias="Denials", tests=[ eq("OK", column="Denials", alias="Is not a refusal")]), TestSummary(success_all=True, alias="Test result"), #returns True if all conditions are satisfied ] ) ``` `TestSummary` will only consider tests added **before it** in the list of descriptors. For LLM judge descriptors returning multiple columns (e.g., label and reasoning), you must specify the target column for the test — see `DeclineLLMEval` in the example. You can aggregate Test results differently and include multiple summary columns, such as total count, pass rate, or weighted score: ```python theme={null} eval_dataset.add_descriptors(descriptors=[ TestSummary( success_all=True, # True if all tests pass success_any=True, # True if any test passes success_count=True, # Total number of tests passed success_rate=True, # Share of passed tests score=True, # Weighted score score_weights={ "Sentiment is non-negative": 0.9, "Length is under 100": 0.1, }, ) ]) ``` **Testing existing columns**. Use `ColumnTest` to apply checks to any column, even ones not generated by descriptors. This is useful for working with metadata or precomputed values: ```python theme={null} dataset = Dataset.from_pandas(pd.DataFrame(data), descriptors=[ ColumnTest("Feedback", eq("Positive")), ]) ``` ## Summary Reports You've already seen how to generate a report using the `TextEvals` preset. It's the simplest and useful way to summarize evaluation results. However, you can also create custom reports using different metric combinations for more control. **Imports**. Import the components you'll need: ```python theme={null} from evidently import Report from evidently.presets import TextEvals from evidently.metrics import * from evidently.tests import * ``` **Selecting a list of columns**. You can apply `TextEvals` to specific descriptors in your dataset. This makes your report more focused and lightweight. ```python theme={null} report = Report([ TextEvals(columns=["Sentiment", "Length", "Test result"]) ]) my_eval = report.run(eval_dataset, None) my_eval ``` **Custom Report with different Metrics**. Each Evidently Report is built from individual Metrics. For example, `TextEvals` internally uses `ValueStats` Metric for each descriptor. To customize the Report, you can reference specific descriptors and use metrics like `MeanValue`, `MaxValue`, etc: ```python theme={null} custom_report = Report([ MeanValue(column="Length"), MeanValue(column="Sentiment") ]) my_custom_eval = custom_report.run(eval_dataset, None) my_custom_eval ``` **List of all Metrics**. Check the [Reference table](/metrics/all_metrics). Consider using column-level Metrics like `MeanValue`, `MeanValue`, `MaxValue`, `QuantileValue`, `OutRangeValueCount` and `CategoryCount`. **Drift detection**. You can also run advanced checks, like comparing distributions between two datasets, for example, to detect text length drift: ```python theme={null} custom_report = Report([ ValueDrift(column="Length"), ]) my_custom_eval = custom_report.run(eval_dataset, eval_dataset) my_custom_eval ``` ## Dataset-level Test Suites You can also attach Tests to your Metrics to get pass/fail results at the **dataset** Report level. Example tests: * No response has sentiment \< 0 * No response exceeds 150 characters * No more than 10% of rows fail the summary test ```python theme={null} tests = Report([ MinValue(column="Sentiment", tests=[gte(0)]), MaxValue(column="Length", tests=[lte(150)]), CategoryCount(column="Test result", category=False, share_tests=[lte(0.1)]) ]) my_test_eval = tests.run(eval_dataset, None) my_test_eval # my_test_eval.json() ``` This produces a Test Suite that shows clear pass/fail results for the overall dataset. This is useful for automated checks and regression testing. **Report and Tests API**. Check separate guides on [generating Reports](/docs/library/report) and setting [Test conditions](/docs/library/tests). # Overview Source: https://docs.evidentlyai.com/docs/library/evaluations_overview Core eval workflow using the Evidently library at a glance. ## Define and run the eval To log the evaluation results to the Evidently Platform, first connect to [Evidently Cloud](/docs/setup/cloud) or your [local workspace](/docs/setup/self-hosting) and [create a Project](/docs/platform/projects_manage). It's optional: you can also run evals locally in Python. Get your data in a table like a `pandas.DataFrame`. More on [data requirements](/docs/library/overview#dataset). You can also [load data](/docs/platform/datasets_workflow) from Evidently Platform, like tracing data you captured or synthetic datasets. Create a Dataset object with `DataDefinition()` that specifies column role and types. You can also use default type detection. [How to set Data Definition](/docs/library/data_definition). ```python theme={null} eval_data = Dataset.from_pandas( source_df, data_definition=DataDefinition() ) ``` For LLM and text evals, define row-level `descriptors` to compute. Here, you can use a variety of methods, from deterministic to LLM judges. Optionally, add row-level tests to get explicit pass/fail outcomes on set conditions. [How to use Descriptors](/docs/library/descriptors). ```python theme={null} eval_data.add_descriptors(descriptors=[ TextLength("Question", alias="Length"), Sentiment("Answer", alias="Sentiment") ]) ``` For dataset-level evals (classification, data drift) or to summarize descriptors, create a `Report` with chosen `metrics` or `presets`. How to [configure Reports](/docs/library/report). ```python theme={null} report = Report([ DataSummaryPreset() ]) ``` Add dataset-level Pass/Fail conditions, like to check if all texts in the dataset are in \< 100 symbols length. How to [configure Tests](/docs/library/tests). ```python theme={null} report = Report([ DataSummaryPreset(), MaxValue(column="Length", tests=[lt(100)]), ]) ``` Add `tags` or `metadata` to identify specific evaluation runs or datasets, or override the default `timestamp `. [How to add metadata](/docs/library/tags_metadata). To execute the eval, `run`the Report on the `Dataset` (or two). ```python theme={null} my_eval = report.run(eval_data, None) ``` * To upload to the Evidently Platform. [How to upload results](/docs/platform/evals_api). ```python theme={null} ws.add_run(project.id, my_eval, include_data=True) ``` * To view locally. [All output formats](/docs/library/output_formats). ```python theme={null} my_eval ##my_eval.json() ``` ## Quickstarts Check for end-to-end examples: Evaluate the quality of text outputs. Test tabular data quality and data drift. # Metric generators Source: https://docs.evidentlyai.com/docs/library/metric_generator How to generate multiple metrics at once. Sometimes you need to generate multiple column-level Tests or Metrics. To simplify this, you can use metric generator helper functions. **Pre-requisites**: * You know how to [generate Reports](/docs/library/report). ## Imports Use the following code to generate toy data for this guide. ```python theme={null} import pandas as pd import numpy as np from evidently import Dataset from evidently import DataDefinition np.random.seed(42) data = { "Age": np.random.randint(18, 60, size=30), "Salary": np.random.randint(30000, 120000, size=30), "Department": np.random.choice(["HR", "IT", "Finance", "Marketing", "Operations"], size=30), "YearsExperience": np.random.randint(1, 15, size=30), "EducationLevel": np.random.choice(["High School", "Bachelor", "Master", "PhD"], size=30) } dummy_df = pd.DataFrame(data) eval_data_1 = Dataset.from_pandas( dummy_df.iloc[:15], data_definition=DataDefinition() ) eval_data_2 = Dataset.from_pandas( dummy_df.iloc[15:], data_definition=DataDefinition() ) ``` Imports ```python theme={null} from evidently import Report from evidently.metrics import * from evidently.generators import ColumnMetricGenerator ``` ## Metric generators **Example 1**. Apply the selected metric (`ValueDrift`) to all columns in the dataset. ```python theme={null} report = Report([ ColumnMetricGenerator(ValueDrift) ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval ``` **Example 2**. Apply the selected metric (`ValueDrift`) to the listed columns in the dataset. Use `metric_kwargs` to pass any applicable metric parameters. ```python theme={null} report = Report([ ColumnMetricGenerator(ValueDrift, columns=["EducationLevel", "Salary"], metric_kwargs={"method":"psi"}), # metric parameters ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval ``` **Example 3**. Apply the selected metric (`ValueDrift`) only to the categorical (`cat`) columns in the dataset. ```python theme={null} report = Report([ ColumnMetricGenerator(UniqueValueCount, column_types='cat'), #apply to categorical columns only ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval ``` Available: * `num` - numerical * `cat` - categorical * `all` - all ## Test generators You can use the same approach to generate Tests. Use `metric_kwargs` to pass test conditions. **Example.** Generate the same Test for all the columns in the dataset. It will use defaults if you do not specify the test condition. ```python theme={null} from evidently.future.tests import * report = Report([ ColumnMetricGenerator(MinValue, column_types='num', metric_kwargs={"tests":[gt(0)]}), ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval ``` This will apply the minimum value test to all numerical columns in the dataset and check that they are above 0. # Output formats Source: https://docs.evidentlyai.com/docs/library/output_formats How to export the evaluation results. You can view or export Reports in multiple formats. **Pre-requisites**: * You know how to [generate Reports](/docs/library/report). ## Log to Workspace You can save the computed Report in Evidently Cloud or your local workspace. ```python theme={null} ws.add_run(project.id, my_eval, include_data=False) ``` **Uploading evals**. Check Quickstart examples [for ML](/quickstart_ml) or [for LLM](/quickstart_llm) for a full workflow. ## View in Jupyter notebook You can directly render the visual summary of evaluation results in interactive Python environments like Jupyter notebook or Colab. After running the Report, simply call the resulting Python object: ```python theme={null} my_report ``` This will render the HTML object directly in the notebook cell. ## HTML You can also save this interactive visual Report as an HTML file to open in a browser: ```python theme={null} my_report.save_html(“file.html”) ``` This option is useful for sharing Reports with others or if you're working in a Python environment that doesn’t display interactive visuals. ## JSON You can get the results of the calculation as a JSON. It is useful for storing and exporting results elsewhere. To view the JSON in Python: ```python theme={null} my_report.json() ``` To save the JSON as a separate file: ```python theme={null} my_report.save_json("file.json") ``` ## Python dictionary You can get the output as a Python dictionary. This format is convenient for automated evaluations in data or ML pipelines, allowing you to transform the output or extract specific values. To get the dictionary: ```python theme={null} my_report.dict() ``` # Introduction Source: https://docs.evidentlyai.com/docs/library/overview Core concepts and components of the Evidently Python library. The Evidently Python library is an open-source tool designed to evaluate, test and monitor the quality of AI systems, from experimentation to production. You can use the evaluation library on its own, or as part of the [Monitoring Platform](/docs/platform/overview) (self-hosted or Evidently Cloud). This page provides a conceptual overview of the Evidently library. # At a glance Evidently library covers 4 core workflows. You can these features together or standalone. ## **1. AI/ML Evaluations** **TL;DR**: Lots of useful AI/ML/data metrics out of the box. Exportable as scores or visual reports. Evidently’s core capability is running evaluations on AI system inputs and outputs. It includes 100+ built-in metrics and checks, and also useful configurable templates for custom evaluations. You can get raw either metrics or pass/fail test results. We support metrics that make sense both for predictive ML tasks and generative LLM system outputs. Example built-in checks: | **Type** | **Example checks** | | ------------------------- | ------------------------------------------------------------------------- | | **🔡 Text qualities** | Length, sentiment, special symbols, pattern matches, etc. | | **📝 LLM output quality** | Semantic similarity, relevance, RAG faithfulness, custom LLM judges, etc. | | **🛢 Data quality** | Missing values, duplicates, min-max ranges, correlations, etc. | | **📊 Data drift** | 20+ tests and distance metrics to detect distribution drift. | | **🎯 Classification** | Accuracy, precision, recall, ROC AUC, confusion matrix, bias, etc. | | **📈 Regression** | MAE, ME, RMSE, error distribution, error normality, error bias, etc. | | **🗂 Ranking (inc. RAG)** | NDCG, MAP, MRR, Hit Rate, etc. | You can get evaluation results in multiple formats: * **Export scores** as JSON or Python dictionary. * **As a DataFrame**, either as a raw metrics table or by attaching scores to existing data rows. * **Generate visual reports** in Jupyter, Colab, or export as HTML * **Upload to Evidently Platform** to track evaluations over time This exportability makes it easy to integrate Evidently into your existing workflows and pipelines – even if you are not using the Evidently Platform. Here is an example visual report showing various data quality metrics and test results. Other evaluations can be presented in the same way, or exported as raw scores: **📌 Links:** * Quickstart for [LLM evaluation](/quickstart_llm) * Quickstart for [ML evaluation](/quickstart_ml) Or read on through this page for conceptual introduction. ## **2. Synthetic data generation \[NEW]** **TL;DR**: We have a nice config for structured synthetic data generation using LLMs. Primarily designed for LLM use cases, Evidently also helps you generate synthetic test datasets - such as RAG-style question-answer pairs from a knowledge base or synthetic inputs to cold-start your AI app testing. **📌 Links:** * [Synthetic data](docs/library/synthetic_data_api) ## **3. Prompt optimization \[NEW]** **TL;DR**: We help write prompts using labeled or annotated data as a target. Evidently also includes tools for automated prompt writing. This features uses built-in evaluation capabilities to score prompt variations, optimizing them based on a target dataset and/or free-form user feedback. This feature also help automatically generate LLM judge prompts to streamline the creation of custom evaluations. **📌 Links:** * [Prompt optimization](docs/library/prompt_optimization) ## 4. **Tracking and Visualization UI** **TL;DR**: There is also a minimal UI to store and track evaluation results. The Evidently library also includes a lightweight self-hostable UI for storing, comparing, and visualizing evaluation results over time. While visual reports provide a snapshot of an evaluation for a specific period, dataset, or prompt version, the UI allows you to store multiple evaluations and track changes over time. **📌 Links:** * See live demo: [https://demo.evidentlyai.com](https://demo.evidentlyai.com/). * [Self-hosting guide](/docs/setup/self-hosting) The open-source UI is different from the Evidently Cloud / Enterprise platform version which has muliple additional features. Explore the [Evidently Platform capabailities](/docs/platform/overview). # Core evaluation concepts Let's take a look at the end-to-end evaluation process. It can be adapted to different metrics or data types, following the same worklows. ## Dataset To run an evaluation, you first need to prepare the data. For example, generate and trace outputs from your ML or LLM system. 1. **Prepare your data as a pandas DataFrame**. The table can include any combination of numerical, categorical, text, metadata (including timestamps or IDs), and embedding columns. Here are a few examples of data inputs Evidently can handle: **LLM logs**. Pass any text columns with inputs/outputs, context or ground truth. | Question | Context | Answer | | ------------------------------------ | --------------------------------------------------------------------------------------------------------- | ------------------------------- | | How old is the universe? | The universe is believed to have originated from the Big Bang that occurred 13.8 billion years ago. | 13.8 billion years old. | | What’s the lifespan of Baobab trees? | Baobab trees can live up to 2,500 years. They are often called the “Tree of Life”. | Up to 2,500 years. | | What is the speed of light? | The speed of light in a vacuum is approximately 299,792 kilometers per second (186,282 miles per second). | Close to 299,792 km per second. | **Data table**. You can pass any dataset to run run data quality and data drift checks. Use this when evaluating ML model performance without ground truth: include input features and predictions. | Order ID | Product | Category | Quantity | Price | Payment Method | Shipping Status | | -------- | ---------------------- | ----------- | -------- | ------ | -------------- | --------------- | | ORD001 | Wireless Headphones | Electronics | 1 | 120.00 | Credit Card | Shipped | | ORD002 | Yoga Mat | Sports | 2 | 45.00 | PayPal | In Transit | | ORD003 | Stainless Steel Bottle | Kitchen | 3 | 30.00 | Debit Card | Delivered | **Classification logs**. To evaluate classification quality, pass a table that contains columns with predicted and actual labels. Input features are optional but useful for some evals. | Timestamp | Transaction ID | Amount | Location | Device Type | Fraud Label | Target | | ------------------- | -------------- | ------- | ------------- | ----------- | ----------- | ------ | | 2023-12-01 10:15:23 | TXN001 | 250.00 | New York, USA | Mobile | 0 | 0 | | 2023-12-01 10:17:45 | TXN002 | 5000.00 | London, UK | Desktop | 1 | 1 | | 2023-12-01 10:20:10 | TXN003 | 1200.00 | Sydney, AUS | Tablet | 0 | 0 | **Regression logs**. To evaluate regression quality, pass a table that contains columns with predicted and actual values. Input features are optional but useful for some evals. | Prop ID | Location | Sq ft | Type | Bedrooms | Has Garden | Predicted (\$) | Actual (\$) | | ------- | ------------- | ----- | --------- | -------- | ---------- | --------------- | ----------- | | P01 | New York, USA | 850 | Apartment | 2 | No | 850,000 | 870,000 | | P02 | New York, USA | 1200 | House | 3 | Yes | 1,250,000 | 1,300,000 | | P03 | London, UK | 950 | Flat | 2 | No | 700,000 | 720,000 | **Ranking logs**. To evaluate ranking or recommendations, pass data that contains columns with rank/score and interaction result. Features are optional but useful for some evals. | User ID | Movie ID | Title | Genre | Avg Rating | Watched (%) | Predicted Rank | | ------- | -------- | ------------ | ------------- | ---------- | ----------- | -------------- | | U001 | M001 | The Matrix | Sci-Fi | 4.8 | 100 | 1 | | U002 | M002 | Titanic | Romance/Drama | 4.5 | 80 | 2 | | U001 | M003 | Interstellar | Sci-Fi | 4.7 | 90 | 2 | **Embeddings**. To evaluate embeddings drift, pass embeddings as numerical columns. | col\_0 | col\_1 | col\_2 | col\_3 | col\_4 | ... | col\_98 | col\_99 | col\_100 | | -------- | -------- | -------- | -------- | -------- | --- | -------- | -------- | -------- | | 0.171242 | 0.149020 | 0.122876 | 0.121569 | 0.137255 | ... | 0.614379 | 0.613072 | 0.612000 | | 0.619608 | 0.628758 | 0.670588 | 0.661438 | 0.636601 | ... | 0.525490 | 0.509804 | 0.500000 | These are examples: you data can have other structure. 2. **Create a Dataset object**. Once you have the data, you must create an Evidently `Dataset` object. This allows attaching extra meta-information so that your data is processed correctly. This is needed because some evaluations may require specific columns or data types present. For example, to evaluate classification quality, you need both predictions and actual labels. To specify where they are located in your table, you can map the data schema using [Data Definition](/docs/library/data_definition). 3. **\[Optional] Preparing two datasets**. Typically you evaluate a single (`current` ) dataset. Optionally, you can prepare a second (`reference`) dataset that will be used during the evaluation. Both must have identical structures. When to use two datasets: * **Side-by-side comparison**. This lets you compare outputs or data quality across two periods, prompt/model versions, etc. in a single Report. * **Data drift detection. (Required)**. You can detect distribution shifts by comparing datasets, such as this week’s data to the previous one. * **Simplify test setup**. You can automatically generate test conditions (e.g., min-max ranges) from the reference dataset without manual configuration. **Data sampling**. For large datasets (millions of rows), evals can take some time. The depends on: * the specific evaluation: some are more computationally intensive than others * your dataset: e.g., if you run column-level evals and have lots of columns * your infrastructure: data is processed in-memory. If the computation takes too long, it’s often more efficient to use samples. For example, in data drift detection, you can apply random or stratified sampling. Once your `Dataset` is ready, you can run evaluations. You can either: * Add `descriptors` to your dataset, and then compute a summary Report. * Compute a Report directly over raw data. ## Descriptors To evaluate text data and LLM outputs, you need `Descriptors`. A **Descriptor** is a *row-level* score or label that assesses a specific quality of a given text. It’s different from metrics (like accuracy or precision) that give a score for an entire *dataset*. You can use descriptors to assess LLM outputs in summarization, Q\&A, chatbots, agents, RAGs, etc. Descriptors range from deterministic to complex ML- or LLM-based checks. A simple example of a descriptor is `TextLength`. A more complex example is a customizable `LLMEval` descriptor: where you prompt an LLM to act as a judge and, for example, label responses as "relevant" or "not relevant". Descriptors can also use two texts at once, like checking `SemanticSimilarity` between two columns to compare new response to the reference one. You can use [built-in descriptors](/metrics/all_descriptors), configure templates (like LLM judges or regular expressions) or add custom checks in Python. Each Descriptor returns a result that can be: * **Numerical**. Any scores like symbol count or sentiment score. * **Categorical**. Labels or binary “true”/“false” results for pattern matches. * **Text string**. Like explanations generated by LLM. Evidently adds the computed descriptor values directly to the dataset. This helps with debugging: for example, you can sort to find the negative responses. You can view the results as a Pandas DataFrame or on the Evidently Platform. **Descriptor tests**. Additionally, you can add a pass/fail condition on top of computed descriptors. For example, consider output a "pass" only when both conditions are true: it has expected length and is labeled "correct" by the LLM judge. After you get the row-level Descriptors, you can also compute Metrics and Tests on the dataset level – using Reports. ## Reports A **Report** lets you structure and run evals on the dataset or column-level. You can generate Reports after you get the descriptors, or for any existing dataset like a table with ML model logs. Use Reports to: * summarize the computed text descriptors across all inputs * analyze any tabular dataset (descriptive stats, quality, drift) * evaluate AI system performance (regression, classification, ranking, etc.) Each Report runs a computation and visualizes a set of **Metrics** and conditional **Tests.** If you pass two datasets, you get a side-by-side comparison.  The easiest way to start is by using **Presets**. ### Metric Presets Presets are pre-configured evaluation templates. They help compute multiple related Metrics using a single line of code. Evidently has a number of **comprehensive Presets** ([see all](/metrics/all_presets)) for specific evaluation scenarios: from exploratory data analysis to AI quality assessments. For example: `TextEvals` summarizes the scores from all text descriptors. `DataDriftPreset` identifies shifts in data distribution for all dataset columns. `DataSummaryPreset` summarizes all dataset columns, generating statistics and profiles for each. `ClassificationPreset` breaks down classification metrics and includes debugging plots. ### Metrics Each Preset is made of individual Metrics. You can also create your own **custom Report** by listing the `Metrics` you want to include. * You can combine multiple Metrics and Presets in a Report.  * You can include both built-in Metrics and custom Metrics. Built-in Metrics range from simple statistics like `MeanValue` or `MissingValueCount` to complex algorithmic evals like `DriftedColumnsCount`. Each **Metric** computes a single value and has an optional visual representation (or several to choose from). For convenience, there are also **small Presets** that combine a handful of scores in a single widget, like `ValueStats` that shows many relevant descriptive value statistics at once. Similarly `DatasetStats` give quick overview of all dataset-level stats, `ClassificationQuality` computes multiple metrics like Precision, Recall, Accuracy, ROC AUC, etc. Explore all [**Built-in Metrics**](/metrics/all_metrics). ## Test Suites Reports are great for analysis and debugging, or logging metrics during monitoring. However, in many cases, you don’t want to review all the scores but run a **conditional check** to confirm that nothing is off. In this case, **Tests** are a great option. ### Tests **Tests** let you validate your results against specific expectations. You create a Test by adding a **condition** parameter to a Metric. Each Test will calculate a given value, check it against the rule, and report a pass/fail result. * You can run multiple Tests in one go. * You can create Tests on the dataset or column level. * You can formulate custom conditions or use defaults. A **Test Suite** is a collection of individual Tests. It works as an extension to a Report. Once you configure Tests, your Report will get an **additional tab** that shows a summary of outcomes.; You can navigate the results by test outcome. Each Test results in one of the following statuses: * **Pass:** The condition was met. * **Fail:** The condition wasn’t met. * **Warning:** The condition wasn’t met, but the check is marked as non-critical. * **Error:** Something went wrong with the Test itself, such as an execution error. You can view extra details to debug. For example, if you run a Test to check that less than 5% of LLM responses fall outside the approved length, you can see the corresponding distribution: ### Test Conditions Evidently has a powerful API to [set up Test conditions](/docs/library/tests). * **Manual setup.** You can add thresholds to Metrics one by one, using simple syntax like **`greater than (gt)`** or **`less than (lt)`**. By picking different Metrics to test against, you can formulate fine-grained conditions like "less than 10% of texts can fall outside 10–100 character length." * **Manual setup with reference.** If you have a reference dataset (like a previous data batch), you can set conditions **relative** to it. For example, you can check if the min-max value range stays within ±5% of the reference range without setting exact thresholds. * **Automatic setup.** You can run any Test using built-in defaults. These are either: * **Heuristics**. For example, the Test on missing values assumes none should be preset. * **Heuristics relative to reference.** Here, conditions adjust to a reference. For instance, the Test on missing values assumes their share should stay within ±10% of the reference. ### Test Presets For even faster setup, there are **Test Presets**. Each Metric Preset has a corresponding Test Preset that you can enable as an add-on. When you do this: * Evidently adds a predefined set of Tests to your Report. * These Tests use default conditions, either static or inferred from the reference dataset. For example:  * **Data Summary**. The Metric Preset gives an overview and stats for all columns. The Test Suite checks for quality issues like missing values, duplicates, etc. across all values. * **Classification.** The Metric Preset shows quality metrics like precision or recall. The Test Suite verifies these metrics against a baseline, like a dummy baseline calculated by Evidently or previous model performance. ## Building your workflow You can use Evidently Reports and Test Suites on their own or as part of a monitoring system.  ### Independent use Reports are great for exploratory evals: * **Ad hoc evals.** Run one-time analyses on your data, models or LLM outputs. * **Experiments.** Compare models, prompts, or datasets side by side. * **Debugging.** Investigate data or model issues. Test Suites are great for automated checks like: * **Data validation.** Test inputs and outputs in prediction pipelines.  * **CI/CD and regression testing.** Check AI system performance after updates. * **Safety testing**. Run structured behavioral tests like adversarial testing.  For automation, you can integrate Evidently with tools like Airflow. You can trigger actions based on Test results, such as sending alerts or halting a pipeline. ### As part of platform You can use **Reports** together with the **Evidently Platform** in production workflows: * **Reports** serve as a metric computation layer, running evaluations on your data. * The **Platform** lets you store, compare, track and alert on evaluation results. Reports are stored as JSON files, which can be natively parsed to visualize metrics on a Dashboard. This setup works for both experiments and production monitoring. For example: * **Experiments.** Log evaluations while experimenting with prompts or model versions. Use the Platform to compare runs and track progress. * **Regression Tests.** Use Test Suites to validate updates on your golden dataset. Debug failures and maintain a history of results on the Platform. * **Batch Monitoring.** Integrate Reports into your data pipelines to compute Metrics for data batches. Use the Platform for performance tracking and alerting. **Evidently Cloud** also offers managed evaluations to generate Reports directly on the platform, and other features such as synthetic data and test generation. **Platform deployment options.** You can choose: * Self-host the open-source platform version.  * Sign up for [Evidently Cloud](https://www.evidentlyai.com/register) (Recommended). The Evidently Platform has additional features beyond evaluation: from synthetic data to tracing. [Read more on the platform](/docs/platform/overview). # Prompt optimization Source: https://docs.evidentlyai.com/docs/library/prompt_optimization [NEW] Automated prompt optimization. More detailed documentation coming soon. Read the release blog on [prompt optimization for LLM judges](https://www.evidentlyai.com/blog/llm-judge-prompt-optimization). Example notebooks: * Code review binary LLM judge prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_code_review_example.ipynb) * Topic multi-class LLM judge prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_bookings_example.ipynb) * Tweet generation prompt optimization: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/prompt_optimization_tweet_generation_example.ipynb) # Report Source: https://docs.evidentlyai.com/docs/library/report How to generate Report. Reports perform evaluations on the Dataset level and/or summarize results of the row-level evaluations. For a general introduction, check [Core Concepts](/docs/library/overview). **Pre-requisites**: * You [installed Evidently](/docs/setup/installation). * You created a Dataset with the [Data Definition](/docs/library/data_definition). * (Optional) for text data, you added Descriptors. For a quick end-to-end example of generating Reports, check the Quickstart [for ML](/quickstart_ml) or [LLM](/quickstart_llm). ## Imports Import the Metrics and Presets you plan to use. ```python theme={null} from evidently import Report from evidently.metrics import * from evidently.presets import * ``` You can use Metric Presets, which are pre-built Reports that work out of the box, or create a custom Report selecting Metrics one by one. ## Presets **Available Presets**. Check available evals in the [Reference table](/metrics/all_metrics). To generate a template Report, simply pass the selected Preset to the Report and run it over your data. If nothing else is specified, the Report will run with the default parameters for all columns in the dataset. **Single dataset**. To generate the Data Summary Report for a single dataset: ```python theme={null} report = Report([ DataSummaryPreset() ]) my_eval = report.run(eval_data_1, None) my_eval #my_eval.json ``` After you `run` the Report, the resulting `my_eval` will contains the computed values for each metric, along with associated metadata and visualizations. (We sometimes refer to this computation result as a `snapshot`). You can render the results in Python, export as HTML, JSON or Python dictionary or upload to the Evidently platform. Check more in [output formats](/docs/library/output_formats). **Two datasets**. To generate reports like Data Drift that needs two datasets, pass the second one as a reference when you `run` it: ```python theme={null} report = Report([ DataDriftPreset() ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval #my_eval.json ``` In this case the first `eval_data_1` is the current data you evaluate, the second `eval_data_2` is the reference dataset you consider as a baseline for drift detection. You can also pass it explicitly: ``` my_eval = report.run(current_data=eval_data_1, reference_data=eval_data_2) ``` **Combine Presets**. You can also include multiple Presets in the same Report. List them one by one. ```python theme={null} report = Report([ DataDriftPreset(), DataSummaryPreset() ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval #my_eval.json ``` **Limit columns**. You can limit the columns to which the Preset is applied. ```python theme={null} report = Report([ DataDriftPreset(column=["target", "prediction"]) ]) my_eval = report.run(eval_data_1, eval_data_2) my_eval #my_eval.json ``` ## Custom Report **Available Metrics and parameters**. Check available evals in the [Reference table](/metrics/all_metrics). **Choose Metrics**. To create a custom Report, simply list the Metics one by one. You can combine both dataset-level and column-level Metrics, and combine Presets and Metrics in one Report. When you use a column-level Metric, you must specify the column it refers to. ```python theme={null} report = Report([ ColumnCount(), ValueStats(column="target") ]) my_eval = report.run(eval_data_1, None) my_eval #my_eval.json ``` **Generating multiple column-level Metrics**: You can use a helper function to easily generate multiple column-level Metrics for a list of columns. See the page on [Metric Generator](/docs/library/metric_generator). **Metric Parameters**. Metrics can have optional or required parameters. For example, the data drift detection algorithm automatically selects a method, but you can override this by specifying your preferred method (Optional). ```python theme={null} report = Report([ ValueDrift(column="target", method="psi") ]) ``` To calculate the Precision at K for a ranking task, you must always pass the `k` parameter (Required). ```python theme={null} report = Report([ PrecisionTopK(k=10) ]) ``` ## Compare results If you computed multiple snapshots, you can quickly compare the resulting metrics side-by-side in a dataframe: ```python theme={null} from evidently import compare compare_dataframe = compare(my_eval_1, my_eval_2, my_eval_3) ``` ## Group by You can calculate metrics separately for different groups in your data, using a column with categories to split by. Use the `GroupyBy` metric as shown below. **Example**. This will compute the maximum value of salaries by each label in the "Department" column. ```python theme={null} from evidently.metrics.group_by import GroupBy report = Report([ GroupBy(MaxValue(column="Salary"), "Department"), ]) my_eval = report.run(data, None) my_eval.dict() ``` Note: you cannot use auto-generated Test conditions when you use GroupBy. ## What's next? You can also add conditions to Metrics: check the [Tests guide](/docs/library/tests). # Synthetic data generation Source: https://docs.evidentlyai.com/docs/library/synthetic_data_api [NEW] Code-first synthetic data generation. You can generate synthetic test data from RAG knowledge base or using a simple config. More detailed documentation coming soon. Example notebooks: * Synthetic data generation: [code example](https://github.com/evidentlyai/evidently/blob/main/examples/cookbook/datagen.ipynb) # Add tags and metadata Source: https://docs.evidentlyai.com/docs/library/tags_metadata How to add metadata to evaluations. This is relevant when you logging Reports to the Platform. Tags help you associate each Report with a specific model / prompt version, time period, or other context. ## Add timestamp Each Report run has a single timestamp. By default, Evidently assigns `datetime.now()` as the run time based on the user's time zone. You can also specify a custom timestamp by passing it to the `run()` method: ```python theme={null} from datetime import datetime my_eval_4 = report.run(eval_data_1, eval_data_2, timestamp=datetime(2024, 1, 29)) ``` Because timestamps are fully customizable, you can log Reports asynchronously or with a delay. For example, make an evaluation after receiving ground truth and backdate Reports to the relevant time period. ## Add tags and metadata You can add `tags` and `metadata` to Reports to support search and ease of filtering. Tags also let you visualize data from specific subsets of Reports on monitoring Panels. Use tags in the following scenarios: * Mark evaluation runs by model version, prompt version, or test scenario. * Indicate status: production, shadow, champion/challenger, A/B versions. * Identify Reports by geography, use case, user segment, or role. * Tag based on reference dataset windows (for example, weekly vs. monthly drift comparisons) * Highlight Reports with a specific role, such as datasheet or model card. **Custom tags**. You can add tags to the Report. Pass any custom Tags as a list: ```python theme={null} report = Report([ ClassificationPreset() ], tags=["classification", "production"]) ``` **Custom metadata**. Pass metadata as a Python dictionary in key:value pairs: ```python theme={null} report = Report([ ClassificationPreset() ], metadata = { "deployment": "shadow", "status": "production", }) ``` **Default metadata**. Use built-in metadata fields `model_id`, `reference_id`, `batch_size`, `dataset_id`: ```python theme={null} report = Report([ ClassificationPreset() ], model_id="model_id", reference_id="reference_id", batch_size="batch_size", dataset_id="dataset_id" ) ``` **Add tags to run**: You can also tag individual Report runs. This is useful for experiments where you re-run the same Report with different prompts or hyperparameter settings. ```python theme={null} my_eval = report.run(eval_data_1, eval_data_2, tags=["prompt_v1", "claude"]) ``` # Tests Source: https://docs.evidentlyai.com/docs/library/tests How to run conditional checks. Tests let you validate specific conditions and get Pass/Fail results on the dataset level. Tests are an add-on to the Report and appear in a separate tab. **Pre-requisites**: * You know how to [generate Reports and select Metrics](/docs/library/report). For a quick end-to-end example of generating Tests, сheck the Quickstart [for ML](/quickstart_ml) or [LLM](/quickstart_llm). ## Imports To use Tests, import the following modules: ```python theme={null} from evidently import Report from evidently.metrics import * from evidently.presets import * from evidently.tests import * ``` ## Auto-generated conditions There are 3 ways to run conditional checks: * **Tests Presets**. Get a suite of pre-selected Tests with auto-generated conditions. * **Tests with defaults**. Pick Tests one by one, with auto-generate conditions. * **Custom Tests**. Choose all Tests and set conditions manually. Let's first cover the automatic Tests. ### Test Presets Test Presets automatically generate a set of Tests to evaluate your data or AI system. Each Report Preset has this option. Enable it by setting `include_tests=True` on the Report level. (Default: False). ```python theme={null} report = Report([ DataSummaryPreset(), ], include_tests=True) ``` For example, while the `DataSummaryPreset()` Report simply shows descriptive stats of your data, adding the Tests will additionally run multiple checks on data quality and expected column statistics. The automatic Test conditions can either * be derived from a reference dataset, or * use built-in heuristics. **Using reference**. When you provide a reference dataset, Tests compare the new data against it: ```Python theme={null} my_eval = report.run(eval_data_1, eval_data_2) # eval_data_2 is reference ``` For example, the check on missing values will validate if the current share of missing values is within +/-10% of the reference. Note that in this case the order matters: the first `eval_data_1` is the current data you evaluate, the second `eval_data_2` is the reference dataset you consider as a baseline and use to generate test conditions. **Using heuristics**. Without reference, Tests use predefined rules: ```Python theme={null} my_eval = report.run(eval_data_1, None) # no reference data ``` In this case, the missing values Test simply expects 0% missing values. Similarly, classification accuracy Test will compare the performance against a dummy model, etc. Some metrics (like min/max/mean values) don't have default heuristics. **How to check Test defaults?** Consult the [All Metrics](/metrics/all_metrics) reference table. ### Individual Tests with defaults Presets are great for a start or quick sanity checks, but often you'd want to select specific Tests. For example, instead of running checks on all value statistics, validate only mean or max. You can pick the Tests while still using default conditions. **Select Tests**. List the individual Metrics, and choose the the `include_Tests` option: ```Python theme={null} report = Report([ MissingValueCount(column="Age"), MinValue(column="Age"), ], include_tests=True) ``` The Report will use reference conditions with two datasets, or heuristics with one dataset. **Exclude some Tests**. To prevent Test generation for certain Metrics/Presets, set the list of `tests` to `None` or leave empty: ```Python theme={null} report = Report([ MissingValueCount(column="Age", tests=[]), MinValue(column="Age"), ], include_tests=True) ``` This Report will include only the Test for `MinValue()` with auto-generated conditions. ## Custom Test conditions You can define specific pass/fail conditions for each Test. For example, set minimum expected precision or share of a certain category. Tests fail when conditions aren't met. **Setting conditions**. For each Metric you want to validate, define a list of `tests` and set expected behavior using parameters like `gt` (greater than), `lt` (less than), `eq` (equal). For example, to verify that there are no missing values and no values below 18 in the "Age" column: ```Python theme={null} report = Report([ MissingValueCount(column="Age", tests=[eq(0)]), MinValue(column="Age", tests=[gte(18)]), ]) ``` Note that you don't need to use `include_tests` when setting Tests manually. **Sometimes you may need to use other parameters to set test conditions**. The `tests` parameter applies when a metric returns a single value, or to test `count` for metrics that return both `count` and `share`. For metrics with multiple outputs (e.g. MAE returns `mean` and `std`), you may need to use specific test parameters like `mean_tests` and `std_tests`. You can check metric outputs at the [All Metric page](/metrics/all_metrics). ### Test parameters Here are the conditions you can set: | Condition | Explanation | Example | | -------------- | ------------------------------------------------- | ------------------------------------------------------ | | `eq(val)` | equal to
`test_result == val`

| `MinValue(column="Age", tests=[eq(18)])` | | `not_eq(val)` | not equal
`test_result != val` | `MinValue(column="Age", tests=[not_eq(18)])` | | `gt(val)` | greater than
`test_result > val` | `MinValue(column="Age", tests=[gt(18)])` | | `gte(val)` | greater than or equal
`test_result >= val` | `MinValue(column="Age", tests=[gte(18)])` | | `lt(val)` | less than
`test_result < val` | `MinValue(column="Age", tests=[lt(18)])` | | `lte(val)` | less than or equal
`test_result <= val` | `MinValue(column="Age", tests=[lte(18)])` | | `is_in: list` | `test_result ==` one of the values | `MinValue(column="Age", tests=[is_in([18, 21, 30])])` | | `not_in: list` | `test_result !=` any of the values | `MinValue(column="Age", tests=[not_in([16, 17, 18])])` | **Additional parameters**. Some Metrics need extra parameters. For example, to check for values outside fixed range, you must set this range. To test that no value is out of 18-80 range: ```python theme={null} report = Report([ OutRangeValueCount(column="Age", left=18, right=80, tests=[eq(0)]), ]) ``` **How to check available parameters?** Consult the [All Metrics](/metrics/all_metrics) reference table. **Combine custom and default conditions**. You can use both default and custom conditions across the Report by setting `include_tests=True` and adding custom conditions where needed. ```Python theme={null} report = Report([ RowCount(tests=[gt(10)]), MissingValueCount(column="Age"), ], include_tests=True) ``` Your custom conditions override the defaults for those specific Tests where you add them. **Multiple conditions**. You can add multiple checks to the same Metric at once: ```python theme={null} report = Report([ MinValue(column="Age", tests=[gte(17), lte(19)]), ]) ``` This creates two separate Tests for the Min value. **Testing count vs. share**. Some Metrics like `MissingValueCount` or `CategoryCount` return both absolute counts and percentage. The default `tests` parameter lets you set condition against the absolute value. To test the relative value, use `share_tests` parameter. To test for fewer than 5 missing values (absolute): ```python theme={null} report = Report([ MissingValueCount(column="Age", tests=[lte(5)]) ]) ``` To test for less than 10% missing values (relative): ```python theme={null} report = Report([ MissingValueCount(column="Age", share_tests=[lte(0.1)]), ]) ``` ### Tests relative to reference **Testing against reference**. If you pass a reference dataset, you can set conditions relative to the reference values. For example, to Test that the number of rows in the current dataset is equal or greater than the reference number of rows +/- 10%: ```python theme={null} from evidently.future.tests import Reference report = Report([ RowCount(tests=[gte(Reference(relative=0.1))]), ]) my_eval = report.run(eval_data_1, eval_data_2) ``` You can also define the absolute difference from reference: ```python theme={null} report = Report([ RowCount(tests=[gte(Reference(absolute=5))]), ]) ``` This checks that the the number of rows is greater or equal to reference +/-5. ### Set Test criticality By default, failed Tests return Fail. To get a Warning instead, set `is_critical=False`: ```python theme={null} report = Report([ MissingValueCount(column="Age", share_tests=[eq(0, is_critical=False)]), ]) ``` This helps manage alert fatigue and prioritize Tests. If you [set alerts](/docs/platform/alerts) on failed Tests, the "Warning" result won't trigger an alert. Warnings are labeled yellow. You can also use this to set "layered" conditions. For example, get a Warning for any missing values, Fail if over 10%: ```python theme={null} report = Report([ MissingValueCount(column="Age", share_tests=[eq(0, is_critical=False), lte(0.1, is_critical=True)]), ]) my_eval = report.run(eval_data_1, None) my_eval ``` # Alerts Source: https://docs.evidentlyai.com/docs/platform/alerts How to set up alerts. Built-in alerting is a Pro feature available in the **Evidently Cloud** and **Evidently Enterprise**. To enable alerts, open the Project and navigate to the "Alerts" in the left menu. You must set: * A notification channel. * An alert condition. ## Notification channels You can choose between the following options: * **Email**. Add email addresses to send alerts to. * **Slack**. Add a Slack webhook. * **Discord**. Add a Discord webhook. ## Alert conditions ### Failed tests If you use Tests (conditional checks) in your Project, you can tie alerting to the failed Tests in a Test Suite. Toggle this option on the Alerts page. Evidently will set an alert to the defined channel if any of the Tests fail. **How to avoid alert fatigue?** Use the `is_critical` parameter to mark non-critical Test as Warnings. Setting it to `False` prevent alerts for those checks even if they fail. ### Custom conditions You can also set alerts on individual Metric values. For example, you can generate Alerts when the share of drifting features is above a certain threshold. Click on the plus sign below the “Add new Metric alert” and follow the prompts to set an alert condition. # Add dashboard panels (API) Source: https://docs.evidentlyai.com/docs/platform/dashboard_add_panels How to design your Dashboard with custom Panels. You can add Panels in the user interface or using Python API. This pages describes the Python API. Check how to [add panels in the UI](dashboard_add_panels_ui). ## Dashboard Management Dashboards as code are available in Evidently OSS, Cloud, Enterprise. You must first connect to [Evidently Cloud](/docs/setup/cloud) and [create a Project](/docs/platform/projects_manage). **Adding Tabs**. To add a new Tab: ```python theme={null} project.dashboard.add_tab("Another Tab") ``` You can also create a new Tab while adding a Panel as shown below. If the destination Tab doesn't exist, it will be created. If it does, the Panel will be added below existing ones in that Tab. **Deleting Tabs**. To delete a Tab: ```python theme={null} project.dashboard.delete_tab("Another Tab") ``` **Deleting Panels**. To delete a specific Panel: ```python theme={null} project.dashboard.delete_panel("Dashboard title", "My new tab") ``` (First list the Panel name, then the Tab name). **\[DANGER]. Delete Dashboard**. To delete all Tabs and Panels on the Dashboard: ```python theme={null} project.dashboard.clear_dashboard() ``` Note: This does **not** delete the underlying Reports or dataset; it only clears the Panels. ## Adding Panels Imports: ``` from evidently.sdk.models import PanelMetric from evidently.sdk.panels import DashboardPanelPlot ``` You can add multiple Panels at once: they will appear in the listed order. ### Text Text-only panels are perfect for titles. **Add a text panel**. Add a new text panel to the specified Tab. ```python theme={null} project.dashboard.add_panel( DashboardPanelPlot( title="Dashboard title", size="full", values=[], #leave empty plot_params={"plot_type": "text"}, ), tab="My new tab", #will create a Tab if there is no Tab with this name ) ``` ### Counters Counter panels show a value with optional supporting text. Shows the specified value(s) and optional text. Shows the specified value(s) in a pie chart. **Add Counters**. To add panels for the `RowCount` metric with different aggregations: ```python theme={null} # Sum project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle="Total number of evaluations over time.", size="half", values=[PanelMetric(legend="Row count", metric="RowCount")], plot_params={"plot_type": "counter", "aggregation": "sum"}, ), tab="My tab", ) # Average project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle="Average number of evaluations per Report.", size="half", values=[PanelMetric(legend="Row count", metric="RowCount")], plot_params={"plot_type": "counter", "aggregation": "avg"}, ), tab="My tab", ) # Last project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle="Latest number of evaluations.", size="half", values=[PanelMetric(legend="Row count", metric="RowCount")], plot_params={"plot_type": "counter", "aggregation": "last"}, ), tab="My tab", ) ``` **Add pie charts**. You can use the same aggregation params (`sum`, `last`, `avg`). ```python theme={null} project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle="Total number of evaluations over time.", size="half", values=[PanelMetric(legend="Row count", metric="RowCount")], plot_params={"plot_type": "pie", "aggregation": "sum"}, ), tab="My tab", ) ``` ### Plots These Panels display values as bar or line plots. Shows the selected values over time. You can add multiple series to the same chart as multiple lines. Shows selected values or distributions over time (if stored in each Report). Stacked in a single bar. Shows selected values or distributions over time (if stored in each Report). Multiple bars. **Add Plots**. To add time series panels for the `RowCount` metric. ```python theme={null} # line chart project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle = "Number of evaluations over time.", size="half", values=[ PanelMetric( legend="Row count", metric="RowCount", ), ], plot_params={"plot_type": "line"}, ), tab="My tab", ) # bar chart project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle = "Number of evaluations over time.", size="half", values=[ PanelMetric( legend="Row count", metric="RowCount", ), ], plot_params={"plot_type": "bar", "is_stacked": False}, #default False, set as True to get stacked bars ), tab="My tab", ) ``` **Multiple values**. A single Panel can show multiple values. For example, this will add multiple lines on a Line chart: ```python theme={null} project.dashboard.add_panel( DashboardPanelPlot( title="Text Length", subtitle="Text length stats (symbols).", size="full", values=[ PanelMetric(legend="max", metric="MaxValue", metric_labels={"column": "length"}), PanelMetric(legend="mean", metric="MeanValue", metric_labels={"column": "length"}), PanelMetric(legend="min", metric="MinValue", metric_labels={"column": "length"}), ] ) ) ``` ### Dashboard Panel options A summary of all parameters: | Parameter | Type | Required | Default | Description | | ---------------------- | ------ | -------- | -------- | ----------------------------------------------------------------------------------------- | | `title` | `str` | ❌ | `None` | Title of the panel. | | `description` | `str` | ❌ | `None` | Optional panel description shown as a subtitle. | | `size` | `str` | ❌ | `"full"` | Panel size: `"full"` (100% width) or `"half"` (50%). | | `values` | `list` | ✅ | — | List of `PanelMetric` objects to display. | | `tab` | `str` | ❌ | `None` | Dashboard tab name. If not set, defaults to the first tab or creates a new "General" tab. | | `create_if_not_exists` | `bool` | ❌ | `True` | If `True`, creates the tab if it doesn't exist. Throws exception if `False`. | | `plot_params` | `dict` | ❌ | `{}` | Panel visualization settings like `"plot_type"`: `"text"`, `"line"`, `"counter"`. | ## Configuring Panel values ### Metric To define which value the Panel displays, you must reference the name of the corresponding Evidently Metric. This metric must be present in the Reports logged to your Project. If the metric isn't present, the Panel will appear empty. **Dataset-level Metrics**: pass the Metric name directly to `PanelMetric`, e.g., `"RowCount"`. Example: ```python theme={null} project.dashboard.add_panel( DashboardPanelPlot( title="Row count", subtitle = "Number of evaluations over time.", size="half", values=[ PanelMetric( legend="Row count", metric="RowCount", ## <- metric name ), ], plot_params={"plot_type": "line"}, ), tab="My tab", ) ``` **Presets** (like `TextEvals`, `ClassificationPreset`, `DataDriftPreset`) contain multiple sub-metrics. When logging Reports using a Preset, you must reference the specific **metric** inside it, such as `Accuracy`, `Recall`, etc. **Need help finding metric names?** See the [All Metrics Reference Table](/metrics/all_metrics) for a full list of Metrics. ### Metric labels Some Metrics require additional context. This applies when the metrics: * Operate at the column level * Return multiple values (metric results) * Have user-defined custom parameters In these cases, use `metric_labels` to specify what exactly you want to plot. **Example**. To plot the share of categories inside "Denials" column: ```python theme={null} project.dashboard.add_panel( DashboardPanelPlot( title="Denials", subtitle = "Number of denials.", size="half", values=[ PanelMetric( legend="""{{label}}""", metric="UniqueValueCount", # <- metric from TextEvals Preset that computes distinct values metric_labels={"column": "denials", #column name "value_type": "share" #metric result } ), ], plot_params={"plot_type": "bar", "is_stacked": True}, ), tab="My tab", ) ``` **Column / Descriptor**. When you compute a text descriptor or any metric that operates at the column level, use the `column` label to specify which column or descriptor it refers to. For example, in a `TextEvals` Report, each text descriptor (e.g., text length, LLM judged "denials", etc.) is treated as a column. These descriptors are summarized with various statistics. To plot one of these values, you need to: * Choose a summary Metric like `UniqueValueCount`, `MissingValueCount`, `MaxValue`, etc. * Use the `column` label to point the specific descriptor. **Example**. To plot the min value from the "Text Length" column: ```python theme={null} values=[ PanelMetric( legend="Min text length", metric="MinValue", # <- metric from TextEvals Preset that computes min value metric_labels={ "column": "TextLength", # <- target column name } ) ] ``` **Value type**. Most Evidently Metrics return a single `value`. For example, `Accuracy` returns the corresponding accuracy `value`. So listing just the `Metric` name is enough to specify what exactly you want to plot. However, some metrics produce more than one metric result, like: * `CategoryCount`: returns both `share` and `count` * `MAE`: returns both `mean` and `std` In this case, you must point to which value you want using the `value_type` key, e.g. `{"value_type": "share"}` ```python theme={null} values = [ PanelMetric( legend="Share", metric="DriftedColumnsCount", # <- metric from Data Drift Preset that returns `count` or `share` of drifting columns metric_labels={"value_type": "share"} # <- plot relative share ), ] ``` **How to verify the metric result for a specific metric?** * Look up the expected outputs in the [All Metrics Table](/metrics/all_metrics). * Or, generate a Report with the target `metric` and inspect its structure via`report.dict()` or `report.json()`. **Metrics with extra parameters**. If a metric has configurable options (like drift method), you must also include those in `metric_labels`. ### `PanelMetric` options A summary of all parameters: | Parameter | Type | Required | Default | Description | | --------------- | ------ | -------- | ------- | -------------------------------------------------------------------------------- | | `legend` | `str` | ❌ | `None` | Legend name in the panel. If `None`, one is auto-generated. | | `tags` | `list` | ❌ | `[]` | Optional tags to select values only from a subset of Reports in the Project. | | `metadata` | `dict` | ❌ | `{}` | Optional metadata to select values only from a subset of Reports in the Project. | | `metric` | `str` | ✅ | — | Metric name (e.g., `"RowCount"`). | | `metric_labels` | `dict` | ❌ | `{}` | Parameters like `column` names (applies to descriptors too) or `value_type`. | # Add dashboard panels (UI) Source: https://docs.evidentlyai.com/docs/platform/dashboard_add_panels_ui How to design your Dashboard with custom Panels. Dashboards let you create Panels to visualize evaluation results over time. Note that to be able to populate the panels, you must first add Reports with evaluation results to the Project. No-code Dashboards are available in the Evidently Cloud and Enterprise. ## Adding Tabs By default, new Panels appear on a single Dashboard. You can add multiple Tabs to organize them. **To add a Tab**: * Enter "Edit" mode on the Dashboard (top right corner). * Click the plus sign with "add Tab" on the left. * To create a custom Tab, select "empty" and enter a name. To simplify setup, you can start with pre-built Tabs. These are dashboard templates with preset Panel combinations: Add Dashboard Tab **Pre-built Tabs** rely on having related Metrics (or Presets that include the specific Metrics) within the Project. If the necessary data is not available, the Panels will appear empty until you add Reports that contain those Metrics. Available Tabs: | Template | Description | Data source | | ----------- | ------------------------------------------------------------------------------------------------------------------------------ | --------------------------------------------------------------------------- | | **Columns** | Shows the results of text evaluations over time OR plots column distributions over time for categorical and numerical columns. | `TextEvals()`, `DataSumaryPreset()`or`ValueStats()` for individual columns. | **To delete a Tab**: enter the "Edit" mode again, choose "edit Tabs" sign next to the Tab names on the left, and choose which one to delete. ## Adding Panels You can add any number of Panels to your Dashboard, including text panels, counters, pie charts, line plots, and bar plots (grouped and stacked). When you create a Panel, you pull the corresponding value from multiple Reports and show it over time or using the specified aggregation (sum, average, last). Check the preview and description of each Panel here: [How to add panels via Python API](dashboard_add_panels). **How to add a Panel:** * Enter "Edit" mode on the Dashboard (top right corner). * Click on the "Add Panel" button next to it. * Follow the prompts to configure the panel. * Use the preview to review your setup. * Click "Save" and select the Tab where you want to add the Panel. Here is an example of the panel configuration view: * **Select Metrics**. To point to a specific Metric, you must choose the Metric name that matches the name of the Evidently Metric logged inside the Reports in the given Project. * **Filter by Tag.** By default, the metrics will be parsed from all Reports in the Project. Use the "From" field to filter by Tags. (You must first attach these tags to the corresponding Reports). * **Filter by Metric label.** If you have a single Metric of that type in the Project (like `RowCount`), it may be enough to just specify the metric name. However, if you have multiple instances of the same metric - as is often the case for column-level Metrics like `UniqueValueCount` - you need to specify additional parameters. Use the "Where" selector to specify further keys like: * **Column**: Use this to select the name of the column or descriptor. * **Value type**: Choose whether to plot value or count for metrics that return both. You can see all keys available for a given Metric in the dropdown menu. You can add multiple keys, depending on the metric type, like metric-specific parameters. * **Set Legend**. You can use the "Label" field to modify what appears on the legend. * **Set Panel Type**. You can also specify the plot type and aggregation level. For example, you can switch the view for the same metric as on the screenshot above to a pie chart and set the view to show only the last value instead of all values over time: ## **Deleting/Editing** To delete or edit a Panel, enter Edit mode and hover over a specific Panel to choose an action. # Overview Source: https://docs.evidentlyai.com/docs/platform/dashboard_overview Introduction to Dashboard. Dashboard is available in **Evidently OSS**, **Evidently Cloud** and **Evidently Enterprise**. ## What is a Dashboard? A Dashboard provides a clear view of your AI application performance. You can use it: * to track evaluation results across multiple experiments; * to track live production quality over time. Each Project has its own Dashboard. It's empty at first. To populate it, you need to run an evaluation and **save at least one Report** to the Project. You can then choose values from Reports to plot. ## Dashboard Tabs Multiple Tabs are available in **Evidently Cloud** and **Evidently Enterprise**. You can logically organize Panels within the same Dashboard into different Tabs. ## **Dashboard Panels** A Panel is a visual element in the Dashboard that displays specified values in a single widget. Panels can be counters, line plots, bar plots, etc. You can add multiple Panels to the Dashboard and customize their type and values shown. You can add Panels in two ways: * Using the Python API – define your Dashboard as code. * Through the UI – add Panels directly from the interface (Cloud and Enterprise only). To create a Panel, you need to specify: * Value – choose an individual metric to plot. * Parameters – such as title, panel type, and size. * Tags (optional) – use to filter and visualize subsets of your data. ## From Dashboard to Reports By clicking on any individual value on the Dashboard, you can open the associated Report and source Dataset for further debugging. ## Data source Dashboards rely on having **Reports** in the Project as a data source. When adding a Panel, you select a **Metric**, and Evidently pulls the corresponding value(s) from all Reports in the Project to plot them. For example, if you log multiple Data Drift Reports (each includes the`DriftedColumnsCount` for the corresponding batch), you can plot how this Metric value changes over time. The Panel time resolution depends on logged Report frequency. For instance, if you log Reports daily, you'll see values at daily granularity. You can use **Tags** to filter data from specific Reports. For example, you can plot the accuracy of Model A and Model B on separate Panels. To achieve this, you must first [add relevant Tags](/docs/library/tags_metadata) to the Report, and then filter by these Tags when creating a Panel. ## What’s next? * See how to [customize dashboard via API](/docs/platform/dashboard_add_panels). * See how to [customize dashboard via UI](/docs/platform/dashboard_add_panels_ui). # Synthetic data Source: https://docs.evidentlyai.com/docs/platform/datasets_generate Generating synthetic data. Synthetic data generation is an add-on available on some Evidently Cloud and Enterprise plans. Check details on the [pricing](https://www.evidentlyai.com/pricing) page. [Request a demo](https://www.evidentlyai.com/get-demo) or contact [sales@evidentlyai.com](mailto:sales@evidentlyai.com) for extended trial access. You can also apply for a [startup discount](https://www.evidentlyai.com/sign-up-startups). To use synthetic data feature: * Create a Project * Set up an API key for Open AI * Open "Datasets" and choose "Generate Dataset." You can use synthetic data to augment your test scenarios as you evaluate the performance of your AI system. **Synthetic data docs**. Explore this functionality in the separate [docs section](/synthetic-data/introduction). Check the video with the basic flow from our **LLM evaluation course:**