|
|
(4 intermediate revisions by the same user not shown) |
Line 1: |
Line 1: |
| import re
| | Kotoba |
| from langchain_core.pydantic_v1 import BaseModel, Field
| |
| from typing import Dict
| |
| from langchain.output_parsers import RegexParser
| |
| from langchain_core.prompts import ChatPromptTemplate
| |
| from langchain_core.prompts.prompt import PromptTemplate
| |
| from langchain import hub
| |
| | |
| promptConf = """You are an agent designed to answer questions. You are give a context delimited by triple backticks.
| |
| Don't give information not mentioned in the context. If you don't know the answer just say I don't know.
| |
| In additon to the answer provide the reason. The reason should be explanation why you think this answer is correct. Use context to generate reason. You may also revise the original input if you think that revising it may ultimately lead to a better response.
| |
| It should always be formatted like this:
| |
| Answer: string with answer
| |
| Confidence: number from 0 to 1
| |
| Reason: string with reason
| |
| ```
| |
| {context}
| |
| ```
| |
| | |
| Question: {question}
| |
| Answer:
| |
| Confidence:
| |
| Reason:
| |
| """
| |
| | |
| simple_extraction_temp = """
| |
| Based on the following context, answer the user's query:
| |
| <context>
| |
| {table}
| |
| </context>
| |
| <question>
| |
| {question}
| |
| </question>
| |
| Let's think step by step:
| |
| """
| |
| simple_extraction_prompt = ChatPromptTemplate.from_template(simple_extraction_temp)
| |
| | |
| complex_extraction_temp = """
| |
| From the table below, extract the data related to the user's question in a way that is easy to interpret.
| |
| Take a look on following examples:
| |
| Example1:
| |
| <question>
| |
| what year is it today?
| |
| </question>
| |
| Assistant: Today's year: 2024
| |
| Example2:
| |
| <question>
| |
| what are the continents in the world and the largest country?
| |
| </question>
| |
| Assistant: Continents in the world: Asia, Africa, North America, South America, Antarctica, Europe, Australia.
| |
| Largest country in the world: Russia
| |
| | |
| Based on the following context and user's question, extract relevant data:
| |
| <context>
| |
| {table}
| |
| </context>
| |
| Provide easy to interpret answer for following question:
| |
| <question>
| |
| {decomp_dict}
| |
| </question>
| |
| """
| |
| complex_extraction_prompt = ChatPromptTemplate.from_template(complex_extraction_temp)
| |
| | |
| simple_or_complex_temp = """
| |
| Classify whether question is simple or complex. Do NOT explain.
| |
| You will be given a table and a question about that table. \
| |
| Say 'simple' if question only requires extracting data from a table \
| |
| Say 'complex' if question requires additional operations, for example calculating the sum \
| |
| | |
| example1:
| |
| question: 'what is the square root of all numbers in the table?'
| |
| Assistant: complex
| |
| | |
| table: {table}
| |
| question: {question}
| |
| Assistant:
| |
| """
| |
| simple_or_complex_prompt = ChatPromptTemplate.from_template(simple_or_complex_temp)
| |
| | |
| decomp_temp = """
| |
| Question is too complex to be answered at once as it requires additional operations, for example calculating the sum \
| |
| Decompose the question by breaking it into two following parts: \
| |
| 'extraction' - concerns the data that should be extracted \
| |
| 'operation' - concerns what operations on this data should be performed to obtain the result.
| |
| | |
| Output must be structured as following example:
| |
| | |
| Example:
| |
| question: 'what is the square root of all numbers in the table?'
| |
| decomposed: {{'extraction':'exctract all numbers from the table', 'operation':'what is the square root of all numbers?'}}
| |
| | |
| Provide structured answer as a dictionary for following question:
| |
| question: {question}
| |
| decomposed:
| |
| """
| |
| decomp_prompt = ChatPromptTemplate.from_template(decomp_temp)
| |
| | |
| base_prompt = hub.pull("langchain-ai/react-agent-template")
| |
| instructions = """You are an agent designed to solve complex problems \
| |
| You will receive a question and information about data \
| |
| You have access to a python REPL, which you can use to execute python code. \
| |
| If you get an error, debug your code and try again \
| |
| You are allowed to debug your code only 2 times \
| |
| Let's think step by step:
| |
| """
| |
| agent_prompt = base_prompt.partial(instructions=instructions)
| |
| | |
| answer_temp = """
| |
| Always answer a question with a list in the following format, if you don't know the answer return: []
| |
| Example1:
| |
| <question>
| |
| what year is it today?
| |
| </question>
| |
| Assistant: [2024]
| |
| Example2:
| |
| <question>
| |
| what are the continents in the world?
| |
| </question>
| |
| Assistant: ["Asia, Africa, North America, South America, Antarctica, Europe, Australia"]
| |
| | |
| Based on the following context, answer the user's query:
| |
| <context>
| |
| {response}
| |
| </context>
| |
| Provide structured answer as a list of items for following question:
| |
| <question>
| |
| {question}
| |
| </question>
| |
| """
| |
| answer_prompt = ChatPromptTemplate.from_template(answer_temp)
| |
| | |
| template = """
| |
| Do NOT answer the question!
| |
| Based on below previous conversation history, generate question with all necessary context to answer that question.
| |
| If there are no relevant information in the previous conversation just return the question itself.
| |
| Example1:
| |
| Question: What is the sum of all numbers in the table?
| |
| Assistant: What is the sum of all numbers in the table?
| |
| | |
| Example2:
| |
| Current conversation:
| |
| So the extracted numbers are 1 and 2.
| |
| Question: What is the sum?
| |
| Assistant: What is the sum of 1 and 2?
| |
| | |
| Begin!
| |
| Current conversation:
| |
| {chat_history}
| |
| | |
| Question: {input}
| |
| AI Assistant:"""
| |
| | |
| PROMPT = PromptTemplate(input_variables=["chat_history","input"], template=template)
| |
| | |
| prompt_temp = """
| |
| Based on the following context, answer the user's query:
| |
| <context>
| |
| {context}
| |
| </context>
| |
| Previous conversation:
| |
| {chat_history}
| |
| <question>
| |
| {human_input}
| |
| </question>
| |
| Let's think step by step:
| |
| """
| |
| | |
| prompt_model_v3 = PromptTemplate(
| |
| input_variables=["chat_history", "human_input", "context"], template=prompt_temp
| |
| )
| |
| | |
| | |
| class AnswerDict(BaseModel):
| |
| answer: str = Field()
| |
| confidence: float = Field()
| |
| reason: str = Field()
| |
| | |
| class RegexParserConf(RegexParser):
| |
| def parse(self, text:str) -> Dict[str,str]:
| |
| """parse llm output"""
| |
| matchF = re.search(self.regex, text, flags=re.IGNORECASE | re.MULTILINE | re.DOTALL)
| |
| if matchF:
| |
| return {key: matchF.group(i + 1) for i, key in enumerate(self.output_keys)}
| |
| else:
| |
| if self.default_output_key is None:
| |
| raise ValueError(f"could not parse output: {text}")
| |
| else:
| |
| return {
| |
| key: text if key == self.default_output_key else ""
| |
| for key in self.output_keys
| |
| }
| |
| | |
| parserS = RegexParserConf(regex=r"Answer:\s*(?P<Answer>.*)\s*Confidence:\s*(?P<Confidence>.*)\s*Reason:\s*(?P<Reason>.*)",output_keys=["answer","confidence","reason"])
| |
| yesNo = re.compile(r'^\s*(yes|no).*',flags=re.IGNORECASE)
| |
| yesRe = re.compile(r'^\s*(yes).*',flags=re.IGNORECASE)
| |