From 2657aa70963da78283ebb4fbbc01a4158db4f745 Mon Sep 17 00:00:00 2001 From: Vasilije <8619304+Vasilije1990@users.noreply.github.com> Date: Sun, 19 May 2024 20:35:54 +0200 Subject: [PATCH] Add evals for cognee --- cognee/api/v1/cognify/cognify.py | 26 +++--- .../modules/cognify/graph/add_data_chunks.py | 42 ++++++++++ evals/generate_test_set.py | 46 +++++++++++ evals/natural_language_processing.txt | 2 + evals/simple_rag_vs_cognee_eval.py | 75 ++++++++++++++++++ evals/soldiers_home.pdf | Bin 0 -> 33733 bytes evals/trump.txt | 15 ++++ pyproject.toml | 5 +- 8 files changed, 199 insertions(+), 12 deletions(-) create mode 100644 evals/generate_test_set.py create mode 100644 evals/natural_language_processing.txt create mode 100644 evals/simple_rag_vs_cognee_eval.py create mode 100644 evals/soldiers_home.pdf create mode 100644 evals/trump.txt diff --git a/cognee/api/v1/cognify/cognify.py b/cognee/api/v1/cognify/cognify.py index 4ccfccdbd..b18b88375 100644 --- a/cognee/api/v1/cognify/cognify.py +++ b/cognee/api/v1/cognify/cognify.py @@ -12,7 +12,7 @@ from cognee.api.v1.prune import prune from cognee.config import Config from cognee.infrastructure.data.chunking.LangchainChunkingEngine import LangchainChunkEngine from cognee.infrastructure.databases.vector.embeddings.DefaultEmbeddingEngine import LiteLLMEmbeddingEngine -from cognee.modules.cognify.graph.add_data_chunks import add_data_chunks +from cognee.modules.cognify.graph.add_data_chunks import add_data_chunks, add_data_chunks_basic_rag from cognee.modules.cognify.graph.add_document_node import add_document_node from cognee.modules.cognify.graph.add_classification_nodes import add_classification_nodes from cognee.modules.cognify.graph.add_cognitive_layer_graphs import add_cognitive_layer_graphs @@ -80,7 +80,6 @@ async def cognify(datasets: Union[str, List[str]] = None): if dataset_name in added_dataset: dataset_files.append((added_dataset, db_engine.get_files_metadata(added_dataset))) - # print("dataset_files", dataset_files) data_chunks = {} @@ -109,13 +108,14 @@ async def cognify(datasets: Union[str, List[str]] = None): logger.warning("File (%s) has an unknown file type. We are skipping it.", file_metadata["id"]) added_chunks = await add_data_chunks(data_chunks) + added__basic_rag_chunks = await add_data_chunks_basic_rag(data_chunks) - await asyncio.gather( - *[process_text(chunk["collection"], chunk["chunk_id"], chunk["text"], chunk["file_metadata"],chunk['document_id']) for chunk in - added_chunks] - ) - + # await asyncio.gather( + # *[process_text(chunk["collection"], chunk["chunk_id"], chunk["text"], chunk["file_metadata"],chunk['document_id']) for chunk in + # added_chunks] + # ) + # batch_size = 20 file_count = 0 files_batch = [] @@ -260,12 +260,16 @@ if __name__ == "__main__": config.set_graph_model(SourceCodeGraph) config.set_classification_model(CodeContentPrediction) - graph = await cognify() - # - from cognee.utils import render_graph + vector_client = infrastructure_config.get_config("vector_engine") - await render_graph(graph, include_color=True, include_nodes=False, include_size=False) + out = await vector_client.search(collection_name ="basic_rag", query_text="show_all_processes", limit=10) + + print("results", out) + # + # from cognee.utils import render_graph + # + # await render_graph(graph, include_color=True, include_nodes=False, include_size=False) import asyncio asyncio.run(test()) diff --git a/cognee/modules/cognify/graph/add_data_chunks.py b/cognee/modules/cognify/graph/add_data_chunks.py index 291c15716..b95db08e6 100644 --- a/cognee/modules/cognify/graph/add_data_chunks.py +++ b/cognee/modules/cognify/graph/add_data_chunks.py @@ -52,3 +52,45 @@ async def add_data_chunks(dataset_data_chunks: dict[str, list[TextChunk]]): ) return identified_chunks + + +async def add_data_chunks_basic_rag(dataset_data_chunks: dict[str, list[TextChunk]]): + vector_client = infrastructure_config.get_config("vector_engine") + + identified_chunks = [] + + class PayloadSchema(BaseModel): + text: str = Field(...) + + for (dataset_name, chunks) in dataset_data_chunks.items(): + try: + + await vector_client.create_collection("basic_rag", payload_schema = PayloadSchema) + except Exception as error: + print(error) + pass + + dataset_chunks = [ + dict( + chunk_id = chunk["chunk_id"], + collection = "basic_rag", + text = chunk["text"], + document_id = chunk["document_id"], + file_metadata = chunk["file_metadata"], + ) for chunk in chunks + ] + + identified_chunks.extend(dataset_chunks) + + await vector_client.create_data_points( + "basic_rag", + [ + DataPoint[PayloadSchema]( + id = chunk["chunk_id"], + payload = PayloadSchema.parse_obj(dict(text = chunk["text"])), + embed_field = "text", + ) for chunk in dataset_chunks + ], + ) + + return identified_chunks diff --git a/evals/generate_test_set.py b/evals/generate_test_set.py new file mode 100644 index 000000000..9099a81ed --- /dev/null +++ b/evals/generate_test_set.py @@ -0,0 +1,46 @@ +from deepeval.dataset import EvaluationDataset +from deepeval.synthesizer import Synthesizer +import dotenv +from deepeval.test_case import LLMTestCase + +dotenv.load_dotenv() + +# synthesizer = Synthesizer() +# synthesizer.generate_goldens_from_docs( +# document_paths=['natural_language_processing.txt', 'soldiers_home.pdf', 'trump.txt'], +# max_goldens_per_document=5, +# num_evolutions=5, +# include_expected_output=True, +# enable_breadth_evolve=True, +# ) +# +# synthesizer.save_as( +# file_type='json', # or 'csv' +# directory="./synthetic_data" +# ) + + +dataset = EvaluationDataset() +dataset.generate_goldens_from_docs( + document_paths=['soldiers_home.pdf'], + max_goldens_per_document=10 +) + + +print(dataset.goldens) +print(dataset) + + +import pytest +from deepeval import assert_test +from deepeval.metrics import AnswerRelevancyMetric + + +answer_relevancy_metric = AnswerRelevancyMetric(threshold=0.5) + +from deepeval import evaluate + + +# evaluate(dataset, [answer_relevancy_metric]) + + diff --git a/evals/natural_language_processing.txt b/evals/natural_language_processing.txt new file mode 100644 index 000000000..a6fad3b47 --- /dev/null +++ b/evals/natural_language_processing.txt @@ -0,0 +1,2 @@ +Natural language processing (NLP) is an interdisciplinary subfield of computer science and information retrieval. It is primarily concerned with giving computers the ability to support and manipulate human language. It involves processing natural language datasets, such as text corpora or speech corpora, using either rule-based or probabilistic (i.e. statistical and, most recently, neural network-based) machine learning approaches. The goal is a computer capable of "understanding"[citation needed] the contents of documents, including the contextual nuances of the language within them. To this end, natural language processing often borrows ideas from theoretical linguistics. The technology can then accurately extract information and insights contained in the documents as well as categorize and organize the documents themselves. +Challenges in natural language processing frequently involve speech recognition, natural-language understanding, and natural-language generation. diff --git a/evals/simple_rag_vs_cognee_eval.py b/evals/simple_rag_vs_cognee_eval.py new file mode 100644 index 000000000..87506a5b2 --- /dev/null +++ b/evals/simple_rag_vs_cognee_eval.py @@ -0,0 +1,75 @@ +from deepeval.dataset import EvaluationDataset +from pydantic import BaseModel + + +from typing import List, Type +from deepeval.test_case import LLMTestCase +from deepeval.dataset import Golden +import dotenv +dotenv.load_dotenv() + +from cognee.infrastructure.llm.get_llm_client import get_llm_client + +dataset = EvaluationDataset() +dataset.add_test_cases_from_json_file( + # file_path is the absolute path to you .json file + file_path="synthetic_data/20240519_185842.json", + input_key_name="query", + actual_output_key_name="actual_output", + expected_output_key_name="expected_output", + context_key_name="context", + retrieval_context_key_name="retrieval_context", +) + + + +import logging +from typing import List, Dict +from cognee.infrastructure import infrastructure_config + +logger = logging.getLogger(__name__) + +def AnswerModel(BaseModel): + response:str +def get_answer_base(content: str, response_model: Type[BaseModel]): + llm_client = get_llm_client() + + system_prompt = "Answer the following question: and use the context" + + return llm_client.create_structured_output(content, system_prompt, response_model) +def get_answer(content: str, model: Type[BaseModel]= AnswerModel): + + try: + return (get_answer_base( + content, + model + )) + except Exception as error: + logger.error("Error extracting cognitive layers from content: %s", error, exc_info = True) + raise error + + + + +def convert_goldens_to_test_cases(goldens: List[Golden]) -> List[LLMTestCase]: + test_cases = [] + for golden in goldens: + test_case = LLMTestCase( + input=golden.input, + # Generate actual output using the 'input' and 'additional_metadata' + actual_output= get_answer(golden.input), + expected_output=golden.expected_output, + context=golden.context, + ) + test_cases.append(test_case) + return test_cases + +# Data preprocessing before setting the dataset test cases +dataset.test_cases = convert_goldens_to_test_cases(dataset.goldens) + + +from deepeval.metrics import HallucinationMetric + + +metric = HallucinationMetric() +dataset.evaluate([metric]) \ No newline at end of file diff --git a/evals/soldiers_home.pdf b/evals/soldiers_home.pdf new file mode 100644 index 0000000000000000000000000000000000000000..e453ca4bc64157ac078193238ce2a1f5982b557c GIT binary patch literal 33733 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

) z_lq^QJEkc{R?GA&7y*&c+W8`Wv%PC%h{N37*xmjBR-ss)QaJ@ZRTWKls$K-nTCF#O zUOYmczd{M54z-*v#nBqFpPoKPF|`uBuf(yXBX4|Rc{*$*#M;VoeOZiBxLK-nK&~DY zwRKm5qB1F?u=&9cDmq9!@HpSV9Z{8t5HZXz!i;%}Z1}nZXBV@mRS@osb%|1M3N*O1 z;$U3(I5S6*7DK={{E|l-8rcbLvdiAxAGQ1nc5?#Lw0q?Wf}`Ro)jd&%>Q>)F#kouw zleeGFvg0ak>cqmXmw_3QrFkKz{kE1YXoY6Q_f-<34NNj!fz;Y`)utkzfKoRBdl0R{AmCCcfs$ zb3P`ZzBv`JQ+h_SMcjqpECu5PC7;@aUmzSI@(QH__)J85XG>|kWQDp>M3I@{4lZa{ zA+LKJ<<=(-Po6HK#O$xim-H#+N$?8ISXIV&56K9~>@L1pb6P5}l{Y=6Sc>))vPpVJ z0ObQdM?w1*2A}$Ga*91r6~nl2_ybFTp=K-mAy0li5YuH}#VP8~{|e4c7~i7{4Ky_j zSWSr-G%9px%lw4I#|Ua3LFxjjdwe|AVw!cF+OTA}zbyK>lyqCNwEa3fioLCzJ(UC7B*p125~}Ks;nG5cw?- z%fv|`mq%3EpXSQ^&o@6c#??4kypQu(IT*xJO1T3nENmtWjR4s_&Dc8*CcrZr!`y`&=S zkJL%nfK|rX$qFvJb2x82lkKa}gZM<)Ti2GF#3MOS{6H`OIAu$4ZsC9q5p8cC;%5GLA@)2El)KJwCmKXYNnamic=aEj)y6;wm$1}}~q zFG7kS#t-Y0xAa~T&!pbH_UPQG_uBAr_fDeL<9Uby{xA;2*5w?1X>LEWbbd1Oek7-l zVX=RJeeNUUpX(^>p@)ht{P6|FJR#7X#9MAZ$Wil6x>WlJ>*8?~`Wtc;O6Oj`Xd>2n zD->59ovKnA%G)WF3kai9=GT9a=_|sbKnp1v9*6_uPvLV^#6}^3MZ0OTQl4K3g4F+jMs%bcw6aA`(j|F=i~Wp6mI$)pm{0sX=7tU#i`$O;L9_JcCobv zjyobbR@iYWiL580%lVmgiDvL=rFF8=^h)AJ#}@I5AA7a+r}V_^*FqV$C#I@hG*wDX z*|>J6kJ2#$e4e3x>a$;%6YR!I$@`Ca!EkPG*o{r>dd(x3g*~jj6c#pzIi8i-R9k-7 zXyj~MFL0)5FcI!??m|5q^w5x$y^S%4I#c(y5w1;}ut|$K-{9>t`^BkZLVvQH+$&Y2m%5WAn=3D=@K9&OG6tA$V&3OcqsIK!(Qx?w|j zf&LZ6yJY8_G0ced3?cO(mA%@VuH_>5gy)|tx54BnEe#VyEcYxI=Tv*8g#RetGPXg31o3=H<|9`S?l^ft2<^5;DxB0)> zw>jZI858?A)BCSFCf0AF_JuAzTG;eTZe4Buq+zp`(gz`rsE0D$e^bquVG|G>rn zyY075;Xm7DWc&6I{JW0zA58gwxBWI8d^<<}m3>0PS3#3Y|O%g g|Nmd|Kg7GElfHw~|J;^LjI8XeP$VS6vLaCb2SB~|TL1t6 literal 0 HcmV?d00001 diff --git a/evals/trump.txt b/evals/trump.txt new file mode 100644 index 000000000..ee35f2a60 --- /dev/null +++ b/evals/trump.txt @@ -0,0 +1,15 @@ +Donald Trump flirted with the idea of being president for three terms – a clear violation of the US constitution – during a bombastic speech for the National Rifle Association in which he vowed to reverse gun safety measures green-lighted during the Biden administration. + +“You know, FDR 16 years – almost 16 years – he was four terms. I don’t know, are we going to be considered three-term? Or two-term?” The ex-president and GOP presidential frontrunner said to the organization’s annual convention in Dallas, prompting some in the crowd to yell “three!” Politico reported. + +Trump has floated a third term in past comments, even mentioning a prolonged presidency while campaigning in 2020. He has also tried distancing himself from this idea, telling Time magazine in April: “I wouldn’t be in favor of it at all. I intend to serve four years and do a great job.” + +The 22nd amendment, which was enacted following Franklin Delano Rosevelt’s fourth term, limits the presidency to two terms. + +In his speech to the NRA, Trump spoke on abortion, immigration and criticized Robert F Kennedy Jr as being part of the “radical left”. He also complained about the multiple criminal cases against him, including a gag order that bars him from commenting about witnesses in his ongoing New York City criminal trial. + +Trump has the NRA’s endorsement, but the organization has recently been reeling from legal and financial woe and is not quite the force in US politics it once was. + +The NRA is holding its convention less than three months after its former long-serving leader Wayne LaPierre – as well as other executives of the group – were held liable in a lawsuit centered on the organization’s lavish spending. + +Trump, who said he heard that gun owners “don’t vote,” pushed NRA members to hit the polls in November: “Let’s be rebellious and vote this time, OK?” \ No newline at end of file diff --git a/pyproject.toml b/pyproject.toml index 129a38798..979d67a68 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -38,7 +38,7 @@ greenlet = "^3.0.3" ruff = "^0.2.2" filetype = "^1.2.0" nltk = "^3.8.1" -dlt = "^0.4.7" +dlt = "0.4.10" duckdb = {version = "^0.10.0", extras = ["dlt"]} overrides = "^7.7.0" aiofiles = "^23.2.1" @@ -68,6 +68,9 @@ tantivy = "^0.21.0" langfuse = "^2.32.0" spacy = "^3.7.4" protobuf = "<5.0.0" +langchain-community = "0.0.38" +langchain ="0.1.10" +deepeval = "^0.21.42" [tool.poetry.extras]