save environment/step.json after movement and add more logs

This commit is contained in:
better629 2023-10-08 17:57:50 +08:00
parent 7b0323e76f
commit a37be1bd33
8 changed files with 81 additions and 56 deletions

View file

@ -121,7 +121,7 @@ class GenHourlySchedule(STAction):
output = self._run_v1(prompt)
CONFIG.max_tokens_rsp = raw_max_tokens_rsp
logger.info(f"max_tokens_rsp: {CONFIG.max_tokens_rsp}")
logger.debug(f"max_tokens_rsp: {CONFIG.max_tokens_rsp}")
logger.info(f"Role: {role.name} _generate_schedule_for_given_hour prompt_input: {prompt_input_str}, "
f"output: {output}")
return output

View file

@ -8,6 +8,7 @@ import json
from metagpt.actions.action import Action
from metagpt.schema import Message
from metagpt.logs import logger
from examples.st_game.utils.const import PROMPTS_DIR
@ -63,6 +64,7 @@ class STAction(Action):
"""
for idx in range(retry):
llm_resp = self._ask(prompt)
logger.info(f"_run_v1 llm raw resp: {llm_resp}")
if self._func_validate(llm_resp, prompt):
return self._func_cleanup(llm_resp, prompt)
return self.fail_default_resp
@ -81,7 +83,7 @@ class STAction(Action):
for idx in range(retry):
try:
llm_resp = self._ask(prompt)
print("llm_resp ", llm_resp)
logger.info(f"_run_v2 llm raw resp: {llm_resp}")
end_idx = llm_resp.strip().rfind("}") + 1
llm_resp = llm_resp[:end_idx]
llm_resp = json.loads(llm_resp)["output"]

View file

@ -71,7 +71,7 @@ class TaskDecomp(STAction):
def _func_validate(self, llm_resp: str, prompt: str) -> bool:
# TODO -- this sometimes generates error
try:
self._func_cleanup(llm_resp)
self._func_cleanup(llm_resp, prompt)
except Exception as exp:
return False
return True

View file

@ -54,6 +54,7 @@ def plan(role: "STRole", maze: Maze, roles: list["STRole"], new_day: bool, retri
# c) False
if focused_event:
reaction_mode = _should_react(role, focused_event, roles)
logger.info(f"Role: {role.name} reaction_mode: {reaction_mode}")
if reaction_mode:
# If we do want to chat, then we generate conversation
if reaction_mode[:9] == "chat with":

View file

@ -6,6 +6,7 @@ import datetime
from metagpt.logs import logger
from examples.st_game.utils.utils import get_embedding
from examples.st_game.memory.retrieve import new_agent_retrieve
from examples.st_game.actions.run_reflect_action import (
AgentFocusPt, AgentInsightAndGuidance, AgentEventTriple,
AgentEventPoignancy, AgentChatPoignancy, AgentPlanThoughtOnConvo,
@ -102,13 +103,14 @@ def run_reflect(role: "STRole"):
focal_points = generate_focal_points(role, 3)
# Retrieve the relevant Nodesobject for each of the focal points.
# <retrieved> has keys of focal points, and values of the associated Nodes.
retrieved = role.retrieve(focal_points)
retrieved = new_agent_retrieve(role, focal_points)
# For each of the focal points, generate thoughts and save it in the
# agent's memory.
for focal_pt, nodes in retrieved.items():
xx = [i.embedding_key for i in nodes]
for xxx in xx: logger.info(f"Nodes retrieved for {focal_pt} are {xxx}.")
for xxx in xx:
logger.info(f"Nodes retrieved for `{focal_pt}` are `{xxx}`.")
thoughts = generate_insights_and_evidence(role, nodes, 5)
# 生成的是字典类型

View file

@ -33,7 +33,7 @@ from examples.st_game.memory.scratch import Scratch
from examples.st_game.utils.utils import get_embedding, path_finder
from examples.st_game.utils.const import collision_block_id, STORAGE_PATH
from examples.st_game.reflect.reflect import generate_poig_score
from examples.st_game.utils.mg_ga_transform import save_movement, get_role_environment
from examples.st_game.utils.mg_ga_transform import save_movement, get_role_environment, save_environment
from examples.st_game.actions.inner_voice_action import AgentWhisperThoughtAction
from examples.st_game.actions.run_reflect_action import AgentEventTriple
from examples.st_game.reflect.reflect import role_reflect
@ -261,51 +261,52 @@ class STRole(Role):
obj = p_event[2].split(":")[-1]
keywords.update([sub, obj])
# Get event embedding
desc_embedding_in = desc
if "(" in desc:
desc_embedding_in = (desc_embedding_in.split("(")[1]
.split(")")[0]
.strip())
if desc_embedding_in in self._rc.memory.embeddings:
event_embedding = self._rc.memory.embeddings[desc_embedding_in]
else:
event_embedding = get_embedding(desc_embedding_in)
event_embedding_pair = (desc_embedding_in, event_embedding)
# Get event poignancy.
event_poignancy = generate_poig_score(self,
"action",
desc_embedding_in)
# If we observe the persona's self chat, we include that in the memory
# of the persona here.
chat_node_ids = []
if p_event[0] == f"{self.name}" and p_event[1] == "chat with":
curr_event = self._rc.scratch.act_event
if self._rc.scratch.act_description in self._rc.memory.embeddings:
chat_embedding = self._rc.memory.embeddings[
self._rc.scratch.act_description]
# Get event embedding
desc_embedding_in = desc
if "(" in desc:
desc_embedding_in = (desc_embedding_in.split("(")[1]
.split(")")[0]
.strip())
if desc_embedding_in in self._rc.memory.embeddings:
event_embedding = self._rc.memory.embeddings[desc_embedding_in]
else:
chat_embedding = get_embedding(self._rc.scratch
.act_description)
chat_embedding_pair = (self._rc.scratch.act_description,
chat_embedding)
chat_poignancy = generate_poig_score(self._rc.scratch, "chat",
self._rc.scratch.act_description)
chat_node = self._rc.memory.add_chat(self._rc.scratch.curr_time, None,
curr_event[0], curr_event[1], curr_event[2],
self._rc.scratch.act_description, keywords,
chat_poignancy, chat_embedding_pair,
self._rc.scratch.chat)
chat_node_ids = [chat_node.node_id]
event_embedding = get_embedding(desc_embedding_in)
event_embedding_pair = (desc_embedding_in, event_embedding)
# Finally, we add the current event to the agent's memory.
ret_events += [self._rc.memory.add_event(self._rc.scratch.curr_time, None,
s, p, o, desc, keywords, event_poignancy,
event_embedding_pair, chat_node_ids)]
self._rc.scratch.importance_trigger_curr -= event_poignancy
self._rc.scratch.importance_ele_n += 1
# Get event poignancy.
event_poignancy = generate_poig_score(self,
"event",
desc_embedding_in)
logger.info(f"Role {self.name} event_poignancy: {event_poignancy}")
# If we observe the persona's self chat, we include that in the memory
# of the persona here.
chat_node_ids = []
if p_event[0] == f"{self.name}" and p_event[1] == "chat with":
curr_event = self._rc.scratch.act_event
if self._rc.scratch.act_description in self._rc.memory.embeddings:
chat_embedding = self._rc.memory.embeddings[
self._rc.scratch.act_description]
else:
chat_embedding = get_embedding(self._rc.scratch
.act_description)
chat_embedding_pair = (self._rc.scratch.act_description,
chat_embedding)
chat_poignancy = generate_poig_score(self._rc.scratch, "chat",
self._rc.scratch.act_description)
chat_node = self._rc.memory.add_chat(self._rc.scratch.curr_time, None,
curr_event[0], curr_event[1], curr_event[2],
self._rc.scratch.act_description, keywords,
chat_poignancy, chat_embedding_pair,
self._rc.scratch.chat)
chat_node_ids = [chat_node.node_id]
# Finally, we add the current event to the agent's memory.
ret_events += [self._rc.memory.add_event(self._rc.scratch.curr_time, None,
s, p, o, desc, keywords, event_poignancy,
event_embedding_pair, chat_node_ids)]
self._rc.scratch.importance_trigger_curr -= event_poignancy
self._rc.scratch.importance_ele_n += 1
return ret_events
@ -353,7 +354,7 @@ class STRole(Role):
# <target_tiles> is a list of tile coordinates where the persona may go
# to execute the current action. The goal is to pick one of them.
target_tiles = None
logger.info("plan: ", plan)
logger.info(f"Role {self.name} plan: {plan}")
if "<persona>" in plan:
# Executing persona-persona interaction.
@ -510,7 +511,7 @@ class STRole(Role):
elif (self.scratch.curr_time.strftime('%A %B %d')
!= self.curr_time.strftime('%A %B %d')):
new_day = "New day"
logger.info(f"Role: {self.name} {new_day}")
logger.info(f"Role: {self.name} new_day: {new_day}")
self._rc.scratch.curr_time = self.curr_time
# get maze_env from self._rc.env, and observe env info
@ -536,7 +537,9 @@ class STRole(Role):
# step update
logger.info(f"Role: {self.name} run at {self.step} step on {self.curr_time}")
self.step += 1
save_environment(self.name, self.step, self.sim_code, next_tile)
self.curr_time += datetime.timedelta(seconds=self.sec_per_step)
self.inner_voice = False
time.sleep(0.5)
return DummyMessage()

View file

@ -21,8 +21,7 @@ def save_movement(role_name: str, role_move: dict, step: int, sim_code: str, cur
if not movement_path.parent.exists():
movement_path.parent.mkdir(exist_ok=True)
if movement_path.exists():
with open(movement_path, "r") as fin:
movement = json.load(fin)
movement = read_json_file(movement_path)
else:
movement = {
"persona": dict(),
@ -35,6 +34,24 @@ def save_movement(role_name: str, role_move: dict, step: int, sim_code: str, cur
logger.info(f"save_movement at step: {step}, curr_time: {movement['meta']['curr_time']}")
def save_environment(role_name: str, step: int, sim_code: str, movement: list[int]):
environment_path = STORAGE_PATH.joinpath(f"{sim_code}/environment/{step}.json")
if not environment_path.parent.exists():
environment_path.parent.mkdir(exist_ok=True)
if environment_path.exists():
environment = read_json_file(environment_path)
else:
environment = {}
environment[role_name] = {
"maze": "the_ville",
"x": movement[0],
"y": movement[1]
}
write_json_file(environment_path, environment)
logger.info(f"save_environment at step: {step}")
def get_role_environment(sim_code: str, role_name: str, step: int = 0) -> dict:
env_path = STORAGE_PATH.joinpath(f"{sim_code}/environment/{step}.json")
role_env = None

View file

@ -212,7 +212,7 @@ class OpenAIGPTAPI(BaseGPTAPI, RateLimiter):
def _chat_completion(self, messages: list[dict]) -> dict:
rsp = self.llm.ChatCompletion.create(**self._cons_kwargs(messages))
self._update_costs(rsp)
self._update_costs(rsp.get("usage"))
return rsp
def completion(self, messages: list[dict]) -> dict:
@ -249,7 +249,7 @@ class OpenAIGPTAPI(BaseGPTAPI, RateLimiter):
usage["completion_tokens"] = completion_tokens
return usage
except Exception as e:
logger.error("usage calculation failed!", e)
logger.error("usage calculation failed! {e}")
else:
return usage
@ -286,7 +286,7 @@ class OpenAIGPTAPI(BaseGPTAPI, RateLimiter):
completion_tokens = int(usage["completion_tokens"])
self._cost_manager.update_cost(prompt_tokens, completion_tokens, self.model)
except Exception as e:
logger.error("updating costs failed!", e)
logger.error("updating costs failed! {e}")
def get_costs(self) -> Costs:
return self._cost_manager.get_costs()