jinysun commited on
Commit
dbf3154
·
verified ·
1 Parent(s): 9bacd4f

Upload 6 files

Browse files
rmrkl/__init__.py ADDED
@@ -0,0 +1,3 @@
 
 
 
 
1
+ from .version import __version__
2
+ from .agent import ChatZeroShotAgent
3
+ from .executor import RetryAgentExecutor
rmrkl/agent.py ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from __future__ import annotations
2
+ from langchain.chat_models.base import BaseChatModel
3
+ from langchain.prompts import PromptTemplate
4
+ from langchain.chains import LLMChain
5
+ from langchain.callbacks.base import BaseCallbackManager
6
+ from .prompts import FORMAT_INSTRUCTIONS, SUFFIX, QUESTION_PROMPT, PREFIX
7
+ from langchain.agents.agent import Agent, AgentOutputParser
8
+ from typing import Any, Optional, Sequence
9
+ from langchain.tools import BaseTool
10
+ from langchain.agents.mrkl.base import ZeroShotAgent
11
+ from langchain.prompts.chat import (
12
+ ChatPromptTemplate,
13
+ SystemMessagePromptTemplate,
14
+ HumanMessagePromptTemplate,
15
+ AIMessagePromptTemplate,
16
+ )
17
+ from .output_parser import ChatZeroShotOutputParser
18
+
19
+
20
+ class ChatZeroShotAgent(ZeroShotAgent):
21
+ """Agent for the MRKL chain."""
22
+
23
+ @classmethod
24
+ def create_prompt(
25
+ cls,
26
+ tools: Sequence[BaseTool],
27
+ prefix: str = PREFIX,
28
+ suffix: str = SUFFIX,
29
+ format_instructions: str = FORMAT_INSTRUCTIONS,
30
+ question_prompt: str = QUESTION_PROMPT,
31
+ ) -> PromptTemplate:
32
+ """Create prompt in the style of the zero shot agent.
33
+
34
+ Args:
35
+ tools: List of tools the agent will have access to, used to format the
36
+ prompt.
37
+ prefix: String to put before the list of tools.
38
+ suffix: String to put after the list of tools.
39
+ input_variables: List of input variables the final prompt will expect.
40
+
41
+ Returns:
42
+ A PromptTemplate with the template assembled from the pieces here.
43
+ """
44
+ tool_strings = "\n".join(
45
+ [f" {tool.name}: {tool.description}" for tool in tools]
46
+ )
47
+ tool_names = ", ".join([tool.name for tool in tools])
48
+ format_instructions = format_instructions.format(
49
+ tool_names=tool_names, tool_strings=tool_strings
50
+ )
51
+ human_prompt = PromptTemplate(
52
+ template=question_prompt,
53
+ input_variables=["input"],
54
+ partial_variables={"tool_strings": tool_strings},
55
+ )
56
+ human_message_prompt = HumanMessagePromptTemplate(prompt=human_prompt)
57
+ ai_message_prompt = AIMessagePromptTemplate.from_template(suffix)
58
+ system_message_prompt = SystemMessagePromptTemplate.from_template(
59
+ '\n\n'.join(
60
+ [
61
+ prefix,
62
+ format_instructions
63
+ ]
64
+ )
65
+ )
66
+ # ignore suffix
67
+ return ChatPromptTemplate.from_messages(
68
+ [system_message_prompt, human_message_prompt, ai_message_prompt]
69
+ )
70
+
71
+ @classmethod
72
+ def from_llm_and_tools(
73
+ cls,
74
+ llm: BaseChatModel,
75
+ tools: Sequence[BaseTool],
76
+ callback_manager: Optional[BaseCallbackManager] = None,
77
+ output_parser: Optional[AgentOutputParser] = ChatZeroShotOutputParser(),
78
+ prefix: str = PREFIX,
79
+ suffix: str = SUFFIX,
80
+ format_instructions: str = FORMAT_INSTRUCTIONS,
81
+ question_prompt: str = QUESTION_PROMPT,
82
+ **kwargs: Any,
83
+ ) -> Agent:
84
+ """Construct an agent from an LLM and tools."""
85
+ cls._validate_tools(tools)
86
+ prompt = cls.create_prompt(
87
+ tools,
88
+ prefix=prefix,
89
+ suffix=suffix,
90
+ format_instructions=format_instructions,
91
+ question_prompt=question_prompt,
92
+ )
93
+ llm_chain = LLMChain(
94
+ llm=llm,
95
+ prompt=prompt,
96
+ callback_manager=callback_manager,
97
+ )
98
+ tool_names = [tool.name for tool in tools]
99
+ _output_parser = output_parser or cls._get_default_output_parser()
100
+ return cls(
101
+ llm_chain=llm_chain,
102
+ allowed_tools=tool_names,
103
+ output_parser=_output_parser,
104
+ **kwargs,
105
+ )
rmrkl/executor.py ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from typing import Dict, List, Tuple, Union, Optional
2
+
3
+ from langchain.agents import AgentExecutor
4
+ from langchain.schema import AgentAction, AgentFinish, OutputParserException
5
+ from langchain.tools import BaseTool
6
+ from langchain.callbacks.manager import CallbackManagerForChainRun
7
+
8
+
9
+ class ExceptionTool(BaseTool):
10
+ name: str = "_Exception"
11
+ description: str = "Exception tool"
12
+
13
+ def _run(self, query: str) :
14
+ return query
15
+
16
+ async def _arun(self, query: str) :
17
+ return query
18
+
19
+
20
+ class RetryAgentExecutor(AgentExecutor):
21
+ """Agent executor that retries on output parser exceptions."""
22
+ # for backwards compatibility
23
+ handle_parsing_errors: bool = True
rmrkl/output_parser.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ import re
2
+ from typing import Any, Dict, List, Optional, Sequence, Tuple, Union
3
+
4
+ import langchain
5
+ from langchain import LLMChain
6
+ from langchain.agents.agent import AgentOutputParser
7
+ from langchain.schema import AgentAction, AgentFinish, OutputParserException
8
+
9
+ from .prompts import (FINAL_ANSWER_ACTION, FORMAT_INSTRUCTIONS,
10
+ QUESTION_PROMPT, SUFFIX)
11
+
12
+
13
+ class ChatZeroShotOutputParser(AgentOutputParser):
14
+ def get_format_instructions(self) -> str:
15
+ return FORMAT_INSTRUCTIONS
16
+
17
+ def parse(self, text: str) -> Union[AgentAction, AgentFinish]:
18
+ if FINAL_ANSWER_ACTION in text:
19
+ return AgentFinish(
20
+ {"output": text.split(FINAL_ANSWER_ACTION)[-1].strip()}, text
21
+ )
22
+
23
+
24
+ # Remove 'Thought' SUFFIX
25
+ if text.startswith('Thought:'):
26
+ text = text[8:]
27
+
28
+ # \s matches against tab/newline/whitespace
29
+ regex = (
30
+ r"Action\s*\d*\s*:[\s]*(.*?)[\s]*Action\s*\d*\s*Input\s*\d*\s*:[\s]*(.*)"
31
+ )
32
+ match = re.search(regex, text, re.DOTALL)
33
+ if not match:
34
+ raise OutputParserException(f"Could not parse LLM output: `{text}`")
35
+ action = match.group(1).strip()
36
+ action_input = match.group(2)
37
+ return AgentAction(action, action_input.strip(" ").strip('"'), text.strip())
rmrkl/prompts.py ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ # flake8: noqa
2
+
3
+ PREFIX = """
4
+ You are an AI system called TeLLAgent and your task is to respond to the question or
5
+ solve the problem to the best of your ability using the provided tools.
6
+
7
+ """
8
+
9
+ FORMAT_INSTRUCTIONS = """
10
+ You should only respond with a single complete
11
+ Thought, Action, Action Input format
12
+ OR a single Final Answer format.
13
+
14
+ Complete Format:
15
+
16
+ Thought: (reflect on your progress and decide what to do next)
17
+ Action: (the action name, should be one of [{tool_names}])
18
+ Action Input: (the input string to the action)
19
+
20
+ OR
21
+
22
+ Final Answer: (the final answer to the original input question)
23
+
24
+ """
25
+ QUESTION_PROMPT = """
26
+ Answer the question below using the following tools:
27
+ Note: Direct output the results when using the following tools:Imageanalysis, codewriter, pdfreader, rag without further processing.
28
+
29
+ {tool_strings}
30
+
31
+ Question: {input}
32
+ """
33
+ SUFFIX = """
34
+ Direct output the results when using Imageanalysis, codewriter, pdfreader, rag tools without further processing.
35
+ Thought: {agent_scratchpad}
36
+ """
37
+ FINAL_ANSWER_ACTION = "Final Answer:"
rmrkl/version.py ADDED
@@ -0,0 +1 @@
 
 
1
+ __version__ = "0.0.3"