Skip to content

Commit ce2523a

Browse files
committed
Dynamic Tools
1 parent c0db838 commit ce2523a

21 files changed

+350
-304
lines changed

.env.example

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,11 +6,11 @@ DOCUMENT_STORE_NAME=brainchulo_docs
66
CONVERSATION_STORE_NAME=brainchulo_convos
77
DATABASE_URL=sqlite:///data/brainchulo.db
88
ANDROMEDA_URL=http://0.0.0.0:9000/
9-
109
MODEL_PATH=/models/vicuna-AlekseyKorshuk-7B-GPTQ-4bit-128g
11-
# General Settings
10+
USE_FLOW_AGENTS=true
11+
# General Settings
1212
GENERAL_LOADING_METHOD=GPTQ
13-
GENERAL_BOOL_CPU_OFFLOADING=true
13+
GENERAL_BOOL_CPU_OFFLOADING=false
1414
# HuggingFace
1515
HF_BOOL_USE_QUANT=true
1616
HF_BOOL_USE_4_BIT=true

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,12 @@ docker compose down
117117
docker-compose exec backend alembic upgrade head
118118
```
119119

120+
## Enabling Flow Agents
121+
We have a experimental feature that enables what we call flow agents. To activate it, set the feature flag to true in the .env file:
122+
```
123+
USE_FLOW_AGENTS=true
124+
```
125+
120126
## Creating a Plugin
121127

122128
1. Create a new directory for your plugin, e.g. `/app/plugins/my_plugin`

app/agents/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
from agents.document import DocumentQuestionAnswerAgent
2-
from agents.chain_of_thoughts import ChainOfThoughtsAgent
1+
from agents.chain_of_thoughts import ChainOfThoughtsAgent
2+
from agents.flow_cot import ChainOfThoughtsFlowAgent

app/agents/base.py

Lines changed: 23 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,20 @@
11
# import the necessary libraries
22
from abc import abstractmethod
33
from colorama import Style, Fore
4-
from typing import Dict, Callable
4+
from typing import List
55
from andromeda_chain import AndromedaChain
6+
from tools.base import BaseTool
67

78
def color_print(msg, color):
89
print(color + Style.BRIGHT + msg + Style.RESET_ALL, flush=True)
910

1011

1112
class BaseAgent:
1213
"""Base Agent.
13-
14+
1415
Nothing too exciting here.
1516
"""
16-
def __init__(self, andromeda: AndromedaChain, tools: Dict[str, Callable[[str], str]]):
17+
def __init__(self, andromeda: AndromedaChain, tools: List[BaseTool]):
1718
self.andromeda = andromeda
1819
self.tools = tools
1920

@@ -27,3 +28,22 @@ def do_tool(self, tool_name, act_input):
2728
color_print(f"Tool result: {result}", Fore.BLUE)
2829
return result
2930

31+
def _build_tool_description_line(self, tool: BaseTool):
32+
return f"{tool.name}: {tool.short_description()}"
33+
34+
def prepare_start_prompt(self, prompt_start_template):
35+
tools = [item for _, item in self.tools.items()]
36+
tools_descriptions = "\n".join([self._build_tool_description_line(tool) for tool in tools])
37+
action_list = str([tool.name for tool in tools]).replace('"', "")
38+
few_shot_examples = "\n".join(
39+
[
40+
f"Example {idx}:\n{tool.few_shot_examples()}"
41+
for idx, tool in enumerate(tools)
42+
]
43+
)
44+
self.valid_tools = [tool.name for tool in tools]
45+
self.prepared_prompt = prompt_start_template.format(
46+
tools_descriptions=tools_descriptions,
47+
action_list=action_list,
48+
few_shot_examples=few_shot_examples
49+
)

app/agents/chain_of_thoughts.py

Lines changed: 2 additions & 52 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,10 @@
1-
from typing import Dict, Callable
2-
from andromeda_chain import AndromedaChain
3-
from agents.flow_based import BaseAgent, BaseFlowAgent
4-
from flow.flow import Flow, PromptNode, ToolNode, ChoiceNode, StartNode
5-
from prompts.flow_guidance_cot import FlowChainOfThoughts, PROMPT_START_STRING
1+
from agents.base import BaseAgent
62
from guidance_tooling.guidance_programs.tools import ingest_file
73
from guidance_tooling.guidance_programs.tools import clean_text
8-
from guidance_tooling.guidance_programs.tools import load_tools
94

105
import os
116
from langchain.llms import LlamaCpp
12-
from dotenv import load_dotenv
137
import os
14-
from chromadb.config import Settings
158
from colorama import Fore, Style
169
from langchain.chains import RetrievalQA
1710
from langchain.llms import LlamaCpp
@@ -25,58 +18,15 @@ def get_llm():
2518
global llm
2619
if llm is None:
2720
print("Loading guidance model...")
28-
model_type = "LlamaCpp"
2921
model_path ="/home/karajan/Downloads/airoboros-13b-gpt4.ggmlv3.q8_0.bin"
3022
model_n_ctx =1000
31-
target_source_chunks = 4
3223
n_gpu_layers = 500
3324
use_mlock = 0
3425
n_batch = os.environ.get('N_BATCH') if os.environ.get('N_BATCH') != None else 512
3526
callbacks = []
36-
qa_prompt = ""
3727
llm = LlamaCpp(model_path=model_path, n_ctx=model_n_ctx, callbacks=callbacks, verbose=False,n_gpu_layers=n_gpu_layers, use_mlock=use_mlock,top_p=0.9, n_batch=n_batch)
3828
return llm
39-
40-
class ChainOfThoughtsFlowAgent(BaseFlowAgent):
41-
def __init__(self, andromeda: AndromedaChain, tools: Dict[str, Callable[[str], str]]):
42-
def execute_tool(variables):
43-
action_name = variables["tool_name"]
44-
action_input = variables["act_input"]
45-
return self.do_tool(action_name, action_input)
46-
47-
start = StartNode("start", FlowChainOfThoughts.flow_prompt_start, {
48-
"Action": "choose_action",
49-
"Final Answer": "final_prompt"
50-
})
51-
thought = PromptNode("thought", FlowChainOfThoughts.thought_gen)
52-
choose_action = PromptNode("choose_action", FlowChainOfThoughts.choose_action)
53-
perform_action = PromptNode("perform_action", FlowChainOfThoughts.action_input)
54-
execute_tool_node = ToolNode("execute_tool", execute_tool)
55-
decide = ChoiceNode("decide", ["thought", "final_prompt"], max_decisions=3, force_exit_on="final_prompt")
56-
final = PromptNode("final_prompt", FlowChainOfThoughts.final_prompt)
57-
58-
thought.set_next(choose_action)
59-
choose_action.set_next(perform_action)
60-
perform_action.set_next(execute_tool_node)
61-
execute_tool_node.set_next(decide)
62-
63-
flow = Flow(
64-
[start, thought, choose_action, perform_action, execute_tool_node, decide, final]
65-
)
66-
67-
super().__init__(andromeda, tools, flow)
68-
self.valid_tools = list(tools.keys())
69-
self.valid_answers = ["Action", "Final Answer"]
70-
71-
72-
def run(self, query: str) -> str:
73-
return super().run(query, variables={
74-
"prompt_start": PROMPT_START_STRING,
75-
"question": query,
76-
"valid_tools": self.valid_tools,
77-
"valid_answers": self.valid_answers,
78-
})
79-
29+
8030
class ChainOfThoughtsAgent(BaseAgent):
8131
def __init__(self, guidance, retriever, num_iter=3):
8232
self.guidance = guidance

app/agents/document.py

Lines changed: 0 additions & 103 deletions
This file was deleted.

app/agents/flow_cot.py

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
from typing import Dict, Callable
2+
from andromeda_chain import AndromedaChain
3+
from agents.flow_based import BaseFlowAgent
4+
from flow.flow import Flow, PromptNode, ToolNode, ChoiceNode, StartNode
5+
from prompts.flow_guidance_cot import FlowChainOfThoughts, PROMPT_START_STRING
6+
7+
8+
class ChainOfThoughtsFlowAgent(BaseFlowAgent):
9+
def __init__(self, andromeda: AndromedaChain, tools: Dict[str, Callable[[str], str]]):
10+
def execute_tool(variables):
11+
action_name = variables["tool_name"]
12+
action_input = variables["act_input"]
13+
return self.do_tool(action_name, action_input)
14+
15+
start = StartNode("start", FlowChainOfThoughts.flow_prompt_start, {
16+
"Action": "choose_action",
17+
"Final Answer": "final_prompt"
18+
})
19+
thought = PromptNode("thought", FlowChainOfThoughts.thought_gen)
20+
choose_action = PromptNode("choose_action", FlowChainOfThoughts.choose_action)
21+
perform_action = PromptNode("perform_action", FlowChainOfThoughts.action_input)
22+
execute_tool_node = ToolNode("execute_tool", execute_tool)
23+
decide = ChoiceNode("decide", ["thought", "final_prompt"], max_decisions=3, force_exit_on="final_prompt")
24+
final = PromptNode("final_prompt", FlowChainOfThoughts.final_prompt)
25+
26+
thought.set_next(choose_action)
27+
choose_action.set_next(perform_action)
28+
perform_action.set_next(execute_tool_node)
29+
execute_tool_node.set_next(decide)
30+
31+
flow = Flow(
32+
[start, thought, choose_action, perform_action, execute_tool_node, decide, final]
33+
)
34+
35+
super().__init__(andromeda, tools, flow)
36+
self.valid_answers = ["Action", "Final Answer"]
37+
self.prepare_start_prompt(PROMPT_START_STRING)
38+
39+
40+
def run(self, query: str) -> str:
41+
if not self.prepared_prompt:
42+
raise TypeError("Your inherinted BaseFlowAgent class must call 'prepare_start_prompt' in it's constructor.")
43+
44+
return super().run(query, variables={
45+
"prompt_start": self.prepared_prompt,
46+
"question": query,
47+
"valid_tools": self.valid_tools,
48+
"valid_answers": self.valid_answers,
49+
})

app/conversations/document_based.py

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
from langchain.text_splitter import RecursiveCharacterTextSplitter
44

55
from andromeda_chain import AndromedaChain
6-
from agents import DocumentQuestionAnswerAgent, ChainOfThoughtsAgent
6+
from agents import ChainOfThoughtsAgent
77

88
from settings import logger, load_config
99
import guidance
@@ -47,7 +47,6 @@ def __init__(self):
4747
}
4848
self.andromeda = AndromedaChain(config.andromeda_url)
4949
self.document_qa_agent = ChainOfThoughtsAgent(guidance, tools)
50-
# self.document_qa_agent = DocumentQuestionAnswerAgent(self.andromeda, tools)
5150

5251

5352
def load_document(self, document_path, conversation_id=None):

0 commit comments

Comments
 (0)