mafzaal commited on
Commit
a018353
Β·
1 Parent(s): 8825f6e

Add Jupyter Notebook for Fine Tuning Dataset with Question Generation

Browse files

- Created a new notebook `07_Fine_Tuning_Dataset.ipynb` for fine-tuning tasks.
- Implemented code to load blog posts, update metadata, and split documents.
- Integrated LangChain's ChatOpenAI for generating questions based on document context.
- Added functions for extracting questions from the generated responses.
- Included asynchronous processing for creating questions from multiple documents.
- Handled potential kernel crashes during execution.

py-src/lets_talk/utils/blog.py CHANGED
@@ -12,6 +12,7 @@ from pathlib import Path
12
  from typing import List, Dict, Any, Optional
13
  from datetime import datetime
14
 
 
15
  from langchain_community.document_loaders import DirectoryLoader
16
  from langchain.text_splitter import RecursiveCharacterTextSplitter
17
  from langchain.schema.document import Document
@@ -48,7 +49,9 @@ def load_blog_posts(data_dir: str = DATA_DIR,
48
  data_dir,
49
  glob=glob_pattern,
50
  show_progress=show_progress,
51
- recursive=recursive
 
 
52
  )
53
 
54
  documents = text_loader.load()
@@ -85,8 +88,12 @@ def update_document_metadata(documents: List[Document],
85
  if len(path_parts) > 1:
86
  # Use the directory name as post_slug
87
  doc.metadata["post_slug"] = path_parts[-2]
88
- doc.metadata["post_title"] = path_parts[-2].replace("-", " ").title()
89
-
 
 
 
 
90
  # Add document length as metadata
91
  doc.metadata["content_length"] = len(doc.page_content)
92
 
@@ -249,7 +256,9 @@ def load_vector_store(storage_path: str = VECTOR_STORAGE_PATH,
249
  def process_blog_posts(data_dir: str = DATA_DIR,
250
  create_embeddings: bool = True,
251
  force_recreate_embeddings: bool = False,
252
- storage_path: str = VECTOR_STORAGE_PATH):
 
 
253
  """
254
  Complete pipeline to process blog posts and optionally create vector embeddings.
255
 
@@ -267,11 +276,17 @@ def process_blog_posts(data_dir: str = DATA_DIR,
267
 
268
  # Update metadata
269
  documents = update_document_metadata(documents)
 
 
 
 
270
 
271
 
272
  # Get and display stats
273
  stats = get_document_stats(documents)
274
- display_document_stats(stats)
 
 
275
 
276
  result = {
277
  "documents": documents,
@@ -284,7 +299,8 @@ def process_blog_posts(data_dir: str = DATA_DIR,
284
  # Using in-memory vector store to avoid pickling issues
285
  vector_store = create_vector_store(
286
  documents,
287
- force_recreate=force_recreate_embeddings
 
288
  )
289
  result["vector_store"] = vector_store
290
 
 
12
  from typing import List, Dict, Any, Optional
13
  from datetime import datetime
14
 
15
+ from langchain_community.document_loaders.text import TextLoader
16
  from langchain_community.document_loaders import DirectoryLoader
17
  from langchain.text_splitter import RecursiveCharacterTextSplitter
18
  from langchain.schema.document import Document
 
49
  data_dir,
50
  glob=glob_pattern,
51
  show_progress=show_progress,
52
+ recursive=recursive,
53
+ loader_cls=TextLoader
54
+
55
  )
56
 
57
  documents = text_loader.load()
 
88
  if len(path_parts) > 1:
89
  # Use the directory name as post_slug
90
  doc.metadata["post_slug"] = path_parts[-2]
91
+ try:
92
+ #extract title from `doc.page_content`'s front matter like `title:`
93
+ doc.metadata["post_title"] = doc.page_content.split("title:")[1].split("\n")[0].strip()
94
+ except Exception as e:
95
+ doc.metadata["post_title"] = path_parts[-2].replace("-", " ").title()
96
+
97
  # Add document length as metadata
98
  doc.metadata["content_length"] = len(doc.page_content)
99
 
 
256
  def process_blog_posts(data_dir: str = DATA_DIR,
257
  create_embeddings: bool = True,
258
  force_recreate_embeddings: bool = False,
259
+ storage_path: str = VECTOR_STORAGE_PATH,
260
+ split_docs: bool = True,
261
+ display_stats:bool = False) -> Dict[str, Any]:
262
  """
263
  Complete pipeline to process blog posts and optionally create vector embeddings.
264
 
 
276
 
277
  # Update metadata
278
  documents = update_document_metadata(documents)
279
+
280
+ if split_docs:
281
+ # Split documents into smaller chunks
282
+ documents = split_documents(documents)
283
 
284
 
285
  # Get and display stats
286
  stats = get_document_stats(documents)
287
+
288
+ if display_stats:
289
+ display_document_stats(stats)
290
 
291
  result = {
292
  "documents": documents,
 
299
  # Using in-memory vector store to avoid pickling issues
300
  vector_store = create_vector_store(
301
  documents,
302
+ force_recreate=force_recreate_embeddings,
303
+ storage_path=storage_path
304
  )
305
  result["vector_store"] = vector_store
306
 
py-src/notebooks/{05_SGD_Eval.ipynb β†’ 05_SDG_Eval.ipynb} RENAMED
@@ -2,7 +2,7 @@
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
- "execution_count": null,
6
  "id": "ca8bd0e4",
7
  "metadata": {},
8
  "outputs": [
@@ -10,7 +10,9 @@
10
  "name": "stdout",
11
  "output_type": "stream",
12
  "text": [
13
- "Adding project root to sys.path: /home/mafzaal/source/lets-talk/py-src\n"
 
 
14
  ]
15
  }
16
  ],
@@ -20,14 +22,21 @@
20
  "\n",
21
  "# Add the project root to the Python path\n",
22
  "package_root = os.path.abspath(os.path.join(os.getcwd(), \"../\"))\n",
23
- "print(f\"Adding project root to sys.path: {package_root}\")\n",
24
  "if package_root not in sys.path:\n",
25
- "\tsys.path.append(package_root)"
 
 
 
 
 
 
 
26
  ]
27
  },
28
  {
29
  "cell_type": "code",
30
- "execution_count": 35,
31
  "id": "b48fa7d4",
32
  "metadata": {},
33
  "outputs": [],
@@ -38,7 +47,7 @@
38
  },
39
  {
40
  "cell_type": "code",
41
- "execution_count": null,
42
  "id": "cd3c7329",
43
  "metadata": {},
44
  "outputs": [],
@@ -50,48 +59,47 @@
50
  },
51
  {
52
  "cell_type": "code",
53
- "execution_count": 20,
54
- "id": "c8c9ef46",
55
  "metadata": {},
56
  "outputs": [
57
  {
58
- "name": "stdout",
59
- "output_type": "stream",
60
- "text": [
61
- "Current notebook directory: /home/mafzaal/source/lets-talk/py-src/notebooks\n",
62
- "Project root: /home/mafzaal/source/lets-talk\n"
63
- ]
 
 
64
  }
65
  ],
66
  "source": [
67
- "# We already have project_root from the first cell, so we can use that\n",
68
- "# or get the current notebook directory\n",
69
- "notebook_dir = os.getcwd()\n",
70
- "print(f\"Current notebook directory: {notebook_dir}\")\n",
71
- "# change to the directory to the root of the project\n",
72
- "project_root = os.path.abspath(os.path.join(os.getcwd(), \"../../\"))\n",
73
- "print(f\"Project root: {project_root}\")\n",
74
- "os.chdir(project_root)"
75
  ]
76
  },
77
  {
78
  "cell_type": "code",
79
- "execution_count": 21,
80
- "id": "21d9a2df",
81
  "metadata": {},
82
  "outputs": [
83
  {
84
  "name": "stderr",
85
  "output_type": "stream",
86
  "text": [
87
- "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 14/14 [00:00<00:00, 41.59it/s]"
88
  ]
89
  },
90
  {
91
  "name": "stdout",
92
  "output_type": "stream",
93
  "text": [
94
- "Loaded 14 documents from data/\n"
 
95
  ]
96
  },
97
  {
@@ -103,75 +111,67 @@
103
  }
104
  ],
105
  "source": [
106
- "docs = blog.load_blog_posts()\n",
107
- "docs = blog.update_document_metadata(docs)"
 
 
108
  ]
109
  },
110
  {
111
  "cell_type": "code",
112
- "execution_count": 22,
113
- "id": "33949cc9",
114
  "metadata": {},
115
  "outputs": [
116
  {
117
- "data": {
118
- "text/plain": [
119
- "Document(metadata={'source': 'data/introduction-to-ragas/index.md', 'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'post_slug': 'introduction-to-ragas', 'post_title': 'Introduction To Ragas', 'content_length': 6071}, page_content='title: \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\" date: 2025-04-26T18:00:00-06:00 layout: blog description: \"Explore the essential evaluation framework for LLM applications with Ragas. Learn how to assess performance, ensure accuracy, and improve reliability in Retrieval-Augmented Generation systems.\" categories: [\"AI\", \"RAG\", \"Evaluation\",\"Ragas\"] coverImage: \"https://images.unsplash.com/photo-1593642634367-d91a135587b5?q=80&w=1770&auto=format&fit=crop&ixlib=rb-4.0.3\" readingTime: 7 published: true\\n\\nAs Large Language Models (LLMs) become fundamental components of modern applications, effectively evaluating their performance becomes increasingly critical. Whether you\\'re building a question-answering system, a document retrieval tool, or a conversational agent, you need reliable metrics to assess how well your application performs. This is where Ragas steps in.\\n\\nWhat is Ragas?\\n\\nRagas is an open-source evaluation framework specifically designed for LLM applications, with particular strengths in Retrieval-Augmented Generation (RAG) systems. Unlike traditional NLP evaluation methods, Ragas provides specialized metrics that address the unique challenges of LLM-powered systems.\\n\\nAt its core, Ragas helps answer crucial questions: - Is my application retrieving the right information? - Are the responses factually accurate and consistent with the retrieved context? - Does the system appropriately address the user\\'s query? - How well does my application handle multi-turn conversations?\\n\\nWhy Evaluate LLM Applications?\\n\\nLLMs are powerful but imperfect. They can hallucinate facts, misinterpret queries, or generate convincing but incorrect responses. For applications where accuracy and reliability matterβ€”like healthcare, finance, or educationβ€”proper evaluation is non-negotiable.\\n\\nEvaluation serves several key purposes: - Quality assurance: Identify and fix issues before they reach users - Performance tracking: Monitor how changes impact system performance - Benchmarking: Compare different approaches objectively - Continuous improvement: Build feedback loops to enhance your application\\n\\nKey Features of Ragas\\n\\n🎯 Specialized Metrics\\n\\nRagas offers both LLM-based and computational metrics tailored to evaluate different aspects of LLM applications:\\n\\nFaithfulness: Measures if the response is factually consistent with the retrieved context\\n\\nContext Relevancy: Evaluates if the retrieved information is relevant to the query\\n\\nAnswer Relevancy: Assesses if the response addresses the user\\'s question\\n\\nTopic Adherence: Gauges how well multi-turn conversations stay on topic\\n\\nπŸ§ͺ Test Data Generation\\n\\nCreating high-quality test data is often a bottleneck in evaluation. Ragas helps you generate comprehensive test datasets automatically, saving time and ensuring thorough coverage.\\n\\nπŸ”— Seamless Integrations\\n\\nRagas works with popular LLM frameworks and tools: - LangChain - LlamaIndex - Haystack - OpenAI\\n\\nObservability platforms - Phoenix - LangSmith - Langfuse\\n\\nπŸ“Š Comprehensive Analysis\\n\\nBeyond simple scores, Ragas provides detailed insights into your application\\'s strengths and weaknesses, enabling targeted improvements.\\n\\nGetting Started with Ragas\\n\\nInstalling Ragas is straightforward:\\n\\nbash uv init && uv add ragas\\n\\nHere\\'s a simple example of evaluating a response using Ragas:\\n\\n```python from ragas.metrics import Faithfulness from ragas.evaluation import EvaluationDataset from ragas.dataset_schema import SingleTurnSample from langchain_openai import ChatOpenAI from ragas.llms import LangchainLLMWrapper from langchain_openai import ChatOpenAI\\n\\nInitialize the LLM, you are going to new OPENAI API key\\n\\nevaluator_llm = LangchainLLMWrapper(ChatOpenAI(model=\"gpt-4o\"))\\n\\nYour evaluation data\\n\\ntest_data = { \"user_input\": \"What is the capital of France?\", \"retrieved_contexts\": [\"Paris is the capital and most populous city of France.\"], \"response\": \"The capital of France is Paris.\" }\\n\\nCreate a sample\\n\\nsample = SingleTurnSample(**test_data) # Unpack the dictionary into the constructor\\n\\nCreate metric\\n\\nfaithfulness = Faithfulness(llm=evaluator_llm)\\n\\nCalculate the score\\n\\nresult = await faithfulness.single_turn_ascore(sample) print(f\"Faithfulness score: {result}\") ```\\n\\nπŸ’‘ Try it yourself: Explore the hands-on notebook for this workflow: 01_Introduction_to_Ragas\\n\\nWhat\\'s Coming in This Blog Series\\n\\nThis introduction is just the beginning. In the upcoming posts, we\\'ll dive deeper into all aspects of evaluating LLM applications with Ragas:\\n\\nPart 2: Basic Evaluation Workflow We\\'ll explore each metric in detail, explaining when and how to use them effectively.\\n\\nPart 3: Evaluating RAG Systems Learn specialized techniques for evaluating retrieval-augmented generation systems, including context precision, recall, and relevance.\\n\\nPart 4: Test Data Generation Discover how to create high-quality test datasets that thoroughly exercise your application\\'s capabilities.\\n\\nPart 5: Advanced Evaluation Techniques Go beyond basic metrics with custom evaluations, multi-aspect analysis, and domain-specific assessments.\\n\\nPart 6: Evaluating AI Agents Learn how to evaluate complex AI agents that engage in multi-turn interactions, use tools, and work toward specific goals.\\n\\nPart 7: Integrations and Observability Connect Ragas with your existing tools and platforms for streamlined evaluation workflows.\\n\\nPart 8: Building Feedback Loops Learn how to implement feedback loops that drive continuous improvement in your LLM applications. Transform evaluation insights into concrete improvements for your LLM applications.\\n\\nConclusion\\n\\nIn a world increasingly powered by LLMs, robust evaluation is the difference between reliable applications and unpredictable ones. Ragas provides the tools you need to confidently assess and improve your LLM applications.\\n\\nReady to Elevate Your LLM Applications?\\n\\nStart exploring Ragas today by visiting the official documentation. Share your thoughts, challenges, or success stories. If you\\'re facing specific evaluation hurdles, don\\'t hesitate to reach outβ€”we\\'d love to help!')"
120
- ]
121
- },
122
- "execution_count": 22,
123
- "metadata": {},
124
- "output_type": "execute_result"
125
  }
126
  ],
127
  "source": [
128
- "docs[0]"
129
  ]
130
  },
131
  {
132
  "cell_type": "code",
133
- "execution_count": 44,
134
- "id": "83f7166c",
 
 
 
 
 
 
 
 
 
 
135
  "metadata": {},
136
  "outputs": [
137
  {
138
  "data": {
139
  "text/plain": [
140
- "<module 'lets_talk.utils.eval' from '/home/mafzaal/source/lets-talk/py-src/lets_talk/utils/eval.py'>"
141
  ]
142
  },
143
- "execution_count": 44,
144
  "metadata": {},
145
  "output_type": "execute_result"
146
  }
147
  ],
148
  "source": [
149
- "# hot reload the module\n",
150
- "import importlib\n",
151
- "importlib.reload(eval)"
152
  ]
153
  },
154
  {
155
  "cell_type": "code",
156
- "execution_count": 31,
157
  "id": "03663a91",
158
  "metadata": {},
159
- "outputs": [
160
- {
161
- "name": "stderr",
162
- "output_type": "stream",
163
- "text": [
164
- "Applying HeadlineSplitter: 0%| | 0/14 [00:00<?, ?it/s] unable to apply transformation: 'headlines' property not found in this node\n",
165
- "Applying SummaryExtractor: 20%|β–ˆβ–ˆ | 3/15 [00:02<00:09, 1.20it/s]Property 'summary' already exists in node 'ed7c49'. Skipping!\n",
166
- "Applying SummaryExtractor: 33%|β–ˆβ–ˆβ–ˆβ–Ž | 5/15 [00:06<00:15, 1.58s/it]Property 'summary' already exists in node 'f14d00'. Skipping!\n",
167
- "Applying [EmbeddingExtractor, ThemesExtractor, NERExtractor]: 0%| | 0/71 [00:00<?, ?it/s]Property 'summary_embedding' already exists in node 'ed7c49'. Skipping!\n",
168
- "Property 'summary_embedding' already exists in node 'f14d00'. Skipping!\n",
169
- "Generating personas: 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 3/3 [00:00<00:00, 3.11it/s] \n",
170
- "Generating Scenarios: 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 3/3 [00:13<00:00, 4.46s/it]\n",
171
- "Generating Samples: 100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 12/12 [00:53<00:00, 4.50s/it]\n"
172
- ]
173
- }
174
- ],
175
  "source": [
176
  "from lets_talk.config import EMBEDDING_MODEL,SDG_LLM_MODLEL,EVAL_LLM_MODEL\n",
177
  "testset = eval.generate_testset(docs=docs,llm_model = SDG_LLM_MODLEL, embedding_model = EMBEDDING_MODEL,testset_size=10)"
@@ -490,12 +490,12 @@
490
  },
491
  {
492
  "cell_type": "code",
493
- "execution_count": 40,
494
  "id": "4ae903d8",
495
  "metadata": {},
496
  "outputs": [],
497
  "source": [
498
- "df.to_csv(\"evals/testset.csv\",index=False)"
499
  ]
500
  },
501
  {
@@ -918,12 +918,12 @@
918
  },
919
  {
920
  "cell_type": "code",
921
- "execution_count": 47,
922
  "id": "f5d50d7b",
923
  "metadata": {},
924
  "outputs": [],
925
  "source": [
926
- "eval_df.to_csv(\"evals/rag_eval.csv\",index=False)"
927
  ]
928
  },
929
  {
@@ -1003,12 +1003,12 @@
1003
  },
1004
  {
1005
  "cell_type": "code",
1006
- "execution_count": 59,
1007
  "id": "49fa29f2",
1008
  "metadata": {},
1009
  "outputs": [],
1010
  "source": [
1011
- "result.to_pandas().to_csv(\"evals/rag_eval_result.csv\",index=False)"
1012
  ]
1013
  }
1014
  ],
 
2
  "cells": [
3
  {
4
  "cell_type": "code",
5
+ "execution_count": 1,
6
  "id": "ca8bd0e4",
7
  "metadata": {},
8
  "outputs": [
 
10
  "name": "stdout",
11
  "output_type": "stream",
12
  "text": [
13
+ "Adding package root to sys.path: /home/mafzaal/source/lets-talk/py-src\n",
14
+ "Current notebook directory: /home/mafzaal/source/lets-talk/py-src/notebooks\n",
15
+ "Project root: /home/mafzaal/source/lets-talk\n"
16
  ]
17
  }
18
  ],
 
22
  "\n",
23
  "# Add the project root to the Python path\n",
24
  "package_root = os.path.abspath(os.path.join(os.getcwd(), \"../\"))\n",
25
+ "print(f\"Adding package root to sys.path: {package_root}\")\n",
26
  "if package_root not in sys.path:\n",
27
+ "\tsys.path.append(package_root)\n",
28
+ "\n",
29
+ "notebook_dir = os.getcwd()\n",
30
+ "print(f\"Current notebook directory: {notebook_dir}\")\n",
31
+ "# change to the directory to the root of the project\n",
32
+ "project_root = os.path.abspath(os.path.join(os.getcwd(), \"../../\"))\n",
33
+ "print(f\"Project root: {project_root}\")\n",
34
+ "os.chdir(project_root)"
35
  ]
36
  },
37
  {
38
  "cell_type": "code",
39
+ "execution_count": 3,
40
  "id": "b48fa7d4",
41
  "metadata": {},
42
  "outputs": [],
 
47
  },
48
  {
49
  "cell_type": "code",
50
+ "execution_count": 2,
51
  "id": "cd3c7329",
52
  "metadata": {},
53
  "outputs": [],
 
59
  },
60
  {
61
  "cell_type": "code",
62
+ "execution_count": 5,
63
+ "id": "1f9f2076",
64
  "metadata": {},
65
  "outputs": [
66
  {
67
+ "data": {
68
+ "text/plain": [
69
+ "<module 'lets_talk.utils.blog' from '/home/mafzaal/source/lets-talk/py-src/lets_talk/utils/blog.py'>"
70
+ ]
71
+ },
72
+ "execution_count": 5,
73
+ "metadata": {},
74
+ "output_type": "execute_result"
75
  }
76
  ],
77
  "source": [
78
+ "# hot reload the module\n",
79
+ "import importlib\n",
80
+ "importlib.reload(eval)\n",
81
+ "importlib.reload(blog)"
 
 
 
 
82
  ]
83
  },
84
  {
85
  "cell_type": "code",
86
+ "execution_count": 3,
87
+ "id": "cc282d9c",
88
  "metadata": {},
89
  "outputs": [
90
  {
91
  "name": "stderr",
92
  "output_type": "stream",
93
  "text": [
94
+ "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 14/14 [00:00<00:00, 3266.23it/s]"
95
  ]
96
  },
97
  {
98
  "name": "stdout",
99
  "output_type": "stream",
100
  "text": [
101
+ "Loaded 14 documents from data/\n",
102
+ "Split 14 documents into 162 chunks\n"
103
  ]
104
  },
105
  {
 
111
  }
112
  ],
113
  "source": [
114
+ "#docs = blog.load_blog_posts()\n",
115
+ "#docs = blog.update_document_metadata(docs)\n",
116
+ "\n",
117
+ "blog_posts = blog.process_blog_posts(create_embeddings=False)"
118
  ]
119
  },
120
  {
121
  "cell_type": "code",
122
+ "execution_count": 7,
123
+ "id": "e768b97b",
124
  "metadata": {},
125
  "outputs": [
126
  {
127
+ "name": "stdout",
128
+ "output_type": "stream",
129
+ "text": [
130
+ "{'total_documents': 162, 'total_characters': 127917, 'min_length': 172, 'max_length': 998, 'avg_length': 789.6111111111111, 'documents': [{'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'source': 'data/introduction-to-ragas/index.md', 'title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'text_length': 6994}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/generating-test-data-with-ragas/', 'source': 'data/generating-test-data-with-ragas/index.md', 'title': '\"Part 4: Generating Test Data with Ragas\"', 'text_length': 14680}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/', 'source': 'data/advanced-metrics-and-customization-with-ragas/index.md', 'title': '\"Part 5: Advanced Metrics and Customization with Ragas\"', 'text_length': 11530}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/building-research-agent/', 'source': 'data/building-research-agent/index.md', 'title': 'Building a Research Agent with RSS Feed Support', 'text_length': 7320}, {'url': 'https://thedataguy.pro/blog/rss-feed-announcement/', 'source': 'data/rss-feed-announcement/index.md', 'title': '\"Subscribe to Our Blog via RSS\"', 'text_length': 2139}, {'url': 'https://thedataguy.pro/blog/rss-feed-announcement/', 'source': 'data/rss-feed-announcement/index.md', 'title': '\"Subscribe to Our Blog via RSS\"', 'text_length': 2139}, {'url': 'https://thedataguy.pro/blog/rss-feed-announcement/', 'source': 'data/rss-feed-announcement/index.md', 'title': '\"Subscribe to Our Blog via RSS\"', 'text_length': 2139}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/metric-driven-development/', 'source': 'data/metric-driven-development/index.md', 'title': '\"Metric-Driven Development: Make Smarter Decisions, Faster\"', 'text_length': 12450}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/', 'source': 'data/basic-evaluation-workflow-with-ragas/index.md', 'title': '\"Part 2: Basic Evaluation Workflow with Ragas\"', 'text_length': 11222}, {'url': 'https://thedataguy.pro/blog/langchain-experience-csharp-perspective/', 'source': 'data/langchain-experience-csharp-perspective/index.md', 'title': \"A C# Programmer's Perspective on LangChain Expression Language\", 'text_length': 3361}, {'url': 'https://thedataguy.pro/blog/langchain-experience-csharp-perspective/', 'source': 'data/langchain-experience-csharp-perspective/index.md', 'title': \"A C# Programmer's Perspective on LangChain Expression Language\", 'text_length': 3361}, {'url': 'https://thedataguy.pro/blog/langchain-experience-csharp-perspective/', 'source': 'data/langchain-experience-csharp-perspective/index.md', 'title': \"A C# Programmer's Perspective on LangChain Expression Language\", 'text_length': 3361}, {'url': 'https://thedataguy.pro/blog/langchain-experience-csharp-perspective/', 'source': 'data/langchain-experience-csharp-perspective/index.md', 'title': \"A C# Programmer's Perspective on LangChain Expression Language\", 'text_length': 3361}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/', 'source': 'data/evaluating-ai-agents-with-ragas/index.md', 'title': '\"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\"', 'text_length': 9821}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/integrations-and-observability-with-ragas/', 'source': 'data/integrations-and-observability-with-ragas/index.md', 'title': '\"Part 7: Integrations and Observability with Ragas\"', 'text_length': 9098}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/building-feedback-loops-with-ragas/', 'source': 'data/building-feedback-loops-with-ragas/index.md', 'title': '\"Part 8: Building Feedback Loops with Ragas\"', 'text_length': 8160}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/coming-back-to-ai-roots/', 'source': 'data/coming-back-to-ai-roots/index.md', 'title': 'Coming Back to AI Roots - My Professional Journey', 'text_length': 5827}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/data-is-king/', 'source': 'data/data-is-king/index.md', 'title': '\"Data is King: Why Your Data Strategy IS Your Business Strategy\"', 'text_length': 6197}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}, {'url': 'https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/', 'source': 'data/evaluating-rag-systems-with-ragas/index.md', 'title': '\"Part 3: Evaluating RAG Systems with Ragas\"', 'text_length': 8811}]}\n"
131
+ ]
 
 
 
132
  }
133
  ],
134
  "source": [
135
+ "print(blog_posts[\"stats\"])"
136
  ]
137
  },
138
  {
139
  "cell_type": "code",
140
+ "execution_count": 4,
141
+ "id": "21d9a2df",
142
+ "metadata": {},
143
+ "outputs": [],
144
+ "source": [
145
+ "docs = blog_posts[\"documents\"]"
146
+ ]
147
+ },
148
+ {
149
+ "cell_type": "code",
150
+ "execution_count": 5,
151
+ "id": "33949cc9",
152
  "metadata": {},
153
  "outputs": [
154
  {
155
  "data": {
156
  "text/plain": [
157
+ "Document(metadata={'source': 'data/introduction-to-ragas/index.md', 'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'post_slug': 'introduction-to-ragas', 'post_title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'content_length': 6994}, page_content='---\\ntitle: \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"\\ndate: 2025-04-26T18:00:00-06:00\\nlayout: blog\\ndescription: \"Explore the essential evaluation framework for LLM applications with Ragas. Learn how to assess performance, ensure accuracy, and improve reliability in Retrieval-Augmented Generation systems.\"\\ncategories: [\"AI\", \"RAG\", \"Evaluation\",\"Ragas\"]\\ncoverImage: \"https://images.unsplash.com/photo-1593642634367-d91a135587b5?q=80&w=1770&auto=format&fit=crop&ixlib=rb-4.0.3\"\\nreadingTime: 7\\npublished: true\\n---\\n\\nAs Large Language Models (LLMs) become fundamental components of modern applications, effectively evaluating their performance becomes increasingly critical. Whether you\\'re building a question-answering system, a document retrieval tool, or a conversational agent, you need reliable metrics to assess how well your application performs. This is where Ragas steps in.\\n\\n## What is Ragas?')"
158
  ]
159
  },
160
+ "execution_count": 5,
161
  "metadata": {},
162
  "output_type": "execute_result"
163
  }
164
  ],
165
  "source": [
166
+ "docs[0]"
 
 
167
  ]
168
  },
169
  {
170
  "cell_type": "code",
171
+ "execution_count": null,
172
  "id": "03663a91",
173
  "metadata": {},
174
+ "outputs": [],
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
175
  "source": [
176
  "from lets_talk.config import EMBEDDING_MODEL,SDG_LLM_MODLEL,EVAL_LLM_MODEL\n",
177
  "testset = eval.generate_testset(docs=docs,llm_model = SDG_LLM_MODLEL, embedding_model = EMBEDDING_MODEL,testset_size=10)"
 
490
  },
491
  {
492
  "cell_type": "code",
493
+ "execution_count": null,
494
  "id": "4ae903d8",
495
  "metadata": {},
496
  "outputs": [],
497
  "source": [
498
+ "df.to_csv(\"evals/testset_2.csv\",index=False)"
499
  ]
500
  },
501
  {
 
918
  },
919
  {
920
  "cell_type": "code",
921
+ "execution_count": null,
922
  "id": "f5d50d7b",
923
  "metadata": {},
924
  "outputs": [],
925
  "source": [
926
+ "eval_df.to_csv(\"evals/rag_eval_2.csv\",index=False)"
927
  ]
928
  },
929
  {
 
1003
  },
1004
  {
1005
  "cell_type": "code",
1006
+ "execution_count": null,
1007
  "id": "49fa29f2",
1008
  "metadata": {},
1009
  "outputs": [],
1010
  "source": [
1011
+ "result.to_pandas().to_csv(\"evals/rag_eval_result_2.csv\",index=False)"
1012
  ]
1013
  }
1014
  ],
py-src/notebooks/07_Fine_Tuning_Dataset.ipynb ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ {
2
+ "cells": [
3
+ {
4
+ "cell_type": "code",
5
+ "execution_count": 1,
6
+ "id": "c95ab233",
7
+ "metadata": {},
8
+ "outputs": [
9
+ {
10
+ "name": "stdout",
11
+ "output_type": "stream",
12
+ "text": [
13
+ "Adding package root to sys.path: /home/mafzaal/source/lets-talk/py-src\n",
14
+ "Current notebook directory: /home/mafzaal/source/lets-talk/py-src/notebooks\n",
15
+ "Project root: /home/mafzaal/source/lets-talk\n"
16
+ ]
17
+ }
18
+ ],
19
+ "source": [
20
+ "import sys\n",
21
+ "import os\n",
22
+ "\n",
23
+ "# Add the project root to the Python path\n",
24
+ "package_root = os.path.abspath(os.path.join(os.getcwd(), \"../\"))\n",
25
+ "print(f\"Adding package root to sys.path: {package_root}\")\n",
26
+ "if package_root not in sys.path:\n",
27
+ "\tsys.path.append(package_root)\n",
28
+ "\n",
29
+ "\n",
30
+ "notebook_dir = os.getcwd()\n",
31
+ "print(f\"Current notebook directory: {notebook_dir}\")\n",
32
+ "# change to the directory to the root of the project\n",
33
+ "project_root = os.path.abspath(os.path.join(os.getcwd(), \"../../\"))\n",
34
+ "print(f\"Project root: {project_root}\")\n",
35
+ "os.chdir(project_root)"
36
+ ]
37
+ },
38
+ {
39
+ "cell_type": "code",
40
+ "execution_count": 4,
41
+ "id": "15e97530",
42
+ "metadata": {},
43
+ "outputs": [],
44
+ "source": [
45
+ "import nest_asyncio\n",
46
+ "\n",
47
+ "nest_asyncio.apply()"
48
+ ]
49
+ },
50
+ {
51
+ "cell_type": "code",
52
+ "execution_count": 2,
53
+ "id": "b4f2ddc0",
54
+ "metadata": {},
55
+ "outputs": [],
56
+ "source": [
57
+ "import lets_talk.utils.blog as blog\n",
58
+ "import lets_talk.utils.eval as eval"
59
+ ]
60
+ },
61
+ {
62
+ "cell_type": "code",
63
+ "execution_count": 3,
64
+ "id": "123779af",
65
+ "metadata": {},
66
+ "outputs": [
67
+ {
68
+ "name": "stderr",
69
+ "output_type": "stream",
70
+ "text": [
71
+ "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 14/14 [00:00<00:00, 16100.98it/s]"
72
+ ]
73
+ },
74
+ {
75
+ "name": "stdout",
76
+ "output_type": "stream",
77
+ "text": [
78
+ "Loaded 14 documents from data/\n",
79
+ "Split 14 documents into 162 chunks\n"
80
+ ]
81
+ },
82
+ {
83
+ "name": "stderr",
84
+ "output_type": "stream",
85
+ "text": [
86
+ "\n"
87
+ ]
88
+ }
89
+ ],
90
+ "source": [
91
+ "docs = blog.load_blog_posts()\n",
92
+ "docs = blog.update_document_metadata(docs)\n",
93
+ "split_docs = blog.split_documents(docs)"
94
+ ]
95
+ },
96
+ {
97
+ "cell_type": "code",
98
+ "execution_count": null,
99
+ "id": "b0f749db",
100
+ "metadata": {},
101
+ "outputs": [],
102
+ "source": [
103
+ "from langchain_core.prompts import ChatPromptTemplate\n",
104
+ "from langchain_openai import ChatOpenAI\n",
105
+ "\n",
106
+ "qa_chat_model = ChatOpenAI(\n",
107
+ " model=\"gpt-4.1-mini\",\n",
108
+ " temperature=0,\n",
109
+ ")\n",
110
+ "\n",
111
+ "qa_prompt = \"\"\"\\\n",
112
+ "Given the following context, you must generate questions based on only the provided context.\n",
113
+ "You are to generate {n_questions} questions which should be provided in the following format:\n",
114
+ "\n",
115
+ "1. QUESTION #1\n",
116
+ "2. QUESTION #2\n",
117
+ "...\n",
118
+ "\n",
119
+ "Context:\n",
120
+ "{context}\n",
121
+ "\"\"\"\n",
122
+ "\n",
123
+ "qa_prompt_template = ChatPromptTemplate.from_template(qa_prompt)\n",
124
+ "question_generation_chain = qa_prompt_template | qa_chat_model"
125
+ ]
126
+ },
127
+ {
128
+ "cell_type": "code",
129
+ "execution_count": 10,
130
+ "id": "adb3ae7b",
131
+ "metadata": {},
132
+ "outputs": [],
133
+ "source": [
134
+ "context = split_docs[0].page_content\n",
135
+ "n_questions = 3\n",
136
+ "response = question_generation_chain.invoke({\"context\": context, \"n_questions\": n_questions})\n"
137
+ ]
138
+ },
139
+ {
140
+ "cell_type": "code",
141
+ "execution_count": 12,
142
+ "id": "6df35cfd",
143
+ "metadata": {},
144
+ "outputs": [
145
+ {
146
+ "data": {
147
+ "text/plain": [
148
+ "'1. What is the primary purpose of the Ragas evaluation framework in LLM applications? \\n2. Why is it important to have reliable metrics when assessing the performance of LLM-based systems? \\n3. In what types of applications can Ragas be used to evaluate performance?'"
149
+ ]
150
+ },
151
+ "execution_count": 12,
152
+ "metadata": {},
153
+ "output_type": "execute_result"
154
+ }
155
+ ],
156
+ "source": [
157
+ "response.content"
158
+ ]
159
+ },
160
+ {
161
+ "cell_type": "code",
162
+ "execution_count": null,
163
+ "id": "dcd0bf6d",
164
+ "metadata": {},
165
+ "outputs": [
166
+ {
167
+ "name": "stdout",
168
+ "output_type": "stream",
169
+ "text": [
170
+ "Extracted questions:\n",
171
+ "1 - What is the primary purpose of the Ragas evaluation framework in LLM applications?\n",
172
+ "2 - Why is it important to have reliable metrics when assessing the performance of LLM-based systems?\n",
173
+ "3 - In what types of applications can Ragas be used to evaluate performance?\n"
174
+ ]
175
+ }
176
+ ],
177
+ "source": [
178
+ "questions = extract_questions(response.content)\n",
179
+ "print(\"Extracted questions:\")\n",
180
+ "for i, question in enumerate(questions):\n",
181
+ " print(f\"{i + 1}. {question}\")"
182
+ ]
183
+ },
184
+ {
185
+ "cell_type": "code",
186
+ "execution_count": 19,
187
+ "id": "e78f93b8",
188
+ "metadata": {},
189
+ "outputs": [],
190
+ "source": [
191
+ "import tqdm\n",
192
+ "import asyncio\n",
193
+ "\n",
194
+ "\n",
195
+ "def extract_questions(response_text):\n",
196
+ " # Split the response text into lines\n",
197
+ " lines = response_text.strip().split('\\n')\n",
198
+ "\n",
199
+ " # Extract questions (format: \"1. QUESTION\")\n",
200
+ " extracted_questions = []\n",
201
+ " for line in lines:\n",
202
+ " line = line.strip()\n",
203
+ " if line and any(line.startswith(f\"{i}.\") for i in range(1, n_questions+1)):\n",
204
+ " # Remove the number prefix and get just the question\n",
205
+ " question = line.split('.', 1)[1].strip()\n",
206
+ " extracted_questions.append(question)\n",
207
+ "\n",
208
+ " return extracted_questions\n",
209
+ "\n",
210
+ "\n",
211
+ "\n",
212
+ "\n",
213
+ "\n",
214
+ "async def create_questions(documents, n_questions):\n",
215
+ " question_set = []\n",
216
+ " \n",
217
+ "\n",
218
+ " for doc in tqdm.tqdm(documents):\n",
219
+ " \n",
220
+ " context = doc.page_content\n",
221
+ "\n",
222
+ " # Generate questions using the question generation chain\n",
223
+ " response = await question_generation_chain.ainvoke({\n",
224
+ " \"context\": context,\n",
225
+ " \"n_questions\": n_questions\n",
226
+ " })\n",
227
+ "\n",
228
+ " questions = extract_questions(response.content)\n",
229
+ " \n",
230
+ " for i, question in enumerate(questions):\n",
231
+ " questions.append({\"question\":question, \"context\": context})\n",
232
+ " \n",
233
+ "\n",
234
+ " \n",
235
+ "\n",
236
+ " return question_set"
237
+ ]
238
+ },
239
+ {
240
+ "cell_type": "code",
241
+ "execution_count": null,
242
+ "id": "b1ece53b",
243
+ "metadata": {},
244
+ "outputs": [],
245
+ "source": [
246
+ "ds = await create_questions(split_docs[:2], 3)"
247
+ ]
248
+ },
249
+ {
250
+ "cell_type": "code",
251
+ "execution_count": null,
252
+ "id": "aa92dd7d",
253
+ "metadata": {},
254
+ "outputs": [
255
+ {
256
+ "name": "stderr",
257
+ "output_type": "stream",
258
+ "text": [
259
+ " 0%| | 0/2 [00:00<?, ?it/s]"
260
+ ]
261
+ },
262
+ {
263
+ "ename": "",
264
+ "evalue": "",
265
+ "output_type": "error",
266
+ "traceback": [
267
+ "\u001b[1;31mThe Kernel crashed while executing code in the current cell or a previous cell. \n",
268
+ "\u001b[1;31mPlease review the code in the cell(s) to identify a possible cause of the failure. \n",
269
+ "\u001b[1;31mClick <a href='https://aka.ms/vscodeJupyterKernelCrash'>here</a> for more info. \n",
270
+ "\u001b[1;31mView Jupyter <a href='command:jupyter.viewOutput'>log</a> for further details."
271
+ ]
272
+ }
273
+ ],
274
+ "source": []
275
+ }
276
+ ],
277
+ "metadata": {
278
+ "kernelspec": {
279
+ "display_name": ".venv",
280
+ "language": "python",
281
+ "name": "python3"
282
+ },
283
+ "language_info": {
284
+ "codemirror_mode": {
285
+ "name": "ipython",
286
+ "version": 3
287
+ },
288
+ "file_extension": ".py",
289
+ "mimetype": "text/x-python",
290
+ "name": "python",
291
+ "nbconvert_exporter": "python",
292
+ "pygments_lexer": "ipython3",
293
+ "version": "3.13.2"
294
+ }
295
+ },
296
+ "nbformat": 4,
297
+ "nbformat_minor": 5
298
+ }
py-src/notebooks/update_blog_data.ipynb CHANGED
@@ -12,25 +12,57 @@
12
  },
13
  {
14
  "cell_type": "code",
15
- "execution_count": null,
16
  "id": "6ec048b4",
17
  "metadata": {},
18
- "outputs": [],
 
 
 
 
 
 
 
 
19
  "source": [
20
  "import sys\n",
21
  "import os\n",
22
  "from pathlib import Path\n",
23
  "from dotenv import load_dotenv\n",
24
- "import importlib.util\n",
25
  "\n",
26
  "import sys\n",
27
  "import os\n",
28
  "\n",
29
  "# Add the project root to the Python path\n",
30
- "project_root = os.path.abspath(os.path.join(os.getcwd(), \"../\"))\n",
31
- "print(f\"Adding project root to sys.path: {project_root}\")\n",
32
- "if project_root not in sys.path:\n",
33
- "\tsys.path.append(project_root)\n"
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
34
  ]
35
  },
36
  {
@@ -56,7 +88,7 @@
56
  "name": "stderr",
57
  "output_type": "stream",
58
  "text": [
59
- "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 14/14 [00:00<00:00, 42.05it/s]"
60
  ]
61
  },
62
  {
@@ -76,11 +108,8 @@
76
  ],
77
  "source": [
78
  "import lets_talk.utils.blog as blog_utils\n",
79
- "\n",
80
  "docs = blog_utils.load_blog_posts()\n",
81
- "docs = blog_utils.update_document_metadata(docs)\n",
82
- "\n",
83
- "\n"
84
  ]
85
  },
86
  {
@@ -88,11 +117,29 @@
88
  "execution_count": null,
89
  "id": "a14c70dc",
90
  "metadata": {},
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
91
  "outputs": [
92
  {
93
  "data": {
94
  "text/plain": [
95
- "Document(metadata={'source': 'data/introduction-to-ragas/index.md', 'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'post_slug': 'introduction-to-ragas', 'post_title': 'Introduction To Ragas', 'content_length': 6071}, page_content='title: \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\" date: 2025-04-26T18:00:00-06:00 layout: blog description: \"Explore the essential evaluation framework for LLM applications with Ragas. Learn how to assess performance, ensure accuracy, and improve reliability in Retrieval-Augmented Generation systems.\" categories: [\"AI\", \"RAG\", \"Evaluation\",\"Ragas\"] coverImage: \"https://images.unsplash.com/photo-1593642634367-d91a135587b5?q=80&w=1770&auto=format&fit=crop&ixlib=rb-4.0.3\" readingTime: 7 published: true\\n\\nAs Large Language Models (LLMs) become fundamental components of modern applications, effectively evaluating their performance becomes increasingly critical. Whether you\\'re building a question-answering system, a document retrieval tool, or a conversational agent, you need reliable metrics to assess how well your application performs. This is where Ragas steps in.\\n\\nWhat is Ragas?\\n\\nRagas is an open-source evaluation framework specifically designed for LLM applications, with particular strengths in Retrieval-Augmented Generation (RAG) systems. Unlike traditional NLP evaluation methods, Ragas provides specialized metrics that address the unique challenges of LLM-powered systems.\\n\\nAt its core, Ragas helps answer crucial questions: - Is my application retrieving the right information? - Are the responses factually accurate and consistent with the retrieved context? - Does the system appropriately address the user\\'s query? - How well does my application handle multi-turn conversations?\\n\\nWhy Evaluate LLM Applications?\\n\\nLLMs are powerful but imperfect. They can hallucinate facts, misinterpret queries, or generate convincing but incorrect responses. For applications where accuracy and reliability matterβ€”like healthcare, finance, or educationβ€”proper evaluation is non-negotiable.\\n\\nEvaluation serves several key purposes: - Quality assurance: Identify and fix issues before they reach users - Performance tracking: Monitor how changes impact system performance - Benchmarking: Compare different approaches objectively - Continuous improvement: Build feedback loops to enhance your application\\n\\nKey Features of Ragas\\n\\n🎯 Specialized Metrics\\n\\nRagas offers both LLM-based and computational metrics tailored to evaluate different aspects of LLM applications:\\n\\nFaithfulness: Measures if the response is factually consistent with the retrieved context\\n\\nContext Relevancy: Evaluates if the retrieved information is relevant to the query\\n\\nAnswer Relevancy: Assesses if the response addresses the user\\'s question\\n\\nTopic Adherence: Gauges how well multi-turn conversations stay on topic\\n\\nπŸ§ͺ Test Data Generation\\n\\nCreating high-quality test data is often a bottleneck in evaluation. Ragas helps you generate comprehensive test datasets automatically, saving time and ensuring thorough coverage.\\n\\nπŸ”— Seamless Integrations\\n\\nRagas works with popular LLM frameworks and tools: - LangChain - LlamaIndex - Haystack - OpenAI\\n\\nObservability platforms - Phoenix - LangSmith - Langfuse\\n\\nπŸ“Š Comprehensive Analysis\\n\\nBeyond simple scores, Ragas provides detailed insights into your application\\'s strengths and weaknesses, enabling targeted improvements.\\n\\nGetting Started with Ragas\\n\\nInstalling Ragas is straightforward:\\n\\nbash uv init && uv add ragas\\n\\nHere\\'s a simple example of evaluating a response using Ragas:\\n\\n```python from ragas.metrics import Faithfulness from ragas.evaluation import EvaluationDataset from ragas.dataset_schema import SingleTurnSample from langchain_openai import ChatOpenAI from ragas.llms import LangchainLLMWrapper from langchain_openai import ChatOpenAI\\n\\nInitialize the LLM, you are going to new OPENAI API key\\n\\nevaluator_llm = LangchainLLMWrapper(ChatOpenAI(model=\"gpt-4o\"))\\n\\nYour evaluation data\\n\\ntest_data = { \"user_input\": \"What is the capital of France?\", \"retrieved_contexts\": [\"Paris is the capital and most populous city of France.\"], \"response\": \"The capital of France is Paris.\" }\\n\\nCreate a sample\\n\\nsample = SingleTurnSample(**test_data) # Unpack the dictionary into the constructor\\n\\nCreate metric\\n\\nfaithfulness = Faithfulness(llm=evaluator_llm)\\n\\nCalculate the score\\n\\nresult = await faithfulness.single_turn_ascore(sample) print(f\"Faithfulness score: {result}\") ```\\n\\nπŸ’‘ Try it yourself: Explore the hands-on notebook for this workflow: 01_Introduction_to_Ragas\\n\\nWhat\\'s Coming in This Blog Series\\n\\nThis introduction is just the beginning. In the upcoming posts, we\\'ll dive deeper into all aspects of evaluating LLM applications with Ragas:\\n\\nPart 2: Basic Evaluation Workflow We\\'ll explore each metric in detail, explaining when and how to use them effectively.\\n\\nPart 3: Evaluating RAG Systems Learn specialized techniques for evaluating retrieval-augmented generation systems, including context precision, recall, and relevance.\\n\\nPart 4: Test Data Generation Discover how to create high-quality test datasets that thoroughly exercise your application\\'s capabilities.\\n\\nPart 5: Advanced Evaluation Techniques Go beyond basic metrics with custom evaluations, multi-aspect analysis, and domain-specific assessments.\\n\\nPart 6: Evaluating AI Agents Learn how to evaluate complex AI agents that engage in multi-turn interactions, use tools, and work toward specific goals.\\n\\nPart 7: Integrations and Observability Connect Ragas with your existing tools and platforms for streamlined evaluation workflows.\\n\\nPart 8: Building Feedback Loops Learn how to implement feedback loops that drive continuous improvement in your LLM applications. Transform evaluation insights into concrete improvements for your LLM applications.\\n\\nConclusion\\n\\nIn a world increasingly powered by LLMs, robust evaluation is the difference between reliable applications and unpredictable ones. Ragas provides the tools you need to confidently assess and improve your LLM applications.\\n\\nReady to Elevate Your LLM Applications?\\n\\nStart exploring Ragas today by visiting the official documentation. Share your thoughts, challenges, or success stories. If you\\'re facing specific evaluation hurdles, don\\'t hesitate to reach outβ€”we\\'d love to help!')"
96
  ]
97
  },
98
  "execution_count": 8,
@@ -101,17 +148,17 @@
101
  }
102
  ],
103
  "source": [
104
- "docs[0]\n"
105
  ]
106
  },
107
  {
108
  "cell_type": "code",
109
- "execution_count": 11,
110
  "id": "72dd14b5",
111
  "metadata": {},
112
  "outputs": [],
113
  "source": [
114
- "vector_store = blog_utils = blog_utils.create_vector_store(docs,'./db/vector_store_4')"
115
  ]
116
  },
117
  {
@@ -126,7 +173,7 @@
126
  },
127
  {
128
  "cell_type": "code",
129
- "execution_count": 12,
130
  "id": "8b552e6b",
131
  "metadata": {},
132
  "outputs": [
@@ -137,27 +184,27 @@
137
  "\n",
138
  "Query: What is RAGAS?\n",
139
  "Retrieved 3 documents:\n",
140
- "1. Introduction To Ragas (https://thedataguy.pro/blog/introduction-to-ragas/)\n",
141
- "2. Evaluating Rag Systems With Ragas (https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/)\n",
142
- "3. Advanced Metrics And Customization With Ragas (https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/)\n",
143
  "\n",
144
  "Query: How to build research agents?\n",
145
  "Retrieved 3 documents:\n",
146
- "1. Building Research Agent (https://thedataguy.pro/blog/building-research-agent/)\n",
147
- "2. Advanced Metrics And Customization With Ragas (https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/)\n",
148
- "3. Evaluating Rag Systems With Ragas (https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/)\n",
149
  "\n",
150
  "Query: What is metric driven development?\n",
151
  "Retrieved 3 documents:\n",
152
- "1. Metric Driven Development (https://thedataguy.pro/blog/metric-driven-development/)\n",
153
- "2. Advanced Metrics And Customization With Ragas (https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/)\n",
154
- "3. Coming Back To Ai Roots (https://thedataguy.pro/blog/coming-back-to-ai-roots/)\n",
155
  "\n",
156
  "Query: Who is TheDataGuy?\n",
157
  "Retrieved 3 documents:\n",
158
- "1. Advanced Metrics And Customization With Ragas (https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/)\n",
159
- "2. Langchain Experience Csharp Perspective (https://thedataguy.pro/blog/langchain-experience-csharp-perspective/)\n",
160
- "3. Evaluating Rag Systems With Ragas (https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/)\n"
161
  ]
162
  }
163
  ],
@@ -185,7 +232,7 @@
185
  },
186
  {
187
  "cell_type": "code",
188
- "execution_count": 13,
189
  "id": "4cdd6899",
190
  "metadata": {},
191
  "outputs": [],
 
12
  },
13
  {
14
  "cell_type": "code",
15
+ "execution_count": 3,
16
  "id": "6ec048b4",
17
  "metadata": {},
18
+ "outputs": [
19
+ {
20
+ "name": "stdout",
21
+ "output_type": "stream",
22
+ "text": [
23
+ "Adding package root to sys.path: /home/mafzaal/source/lets-talk/py-src\n"
24
+ ]
25
+ }
26
+ ],
27
  "source": [
28
  "import sys\n",
29
  "import os\n",
30
  "from pathlib import Path\n",
31
  "from dotenv import load_dotenv\n",
32
+ "\n",
33
  "\n",
34
  "import sys\n",
35
  "import os\n",
36
  "\n",
37
  "# Add the project root to the Python path\n",
38
+ "package_root = os.path.abspath(os.path.join(os.getcwd(), \"../\"))\n",
39
+ "print(f\"Adding package root to sys.path: {package_root}\")\n",
40
+ "if package_root not in sys.path:\n",
41
+ "\tsys.path.append(package_root)\n"
42
+ ]
43
+ },
44
+ {
45
+ "cell_type": "code",
46
+ "execution_count": 4,
47
+ "id": "7a7a9f3f",
48
+ "metadata": {},
49
+ "outputs": [
50
+ {
51
+ "name": "stdout",
52
+ "output_type": "stream",
53
+ "text": [
54
+ "Current notebook directory: /home/mafzaal/source/lets-talk/py-src/notebooks\n",
55
+ "Project root: /home/mafzaal/source/lets-talk\n"
56
+ ]
57
+ }
58
+ ],
59
+ "source": [
60
+ "notebook_dir = os.getcwd()\n",
61
+ "print(f\"Current notebook directory: {notebook_dir}\")\n",
62
+ "# change to the directory to the root of the project\n",
63
+ "project_root = os.path.abspath(os.path.join(os.getcwd(), \"../../\"))\n",
64
+ "print(f\"Project root: {project_root}\")\n",
65
+ "os.chdir(project_root)"
66
  ]
67
  },
68
  {
 
88
  "name": "stderr",
89
  "output_type": "stream",
90
  "text": [
91
+ "100%|β–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆβ–ˆ| 14/14 [00:00<00:00, 4617.46it/s]"
92
  ]
93
  },
94
  {
 
108
  ],
109
  "source": [
110
  "import lets_talk.utils.blog as blog_utils\n",
 
111
  "docs = blog_utils.load_blog_posts()\n",
112
+ "docs = blog_utils.update_document_metadata(docs)\n"
 
 
113
  ]
114
  },
115
  {
 
117
  "execution_count": null,
118
  "id": "a14c70dc",
119
  "metadata": {},
120
+ "outputs": [
121
+ {
122
+ "name": "stdout",
123
+ "output_type": "stream",
124
+ "text": [
125
+ "Split 14 documents into 162 chunks\n"
126
+ ]
127
+ }
128
+ ],
129
+ "source": [
130
+ "split_docs = blog_utils.split_documents(docs)"
131
+ ]
132
+ },
133
+ {
134
+ "cell_type": "code",
135
+ "execution_count": 8,
136
+ "id": "1c40c587",
137
+ "metadata": {},
138
  "outputs": [
139
  {
140
  "data": {
141
  "text/plain": [
142
+ "Document(metadata={'source': 'data/introduction-to-ragas/index.md', 'url': 'https://thedataguy.pro/blog/introduction-to-ragas/', 'post_slug': 'introduction-to-ragas', 'post_title': '\"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"', 'content_length': 6994}, page_content='---\\ntitle: \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\"\\ndate: 2025-04-26T18:00:00-06:00\\nlayout: blog\\ndescription: \"Explore the essential evaluation framework for LLM applications with Ragas. Learn how to assess performance, ensure accuracy, and improve reliability in Retrieval-Augmented Generation systems.\"\\ncategories: [\"AI\", \"RAG\", \"Evaluation\",\"Ragas\"]\\ncoverImage: \"https://images.unsplash.com/photo-1593642634367-d91a135587b5?q=80&w=1770&auto=format&fit=crop&ixlib=rb-4.0.3\"\\nreadingTime: 7\\npublished: true\\n---\\n\\nAs Large Language Models (LLMs) become fundamental components of modern applications, effectively evaluating their performance becomes increasingly critical. Whether you\\'re building a question-answering system, a document retrieval tool, or a conversational agent, you need reliable metrics to assess how well your application performs. This is where Ragas steps in.\\n\\n## What is Ragas?')"
143
  ]
144
  },
145
  "execution_count": 8,
 
148
  }
149
  ],
150
  "source": [
151
+ "split_docs[0]"
152
  ]
153
  },
154
  {
155
  "cell_type": "code",
156
+ "execution_count": 10,
157
  "id": "72dd14b5",
158
  "metadata": {},
159
  "outputs": [],
160
  "source": [
161
+ "vector_store = blog_utils = blog_utils.create_vector_store(split_docs,'./db/vector_store_5')"
162
  ]
163
  },
164
  {
 
173
  },
174
  {
175
  "cell_type": "code",
176
+ "execution_count": 11,
177
  "id": "8b552e6b",
178
  "metadata": {},
179
  "outputs": [
 
184
  "\n",
185
  "Query: What is RAGAS?\n",
186
  "Retrieved 3 documents:\n",
187
+ "1. \"Part 3: Evaluating RAG Systems with Ragas\" (https://thedataguy.pro/blog/evaluating-rag-systems-with-ragas/)\n",
188
+ "2. \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\" (https://thedataguy.pro/blog/introduction-to-ragas/)\n",
189
+ "3. \"Part 4: Generating Test Data with Ragas\" (https://thedataguy.pro/blog/generating-test-data-with-ragas/)\n",
190
  "\n",
191
  "Query: How to build research agents?\n",
192
  "Retrieved 3 documents:\n",
193
+ "1. Building a Research Agent with RSS Feed Support (https://thedataguy.pro/blog/building-research-agent/)\n",
194
+ "2. \"Part 1: Introduction to Ragas: The Essential Evaluation Framework for LLM Applications\" (https://thedataguy.pro/blog/introduction-to-ragas/)\n",
195
+ "3. Building a Research Agent with RSS Feed Support (https://thedataguy.pro/blog/building-research-agent/)\n",
196
  "\n",
197
  "Query: What is metric driven development?\n",
198
  "Retrieved 3 documents:\n",
199
+ "1. \"Metric-Driven Development: Make Smarter Decisions, Faster\" (https://thedataguy.pro/blog/metric-driven-development/)\n",
200
+ "2. \"Metric-Driven Development: Make Smarter Decisions, Faster\" (https://thedataguy.pro/blog/metric-driven-development/)\n",
201
+ "3. \"Part 5: Advanced Metrics and Customization with Ragas\" (https://thedataguy.pro/blog/advanced-metrics-and-customization-with-ragas/)\n",
202
  "\n",
203
  "Query: Who is TheDataGuy?\n",
204
  "Retrieved 3 documents:\n",
205
+ "1. \"Part 2: Basic Evaluation Workflow with Ragas\" (https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/)\n",
206
+ "2. \"Part 2: Basic Evaluation Workflow with Ragas\" (https://thedataguy.pro/blog/basic-evaluation-workflow-with-ragas/)\n",
207
+ "3. \"Part 6: Evaluating AI Agents: Beyond Simple Answers with Ragas\" (https://thedataguy.pro/blog/evaluating-ai-agents-with-ragas/)\n"
208
  ]
209
  }
210
  ],
 
232
  },
233
  {
234
  "cell_type": "code",
235
+ "execution_count": 12,
236
  "id": "4cdd6899",
237
  "metadata": {},
238
  "outputs": [],
scripts/build-vector-db.sh DELETED
@@ -1,6 +0,0 @@
1
- #!/bin/bash
2
-
3
-
4
- uv run python ./utils/pipeline.py
5
-
6
-