Spaces:
Runtime error
Runtime error
# coding=utf-8 | |
# Copyright 2023 The AIWaves Inc. team. | |
# | |
# Licensed under the Apache License, Version 2.0 (the "License"); | |
# you may not use this file except in compliance with the License. | |
# You may obtain a copy of the License at | |
# | |
# http://www.apache.org/licenses/LICENSE-2.0 | |
# | |
# Unless required by applicable law or agreed to in writing, software | |
# distributed under the License is distributed on an "AS IS" BASIS, | |
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. | |
# See the License for the specific language governing permissions and | |
# limitations under the License. | |
"""LLM autonoumous agent""" | |
from LLM.base_LLM import * | |
from Component import * | |
from Action import Action | |
from Prompt import * | |
headers = { | |
"Content-Type": "text/event-stream", | |
"Cache-Control": "no-cache", | |
"X-Accel-Buffering": "no", | |
} | |
class Agent: | |
""" | |
Auto agent, input the JSON of SOP. | |
""" | |
# Agent should have args: agents,states | |
def __init__(self, name, agent_state_roles, **kwargs) -> None: | |
self.state_roles = agent_state_roles | |
self.name = name | |
self.style = kwargs["style"] | |
self.LLMs = kwargs["LLMs"] | |
self.LLM = None | |
self.is_user = kwargs["is_user"] | |
self.begins = kwargs["begins"] if "begins" in kwargs else False | |
self.current_role = "" | |
self.long_term_memory = [] | |
self.short_term_memory = "" | |
self.current_state = None | |
self.first_speak = True | |
self.environment = None | |
def from_config(cls, config_path): | |
""" | |
Initialize agents based on json file | |
Return: | |
agents(dict) : key:agent_name;value:class(Agent) | |
names_to_roles(dict) : key:state_name value:(dict; (key:agent_name ; value:agent_role)) | |
roles_to_names(dict) : key:state_name value:(dict; (key:agent_role ; value:agent_name)) | |
""" | |
with open(config_path) as f: | |
config = json.load(f) | |
roles_to_names = {} | |
names_to_roles = {} | |
agents = {} | |
user_names = json.loads(os.environ["User_Names"]) if "User_Names" in os.environ else [] | |
for agent_name, agent_dict in config["agents"].items(): | |
agent_state_roles = {} | |
agent_LLMs = {} | |
agent_begins = {} | |
for state_name, agent_role in agent_dict["roles"].items(): | |
agent_begins[state_name] = {} | |
if state_name not in roles_to_names: | |
roles_to_names[state_name] = {} | |
if state_name not in names_to_roles: | |
names_to_roles[state_name] = {} | |
roles_to_names[state_name][agent_role] = agent_name | |
names_to_roles[state_name][agent_name] = agent_role | |
agent_state_roles[state_name] = agent_role | |
current_state = config["states"][state_name] | |
current_state["roles"] = list(current_state["agent_states"].keys()) if "roles" not in current_state else current_state["roles"] | |
current_state_begin_role = current_state["begin_role"] if "begin_role" in current_state else current_state["roles"][0] | |
agent_begins[state_name]["is_begin"] = current_state_begin_role==agent_role if "begin_role" in current_state else False | |
agent_begins[state_name]["begin_query"] = current_state["begin_query"] if "begin_query" in current_state else " " | |
agent_LLMs[state_name] = init_LLM("logs"+os.sep+f"{agent_name}",**current_state["agent_states"][agent_role]) | |
agents[agent_name] = cls( | |
agent_name, | |
agent_state_roles, | |
LLMs=agent_LLMs, | |
is_user=agent_name in user_names, | |
style = agent_dict["style"], | |
begins = agent_begins | |
) | |
assert len(config["agents"].keys()) != 2 or (roles_to_names[config["root"]][config["states"][config["root"]]["begin_role"]] not in user_names and "begin_query" in config["states"][config["root"]]),"In a single-agent scenario, there must be an opening statement and it must be the agent" | |
return agents, roles_to_names, names_to_roles | |
def step(self, current_state,input=""): | |
""" | |
return actions by current state and environment | |
Return: action(Action) | |
""" | |
current_state.chat_nums +=1 | |
state_begin = current_state.is_begin | |
agent_begin = self.begins[current_state.name]["is_begin"] | |
self.begins[current_state.name]["is_begin"] = False | |
current_state.is_begin = False | |
environment = self.environment | |
self.current_state = current_state | |
# 先根据当前环境更新信息 | |
# First update the information according to the current environment | |
response = " " | |
res_dict = {} | |
if self.is_user: | |
response = f"{self.name}:{input}" | |
else: | |
if len(environment.shared_memory["long_term_memory"])>0: | |
current_history = self.observe() | |
self.long_term_memory.append(current_history) | |
if agent_begin: | |
response = (char for char in self.begins[current_state.name]["begin_query"]) | |
else: | |
response,res_dict = self.act() | |
action_dict = { | |
"response": response, | |
"res_dict": res_dict, | |
"role": self.state_roles[current_state.name], | |
"name": self.name, | |
"state_begin" : state_begin, | |
"agent_begin" : agent_begin, | |
"is_user" : self.is_user | |
} | |
return Action(**action_dict) | |
def act(self): | |
""" | |
return actions by the current state | |
""" | |
current_state = self.current_state | |
chat_history = self.long_term_memory | |
current_LLM = self.LLMs[current_state.name] | |
system_prompt, last_prompt, res_dict = self.compile() | |
response = current_LLM.get_response( | |
chat_history, system_prompt, last_prompt, stream=True | |
) | |
return response,res_dict | |
def update_memory(self, memory): | |
self.long_term_memory.append( | |
{"role": "assistant", "content": memory.content} | |
) | |
MAX_CHAT_HISTORY = eval(os.environ["MAX_CHAT_HISTORY"]) | |
environment = self.environment | |
current_chat_history_idx = environment.current_chat_history_idx if environment.environment_type == "competive" else 0 | |
current_long_term_memory = environment.shared_memory["long_term_memory"][current_chat_history_idx:] | |
last_conversation_idx = environment._get_agent_last_conversation_idx(self,current_long_term_memory) | |
if len(current_long_term_memory)-last_conversation_idx >= MAX_CHAT_HISTORY: | |
current_state = self.current_state | |
current_role = self.state_roles[current_state.name] | |
current_component_dict = current_state.components[current_role] | |
# get chat history from new conversation | |
conversations = environment._get_agent_new_memory(self,current_long_term_memory) | |
# get summary | |
summary_prompt = ( | |
current_state.summary_prompt[current_role] | |
if current_state.summary_prompt | |
else f"""your name is {self.name},your role is{current_component_dict["style"].role},your task is {current_component_dict["task"].task}.\n""" | |
) | |
summary_prompt =eval(Agent_summary_system_prompt) | |
summary = self.LLMs[current_state.name].get_response(None, summary_prompt,stream = False) | |
self.short_term_memory = summary | |
def compile(self): | |
""" | |
get prompt from state depend on your role | |
Return: | |
system_prompt:system_prompt for agents's LLM | |
last_prompt:last_prompt for agents's LLM | |
res_dict(dict): Other return from tool component.For example: search engine results | |
""" | |
current_state = self.current_state | |
self.current_roles = self.state_roles[current_state.name] | |
current_state_name = current_state.name | |
self.LLM = self.LLMs[current_state_name] | |
components = current_state.components[self.state_roles[current_state_name]] | |
system_prompt = self.current_state.environment_prompt | |
last_prompt = "" | |
res_dict = {} | |
for component in components.values(): | |
if isinstance(component, (OutputComponent, LastComponent)): | |
last_prompt = last_prompt + "\n" + component.get_prompt(self) | |
elif isinstance(component, PromptComponent): | |
system_prompt = ( | |
system_prompt + "\n" + component.get_prompt(self) | |
) | |
elif isinstance(component, ToolComponent): | |
response = component.func(self) | |
if "prompt" in response and response["prompt"]: | |
last_prompt = last_prompt + "\n" + response["prompt"] | |
res_dict.update(response) | |
name = self.name | |
query = self.environment.shared_memory["long_term_memory"][-1] if len(self.environment.shared_memory["long_term_memory"]) else "" | |
last_prompt = eval(Agent_last_prompt) | |
system_prompt = eval(Agent_system_prompt) | |
return system_prompt, last_prompt, res_dict | |
def observe(self): | |
""" | |
Update one's own memory according to the current environment, including: updating short-term memory; updating long-term memory | |
""" | |
return self.environment._observe(self) | |
def generate_sop(self): | |
pass | |
def reflection(self): | |
pass | |