mirror of
https://github.com/agentscope-ai/ReMe.git
synced 2026-10-07 03:00:27 +00:00
clean project
This commit is contained in:
parent
556e8afb5d
commit
40bb3b1052
21 changed files with 26 additions and 404 deletions
|
|
@ -20,7 +20,7 @@ class YourOwnAgentEnhanced(YourOwnAgent):
|
|||
|
||||
def summary_experience(self, query: str):
|
||||
messages = self.run(query)
|
||||
trajectory: Trajectory = Trajectory(query=query, steps=messages, answer=messages[-1].content, done=True)
|
||||
trajectory: Trajectory = Trajectory(query=query, steps=messages, answer=messages[-1].content, is_terminated=True)
|
||||
|
||||
request: SummarizerRequest = SummarizerRequest(trajectories=[trajectory], workspace_id=self.workspace_id)
|
||||
response: SummarizerResponse = self.em_client.call_summarizer(request)
|
||||
|
|
@ -40,7 +40,7 @@ class YourOwnAgentEnhanced(YourOwnAgent):
|
|||
|
||||
trajectory.steps = messages
|
||||
trajectory.answer = messages[-1].content
|
||||
trajectory.done = True
|
||||
trajectory.is_terminated = True
|
||||
trajectory.metadata["experience"] = response.context_msg.content
|
||||
return trajectory
|
||||
|
||||
|
|
|
|||
|
|
@ -21,8 +21,7 @@ def create_sample_trajectory(query: str, steps: List[Message], done: bool = True
|
|||
trajectory = Trajectory(
|
||||
query=query,
|
||||
steps=steps,
|
||||
done=done,
|
||||
current_step=len(steps) - 1,
|
||||
is_terminated=done,
|
||||
metadata={
|
||||
"domain": "coding",
|
||||
"task_type": "problem_solving"
|
||||
|
|
|
|||
|
|
@ -1,78 +0,0 @@
|
|||
from typing import List
|
||||
|
||||
from pydantic import Field
|
||||
|
||||
from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin
|
||||
from experiencemaker.module.environment.base_environment import BaseEnvironment
|
||||
from experiencemaker.schema.trajectory import Trajectory, Message, StateMessage, ActionMessage, ContextMessage
|
||||
|
||||
|
||||
class BaseAgentWrapper(AgentWrapperMixin):
|
||||
max_steps: int = Field(default=10)
|
||||
enable_exploration: bool = Field(default=False)
|
||||
trajectory: Trajectory | None = Field(default_factory=Trajectory)
|
||||
|
||||
def reset(self):
|
||||
self.trajectory.reset()
|
||||
|
||||
def after_step_hook(self, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def build_messages(self,
|
||||
state: StateMessage,
|
||||
context_msg: ContextMessage | None,
|
||||
env: BaseEnvironment, **kwargs) -> List[Message]:
|
||||
raise NotImplementedError
|
||||
|
||||
def explore_messages(self, messages: List[Message], **kwargs) -> List[Message]:
|
||||
raise NotImplementedError
|
||||
|
||||
def action_parser(self, action_msg: ActionMessage) -> ActionMessage: # noqa
|
||||
return action_msg
|
||||
|
||||
def generate_action(self,
|
||||
state: StateMessage,
|
||||
context_msg: ContextMessage | None,
|
||||
env: BaseEnvironment,
|
||||
**kwargs) -> ActionMessage:
|
||||
|
||||
messages: List[Message] = self.build_messages(state, context_msg, env, **kwargs)
|
||||
if self.enable_exploration:
|
||||
messages = self.explore_messages(messages, **kwargs)
|
||||
|
||||
action_msg: ActionMessage = self.llm.chat(messages, tools=env.tools)
|
||||
return self.action_parser(action_msg)
|
||||
|
||||
def execute(self, query: str, env: BaseEnvironment = None, **kwargs) -> Trajectory:
|
||||
self.trajectory.query = query
|
||||
current_state = env.current_state
|
||||
|
||||
for i in range(self.max_steps):
|
||||
self.trajectory.current_step = i
|
||||
|
||||
# generate context
|
||||
context_msg: ContextMessage | None = None
|
||||
if self.context_generator:
|
||||
context_msg = self.context_generator.execute(trajectory=self.trajectory, **kwargs)
|
||||
|
||||
# generate action
|
||||
action_msg = self.generate_action(state=current_state, context_msg=context_msg, env=env, **kwargs)
|
||||
|
||||
# generate next state
|
||||
next_state, reward, done, info = env.step(action_msg, trajectory=self.trajectory, **kwargs)
|
||||
|
||||
self.after_step_hook(step_index=i,
|
||||
current_state=current_state,
|
||||
action_msg=action_msg,
|
||||
reward=reward,
|
||||
next_state=next_state,
|
||||
done=done,
|
||||
info=info,
|
||||
**kwargs)
|
||||
|
||||
if done:
|
||||
break
|
||||
|
||||
current_state = next_state
|
||||
|
||||
return self.trajectory
|
||||
|
|
@ -1,107 +0,0 @@
|
|||
|
||||
# import os
|
||||
# import time
|
||||
# import json
|
||||
# import best_logger
|
||||
# import agentscope
|
||||
# from experiencemaker.module.base_module import BaseModule
|
||||
# from experiencemaker.schema.trajectory import Trajectory as OutputTrajectory
|
||||
# from experiencemaker.schema.trajectory import Message as OutputTrajectoryMessage
|
||||
|
||||
# from datetime import datetime
|
||||
# from pydantic import BaseModel, Field
|
||||
# import uuid
|
||||
# from typing import (
|
||||
# Literal,
|
||||
# Union,
|
||||
# List,
|
||||
# Optional,
|
||||
# Dict,
|
||||
# Any,
|
||||
# Sequence,
|
||||
# )
|
||||
|
||||
|
||||
# from experiencemaker.module.agent_wrapper.base_agent_wrapper import BaseAgentWrapper
|
||||
# from agentscope.agents import ReActAgent, DialogAgent
|
||||
# from beyond.trajectory import Trajectory as TrajectoryOperation
|
||||
# from beyond.solver import TaskExecutor
|
||||
# from agentscope.message import Msg
|
||||
# from beyond.planner import *
|
||||
# from beyond.debug import *
|
||||
# from best_logger import *
|
||||
# from loguru import logger
|
||||
|
||||
|
||||
# def run_agent_and_extract_memory(msg_question, traj, agent):
|
||||
# if not isinstance(msg_question, list):
|
||||
# raise ValueError("msg_question should be a list of Msg objects")
|
||||
# agent_ret = agent(msg_question)
|
||||
# latest_agent_memory_buffer = msg_sort(agent.memory.get_memory())
|
||||
# traj.add_steps(latest_agent_memory_buffer)
|
||||
# return latest_agent_memory_buffer, agent_ret
|
||||
|
||||
|
||||
# def msg_sort(msg_list: List[Msg]) -> List[Msg]:
|
||||
# """
|
||||
# Sort the message list by timestamp.
|
||||
# """
|
||||
# sorted_msg = sorted(
|
||||
# msg_list,
|
||||
# key=lambda msg: datetime.strptime(msg.timestamp, "%Y-%m-%d %H:%M:%S.%f")
|
||||
# )
|
||||
|
||||
# return sorted_msg
|
||||
|
||||
|
||||
# class MainAgent(BaseAgentWrapper):
|
||||
# mcp_url: str = Field(
|
||||
# default=os.getenv('MCP_URL', 'http://localhost:33333/sse'),
|
||||
# description="The URL of the MCP server.",
|
||||
# )
|
||||
|
||||
# def __init__(self, *args, **kwargs):
|
||||
# return super().__init__(*args, **kwargs)
|
||||
|
||||
# def execute(self, query, **kwargs):
|
||||
# question = query.strip()
|
||||
# ref_answer = "not available"
|
||||
|
||||
# print_dict({
|
||||
# 'question': question,
|
||||
# 'ref_answer': ref_answer,
|
||||
# }, mod='gaia_result')
|
||||
|
||||
# try:
|
||||
# except Exception as e:
|
||||
# logger.exception(f"Error in solving task {question}: {e}")
|
||||
# raise RuntimeError(f"Error in solving task {question}: {e}")
|
||||
|
||||
# print_dict({
|
||||
# 'question': question,
|
||||
# 'ref_answer': ref_answer,
|
||||
# 'predicted_result': final_answer,
|
||||
# }, mod='gaia_result')
|
||||
|
||||
|
||||
# role_mapping = {
|
||||
# 'system': 'system',
|
||||
# 'end-user': 'user',
|
||||
# 'commander': 'user',
|
||||
# 'assistant': 'assistant',
|
||||
# 'tool-agent': 'user',
|
||||
# 'tool': 'tool',
|
||||
# }
|
||||
# output_trajectory = OutputTrajectory(
|
||||
# steps=[OutputTrajectoryMessage(
|
||||
# role=role_mapping[step.executor],
|
||||
# content=step.content,
|
||||
# timestamp=step.timestamp
|
||||
# ) for step in traj.raw_steps],
|
||||
# done=True,
|
||||
# query=question,
|
||||
# answer=final_answer,
|
||||
# current_step=len(traj.raw_steps),
|
||||
# )
|
||||
# return output_trajectory
|
||||
|
||||
|
|
@ -15,5 +15,5 @@ class SimpleAgentWrapper(SimpleAgent, AgentWrapperMixin):
|
|||
|
||||
trajectory.steps = messages
|
||||
trajectory.answer = messages[-1].content
|
||||
trajectory.done = True
|
||||
trajectory.is_terminated = True
|
||||
return trajectory
|
||||
|
|
|
|||
|
|
@ -11,10 +11,7 @@ from experiencemaker.schema.vector_store_node import VectorStoreNode
|
|||
class SimpleContextGenerator(BaseContextGenerator):
|
||||
|
||||
def _build_retrieve_query(self, trajectory: Trajectory, **kwargs) -> str:
|
||||
query = ""
|
||||
if trajectory.current_step == 0:
|
||||
query = trajectory.query
|
||||
return query
|
||||
return trajectory.query
|
||||
|
||||
def _retrieve_by_query(self, trajectory: Trajectory, query: str, workspace_id: str, retrieve_top_k: int,
|
||||
**kwargs) -> List[VectorStoreNode]:
|
||||
|
|
|
|||
|
|
@ -1 +0,0 @@
|
|||
from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator
|
||||
|
|
@ -1,56 +0,0 @@
|
|||
from abc import ABC
|
||||
from typing import List
|
||||
|
||||
from pydantic import Field, BaseModel
|
||||
|
||||
from experiencemaker.module.reward_fn.base_reward_fn import BaseRewardFn
|
||||
from experiencemaker.schema.reward import Reward
|
||||
from experiencemaker.schema.trajectory import StateMessage, ActionMessage, ToolCall
|
||||
from experiencemaker.tool.base_tool import BaseTool
|
||||
|
||||
|
||||
class BaseEnvironment(BaseModel, ABC):
|
||||
tools: List[BaseTool] = Field(default_factory=list)
|
||||
reward_fns: List[BaseRewardFn] = Field(default_factory=list)
|
||||
current_state: StateMessage = Field(default_factory=StateMessage)
|
||||
metadata: dict = Field(default_factory=dict, description="add query / answer and etc for reward calculating!")
|
||||
|
||||
def reset(self):
|
||||
self.current_state = StateMessage()
|
||||
self.metadata.clear()
|
||||
|
||||
def step(self, action_msg: ActionMessage, **kwargs):
|
||||
next_state: StateMessage = self.transition(action_msg=action_msg, **kwargs)
|
||||
|
||||
reward: Reward = self.calculate_reward(action_msg=action_msg, next_state=next_state, **kwargs)
|
||||
|
||||
done: bool = self.is_terminated(action_msg=action_msg, next_state=next_state, reward=reward, **kwargs)
|
||||
|
||||
info: dict = self.build_info(action_msg=action_msg, next_state=next_state, reward=reward, done=done, **kwargs)
|
||||
|
||||
self.current_state = next_state
|
||||
return next_state, reward, done, info
|
||||
|
||||
def transition(self, action_msg: ActionMessage, **kwargs) -> StateMessage:
|
||||
tool_dict = {tool.name: tool for tool in self.tools}
|
||||
|
||||
new_tool_calls: List[ToolCall] = []
|
||||
for tool_call in action_msg.tool_calls:
|
||||
if tool_call.name not in tool_dict:
|
||||
continue
|
||||
|
||||
new_tool_call = tool_call.model_copy(deep=True)
|
||||
tool = tool_dict[tool_call.name]
|
||||
new_tool_call.result = tool.execute(**tool_call.argument_dict)
|
||||
new_tool_calls.append(new_tool_call)
|
||||
|
||||
return StateMessage(tool_calls=new_tool_calls)
|
||||
|
||||
def calculate_reward(self, **kwargs) -> Reward:
|
||||
return Reward()
|
||||
|
||||
def is_terminated(self, **kwargs) -> bool:
|
||||
raise NotImplementedError
|
||||
|
||||
def build_info(self, **kwargs):
|
||||
return {}
|
||||
|
|
@ -1,19 +0,0 @@
|
|||
from abc import ABC
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin
|
||||
from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator
|
||||
from experiencemaker.module.environment.base_environment import BaseEnvironment
|
||||
from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer
|
||||
|
||||
|
||||
class BaseEvaluator(BaseModel, ABC):
|
||||
data_path: str = Field(default="")
|
||||
agent_wrapper: AgentWrapperMixin | None = Field(default=None)
|
||||
context_generator: BaseContextGenerator | None = Field(default=None)
|
||||
summarizer: BaseSummarizer | None = Field(default=None)
|
||||
env: BaseEnvironment | None = Field(default=None)
|
||||
|
||||
def evaluate(self, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
|
@ -55,7 +55,7 @@ class SimpleCompareRewardFn(BaseRewardFn, PromptMixin):
|
|||
else:
|
||||
logger.warning(f"no plan exists in result={result}")
|
||||
|
||||
reward_value = 0
|
||||
outcome = 0
|
||||
if valid_cnt > 0:
|
||||
reward_value = better_cnt / valid_cnt
|
||||
return Reward(reward_value=reward_value)
|
||||
outcome = better_cnt / valid_cnt
|
||||
return Reward(outcome=outcome)
|
||||
|
|
|
|||
|
|
@ -1,27 +0,0 @@
|
|||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from experiencemaker.module.agent_wrapper.agent_wrapper_mixin import AgentWrapperMixin
|
||||
from experiencemaker.module.context_generator.base_context_generator import BaseContextGenerator
|
||||
from experiencemaker.module.environment.base_environment import BaseEnvironment
|
||||
from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer
|
||||
from experiencemaker.schema.trajectory import Trajectory
|
||||
|
||||
|
||||
class BaseRunner(BaseModel):
|
||||
agent_wrapper: AgentWrapperMixin | None = Field(default=None)
|
||||
context_generator: BaseContextGenerator | None = Field(default=None)
|
||||
summarizer: BaseSummarizer | None = Field(default=None)
|
||||
env: BaseEnvironment | None = Field(default=None)
|
||||
traj_buffer: List[Trajectory] = Field(default_factory=list)
|
||||
|
||||
def reset(self):
|
||||
self.traj_buffer.clear()
|
||||
self.env.reset()
|
||||
|
||||
def rollout_trajectory(self, query: str, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def summary(self, **kwargs):
|
||||
raise NotImplementedError
|
||||
|
|
@ -80,8 +80,8 @@ class StepSummarizer(BaseSummarizer, PromptMixin):
|
|||
all_experiences = []
|
||||
|
||||
# Classify trajectories based on trajectory.done
|
||||
success_trajectories = [traj for traj in trajectories if traj.done]
|
||||
failure_trajectories = [traj for traj in trajectories if not traj.done]
|
||||
success_trajectories = [traj for traj in trajectories if traj.is_terminated]
|
||||
failure_trajectories = [traj for traj in trajectories if not traj.is_terminated]
|
||||
|
||||
# Process success and failure samples concurrently
|
||||
tasks = []
|
||||
|
|
|
|||
|
|
@ -1,34 +0,0 @@
|
|||
import os
|
||||
from typing import List
|
||||
from pydantic import Field
|
||||
|
||||
from experiencemaker.schema.trajectory import Trajectory, Sample, SummaryMessage
|
||||
from experiencemaker.storage.base_vector_store import BaseVectorStore
|
||||
from experiencemaker.module.summarizer.base_summarizer import BaseSummarizer
|
||||
from beyond.trajectory import Trajectory as TrajectoryOperation
|
||||
from beyond.solver import TaskExecutor
|
||||
|
||||
class TrajectorySummarizer(BaseSummarizer):
|
||||
vector_store: BaseVectorStore | None = Field(default=None)
|
||||
samples: List[Sample] = Field(default=[])
|
||||
|
||||
def extract_samples(self, trajectories: List[Trajectory], **kwargs) -> List[Sample]:
|
||||
raise NotImplementedError
|
||||
|
||||
def insert_into_vector_store(self, samples: List[Sample], **kwargs):
|
||||
raise NotImplementedError
|
||||
|
||||
def process_trajectory(self, traj: Trajectory):
|
||||
traj_operation = TrajectoryOperation()
|
||||
for step in traj.steps:
|
||||
step.executor = step.role.value
|
||||
traj_operation.raw_steps += [step]
|
||||
traj_description = traj_operation.chain_work_steps()
|
||||
mcp_url = os.getenv('MCP_URL', 'http://localhost:33333/sse')
|
||||
world_summary = traj_operation.generate_failure_ask_for_internet_help_raj_abs_post_level_3(mcp_url=mcp_url)
|
||||
self.samples += []
|
||||
|
||||
def execute(self, trajectories: List[Trajectory], return_samples: bool = True, **kwargs) -> List[Sample]:
|
||||
for traj in trajectories:
|
||||
self.process_trajectory(traj)
|
||||
return self.samples
|
||||
|
|
@ -1,34 +0,0 @@
|
|||
from abc import ABC
|
||||
from typing import List
|
||||
|
||||
from pydantic import BaseModel, Field
|
||||
|
||||
from experiencemaker.schema.trajectory import Trajectory
|
||||
|
||||
|
||||
class BaseTrainner(BaseModel, ABC):
|
||||
traj_buffer: List[Trajectory] = Field()
|
||||
|
||||
def fit(self):
|
||||
return
|
||||
|
||||
def save_module_state(self):
|
||||
return
|
||||
|
||||
|
||||
class BaseContextTrainner(BaseTrainner):
|
||||
"""
|
||||
load model/prompt/db/buffer -> new cpt
|
||||
"""
|
||||
|
||||
|
||||
class BaseSummaryTrainner(BaseTrainner):
|
||||
"""
|
||||
load model/prompt/db/buffer -> new cpt
|
||||
"""
|
||||
|
||||
|
||||
class BasePolicyTrainner(BaseTrainner):
|
||||
"""
|
||||
load model/prompt/db/buffer -> new cpt
|
||||
"""
|
||||
|
|
@ -2,5 +2,10 @@ from pydantic import Field, BaseModel
|
|||
|
||||
|
||||
class Reward(BaseModel):
|
||||
reward_value: float | None = Field(default=None)
|
||||
outcome: float = Field(default=0)
|
||||
description: str = Field(default="Outcome 1 denotes success, and 0 denotes failure.")
|
||||
metadata: dict = Field(default_factory=dict)
|
||||
|
||||
@property
|
||||
def success(self) -> bool:
|
||||
return self.outcome > 0
|
||||
|
|
|
|||
|
|
@ -6,6 +6,7 @@ from uuid import uuid4
|
|||
from pydantic import BaseModel, Field, model_validator
|
||||
|
||||
from experiencemaker.enumeration.role import Role
|
||||
from experiencemaker.schema.reward import Reward
|
||||
|
||||
|
||||
class ToolCall(BaseModel):
|
||||
|
|
@ -45,12 +46,7 @@ class ToolCall(BaseModel):
|
|||
|
||||
@property
|
||||
def tool_text_result(self):
|
||||
return f"""
|
||||
tool.{self.index}
|
||||
name={self.name}
|
||||
arguments={self.arguments}
|
||||
result={str(self.result)}
|
||||
""".strip()
|
||||
return f"tool.{self.index}\nname={self.name}\narguments={self.arguments}\nresult={str(self.result)}".strip()
|
||||
|
||||
|
||||
class Message(BaseModel):
|
||||
|
|
@ -117,21 +113,19 @@ class Sample(BaseModel):
|
|||
class Trajectory(BaseModel):
|
||||
id: str = Field(default_factory=lambda: uuid4().hex)
|
||||
steps: List[Message] = Field(default_factory=list)
|
||||
current_step: int = Field(default=0)
|
||||
is_terminated: bool = Field(default=False)
|
||||
reward: Reward = Field(default_factory=Reward)
|
||||
|
||||
done: bool = Field(default=False)
|
||||
query: str = Field(default="")
|
||||
answer: Any = Field(default=None)
|
||||
answer: str = Field(default="")
|
||||
metadata: dict = Field(default_factory=dict)
|
||||
|
||||
def add_step(self, step: Message):
|
||||
self.steps.append(step)
|
||||
|
||||
def reset(self):
|
||||
self.id = uuid4().hex
|
||||
self.steps.clear()
|
||||
self.current_step = 0
|
||||
self.done = False
|
||||
self.query = ""
|
||||
self.answer = ""
|
||||
self.metadata.clear()
|
||||
for name, field in self.model_fields.items():
|
||||
if field.default is not None:
|
||||
setattr(self, name, field.default)
|
||||
elif field.default_factory is not None:
|
||||
setattr(self, name, field.default_factory())
|
||||
|
|
|
|||
|
|
@ -1,17 +0,0 @@
|
|||
from typing import List
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
from experiencemaker.schema.trajectory import Sample
|
||||
|
||||
|
||||
class BaseSampleBuffer(BaseModel):
|
||||
|
||||
def add(self, samples: Sample | List[Sample]):
|
||||
raise NotImplementedError
|
||||
|
||||
def get_all(self):
|
||||
raise NotImplementedError
|
||||
|
||||
def clear(self):
|
||||
raise NotImplementedError
|
||||
Loading…
Add table
Reference in a new issue