Spaces:
Sleeping
Sleeping
| import asyncio | |
| import dotenv | |
| import os | |
| import pandas as pd | |
| import sys | |
| import typing as t | |
| from dataclasses import dataclass, field | |
| from datetime import datetime | |
| from langchain_openai import ChatOpenAI | |
| from pydantic import BaseModel, Field | |
| from ragas import SingleTurnSample | |
| from ragas.llms.base import LangchainLLMWrapper | |
| from ragas.metrics.base import MetricType | |
| from ragas.metrics.base import MetricWithLLM, SingleTurnMetric | |
| from ragas.prompt.pydantic_prompt import PydanticPrompt | |
| from typing import List, Tuple | |
| # Load environment variables from .env file | |
| dotenv.load_dotenv() | |
| # Access the OpenAI API key | |
| OPENAI_API_KEY = os.getenv("OPENAI_API_KEY") | |
| class ObjectionInput(BaseModel): | |
| user_input: str = Field(description="The objection text") | |
| response: str = Field(default="", description="The response to the objection") | |
| reference: str = Field(default="", description="Any reference related to the objection") | |
| class ObjectionOutput(BaseModel): | |
| satisfy: bool = Field(description="Boolean indicating if the objection was satisfied") | |
| def process_salesbud_file(file_path: str) -> List[Tuple[ObjectionInput, ObjectionOutput]]: | |
| """ | |
| Process the salesbud CSV file and return a list of examples for ObjectionlPrompt. | |
| Args: | |
| file_path (str): The path to the salesbud CSV file. | |
| Returns: | |
| List[Tuple[ObjectionInput, ObjectionOutput]]: A list of tuples containing ObjectionInput and ObjectionOutput. | |
| """ | |
| # Print the timestamp and the file being processed | |
| print(f"{datetime.now()}: Processing file: salesbud_examples.csv") | |
| # Read the CSV file into a DataFrame | |
| df = pd.read_csv('data/salesbud_examples.csv') | |
| # List to hold the processed objections | |
| examples = [] # List to hold examples | |
| # Process each row in the DataFrame | |
| for index, row in df.iterrows(): | |
| # Create an ObjectionInput instance for each row | |
| objection_input = ObjectionInput( | |
| user_input=row['objection'], # Assuming your CSV has a column named 'objection' | |
| response=row.get('response', ""), # Use .get() to avoid KeyError if the column doesn't exist | |
| reference=row.get('reference', "") # Use .get() to avoid KeyError if the column doesn't exist | |
| ) | |
| # Create an ObjectionOutput instance (you can modify the logic for 'satisfy' as needed) | |
| objection_output = ObjectionOutput( | |
| satisfy= row['satisfy'] | |
| ) | |
| # Append the example tuple to the examples list | |
| examples.append((objection_input, objection_output)) | |
| #print (examples[0]) | |
| return examples | |
| class ObjectionlPrompt(PydanticPrompt[ObjectionInput, ObjectionOutput]): | |
| instruction = "You are an expert technology sales rep that is tasked with judging if response satisfies potential customer's objection (user input). \ | |
| Given an user input and sales rep response, output True if the response satisfies the objection by the potential customer" | |
| input_model = ObjectionInput | |
| output_model = ObjectionOutput | |
| examples = process_salesbud_file('salesbud_examples.csv') | |
| class SatisfyRate(MetricWithLLM, SingleTurnMetric): | |
| name: str = "satisfy_rate" | |
| _required_columns: t.Dict[MetricType, t.Set[str]] = field( | |
| default_factory=lambda: {MetricType.SINGLE_TURN: {"response", "reference"}} | |
| ) | |
| objection_prompt: PydanticPrompt = ObjectionlPrompt() | |
| async def _ascore(self, row): | |
| pass | |
| async def _single_turn_ascore(self, sample, callbacks): | |
| prompt_input = ObjectionInput( | |
| user_input=sample.user_input, response=sample.response | |
| ) | |
| prompt_response = await self.objection_prompt.generate( | |
| data=prompt_input, llm=self.llm | |
| ) | |
| print("prompt_response") | |
| print(prompt_response) | |
| return int(prompt_response.satisfy) | |
| async def generate_objection_score(question_answer): | |
| print("generate_objection_scores()") | |
| # user_response= pd.read_csv(file_path) | |
| openai_model = LangchainLLMWrapper(ChatOpenAI(model_name="gpt-4o", api_key=OPENAI_API_KEY)) | |
| scorer = SatisfyRate(llm=openai_model) | |
| sample = SingleTurnSample(user_input=question_answer['objection'], response=question_answer['answer']) | |
| #(user_response['objection'][num], user_response['response'][num]) | |
| satisfy_0_1 = await scorer.single_turn_ascore(sample) | |
| print(satisfy_0_1) | |
| print (question_answer['objection'], question_answer['answer'], satisfy_0_1) | |
| # Implement your logic to generate a response based on the user's input | |
| return satisfy_0_1 #f"Response to your objection: {user_response['objection'][num]}, {user_response['response'][num]}, {satisfy_0_1}" | |
| async def generate_response_to_objection(file_path, num): | |
| from langchain_openai import ChatOpenAI | |
| from ragas.llms.base import LangchainLLMWrapper | |
| import pandas as pd | |
| user_response= pd.read_csv(file_path) | |
| openai_model = LangchainLLMWrapper(ChatOpenAI(model_name="gpt-4o", api_key=OPENAI_API_KEY)) | |
| scorer = SatisfyRate(llm=openai_model) | |
| sample = SingleTurnSample(user_input=user_response['objection'][num], response=user_response['response'][num]) | |
| #(user_response['objection'][num], user_response['response'][num]) | |
| satisfy_0_1 = await scorer.single_turn_ascore(sample) | |
| print (user_response['objection'][num], user_response['response'][num], satisfy_0_1) | |
| # Implement your logic to generate a response based on the user's input | |
| return satisfy_0_1 #f"Response to your objection: {user_response['objection'][num]}, {user_response['response'][num]}, {satisfy_0_1}" | |
| async def main(file_path): | |
| # Call the async function | |
| #examples_file = process_salesbud_file() | |
| response = await generate_response_to_objection(file_path, 0) | |
| if __name__ == "__main__": | |
| # Check if the file path is provided as a command-line argument | |
| if len(sys.argv) != 2: | |
| print("Usage: python objection_eval.py <path_to_salesbud.csv>") | |
| sys.exit(1) | |
| # Get the file path from the command-line argument | |
| file_path = sys.argv[1] | |
| # Run the main async function | |
| asyncio.run(main(file_path)) |