File size: 3,439 Bytes
03f1c64
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
from modules.base.llm_chain_config import LLMChainConfig
from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
from modules.knowledge_retrieval.base import KnowledgeDomain
from loguru import logger
from langchain import PromptTemplate, LLMChain
from langchain.llms.openai import OpenAI
from typing import Callable
import pprint 

class FamilyDomain(KnowledgeDomain):
    """
    FamilyDomain Class

    Design:
    This class is a specific implementation of the KnowledgeDomain class, providing an 
    implementation for generating responses to family-related questions. Following the 
    Single Responsibility Principle (SRP), its sole responsibility is to generate family-related responses.

    Intended Implementation:
    The generate_response method should generate useful responses to family-related questions. 
    This might involve rule-based logic or a trained machine learning model, depending on the 
    specifics of the problem domain.
    """
    def generate_response(self, question: str) -> str:
        template_cot = """You are asked a family-related question and rather than simply guessing the right answer break down the solution into a series of steps
        The question is {question}

        Write out your step by step reasoning and after considering all of the facts and applying this reasoning write out your final answer
        """
        prompt = PromptTemplate(template=template_cot, input_variables=["question"])
        llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0.7, max_tokens=1500))  # assuming OpenAI is the LLM to be used
        response_cot = llm_chain.run(question)
        return response_cot


class FamilyChain(DestinationChainStrategy):
    """
    FamilyChain Class

    Design:
    This class is a specific implementation of the ChainStrategy class.
    It follows the Open/Closed Principle (OCP) because it extends the ChainStrategy class 
    without modifying its behavior. It also adheres to the Dependency Inversion Principle (DIP) as it 
    depends on the abstraction (FamilyDomain) rather than a concrete class.

    Intended Implementation:
    The FamilyChain class serves as a wrapper around a FamilyDomain instance. It implements the run 
    method from the ChainStrategy class, which simply calls the generate_response method of the FamilyDomain.
    As such, when the run method is called with a question as input, the FamilyChain class will return a 
    response generated by the FamilyDomain.
    """
    def __init__(self, config: LLMChainConfig, display: Callable):
        super().__init__(config=config, display=display, knowledge_domain=FamilyDomain(), usage=config.usage)
        print("Creating Family Chain with config: ")
        pprint.pprint(vars(config))

    def run(self, question):
        print('Using Family Chain of Thought')
        self.display("Using 'Family Chain of Thought'")
        response_cot = super().run(question)
        return response_cot

def get_family_chain_config(temperature: float = 0.7) -> LLMChainConfig:
    usage = """
    This problem is family-related and the solution may be obtained by focusing on generating a coherent series 
    of reasoning steps that lead to the final answer. The problem is related to family plans, personal matters, family relations, and general non business related questions.
    """
    return LLMChainConfig(usage=usage, temperature=temperature)