jpfearnworks commited on
Commit
03f1c64
1 Parent(s): 9d0c72d

Add knowledge domain router

Browse files
README.MD CHANGED
@@ -13,6 +13,12 @@ Strategies for jupyter, gradio, and react will be prioritized in general at this
13
  General problem solving requiring reasoned processing. Utilizing tree of thoughts, chain of thought, and reAct. Current prompts heavily inspired by
14
  work from https://github.com/mrspiggot
15
 
 
 
 
 
 
 
16
  ### Generative Image Prompting Patterns
17
 
18
  Coming soon
 
13
  General problem solving requiring reasoned processing. Utilizing tree of thoughts, chain of thought, and reAct. Current prompts heavily inspired by
14
  work from https://github.com/mrspiggot
15
 
16
+ ### Knowledge Domains
17
+
18
+ Example of knowledge domain retrieval. Given a question the router determines the best knowledge domain chain to use and then calls that chain to handle the response.
19
+
20
+ Includes examples of queries that will return each of the four implemented domains.
21
+
22
  ### Generative Image Prompting Patterns
23
 
24
  Coming soon
modules/{domains → base}/__init__.py RENAMED
File without changes
modules/base/chain.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from loguru import logger
2
+ from pydantic import BaseModel
3
+
4
+ class IChain(BaseModel):
5
+ """
6
+ IChain Class (Interface for Chain)
7
+
8
+ Design:
9
+ This class is an interface that defines the basic structure for a chain class. It's not intended to be
10
+ instantiated directly, but should be extended by other classes that implement the run method. This follows
11
+ the Interface Segregation Principle (ISP), as it provides a simple, specific interface for chain classes.
12
+
13
+ Intended Implementation:
14
+ Classes that extend IChain should provide an implementation for the run method. The run method should take
15
+ a string input and return a string output. The specifics of what the run method does will depend on the
16
+ requirements of the subclass.
17
+ """
18
+ def run(self, input: str) -> str:
19
+ logger.info("Running IChain with input: {}", input)
20
+ pass
21
+
modules/base/llm_chain_config.py ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from langchain.llms.base import BaseLLM
3
+ from langchain.llms import OpenAI
4
+ from typing import Type
5
+
6
+ class LLMChainConfig(BaseModel):
7
+ """
8
+ A configuration class for the chain strategy.
9
+
10
+ Attributes:
11
+ temperature (float): The temperature parameter for the language model.
12
+ max_tokens (int): The maximum number of tokens to generate.
13
+ llm_class (Type[BaseLLM]): The language model class to use for reasoning.
14
+ usage (str): String describing when it is appropriate to use this chain strategy.
15
+ """
16
+ temperature: float = 0.7
17
+ max_tokens: int = 1500
18
+ llm_class: Type[BaseLLM] = OpenAI # Overrideable default
19
+ usage: str
modules/knowledge_retrieval/__init__.py ADDED
File without changes
modules/knowledge_retrieval/base/__init__.py ADDED
@@ -0,0 +1,2 @@
 
 
 
1
+ from modules.knowledge_retrieval.base.router_chain import RouterChain
2
+ from modules.knowledge_retrieval.base.knowledge_domain import KnowledgeDomain
modules/knowledge_retrieval/base/knowledge_domain.py ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from pydantic import BaseModel
2
+ from loguru import logger
3
+
4
+ class KnowledgeDomain(BaseModel):
5
+ """
6
+ KnowledgeDomain Class
7
+
8
+ Design:
9
+ This class acts as a base for knowledge domain classes. It's not intended to be instantiated directly,
10
+ but should be extended by other classes that provide a specific implementation for the generate_response method.
11
+ This adheres to the Open/Closed Principle (OCP) and Liskov Substitution Principle (LSP) by providing a base
12
+ class that can be extended without modification.
13
+
14
+ Intended Implementation:
15
+ Classes that extend KnowledgeDomain should provide an implementation for the generate_response method.
16
+ The generate_response method should take a question string as input and return a response string. The
17
+ specifics of how the response is generated will depend on the requirements of the subclass.
18
+ """
19
+ def generate_response(self, question: str) -> str:
20
+ logger.info("Generating response for question: {}", question)
21
+ pass
modules/knowledge_retrieval/base/router_chain.py ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.chain import IChain
2
+ from typing import Dict , Any, Callable
3
+ import os
4
+
5
+ class RouterChain(IChain):
6
+ """
7
+ RouterChain Class
8
+
9
+ Design:
10
+ The RouterChain class extends the IChain interface and provides an implementation for the run
11
+ method. It also introduces a new method, add_chain, for adding destination chains. The class adheres
12
+ to the Open/Closed Principle (OCP) as it can be extended without modifying its behavior.
13
+
14
+ Intended Implementation:
15
+ The RouterChain class serves as a router that selects the appropriate DestinationChain based on
16
+ the input. The selection logic should be implemented in the run method. The add_chain method
17
+ allows new DestinationChain instances to be added to the RouterChain.
18
+ """
19
+ template : str
20
+ destination_chains: Dict[int, IChain]
21
+ display: Callable = print
22
+ question: str
23
+ usage: str
24
+ llm: Any
25
+ api_key: str = os.environ.get('OPENAI_API_KEY')
26
+
27
+ def add_chain(self, domain: str, chain: IChain) -> None:
28
+ self.destination_chains[domain] = chain
29
+
30
+ def run(self, input: str) -> str:
31
+ # Implement the logic to select the appropriate DestinationChain
32
+ pass
modules/knowledge_retrieval/component.py ADDED
@@ -0,0 +1,26 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.knowledge_retrieval.knowledge_router import KnowledgeDomainRouter, get_knowledge_domain_router_config
2
+ import gradio as gr
3
+ import os
4
+ openai_api_key = os.getenv("OPENAI_API_KEY")
5
+
6
+ def determine_and_execute(question: str, temperature: float):
7
+ config = get_knowledge_domain_router_config(temperature=temperature)
8
+ config.temperature = temperature
9
+ determiner = KnowledgeDomainRouter(api_key=openai_api_key, config=config, question=question, display=print)
10
+ determine_output, execute_output = determiner.determine_and_execute(question=question)
11
+ return determine_output, execute_output
12
+
13
+ examples = [["""When is my grandmothers birthday?""", 0.6], ["What was my tax burden last year?", 0.6 ], ["What is the most recent magic the gathering card set released?", 0.6], ["What products are the most popular with my small business customers?", 0.6]]
14
+
15
+ def create_knowledge_router_ui(cache_examples=False):
16
+ with gr.Row():
17
+ question = gr.Textbox(label="Enter your question here:")
18
+ temperature = gr.Slider(minimum=0, maximum=2, default=.7, label="Temperature")
19
+ with gr.Column():
20
+ reasoning_strategy = gr.Textbox(label="Reasoning Strategy")
21
+ reasoning = gr.Textbox(label="Reasoning")
22
+
23
+ generate_button = gr.Button(label="Generate")
24
+ generate_button.click(determine_and_execute, outputs=[reasoning_strategy, reasoning], inputs=[question, temperature])
25
+ gr.Examples(examples=examples, fn=determine_and_execute, cache_examples=cache_examples, inputs=[question, temperature], outputs=[reasoning_strategy, reasoning])
26
+
modules/knowledge_retrieval/destination_chain.py ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.chain import IChain
2
+ from modules.base.llm_chain_config import LLMChainConfig
3
+ from modules.knowledge_retrieval.base.knowledge_domain import KnowledgeDomain
4
+ from typing import Dict , Any, Callable
5
+ import os
6
+
7
+ class DestinationChain(IChain):
8
+ """
9
+ DestinationChain Class
10
+
11
+ Design:
12
+ The DestinationChain class extends the IChain interface and provides an implementation for the
13
+ run method. It follows the Liskov Substitution Principle (LSP) as it can be used wherever IChain
14
+ is expected. The class also adheres to the Dependency Inversion Principle (DIP) as it depends on
15
+ the abstraction (KnowledgeDomain) rather than a concrete class.
16
+
17
+ Intended Implementation:
18
+ The DestinationChain class serves as a wrapper around a KnowledgeDomain instance. It implements
19
+ the run method from the IChain interface, which simply calls the generate_response method of the
20
+ KnowledgeDomain. As such, when the run method is called with a question as input, the
21
+ DestinationChain class will return a response generated by the KnowledgeDomain.
22
+ """
23
+ knowledge_domain: KnowledgeDomain
24
+ api_key: str = os.environ.get('OPENAI_API_KEY')
25
+ llm: Any
26
+ display: Callable
27
+ usage: str
28
+
29
+ def run(self, input: str) -> str:
30
+ return self.knowledge_domain.generate_response(input)
31
+
32
+ class DestinationChainStrategy(DestinationChain):
33
+ """Base class for Chain Strategies"""
34
+
35
+ def __init__(self, config: LLMChainConfig, display: Callable, knowledge_domain: KnowledgeDomain, usage: str):
36
+ super().__init__(knowledge_domain=knowledge_domain, llm=config.llm_class, display=display, usage=usage)
37
+ self.llm = config.llm_class(temperature=config.temperature, max_tokens=config.max_tokens)
38
+
39
+ self.usage = config.usage
40
+
41
+ def run(self, question):
42
+ response = self.knowledge_domain.generate_response(question)
43
+ self.display(response)
44
+ return response
45
+
46
+
47
+ def get_chain_config(temperature: float = 0.7) -> LLMChainConfig:
48
+ usage = "This is the default chain model that should only be used as a last resort"
49
+ return LLMChainConfig(usage=usage)
modules/knowledge_retrieval/domains/__init__.py ADDED
File without changes
modules/knowledge_retrieval/domains/business_domain.py ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.llm_chain_config import LLMChainConfig
2
+ from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
3
+ from modules.knowledge_retrieval.base import KnowledgeDomain
4
+ from loguru import logger
5
+ from langchain import PromptTemplate, LLMChain
6
+ from langchain.llms.openai import OpenAI
7
+ from typing import Callable
8
+ import pprint
9
+
10
+
11
+ class BusinessDomain(KnowledgeDomain):
12
+ """
13
+ BusinessDomain Class
14
+
15
+ Design:
16
+ This class extends the KnowledgeDomain class following the Open/Closed Principle (OCP)
17
+ and provides a specific implementation for generating responses to business-related questions.
18
+ Its single responsibility, as per the Single Responsibility Principle (SRP), is to generate
19
+ business-related responses.
20
+
21
+ Intended Implementation:
22
+ The generate_response method should be able to generate accurate and helpful responses to
23
+ business-related questions. The logic for generating these responses could be rule-based,
24
+ or it could use a trained machine learning model.
25
+ """
26
+ def generate_response(self, question: str) -> str:
27
+ template_cot = """You are asked a business-related question and rather than simply guessing the right answer break down the solution into a series of steps
28
+ The question is {question}
29
+
30
+ Write out your step by step reasoning and after considering all of the facts and applying this reasoning write out your final answer
31
+ """
32
+ prompt = PromptTemplate(template=template_cot, input_variables=["question"])
33
+ llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0.7, max_tokens=1500)) # assuming OpenAI is the LLM to be used
34
+ response_cot = llm_chain.run(question)
35
+ return response_cot
36
+
37
+
38
+ class BusinessChain(DestinationChainStrategy):
39
+ """
40
+ BusinessChain Class
41
+
42
+ Design:
43
+ This class is a specific implementation of the ChainStrategy class.
44
+ It follows the Open/Closed Principle (OCP) because it extends the ChainStrategy class
45
+ without modifying its behavior. It also adheres to the Dependency Inversion Principle (DIP) as it
46
+ depends on the abstraction (BusinessDomain) rather than a concrete class.
47
+
48
+ Intended Implementation:
49
+ The BusinessChain class serves as a wrapper around a BusinessDomain instance. It implements the run
50
+ method from the ChainStrategy class, which simply calls the generate_response method of the BusinessDomain.
51
+ As such, when the run method is called with a question as input, the BusinessChain class will return a
52
+ response generated by the BusinessDomain. This response will be business-related, as the BusinessDomain is
53
+ designed to generate responses to business-related questions.
54
+ """
55
+ def __init__(self, config: LLMChainConfig, display: Callable):
56
+ super().__init__(config=config, display=display, knowledge_domain=BusinessDomain(), usage=config.usage)
57
+ print("Creating Business Chain with config: ")
58
+ pprint.pprint(vars(config))
59
+
60
+ def run(self, question):
61
+ print('Using Business Chain of Thought')
62
+ self.display("Using 'Business Chain of Thought'")
63
+ response_cot = super().run(question)
64
+ return response_cot
65
+
66
+ def get_business_chain_config(temperature: float = 0.7) -> LLMChainConfig:
67
+ usage = """
68
+ This problem is business-related and requires a business-related response or business data. In general this should be items related to the small family business.
69
+ """
70
+ return LLMChainConfig(usage=usage, temperature=temperature)
modules/knowledge_retrieval/domains/family_domain.py ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.llm_chain_config import LLMChainConfig
2
+ from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
3
+ from modules.knowledge_retrieval.base import KnowledgeDomain
4
+ from loguru import logger
5
+ from langchain import PromptTemplate, LLMChain
6
+ from langchain.llms.openai import OpenAI
7
+ from typing import Callable
8
+ import pprint
9
+
10
+ class FamilyDomain(KnowledgeDomain):
11
+ """
12
+ FamilyDomain Class
13
+
14
+ Design:
15
+ This class is a specific implementation of the KnowledgeDomain class, providing an
16
+ implementation for generating responses to family-related questions. Following the
17
+ Single Responsibility Principle (SRP), its sole responsibility is to generate family-related responses.
18
+
19
+ Intended Implementation:
20
+ The generate_response method should generate useful responses to family-related questions.
21
+ This might involve rule-based logic or a trained machine learning model, depending on the
22
+ specifics of the problem domain.
23
+ """
24
+ def generate_response(self, question: str) -> str:
25
+ 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
26
+ The question is {question}
27
+
28
+ Write out your step by step reasoning and after considering all of the facts and applying this reasoning write out your final answer
29
+ """
30
+ prompt = PromptTemplate(template=template_cot, input_variables=["question"])
31
+ llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0.7, max_tokens=1500)) # assuming OpenAI is the LLM to be used
32
+ response_cot = llm_chain.run(question)
33
+ return response_cot
34
+
35
+
36
+ class FamilyChain(DestinationChainStrategy):
37
+ """
38
+ FamilyChain Class
39
+
40
+ Design:
41
+ This class is a specific implementation of the ChainStrategy class.
42
+ It follows the Open/Closed Principle (OCP) because it extends the ChainStrategy class
43
+ without modifying its behavior. It also adheres to the Dependency Inversion Principle (DIP) as it
44
+ depends on the abstraction (FamilyDomain) rather than a concrete class.
45
+
46
+ Intended Implementation:
47
+ The FamilyChain class serves as a wrapper around a FamilyDomain instance. It implements the run
48
+ method from the ChainStrategy class, which simply calls the generate_response method of the FamilyDomain.
49
+ As such, when the run method is called with a question as input, the FamilyChain class will return a
50
+ response generated by the FamilyDomain.
51
+ """
52
+ def __init__(self, config: LLMChainConfig, display: Callable):
53
+ super().__init__(config=config, display=display, knowledge_domain=FamilyDomain(), usage=config.usage)
54
+ print("Creating Family Chain with config: ")
55
+ pprint.pprint(vars(config))
56
+
57
+ def run(self, question):
58
+ print('Using Family Chain of Thought')
59
+ self.display("Using 'Family Chain of Thought'")
60
+ response_cot = super().run(question)
61
+ return response_cot
62
+
63
+ def get_family_chain_config(temperature: float = 0.7) -> LLMChainConfig:
64
+ usage = """
65
+ This problem is family-related and the solution may be obtained by focusing on generating a coherent series
66
+ 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.
67
+ """
68
+ return LLMChainConfig(usage=usage, temperature=temperature)
modules/knowledge_retrieval/domains/finance_domain.py ADDED
@@ -0,0 +1,75 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.llm_chain_config import LLMChainConfig
2
+ from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
3
+ from modules.knowledge_retrieval.base import KnowledgeDomain
4
+ from loguru import logger
5
+ from langchain import PromptTemplate, LLMChain
6
+ from langchain.llms.openai import OpenAI
7
+ from typing import Callable
8
+ import pprint
9
+
10
+ class FinanceDomain(KnowledgeDomain):
11
+ """
12
+ FinanceDomain Class
13
+
14
+ Design:
15
+ This class is a specific implementation of the KnowledgeDomain class. It provides a specific
16
+ implementation for generating responses to finance-related questions. Following the Single
17
+ Responsibility Principle (SRP), its sole responsibility is to generate finance-related responses.
18
+
19
+ Intended Implementation:
20
+ The generate_response method should generate appropriate responses to finance-related questions.
21
+ Depending on the specifics of the problem domain, this could involve a rule-based approach,
22
+ using a trained machine learning model, or some other method of generating responses.
23
+ """
24
+ def generate_response(self, question: str) -> str:
25
+ template_cot = """You are asked a finance-related question and rather than simply guessing the right answer break down the solution into a series of steps
26
+ The question is {question}
27
+
28
+ Write out your step by step reasoning and after considering all of the facts and applying this reasoning write out your final answer
29
+ """
30
+ prompt = PromptTemplate(template=template_cot, input_variables=["question"])
31
+ llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0.7, max_tokens=1500)) # assuming OpenAI is the LLM to be used
32
+ response_cot = llm_chain.run(question)
33
+ return response_cot
34
+
35
+
36
+ class FinanceChain(DestinationChainStrategy):
37
+ """
38
+ FinanceChain Class
39
+
40
+ Design:
41
+ This class is a specific implementation of the ChainStrategy class.
42
+ It follows the Open/Closed Principle (OCP) because it extends the ChainStrategy class
43
+ without modifying its behavior. It also adheres to the Dependency Inversion Principle (DIP) as it
44
+ depends on the abstraction (FinanceDomain) rather than a concrete class.
45
+
46
+ Intended Implementation:
47
+ The FinanceChain class serves as a wrapper around a FinanceDomain instance. It implements the run
48
+ method from the ChainStrategy class, which simply calls the generate_response method of the FinanceDomain.
49
+ As such, when the run method is called with a question as input, the FinanceChain class will return a
50
+ response generated by the FinanceDomain.
51
+ """
52
+ def __init__(self, config: LLMChainConfig, display: Callable):
53
+ super().__init__(config=config, display=display, knowledge_domain=FinanceDomain(), usage=config.usage)
54
+ print("Creating Finance Chain with config: ")
55
+ pprint.pprint(vars(config))
56
+
57
+ def run(self, question):
58
+ print('Using Finance Chain of Thought')
59
+ self.display("Using 'Finance Chain of Thought'")
60
+ response_cot = super().run(question)
61
+ return response_cot
62
+
63
+ def get_finance_chain_config(temperature: float = 0.7) -> LLMChainConfig:
64
+ usage = """
65
+ This problem is finance-related and relates to the following topics:
66
+ - Financial Planning
67
+ - Financial Analysis
68
+ - Financial Management
69
+ - Financial Markets
70
+ - Financial Instruments
71
+ - Financial Services
72
+
73
+ Or things of this nature
74
+ """
75
+ return LLMChainConfig(usage=usage, temperature=temperature)
modules/knowledge_retrieval/domains/gaming_domain.py ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from modules.base.llm_chain_config import LLMChainConfig
2
+ from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
3
+ from modules.knowledge_retrieval.base import KnowledgeDomain
4
+ from loguru import logger
5
+ from langchain import PromptTemplate, LLMChain
6
+ from langchain.llms.openai import OpenAI
7
+ from typing import Callable
8
+ import pprint
9
+
10
+ class GamingDomain(KnowledgeDomain):
11
+ """
12
+ GamingDomain Class
13
+
14
+ Design:
15
+ This class extends the KnowledgeDomain class and provides a specific implementation for
16
+ generating responses to gaming-related questions. It adheres to the Single Responsibility
17
+ Principle (SRP) with its single responsibility of generating gaming-related responses.
18
+
19
+ Intended Implementation:
20
+ The generate_response method should generate appropriate responses to gaming-related questions.
21
+ Depending on the requirements, this could involve a rule-based approach, a trained machine
22
+ learning model, or some other method of generating responses.
23
+ """
24
+ def generate_response(self, question: str) -> str:
25
+ template_cot = """You are asked a gaming-related question and rather than simply guessing the right answer break down the solution into a series of steps
26
+ The question is {question}
27
+
28
+ Write out your step by step reasoning and after considering all of the facts and applying this reasoning write out your final answer
29
+ """
30
+ prompt = PromptTemplate(template=template_cot, input_variables=["question"])
31
+ llm_chain = LLMChain(prompt=prompt, llm=OpenAI(temperature=0.7, max_tokens=1500)) # assuming OpenAI is the LLM to be used
32
+ response_cot = llm_chain.run(question)
33
+ return response_cot
34
+
35
+
36
+ class GamingChain(DestinationChainStrategy):
37
+ """
38
+ GamingChain Class
39
+
40
+ Design:
41
+ This class is a specific implementation of the ChainStrategy class.
42
+ It follows the Open/Closed Principle (OCP) because it extends the ChainStrategy class
43
+ without modifying its behavior. It also adheres to the Dependency Inversion Principle (DIP) as it
44
+ depends on the abstraction (GamingDomain) rather than a concrete class.
45
+
46
+ Intended Implementation:
47
+ The GamingChain class serves as a wrapper around a GamingDomain instance. It implements the run
48
+ method from the ChainStrategy class, which simply calls the generate_response method of the GamingDomain.
49
+ As such, when the run method is called with a question as input, the GamingChain class will return a
50
+ response generated by the GamingDomain.
51
+ """
52
+ def __init__(self, config: LLMChainConfig, display: Callable):
53
+ super().__init__(config=config, display=display, knowledge_domain=GamingDomain(), usage=config.usage)
54
+ print("Creating Gaming Chain with config: ")
55
+ pprint.pprint(vars(config))
56
+
57
+ def run(self, question):
58
+ print('Using Gaming Chain of Thought')
59
+ self.display("Using 'Gaming Chain of Thought'")
60
+ response_cot = super().run(question)
61
+ return response_cot
62
+
63
+ def get_gaming_chain_config(temperature: float = 0.7) -> LLMChainConfig:
64
+ usage = """
65
+ This problem is gaming-related and related to active play and leasure that we engage in. Example topics are :
66
+ - What is the best way to play a game?
67
+ - What games do you like to play?
68
+ - What games have we played together?
69
+ - Gaming scenario generation
70
+ - Gaming Configurations
71
+
72
+ And related items
73
+ """
74
+ return LLMChainConfig(usage=usage, temperature=temperature)
modules/knowledge_retrieval/knowledge_router.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from loguru import logger
2
+ from modules.knowledge_retrieval.domains.business_domain import BusinessChain, get_business_chain_config
3
+ from modules.knowledge_retrieval.domains.family_domain import FamilyChain, get_family_chain_config
4
+ from modules.knowledge_retrieval.domains.gaming_domain import GamingChain, get_gaming_chain_config
5
+ from modules.knowledge_retrieval.domains.finance_domain import FinanceChain, get_finance_chain_config
6
+ from modules.base.llm_chain_config import LLMChainConfig
7
+ from modules.knowledge_retrieval.base.router_chain import RouterChain
8
+ from modules.knowledge_retrieval.destination_chain import DestinationChainStrategy
9
+ from langchain import PromptTemplate, LLMChain
10
+
11
+ import pprint
12
+ from typing import Callable, Dict, Optional, Tuple
13
+ import re
14
+
15
+ class KnowledgeDomainRouter(RouterChain):
16
+ def __init__(self, api_key: str, config: LLMChainConfig, question: str, display: Callable):
17
+ chains : Dict[int, DestinationChainStrategy] = {
18
+ 1: BusinessChain(config=get_business_chain_config(), display=display),
19
+ 2: FamilyChain(config=get_family_chain_config(), display=display),
20
+ 3: GamingChain(config=get_gaming_chain_config(), display=display),
21
+ 4: FinanceChain(config=get_finance_chain_config(), display=display)
22
+ }
23
+
24
+ usage_block = f"""
25
+ 1. {chains[1].usage} [1].
26
+ 2. {chains[2].usage} [2].
27
+ 3. {chains[3].usage} [3].
28
+ 4. {chains[4].usage} [4].
29
+ """
30
+ template = """
31
+ Consider the following problem : {question}. Based on the characteristics of the problem,
32
+ identify the most suitable knowledge domain to query from the items provided. Consider each carefully
33
+ in the context of the question, write out the likelihood of relevant of each, and then select the most
34
+ appropriate knowledge domain:""" + usage_block + """
35
+ Based on the characteristics of the given problem , select the domain that aligns most closely with the nature of the problem. It is important to first provide the number of the technique that best solves the problem, followed by a period. Then you may provide your reason why you have chosen this technique.
36
+
37
+ The number and name of the selected strategy is...
38
+ """
39
+
40
+ super().__init__(template = template, api_key = api_key, destination_chains=chains, usage=config.usage, llm=config.llm_class, question=question)
41
+ print("Creating Knowledge Domain Router with config: ")
42
+ # pprint.pprint(config)
43
+ self.llm = config.llm_class(temperature=config.temperature, max_tokens=config.max_tokens, api_key=api_key)
44
+ self.question: str = question
45
+
46
+ def run(self, question: str) -> str:
47
+
48
+
49
+ for index, chain in self.destination_chains.items():
50
+ print(f'Running Chain #{index}')
51
+ self.display(f"Running Chain #{index}")
52
+ response = chain.run(question)
53
+ print(response)
54
+ self.display(response)
55
+ return response
56
+
57
+
58
+ @staticmethod
59
+ def find_first_integer(text: str) -> Optional[int]:
60
+ match = re.search(r'\d+', text)
61
+ if match:
62
+ return int(match.group())
63
+ else:
64
+ return None
65
+
66
+ def determine_and_execute(self, question) -> Tuple[str, str]:
67
+ prompt = PromptTemplate(template=self.template, input_variables=["question"])
68
+ llm_chain = LLMChain(prompt=prompt, llm=self.llm)
69
+
70
+ response = llm_chain.run(self.question)
71
+ print(response)
72
+ self.display(response)
73
+ n = self.find_first_integer(response)
74
+
75
+ if n in self.destination_chains:
76
+ chain_resp = self.destination_chains[n].run(self.question)
77
+ else:
78
+ chain_resp = (f"Chain number {n} is not recognized.")
79
+ print(chain_resp)
80
+
81
+ return response, chain_resp
82
+
83
+ def get_knowledge_domain_router_config(temperature: float = 0.6) -> LLMChainConfig:
84
+ usage="This router should be used when determining the most effective strategy for a query requiring domain-specific knowledge to derive"
85
+ return LLMChainConfig(temperature=temperature, max_tokens=3000, usage=usage)
requirements.txt CHANGED
@@ -4,4 +4,5 @@ gradio
4
  python-dotenv
5
  openai
6
  wikipedia
7
- ipykernel
 
 
4
  python-dotenv
5
  openai
6
  wikipedia
7
+ ipykernel
8
+ loguru
server.py CHANGED
@@ -2,6 +2,7 @@ from dotenv import load_dotenv, find_dotenv
2
  import os
3
  import gradio as gr
4
  from modules.reasoning.component import create_reasoning_router_ui
 
5
  load_dotenv(find_dotenv())
6
 
7
  openai_api_key = os.getenv("OPENAI_API_KEY")
@@ -15,7 +16,7 @@ def create_interface():
15
  with gr.Tab("Reasoning Router"):
16
  create_reasoning_router_ui()
17
  with gr.Tab("Knowledge Domains"):
18
- gr.Label("Knowledge Domains")
19
  interface.queue()
20
  interface.launch(server_name="0.0.0.0", server_port=7000)
21
 
 
2
  import os
3
  import gradio as gr
4
  from modules.reasoning.component import create_reasoning_router_ui
5
+ from modules.knowledge_retrieval.component import create_knowledge_router_ui
6
  load_dotenv(find_dotenv())
7
 
8
  openai_api_key = os.getenv("OPENAI_API_KEY")
 
16
  with gr.Tab("Reasoning Router"):
17
  create_reasoning_router_ui()
18
  with gr.Tab("Knowledge Domains"):
19
+ create_knowledge_router_ui()
20
  interface.queue()
21
  interface.launch(server_name="0.0.0.0", server_port=7000)
22