diff --git a/.gitignore b/.gitignore index 539506ee5..bbbe5f4e6 100644 --- a/.gitignore +++ b/.gitignore @@ -162,7 +162,7 @@ cython_debug/ # be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore # and can be added to the global gitignore or merged into this file. For a more nuclear # option (not recommended) you can uncomment the following to ignore the entire idea folder. -#.idea/ +.idea/ # Ragas specific experiments/ diff --git a/docs/alfred.py b/docs/alfred.py index da966d2ab..c7f50e38d 100644 --- a/docs/alfred.py +++ b/docs/alfred.py @@ -1,14 +1,15 @@ from __future__ import annotations -import os -from collections import namedtuple import argparse import asyncio -from tqdm.asyncio import tqdm +import os import typing as t -from langchain_openai.chat_models import ChatOpenAI -from langchain_core.language_models.chat_models import BaseChatModel +from collections import namedtuple + from langchain.prompts import ChatPromptTemplate +from langchain_core.language_models.chat_models import BaseChatModel +from langchain_openai.chat_models import ChatOpenAI +from tqdm.asyncio import tqdm File = namedtuple("File", "name content") diff --git a/docs/concepts/testset_generation.md b/docs/concepts/testset_generation.md index 6d8c31d31..9fe1f83e6 100644 --- a/docs/concepts/testset_generation.md +++ b/docs/concepts/testset_generation.md @@ -60,11 +60,20 @@ Checkout [llama-index](https://gpt-index.readthedocs.io/en/stable/core_modules/d :caption: Customising test data distribution from ragas.testset.generator import TestsetGenerator from ragas.testset.evolutions import simple, reasoning, multi_context +from langchain_openai import ChatOpenAI, OpenAIEmbeddings # documents = load your documents # generator with openai models -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain( + generator_llm, + critic_llm, + embeddings +) # Change resulting question type distribution distributions = { diff --git a/docs/getstarted/testset_generation.md b/docs/getstarted/testset_generation.md index 811ec1d20..312a35230 100644 --- a/docs/getstarted/testset_generation.md +++ b/docs/getstarted/testset_generation.md @@ -41,9 +41,18 @@ Now, we'll import and use Ragas' `TestsetGenerator` to quickly generate a synthe :caption: Create 10 samples using default configuration from ragas.testset.generator import TestsetGenerator from ragas.testset.evolutions import simple, reasoning, multi_context +from langchain_openai import ChatOpenAI, OpenAIEmbeddings # generator with openai models -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain( + generator_llm, + critic_llm, + embeddings +) # generate testset testset = generator.generate_with_langchain_docs(documents, test_size=10, distributions={simple: 0.5, reasoning: 0.25, multi_context: 0.25}) diff --git a/docs/howtos/applications/compare_embeddings.md b/docs/howtos/applications/compare_embeddings.md index eb72f9736..820745181 100644 --- a/docs/howtos/applications/compare_embeddings.md +++ b/docs/howtos/applications/compare_embeddings.md @@ -29,6 +29,7 @@ For this tutorial notebook, I am using papers from Semantic Scholar that is rela :caption: load documents using llama-hub and create test data from llama_index import download_loader from ragas.testset.evolutions import simple, reasoning, multi_context +from langchain_openai import ChatOpenAI, OpenAIEmbeddings SemanticScholarReader = download_loader("SemanticScholarReader") loader = SemanticScholarReader() @@ -36,7 +37,16 @@ query_space = "large language models" documents = loader.load_data(query=query_space, limit=100) # generator with openai models -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain( + generator_llm, + critic_llm, + embeddings +) + distributions = { simple: 0.5, diff --git a/docs/howtos/applications/compare_llms.md b/docs/howtos/applications/compare_llms.md index 719d815ce..73112586a 100644 --- a/docs/howtos/applications/compare_llms.md +++ b/docs/howtos/applications/compare_llms.md @@ -35,6 +35,7 @@ from llama_index import download_loader, SimpleDirectoryReader from ragas.testset import TestsetGenerator from ragas.testset.generator import TestsetGenerator from ragas.testset.evolutions import simple, reasoning, multi_context +from langchain_openai import ChatOpenAI, OpenAIEmbeddings os.environ['OPENAI_API_KEY'] = 'Your OPEN AI key' @@ -43,7 +44,15 @@ reader = SimpleDirectoryReader("./arxiv-papers/",num_files_limit=30) documents = reader.load_data() # generator with openai models -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain( + generator_llm, + critic_llm, + embeddings +) distributions = { simple: 0.5, diff --git a/docs/howtos/applications/use_prompt_adaptation.md b/docs/howtos/applications/use_prompt_adaptation.md index 140f5292c..f24f505d6 100644 --- a/docs/howtos/applications/use_prompt_adaptation.md +++ b/docs/howtos/applications/use_prompt_adaptation.md @@ -125,9 +125,18 @@ Now we can import all the required evolutions and adapt it using `generator.adap from ragas.testset.generator import TestsetGenerator from ragas.testset.evolutions import simple, reasoning, multi_context,conditional +from langchain_openai import ChatOpenAI, OpenAIEmbeddings # generator with openai models -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain( + generator_llm, + critic_llm, + embeddings +) # adapt to language language = "hindi" diff --git a/docs/howtos/customisations/azure-openai.ipynb b/docs/howtos/customisations/azure-openai.ipynb index 2dda0587c..8a2e01e18 100644 --- a/docs/howtos/customisations/azure-openai.ipynb +++ b/docs/howtos/customisations/azure-openai.ipynb @@ -7,7 +7,11 @@ "source": [ "# Using Azure OpenAI\n", "\n", - "This tutorial will show you how to use Azure OpenAI endpoints instead of OpenAI endpoints." + "This tutorial will show you how to use Azure OpenAI endpoints instead of OpenAI endpoints.\n", + "\n", + "\n", + "- [Evaluation](#load-sample-dataset)\n", + "- [Test set generation](#test-set-generation)" ] }, { @@ -416,6 +420,75 @@ "\n", "if you have any suggestion/feedbacks/things your not happy about, please do share it in the [issue section](https://github.com/explodinggradients/ragas/issues). We love hearing from you 😁" ] + }, + { + "cell_type": "markdown", + "id": "3cee41e9", + "metadata": {}, + "source": [ + "### Test set generation\n", + "\n", + "Here you will learn how to generate a test set from your dataset using the Azure OpenAI endpoints." + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "aa9ff398", + "metadata": {}, + "outputs": [], + "source": [ + "! git clone https://huggingface.co/datasets/explodinggradients/2023-llm-papers" + ] + }, + { + "cell_type": "code", + "execution_count": 2, + "id": "d935a561", + "metadata": {}, + "outputs": [], + "source": [ + "from langchain.document_loaders import DirectoryLoader\n", + "from ragas.testset.generator import TestsetGenerator\n", + "from ragas.testset.evolutions import simple, reasoning, multi_context\n", + "\n", + "\n", + "loader = DirectoryLoader(\"./2023-llm-papers/\", use_multithreading=True, silent_errors=True,sample_size=1)\n", + "documents = loader.load()\n", + "\n", + "for document in documents:\n", + " document.metadata['filename'] = document.metadata['source']" + ] + }, + { + "cell_type": "markdown", + "id": "c8f735a7", + "metadata": {}, + "source": [ + "Use the `azure_model` and `azure_embedding` that we initialized in above section to generate the test set" + ] + }, + { + "cell_type": "code", + "execution_count": null, + "id": "04abc4b1", + "metadata": {}, + "outputs": [], + "source": [ + "generator = TestsetGenerator.from_langchain(generator_llm=azure_model,critic_llm=azure_model,embeddings=azure_embeddings)\n", + "\n", + "testset = generator.generate_with_langchain_docs(documents, test_size=10, \n", + " raise_exceptions=False, with_debugging_logs=False,\n", + " distributions={simple: 0.5, reasoning: 0.25, multi_context: 0.25}) " + ] + }, + { + "cell_type": "markdown", + "id": "d2f5a7f7", + "metadata": {}, + "source": [ + "testset.to_pandas()" + ] } ], "metadata": { @@ -434,7 +507,7 @@ "name": "python", "nbconvert_exporter": "python", "pygments_lexer": "ipython3", - "version": "3.10.12" + "version": "3.10.8" } }, "nbformat": 4, diff --git a/docs/howtos/customisations/bring-your-own-llm-or-embs.md b/docs/howtos/customisations/bring-your-own-llm-or-embs.md index b0885ceec..abc92945c 100644 --- a/docs/howtos/customisations/bring-your-own-llm-or-embs.md +++ b/docs/howtos/customisations/bring-your-own-llm-or-embs.md @@ -2,8 +2,8 @@ Ragas uses LLMs and Embeddings for both evaluation and test set generation. By default, the LLM and Embedding models of choice are OpenAI models. -- [Customizing Evaluations](#customizing-evaluations) -- [Customizing Testset Generation](#customizing-testset-generation) +- [Evaluations](#evaluations) +- [Testset Generation](#testset-generation) :::{note} @@ -18,13 +18,38 @@ After understanding the basics, feel free to check out the specific guides here - [Azure OpenAI](./azure-openai.ipynb) - [AWS Bedrock](./aws-bedrock.ipynb) - [Google Cloud (VertexAI)](./gcp-vertexai.ipynb) + +Checkout list of embeddings supported by langchain [here](https://python.langchain.com/docs/integrations/text_embedding/) +Checkout list of llms supported by langchain [here](https://python.langchain.com/docs/integrations/chat/) + ::: -## Customizing Evaluations +For the sake of this example I will be using `m2-bert-80M-8k-retrieval` to replace the default OpenAI Embeddings, and `NousResearch/Nous-Hermes-2-Mixtral-8x7B-SFT` hosted on Together AI as LLM to replace the default gpt-3.5-turbo LLM. So let's start by initializing them. + +```{code-block} python + +from langchain_together import Together +from langchain_together.embeddings import TogetherEmbeddings + +together_key = "" + +embeddings = TogetherEmbeddings(model="togethercomputer/m2-bert-80M-8k-retrieval") + +together_completion = Together( + model="NousResearch/Nous-Hermes-2-Mixtral-8x7B-SFT", + temperature=0.7, + max_tokens=4000, + top_k=1, + together_api_key=together_key +) +``` + + +## Evaluations Depending on which metric you use for evaluations, it will use LLMs and/or Embeddings under-the-hood. You can customize which models to use in 2 ways: -1. By Passing it through `evaluate()`: The evaluate function has 2 arguments `llm=` and `embeddings=`. You can pass any instance of `BaseRagasLLM` or `BaseRagasEmbeddings` respectively. If you are using Langchain, you can pass the Langchain llm and embeddings instances directly and Ragas will wrap it with `LangchainLLMWrapper` or `LangchainEmbeddingsWrapper` as needed. +1. By Passing it through `evaluate()`: The evaluate function has 2 arguments `llm` and `embeddings`. You can pass any instance of `BaseRagasLLM` or `BaseRagasEmbeddings` respectively. If you are using Langchain, you can pass the Langchain llm and embeddings instances directly and Ragas will wrap it with `LangchainLLMWrapper` or `LangchainEmbeddingsWrapper` as needed. ```{code-block} python from langchain_core.language_models import BaseLanguageModel @@ -36,47 +61,106 @@ langchain_embeddings = # any langchain Embeddings instance results = evaluate(metrics=[], llm=langchain_llm, embeddings=embeddings) ``` -Checkout list of embeddings supported by langchain [here](https://python.langchain.com/docs/integrations/text_embedding/) -Checkout list of llms supported by langchain [here](https://python.langchain.com/docs/integrations/language_model/) - -For example, to use `VertexAI embeddings` you can do the following: +For example, to use the embeddings and llm we initialized above, we can do the following: ```{code-block} python -from langchain_comunnity.embeddings import VertexAIEmbeddings -embeddings = VertexAIEmbeddings() -results = evaluate(metrics=[], embeddings=embeddings) -``` +from ragas.metrics import faithfullness +from ragas import evaluate + +results = evaluate(metrics=[faithfullness], llm=together_completion, embeddings=embeddings) +``` 2. Attaching it to `metrics`: You can attach the LLM and Embeddings to the `metrics` object directly. +This method can be more useful when you want a specific metric to use a different LLM or Embeddings than the rest of the metrics. + ```{code-block} python # override the llm and embeddings for a specific metric from ragas.metrics import answer_relevancy + answer_relevancy.llm = langchain_llm answer_relevancy.embeddings = langchain_embeddings # You can also init a new metric with the llm and embeddings of your choice from ragas.metrics import AnswerRelevancy -ar = AnswerRelevancy(llm=langchain_llm, embeddings=langchain_embeddings) +answer_relevancy_duplicate = AnswerRelevancy(llm=langchain_llm, embeddings=langchain_embeddings) # pass to evaluate -result = evaluate(metrics=[ar, answer_relevancy]) -# even if I pass an llm or embeddings to evaluate, it will use the ones attached to the metrics +result = evaluate(metrics=[answer_relevancy_duplicate, answer_relevancy]) result = evaluate( - metrics=[ar, answer_relevancy, faithfullness], - llm=llm, - embeddings=embeddings + metrics=[answer_relevancy_duplicate, answer_relevancy,], ) ``` +For example, to use the embeddings and llm we initialized above, we can do the following: + +```{code-block} python +from ragas.metrics import answer_relevancy + +answer_relevancy.llm = together_completion +answer_relevancy.embeddings = together_embeddings + +result = evaluate(metrics=[answer_relevancy]) +``` + :::{note} A note on precedence: llms and embeddings attached to metrics have higher precedence than the llm and embeddings passed to `evaluate()` function. You can use this to override specific metrics with a different llm or embedding models that perform better for the metric in question. ::: -## Customizing Testset Generation +## Test set Generation + + There are a lot of components in the test set generation pipeline that use LLMs and Embeddings here we will be explaining the top-level components. -1. `DocumentStore`: The `DocumentStore` requires an `Extractor` to extract keywords from the documents and nodes and `embeddings` to calculate the embeddings of nodes and calculate similarity. +- [LLMs and Embeddings](#llms) +- [DocumentStore](#documentstore) + + +### LLMs +There are two type of LLMs used in the test set generation pipeline. The `generator_llm` and `critic_llm`. The `generator_llm` is the component that generates the questions, and evolves the question to make it more relevant. The `critic_llm` is the component that filters the questions and nodes based on the question and node relevance. Both uses OpenAI models by default. To replace them with your own LLMs, you can pass the llms when instantiating the `TestsetGenerator`. + +It also uses `embeddings` for functionalities like calculating the similarity between nodes,etc. + +```{code-block} python +from langchain_core.language_models import BaseLanguageModel +from langchain_core.embeddings import Embeddings + +# define llm and embeddings +langchain_llm = BaseLanguageModel(model="my_model") # any langchain LLM instance +langchain_embeddings = Embeddings(model="my_model") # any langchain Embeddings instance + +# make sure to wrap them with wrappers +from ragas.llms import LangchainLLMWrapper +from ragas.embeddings import LangchainEmbeddingsWrapper + +langchain_llm = LangchainLLMWrapper(langchain_llm) +langchain_embeddings = LangchainEmbeddingsWrapper(langchain_embeddings) + +# you can also use custom LLMs and Embeddings here but make sure +# they are subclasses of BaseRagasLLM and BaseRagasEmbeddings +llm = MyCustomLLM() +embeddings = MyCustomEmbeddings() +``` + +For example, let's replace the default OpenAI LLM and Embeddings with the ones we initialized above. + +```{code-block} python + +from ragas.testset.generator import TestsetGenerator + + +# generator with custom llm and embeddings +generator = TestsetGenerator.from_langchain( + generator_llm=together_completion, + critic_llm=together_completion, + embeddings=together_embeddings, +) + +``` + +### DocumentStore +The `DocumentStore` requires an `Extractor` to extract keywords from the documents and nodes and `embeddings` to calculate the embeddings of nodes and calculate similarity. + ```{code-block} python # default extractor from ragas.testset.extractor import KeyphraseExtractor @@ -107,21 +191,6 @@ docstore = InMemoryDocumentStore( extractor=keyphrase_extractor, ) ``` -2. `TestsetGenerator`: The `TestsetGenerator` requires `generator_llm` for evolutions, `critic_llm` for the question and node filters and `docstore` for accessing the documents. You can pass the llms when instantiating the `TestsetGenerator`. -```{code-block} python -# any langchain LLM instance -generator_llm = BaseLanguageModel( - model="model_for_generation" -) -# any langchain LLM instance -critic_llm = BaseLanguageModel( - model="model_for_critic(ideally more advanced and capable)" -) -# refer above if in doubt -docstore = InMemoryDocumentStore( - splitter=splitter, - embeddings=langchain_embeddings, - extractor=keyphrase_extractor, -) -``` + + The `TestsetGenerator` will now init the `evolutions` and `filters` with the llms you passed. If you need further fine-grained control, you will have to initialize the `evolutions` and `filters` manually and use them. Feel free to raise an issue if the docs need clarity on this. diff --git a/docs/howtos/integrations/ragas-arize.ipynb b/docs/howtos/integrations/ragas-arize.ipynb index cfabdcd52..6da96640c 100644 --- a/docs/howtos/integrations/ragas-arize.ipynb +++ b/docs/howtos/integrations/ragas-arize.ipynb @@ -177,11 +177,16 @@ "source": [ "from ragas.testset.generator import TestsetGenerator\n", "from ragas.testset.evolutions import simple, reasoning, multi_context\n", + "from langchain_openai import ChatOpenAI, OpenAIEmbeddings\n", "\n", "TEST_SIZE = 25\n", "\n", "# generator with openai models\n", - "generator = TestsetGenerator.with_openai()\n", + "generator_llm = ChatOpenAI(model=\"gpt-3.5-turbo-16k\")\n", + "critic_llm = ChatOpenAI(model=\"gpt-4\")\n", + "embeddings = OpenAIEmbeddings()\n", + "\n", + "generator = TestsetGenerator.from_langchain(generator_llm, critic_llm, embeddings)\n", "\n", "# set question type distribution\n", "distribution = {simple: 0.5, reasoning: 0.25, multi_context: 0.25}\n", diff --git a/src/ragas/testset/generator.py b/src/ragas/testset/generator.py index 4febcc5e1..52fb2ef9a 100644 --- a/src/ragas/testset/generator.py +++ b/src/ragas/testset/generator.py @@ -7,6 +7,8 @@ import pandas as pd from datasets import Dataset +from langchain_core.embeddings import Embeddings +from langchain_core.language_models import BaseLanguageModel from langchain_openai.chat_models import ChatOpenAI from langchain_openai.embeddings import OpenAIEmbeddings @@ -28,7 +30,7 @@ ) from ragas.testset.extractor import KeyphraseExtractor from ragas.testset.filters import EvolutionFilter, NodeFilter, QuestionFilter -from ragas.utils import check_if_sum_is_close, get_feature_language, is_nan +from ragas.utils import check_if_sum_is_close, deprecated, get_feature_language, is_nan if t.TYPE_CHECKING: from langchain_core.documents import Document as LCDocument @@ -71,20 +73,19 @@ class TestsetGenerator: docstore: DocumentStore @classmethod - def with_openai( + def from_langchain( cls, - generator_llm: str = "gpt-3.5-turbo-16k", - critic_llm: str = "gpt-4", - embeddings: str = "text-embedding-ada-002", + generator_llm: BaseLanguageModel, + critic_llm: BaseLanguageModel, + embeddings: Embeddings, docstore: t.Optional[DocumentStore] = None, run_config: t.Optional[RunConfig] = None, chunk_size: int = 1024, ) -> "TestsetGenerator": - generator_llm_model = LangchainLLMWrapper(ChatOpenAI(model=generator_llm)) - critic_llm_model = LangchainLLMWrapper(ChatOpenAI(model=critic_llm)) - embeddings_model = LangchainEmbeddingsWrapper( - OpenAIEmbeddings(model=embeddings) - ) + generator_llm_model = LangchainLLMWrapper(generator_llm) + critic_llm_model = LangchainLLMWrapper(critic_llm) + embeddings_model = LangchainEmbeddingsWrapper(embeddings) + keyphrase_extractor = KeyphraseExtractor(llm=generator_llm_model) if docstore is None: from langchain.text_splitter import TokenTextSplitter @@ -110,18 +111,39 @@ def with_openai( docstore=docstore, ) - # if you add any arguments to this function, make sure to add them to - # generate_with_langchain_docs as well + @classmethod + @deprecated("0.1.4", removal="0.2.0", alternative="from_langchain") + def with_openai( + cls, + generator_llm: str = "gpt-3.5-turbo-16k", + critic_llm: str = "gpt-4", + embeddings: str = "text-embedding-ada-002", + docstore: t.Optional[DocumentStore] = None, + chunk_size: int = 1024, + ) -> "TestsetGenerator": + generator_llm_model = ChatOpenAI(model=generator_llm) + critic_llm_model = ChatOpenAI(model=critic_llm) + embeddings_model = OpenAIEmbeddings(model=embeddings) + + return cls.from_langchain( + generator_llm=generator_llm_model, + critic_llm=critic_llm_model, + embeddings=embeddings_model, + docstore=docstore, + chunk_size=chunk_size, + ) + def generate_with_llamaindex_docs( self, documents: t.Sequence[LlamaindexDocument], test_size: int, - distributions: Distributions = {}, + distributions: t.Optional[Distributions] = None, with_debugging_logs=False, is_async: bool = True, raise_exceptions: bool = True, run_config: t.Optional[RunConfig] = None ): + distributions = distributions or {} # chunk documents and add to docstore self.docstore.add_documents( [Document.from_llamaindex_document(doc) for doc in documents] @@ -142,12 +164,13 @@ def generate_with_langchain_docs( self, documents: t.Sequence[LCDocument], test_size: int, - distributions: Distributions = {}, + distributions: t.Optional[Distributions] = None, with_debugging_logs=False, is_async: bool = True, raise_exceptions: bool = True, run_config: t.Optional[RunConfig] = None ): + distributions = distributions or {} # chunk documents and add to docstore self.docstore.add_documents( [Document.from_langchain_document(doc) for doc in documents] @@ -180,16 +203,18 @@ def init_evolution(self, evolution: Evolution) -> None: def generate( self, test_size: int, - distributions: Distributions = DEFAULT_DISTRIBUTION, + distributions: t.Optional[Distributions] = None, with_debugging_logs=False, is_async: bool = True, raise_exceptions: bool = True, run_config: t.Optional[RunConfig] = None ): + distributions = distributions or DEFAULT_DISTRIBUTION # validate distributions if not check_if_sum_is_close(list(distributions.values()), 1.0, 3): raise ValueError( - f"distributions passed do not sum to 1.0 [got {sum(list(distributions.values()))}]. Please check the distributions." + f"distributions passed do not sum to 1.0 [got {sum(list(distributions.values()))}]. Please check the " + f"distributions." ) # configure run_config for docstore @@ -245,7 +270,7 @@ def generate( try: test_data_rows = exec.results() - if test_data_rows == []: + if not test_data_rows: raise ExceptionInRunner() except ValueError as e: diff --git a/src/ragas/utils.py b/src/ragas/utils.py index be8cea269..672967f94 100644 --- a/src/ragas/utils.py +++ b/src/ragas/utils.py @@ -3,6 +3,7 @@ import logging import os import typing as t +import warnings from functools import lru_cache import numpy as np @@ -72,3 +73,74 @@ def get_feature_language(feature: t.Union[Metric, Evolution]) -> t.Optional[str] if isinstance(value, Prompt) ] return languags[0] if len(languags) > 0 else None + + +def deprecated( + since: str, + *, + removal: t.Optional[str] = None, + alternative: t.Optional[str] = None, + addendum: t.Optional[str] = None, + pending: bool = False, +): + """ + Decorator to mark functions or classes as deprecated. + + Args: + since: str + The release at which this API became deprecated. + removal: str, optional + The expected removal version. Cannot be used with pending=True. + Must be specified with pending=False. + alternative: str, optional + The alternative API or function to be used instead + of the deprecated function. + addendum: str, optional + Additional text appended directly to the final message. + pending: bool + Whether the deprecation version is already scheduled or not. + Cannot be used with removal. + + + Examples + -------- + + .. code-block:: python + + @deprecated("0.1", removal="0.2", alternative="some_new_function") + def some_old_function(): + print("This is an old function.") + + """ + + def deprecate(func: t.Callable): + def emit_warning(*args, **kwargs): + if pending and removal: + raise ValueError( + "A pending deprecation cannot have a scheduled removal" + ) + + message = f"The function {func.__name__} was deprecated in {since}," + + if not pending: + if removal: + message += f" and will be removed in the {removal} release." + else: + raise ValueError( + "A non-pending deprecation must have a scheduled removal." + ) + else: + message += " and will be removed in a future release." + + if alternative: + message += f" Use {alternative} instead." + + if addendum: + message += f" {addendum}" + + warnings.warn(message, stacklevel=2, category=DeprecationWarning) + return func(*args, **kwargs) + + return emit_warning + + return deprecate diff --git a/tests/benchmarks/benchmark_testsetgen.py b/tests/benchmarks/benchmark_testsetgen.py index ddb24a27a..30b6e0b91 100644 --- a/tests/benchmarks/benchmark_testsetgen.py +++ b/tests/benchmarks/benchmark_testsetgen.py @@ -1,11 +1,16 @@ import time +from langchain_openai import ChatOpenAI, OpenAIEmbeddings from llama_index import download_loader from ragas.testset.evolutions import conditional, multi_context, reasoning, simple from ragas.testset.generator import TestsetGenerator -generator = TestsetGenerator.with_openai() +generator_llm = ChatOpenAI(model="gpt-3.5-turbo-16k") +critic_llm = ChatOpenAI(model="gpt-4") +embeddings = OpenAIEmbeddings() + +generator = TestsetGenerator.from_langchain(generator_llm, critic_llm, embeddings) distributions = {simple: 0.5, multi_context: 0.3, reasoning: 0.1, conditional: 0.1}