ragas-examples 0.3.5rc2__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- ragas_examples/__init__.py +17 -0
- ragas_examples/_version.py +34 -0
- ragas_examples/agent_evals/__init__.py +0 -0
- ragas_examples/agent_evals/agent.py +409 -0
- ragas_examples/agent_evals/evals.py +78 -0
- ragas_examples/benchmark_llm/__init__.py +0 -0
- ragas_examples/benchmark_llm/datasets/discount_benchmark.csv +11 -0
- ragas_examples/benchmark_llm/evals.py +274 -0
- ragas_examples/benchmark_llm/prompt.py +71 -0
- ragas_examples/prompt_evals/__init__.py +0 -0
- ragas_examples/prompt_evals/evals.py +75 -0
- ragas_examples/prompt_evals/prompt.py +32 -0
- ragas_examples/rag_eval/__init__.py +0 -0
- ragas_examples/rag_eval/evals.py +84 -0
- ragas_examples/rag_eval/rag.py +481 -0
- ragas_examples/text2sql/__init__.py +36 -0
- ragas_examples/text2sql/analyze_errors.py +198 -0
- ragas_examples/text2sql/data_utils.py +380 -0
- ragas_examples/text2sql/datasets/booksql_sample.csv +100 -0
- ragas_examples/text2sql/db_utils.py +458 -0
- ragas_examples/text2sql/evals.py +387 -0
- ragas_examples/text2sql/prompt.txt +111 -0
- ragas_examples/text2sql/prompt_v2.txt +135 -0
- ragas_examples/text2sql/prompt_v3.txt +144 -0
- ragas_examples/text2sql/text2sql_agent.py +522 -0
- ragas_examples/text2sql/validate_sql_dataset.py +317 -0
- ragas_examples/workflow_eval/__init__.py +0 -0
- ragas_examples/workflow_eval/evals.py +107 -0
- ragas_examples/workflow_eval/workflow.py +670 -0
- ragas_examples-0.3.5rc2.dist-info/METADATA +130 -0
- ragas_examples-0.3.5rc2.dist-info/RECORD +34 -0
- ragas_examples-0.3.5rc2.dist-info/WHEEL +5 -0
- ragas_examples-0.3.5rc2.dist-info/licenses/LICENSE +201 -0
- ragas_examples-0.3.5rc2.dist-info/top_level.txt +1 -0
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Ragas Examples Package
|
|
3
|
+
|
|
4
|
+
This package contains official examples demonstrating how to use Ragas for evaluating
|
|
5
|
+
different types of AI applications including RAG systems, agents, prompts, workflows,
|
|
6
|
+
and LLM benchmarking.
|
|
7
|
+
|
|
8
|
+
Available example modules:
|
|
9
|
+
- agent_evals: Agent evaluation examples
|
|
10
|
+
- benchmark_llm: LLM benchmarking and comparison examples
|
|
11
|
+
- prompt_evals: Prompt evaluation examples
|
|
12
|
+
- rag_eval: RAG system evaluation examples
|
|
13
|
+
- text2sql: Text-to-SQL agent evaluation examples
|
|
14
|
+
- workflow_eval: Workflow evaluation examples
|
|
15
|
+
"""
|
|
16
|
+
|
|
17
|
+
from ._version import __version__
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
# file generated by setuptools-scm
|
|
2
|
+
# don't change, don't track in version control
|
|
3
|
+
|
|
4
|
+
__all__ = [
|
|
5
|
+
"__version__",
|
|
6
|
+
"__version_tuple__",
|
|
7
|
+
"version",
|
|
8
|
+
"version_tuple",
|
|
9
|
+
"__commit_id__",
|
|
10
|
+
"commit_id",
|
|
11
|
+
]
|
|
12
|
+
|
|
13
|
+
TYPE_CHECKING = False
|
|
14
|
+
if TYPE_CHECKING:
|
|
15
|
+
from typing import Tuple
|
|
16
|
+
from typing import Union
|
|
17
|
+
|
|
18
|
+
VERSION_TUPLE = Tuple[Union[int, str], ...]
|
|
19
|
+
COMMIT_ID = Union[str, None]
|
|
20
|
+
else:
|
|
21
|
+
VERSION_TUPLE = object
|
|
22
|
+
COMMIT_ID = object
|
|
23
|
+
|
|
24
|
+
version: str
|
|
25
|
+
__version__: str
|
|
26
|
+
__version_tuple__: VERSION_TUPLE
|
|
27
|
+
version_tuple: VERSION_TUPLE
|
|
28
|
+
commit_id: COMMIT_ID
|
|
29
|
+
__commit_id__: COMMIT_ID
|
|
30
|
+
|
|
31
|
+
__version__ = version = '0.3.5rc2'
|
|
32
|
+
__version_tuple__ = version_tuple = (0, 3, 5, 'rc2')
|
|
33
|
+
|
|
34
|
+
__commit_id__ = commit_id = None
|
|
File without changes
|
|
@@ -0,0 +1,409 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import logging
|
|
3
|
+
import os
|
|
4
|
+
from dataclasses import asdict, dataclass
|
|
5
|
+
from datetime import datetime
|
|
6
|
+
from typing import Any, Dict, Optional
|
|
7
|
+
|
|
8
|
+
import openai
|
|
9
|
+
|
|
10
|
+
SYSTEM_MESSAGE = """You are a mathematical problem-solving agent. You can only use these four atomic tools to solve problems:
|
|
11
|
+
- add(a, b): Add two numbers
|
|
12
|
+
- sub(a, b): Subtract b from a
|
|
13
|
+
- mul(a, b): Multiply two numbers
|
|
14
|
+
- div(a, b): Divide a by b
|
|
15
|
+
|
|
16
|
+
Your task is to break down complex mathematical expressions into a sequence of these atomic operations, following proper order of operations (parentheses, multiplication/division, addition/subtraction).
|
|
17
|
+
|
|
18
|
+
For each step, call the appropriate tool with the correct arguments. Work step by step, showing your reasoning.
|
|
19
|
+
|
|
20
|
+
When you have the final answer, respond with just the number."""
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@dataclass
|
|
24
|
+
class TraceEvent:
|
|
25
|
+
"""Single event in the application trace"""
|
|
26
|
+
|
|
27
|
+
event_type: (
|
|
28
|
+
str # "llm_call", "tool_execution", "error", "init", "result_extraction"
|
|
29
|
+
)
|
|
30
|
+
component: str # "openai_api", "math_tools", "agent", "parser"
|
|
31
|
+
data: Dict[str, Any]
|
|
32
|
+
|
|
33
|
+
|
|
34
|
+
@dataclass
|
|
35
|
+
class ToolResult:
|
|
36
|
+
tool_name: str
|
|
37
|
+
args: Dict[str, float]
|
|
38
|
+
result: float
|
|
39
|
+
step_number: int
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
class MathToolsAgent:
|
|
43
|
+
def __init__(
|
|
44
|
+
self,
|
|
45
|
+
client,
|
|
46
|
+
model_name: str = "gpt-4o",
|
|
47
|
+
system_message: str = SYSTEM_MESSAGE,
|
|
48
|
+
logdir: str = "logs",
|
|
49
|
+
):
|
|
50
|
+
"""
|
|
51
|
+
Initialize the LLM agent with OpenAI API
|
|
52
|
+
|
|
53
|
+
Args:
|
|
54
|
+
client: OpenAI client instance
|
|
55
|
+
model_name: Name of the model to use
|
|
56
|
+
system_message: System message for the agent
|
|
57
|
+
logdir: Directory to save trace logs
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
self.client = client
|
|
61
|
+
self.system_message = system_message
|
|
62
|
+
self.model_name = model_name
|
|
63
|
+
self.step_counter = 0
|
|
64
|
+
self.traces = []
|
|
65
|
+
self.logdir = logdir
|
|
66
|
+
|
|
67
|
+
# Create log directory if it doesn't exist
|
|
68
|
+
os.makedirs(self.logdir, exist_ok=True)
|
|
69
|
+
|
|
70
|
+
# Define available tools
|
|
71
|
+
self.tools = [
|
|
72
|
+
{
|
|
73
|
+
"type": "function",
|
|
74
|
+
"function": {
|
|
75
|
+
"name": "add",
|
|
76
|
+
"description": "Add two numbers together",
|
|
77
|
+
"parameters": {
|
|
78
|
+
"type": "object",
|
|
79
|
+
"properties": {
|
|
80
|
+
"a": {"type": "number", "description": "First number"},
|
|
81
|
+
"b": {"type": "number", "description": "Second number"},
|
|
82
|
+
},
|
|
83
|
+
"required": ["a", "b"],
|
|
84
|
+
},
|
|
85
|
+
},
|
|
86
|
+
},
|
|
87
|
+
{
|
|
88
|
+
"type": "function",
|
|
89
|
+
"function": {
|
|
90
|
+
"name": "sub",
|
|
91
|
+
"description": "Subtract second number from first number",
|
|
92
|
+
"parameters": {
|
|
93
|
+
"type": "object",
|
|
94
|
+
"properties": {
|
|
95
|
+
"a": {
|
|
96
|
+
"type": "number",
|
|
97
|
+
"description": "Number to subtract from",
|
|
98
|
+
},
|
|
99
|
+
"b": {
|
|
100
|
+
"type": "number",
|
|
101
|
+
"description": "Number to subtract",
|
|
102
|
+
},
|
|
103
|
+
},
|
|
104
|
+
"required": ["a", "b"],
|
|
105
|
+
},
|
|
106
|
+
},
|
|
107
|
+
},
|
|
108
|
+
{
|
|
109
|
+
"type": "function",
|
|
110
|
+
"function": {
|
|
111
|
+
"name": "mul",
|
|
112
|
+
"description": "Multiply two numbers together",
|
|
113
|
+
"parameters": {
|
|
114
|
+
"type": "object",
|
|
115
|
+
"properties": {
|
|
116
|
+
"a": {"type": "number", "description": "First number"},
|
|
117
|
+
"b": {"type": "number", "description": "Second number"},
|
|
118
|
+
},
|
|
119
|
+
"required": ["a", "b"],
|
|
120
|
+
},
|
|
121
|
+
},
|
|
122
|
+
},
|
|
123
|
+
{
|
|
124
|
+
"type": "function",
|
|
125
|
+
"function": {
|
|
126
|
+
"name": "div",
|
|
127
|
+
"description": "Divide first number by second number",
|
|
128
|
+
"parameters": {
|
|
129
|
+
"type": "object",
|
|
130
|
+
"properties": {
|
|
131
|
+
"a": {
|
|
132
|
+
"type": "number",
|
|
133
|
+
"description": "Number to divide (numerator)",
|
|
134
|
+
},
|
|
135
|
+
"b": {
|
|
136
|
+
"type": "number",
|
|
137
|
+
"description": "Number to divide by (denominator)",
|
|
138
|
+
},
|
|
139
|
+
},
|
|
140
|
+
"required": ["a", "b"],
|
|
141
|
+
},
|
|
142
|
+
},
|
|
143
|
+
},
|
|
144
|
+
]
|
|
145
|
+
|
|
146
|
+
def add(self, a: float, b: float) -> float:
|
|
147
|
+
"""Add two numbers"""
|
|
148
|
+
result = a + b
|
|
149
|
+
|
|
150
|
+
return result
|
|
151
|
+
|
|
152
|
+
def sub(self, a: float, b: float) -> float:
|
|
153
|
+
"""Subtract b from a"""
|
|
154
|
+
result = a - b
|
|
155
|
+
return result
|
|
156
|
+
|
|
157
|
+
def mul(self, a: float, b: float) -> float:
|
|
158
|
+
"""Multiply two numbers"""
|
|
159
|
+
result = a * b
|
|
160
|
+
return result
|
|
161
|
+
|
|
162
|
+
def div(self, a: float, b: float) -> float:
|
|
163
|
+
"""Divide a by b"""
|
|
164
|
+
if b == 0:
|
|
165
|
+
raise ValueError("Division by zero")
|
|
166
|
+
result = a / b
|
|
167
|
+
return result
|
|
168
|
+
|
|
169
|
+
def _execute_tool_call(self, tool_call) -> str:
|
|
170
|
+
"""Execute a tool call and return the result"""
|
|
171
|
+
|
|
172
|
+
self.traces.append(
|
|
173
|
+
TraceEvent(
|
|
174
|
+
event_type="tool_execution",
|
|
175
|
+
component="math_tools",
|
|
176
|
+
data={
|
|
177
|
+
"tool_name": tool_call.function.name,
|
|
178
|
+
"args": json.loads(tool_call.function.arguments),
|
|
179
|
+
},
|
|
180
|
+
)
|
|
181
|
+
)
|
|
182
|
+
|
|
183
|
+
function_name = tool_call.function.name
|
|
184
|
+
arguments = json.loads(tool_call.function.arguments)
|
|
185
|
+
|
|
186
|
+
# Execute the appropriate function
|
|
187
|
+
if function_name == "add":
|
|
188
|
+
result = self.add(arguments["a"], arguments["b"])
|
|
189
|
+
elif function_name == "sub":
|
|
190
|
+
result = self.sub(arguments["a"], arguments["b"])
|
|
191
|
+
elif function_name == "mul":
|
|
192
|
+
result = self.mul(arguments["a"], arguments["b"])
|
|
193
|
+
elif function_name == "div":
|
|
194
|
+
result = self.div(arguments["a"], arguments["b"])
|
|
195
|
+
else:
|
|
196
|
+
raise ValueError(f"Unknown function: {function_name}")
|
|
197
|
+
|
|
198
|
+
self.traces.append(
|
|
199
|
+
TraceEvent(
|
|
200
|
+
event_type="tool_result",
|
|
201
|
+
component="math_tools",
|
|
202
|
+
data={
|
|
203
|
+
"result": result,
|
|
204
|
+
},
|
|
205
|
+
)
|
|
206
|
+
)
|
|
207
|
+
|
|
208
|
+
return str(result)
|
|
209
|
+
|
|
210
|
+
def export_traces_to_log(
|
|
211
|
+
self, run_id: str, problem: str, final_result: Optional[float] = None
|
|
212
|
+
):
|
|
213
|
+
"""
|
|
214
|
+
Export traces to a log file with run_id
|
|
215
|
+
|
|
216
|
+
Args:
|
|
217
|
+
run_id: Unique identifier for this run
|
|
218
|
+
problem: The problem that was solved
|
|
219
|
+
final_result: The final result of the computation
|
|
220
|
+
"""
|
|
221
|
+
timestamp = datetime.now().isoformat()
|
|
222
|
+
log_filename = (
|
|
223
|
+
f"run_{run_id}_{timestamp.replace(':', '-').replace('.', '-')}.json"
|
|
224
|
+
)
|
|
225
|
+
log_filepath = os.path.join(self.logdir, log_filename)
|
|
226
|
+
|
|
227
|
+
log_data = {
|
|
228
|
+
"run_id": run_id,
|
|
229
|
+
"timestamp": timestamp,
|
|
230
|
+
"problem": problem,
|
|
231
|
+
"final_result": final_result,
|
|
232
|
+
"model_name": self.model_name,
|
|
233
|
+
"traces": [asdict(trace) for trace in self.traces],
|
|
234
|
+
}
|
|
235
|
+
|
|
236
|
+
with open(log_filepath, "w") as f:
|
|
237
|
+
json.dump(log_data, f, indent=2)
|
|
238
|
+
|
|
239
|
+
logging.info(f"Traces exported to: {log_filepath}")
|
|
240
|
+
return log_filepath
|
|
241
|
+
|
|
242
|
+
def solve(
|
|
243
|
+
self, problem: str, max_iterations: int = 10, run_id: Optional[str] = None
|
|
244
|
+
) -> Dict[str, Any]:
|
|
245
|
+
"""
|
|
246
|
+
Solve a math problem using iterative planning with LLM and atomic tools
|
|
247
|
+
|
|
248
|
+
Args:
|
|
249
|
+
problem: Mathematical expression or problem to solve
|
|
250
|
+
max_iterations: Maximum number of LLM iterations to prevent infinite loops
|
|
251
|
+
run_id: Optional run identifier. If None, generates one automatically
|
|
252
|
+
|
|
253
|
+
Returns:
|
|
254
|
+
Final numerical result
|
|
255
|
+
"""
|
|
256
|
+
# Generate run_id if not provided
|
|
257
|
+
if run_id is None:
|
|
258
|
+
run_id = f"{datetime.now().strftime('%Y%m%d_%H%M%S')}_{hash(problem) % 10000:04d}"
|
|
259
|
+
|
|
260
|
+
# Reset traces for each new problem
|
|
261
|
+
self.traces = []
|
|
262
|
+
|
|
263
|
+
logging.info(f"Solving: {problem} (Run ID: {run_id})")
|
|
264
|
+
logging.info("=" * 60)
|
|
265
|
+
|
|
266
|
+
# Reset state
|
|
267
|
+
self.execution_history = []
|
|
268
|
+
self.step_counter = 0
|
|
269
|
+
|
|
270
|
+
messages = [
|
|
271
|
+
{"role": "system", "content": self.system_message},
|
|
272
|
+
{
|
|
273
|
+
"role": "user",
|
|
274
|
+
"content": f"Solve this mathematical expression step by step: {problem}",
|
|
275
|
+
},
|
|
276
|
+
]
|
|
277
|
+
|
|
278
|
+
iteration = 0
|
|
279
|
+
while iteration < max_iterations:
|
|
280
|
+
iteration += 1
|
|
281
|
+
logging.info(f"\n--- LLM Iteration {iteration} ---")
|
|
282
|
+
|
|
283
|
+
try:
|
|
284
|
+
self.traces.append(
|
|
285
|
+
TraceEvent(
|
|
286
|
+
event_type="llm_call",
|
|
287
|
+
component="openai_api",
|
|
288
|
+
data={
|
|
289
|
+
"model": self.model_name,
|
|
290
|
+
"messages": messages,
|
|
291
|
+
# "tools": [tool["function"] for tool in self.tools]
|
|
292
|
+
},
|
|
293
|
+
)
|
|
294
|
+
)
|
|
295
|
+
|
|
296
|
+
# Call OpenAI API with function calling
|
|
297
|
+
response = self.client.chat.completions.create(
|
|
298
|
+
model=self.model_name,
|
|
299
|
+
messages=messages,
|
|
300
|
+
tools=self.tools,
|
|
301
|
+
tool_choice="auto",
|
|
302
|
+
# temperature=0
|
|
303
|
+
)
|
|
304
|
+
|
|
305
|
+
message = response.choices[0].message
|
|
306
|
+
messages.append(message.model_dump())
|
|
307
|
+
|
|
308
|
+
self.traces.append(
|
|
309
|
+
TraceEvent(
|
|
310
|
+
event_type="llm_response",
|
|
311
|
+
component="openai_api",
|
|
312
|
+
data={
|
|
313
|
+
"content": message.content,
|
|
314
|
+
"tool_calls": (
|
|
315
|
+
[tool.model_dump() for tool in message.tool_calls]
|
|
316
|
+
if message.tool_calls
|
|
317
|
+
else []
|
|
318
|
+
),
|
|
319
|
+
},
|
|
320
|
+
)
|
|
321
|
+
)
|
|
322
|
+
|
|
323
|
+
# Check if the model wants to call functions
|
|
324
|
+
if message.tool_calls:
|
|
325
|
+
logging.info(
|
|
326
|
+
f"LLM planning: {message.content or 'Executing tools...'}"
|
|
327
|
+
)
|
|
328
|
+
|
|
329
|
+
# Execute each tool call
|
|
330
|
+
for tool_call in message.tool_calls:
|
|
331
|
+
result = self._execute_tool_call(tool_call)
|
|
332
|
+
|
|
333
|
+
# Add tool result to conversation
|
|
334
|
+
messages.append(
|
|
335
|
+
{
|
|
336
|
+
"role": "tool",
|
|
337
|
+
"tool_call_id": tool_call.id,
|
|
338
|
+
"content": result,
|
|
339
|
+
}
|
|
340
|
+
)
|
|
341
|
+
else:
|
|
342
|
+
# No more tool calls - this should be the final answer
|
|
343
|
+
logging.info(f"LLM final response: {message.content}")
|
|
344
|
+
|
|
345
|
+
# Try to extract the numerical result
|
|
346
|
+
try:
|
|
347
|
+
# Look for a number in the response
|
|
348
|
+
import re
|
|
349
|
+
|
|
350
|
+
numbers = re.findall(r"-?\d+\.?\d*", message.content)
|
|
351
|
+
if numbers:
|
|
352
|
+
final_result = float(
|
|
353
|
+
numbers[-1]
|
|
354
|
+
) # Take the last number found
|
|
355
|
+
logging.info("=" * 60)
|
|
356
|
+
logging.info(f"Final result: {final_result}")
|
|
357
|
+
self.traces.append(
|
|
358
|
+
TraceEvent(
|
|
359
|
+
event_type="result_extraction",
|
|
360
|
+
component="math_tools",
|
|
361
|
+
data={"final_result": final_result},
|
|
362
|
+
)
|
|
363
|
+
)
|
|
364
|
+
|
|
365
|
+
# Export traces to log file
|
|
366
|
+
log_filename = self.export_traces_to_log(
|
|
367
|
+
run_id, problem, final_result
|
|
368
|
+
)
|
|
369
|
+
return {"result": final_result, "log_file": log_filename}
|
|
370
|
+
|
|
371
|
+
else:
|
|
372
|
+
logging.info(
|
|
373
|
+
"Could not extract numerical result from LLM response"
|
|
374
|
+
)
|
|
375
|
+
break
|
|
376
|
+
except ValueError:
|
|
377
|
+
logging.info("Could not parse final result as number")
|
|
378
|
+
break
|
|
379
|
+
|
|
380
|
+
except Exception as e:
|
|
381
|
+
logging.info(f"Error in iteration {iteration}: {e}")
|
|
382
|
+
break
|
|
383
|
+
|
|
384
|
+
logging.info("Max iterations reached or error occurred")
|
|
385
|
+
# Export traces even if solve failed
|
|
386
|
+
return {
|
|
387
|
+
"result": 0,
|
|
388
|
+
"log_file": self.export_traces_to_log(run_id, problem, 0.0),
|
|
389
|
+
}
|
|
390
|
+
|
|
391
|
+
|
|
392
|
+
def get_default_agent(
|
|
393
|
+
model_name: str = "gpt-4o", logdir: str = "logs"
|
|
394
|
+
) -> MathToolsAgent:
|
|
395
|
+
"""Get a default instance of the MathToolsAgent with OpenAI client"""
|
|
396
|
+
openai_client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
|
|
397
|
+
return MathToolsAgent(client=openai_client, model_name=model_name, logdir=logdir)
|
|
398
|
+
|
|
399
|
+
|
|
400
|
+
if __name__ == "__main__":
|
|
401
|
+
# Example usage
|
|
402
|
+
client = openai.OpenAI(api_key=os.environ.get("OPENAI_API_KEY"))
|
|
403
|
+
agent = MathToolsAgent(client, logdir="agent_logs")
|
|
404
|
+
|
|
405
|
+
problem = "((2 + 3) * 4) - (6 / 2)"
|
|
406
|
+
print(f"Problem: {problem}")
|
|
407
|
+
|
|
408
|
+
result = agent.solve(problem)
|
|
409
|
+
print(f"Result: {result}")
|
|
@@ -0,0 +1,78 @@
|
|
|
1
|
+
from .agent import get_default_agent
|
|
2
|
+
|
|
3
|
+
from ragas import Dataset, experiment
|
|
4
|
+
from ragas.metrics.numeric import numeric_metric
|
|
5
|
+
from ragas.metrics.result import MetricResult
|
|
6
|
+
|
|
7
|
+
math_agent = get_default_agent()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@numeric_metric(name="correctness", allowed_values=(0.0, 1.0))
|
|
11
|
+
def correctness_metric(prediction: float, actual: float):
|
|
12
|
+
"""Calculate correctness of the prediction."""
|
|
13
|
+
if isinstance(prediction, str) and "ERROR" in prediction:
|
|
14
|
+
return 0.0
|
|
15
|
+
result = 1.0 if abs(prediction - actual) < 1e-5 else 0.0
|
|
16
|
+
return MetricResult(
|
|
17
|
+
value=result, reason=f"Prediction: {prediction}, Actual: {actual}"
|
|
18
|
+
)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def load_dataset():
|
|
22
|
+
# Create a dataset
|
|
23
|
+
dataset = Dataset(
|
|
24
|
+
name="test_dataset",
|
|
25
|
+
backend="local/csv",
|
|
26
|
+
root_dir=".",
|
|
27
|
+
)
|
|
28
|
+
# Create sample data for mathematical expressions and their results
|
|
29
|
+
math_problems = [
|
|
30
|
+
{"question": "15 - 3 / 4", "answer": 14.25},
|
|
31
|
+
{"question": "(2 + 3) * (6 - 2)", "answer": 20.0},
|
|
32
|
+
{"question": "100 / 5 + 3 * 2", "answer": 26.0},
|
|
33
|
+
{"question": "((2 * 3) + (4 * 5)) * ((6 - 2) / (8 / 4))", "answer": 52.0},
|
|
34
|
+
{"question": "2 + 3 * 4 - 5 / 6 + 7", "answer": 20.166666666666664},
|
|
35
|
+
{"question": "(10 / 2) + (20 / 4) + (30 / 6) + (40 / 8)", "answer": 20.0},
|
|
36
|
+
{"question": "1/3 + 1/3 + 1/3", "answer": 1.0},
|
|
37
|
+
]
|
|
38
|
+
|
|
39
|
+
# Add the data to the dataset
|
|
40
|
+
for row in math_problems:
|
|
41
|
+
dataset.append(row)
|
|
42
|
+
|
|
43
|
+
dataset.save() # Save the dataset
|
|
44
|
+
return dataset
|
|
45
|
+
|
|
46
|
+
|
|
47
|
+
@experiment()
|
|
48
|
+
async def run_experiment(row):
|
|
49
|
+
question = row["question"]
|
|
50
|
+
expected_answer = row["answer"]
|
|
51
|
+
|
|
52
|
+
# Get the model's prediction
|
|
53
|
+
prediction = math_agent.solve(question)
|
|
54
|
+
|
|
55
|
+
# Calculate the correctness metric
|
|
56
|
+
correctness = correctness_metric.score(
|
|
57
|
+
prediction=prediction.get("result"), actual=expected_answer
|
|
58
|
+
)
|
|
59
|
+
|
|
60
|
+
return {
|
|
61
|
+
"question": question,
|
|
62
|
+
"expected_answer": expected_answer,
|
|
63
|
+
"prediction": prediction.get("result"),
|
|
64
|
+
"log_file": prediction.get("log_file"),
|
|
65
|
+
"correctness": correctness.value,
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
|
|
69
|
+
async def main():
|
|
70
|
+
dataset = load_dataset()
|
|
71
|
+
experiment_result = await run_experiment.arun(dataset)
|
|
72
|
+
print("Experiment_result: ", experiment_result)
|
|
73
|
+
|
|
74
|
+
|
|
75
|
+
if __name__ == "__main__":
|
|
76
|
+
import asyncio
|
|
77
|
+
|
|
78
|
+
asyncio.run(main())
|
|
File without changes
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
id,customer_profile,expected_discount,description
|
|
2
|
+
1,"Martha is a 70-year-old retiree who enjoys gardening. She has never enrolled in any academic course recently, has an annual pension of 50,000 dollars, signed up for our service nine years ago and never upgraded to premium.",15,"Senior only"
|
|
3
|
+
2,"Arjun, aged 19, is a full-time computer-science undergraduate. His part-time job brings in about 45,000 dollars per year. He opened his account a year ago and has no premium membership.",15,"Student only"
|
|
4
|
+
3,"Cynthia, a 40-year-old freelance artist, earns roughly 25,000 dollars a year. She is not studying anywhere, subscribed to our basic plan five years back and never upgraded to premium.",20,"Low income only"
|
|
5
|
+
4,"Mr. Ocampo is 68, lives on social security of 20,000 dollars yearly, and joined our platform just two months ago after seeing an advertisement. He is not a student and has no premium status.",35,"Senior, low income, new customer (capped)"
|
|
6
|
+
5,"Hannah is a 24-year-old postgraduate student doing her MBA. She earns about 18,000 dollars via internships, has been a premium member for three and a half years, and signed up thirty-six months ago.",35,"Student, low income, premium 3 yrs (capped)"
|
|
7
|
+
6,"Leonardo is 64, turning 65 next month. His salary is exactly 30,000 dollars. He has maintained a premium subscription for two years and seven months and has been with us for five years.",10,"Premium 2+ yrs only"
|
|
8
|
+
7,"Patricia celebrated her 65th birthday last week. She earns 55,000 dollars annually, bought premium last year so her premium tenure is one year and six months, and she created her account five months ago.",20,"Senior and new customer"
|
|
9
|
+
8,"Gurdeep, age 66, draws a yearly income of 28,000 dollars, has enjoyed a premium subscription for three years and two months, and has been shopping with us for four years.",35,"Senior, low income, premium 3 yrs (capped)"
|
|
10
|
+
9,"Maya, aged 22, is pursuing engineering, joined our service only eight weeks ago, makes around 35,000 dollars per annum, and holds no premium subscription.",20,"Student and new customer"
|
|
11
|
+
10,"Oscar is 30 years old, a software developer making 45,000 dollars a year. He subscribed two years ago, uses only the basic plan, and is not attending any school.",0,"No rules apply"
|