Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Support to serialize message objects in AgentScope and remove unused arguments. #388

Merged
merged 10 commits into from
Aug 27, 2024
1 change: 0 additions & 1 deletion docs/sphinx_doc/en/source/tutorial/201-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -35,7 +35,6 @@ class AgentBase(Operator):
sys_prompt: Optional[str] = None,
model_config_name: str = None,
use_memory: bool = True,
memory_config: Optional[dict] = None,
) -> None:

# ... [code omitted for brevity]
Expand Down
1 change: 0 additions & 1 deletion docs/sphinx_doc/zh_CN/source/tutorial/201-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,6 @@ class AgentBase(Operator):
sys_prompt: Optional[str] = None,
model_config_name: str = None,
use_memory: bool = True,
memory_config: Optional[dict] = None,
) -> None:

# ... [code omitted for brevity]
Expand Down
4 changes: 0 additions & 4 deletions examples/conversation_mixture_of_agents/conversation_moa.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,6 @@ def __init__(
name: str,
moa_module: MixtureOfAgents, # changed to passing moa_module here
use_memory: bool = True,
memory_config: Optional[dict] = None,
) -> None:
"""Initialize the dialog agent.

Expand All @@ -35,14 +34,11 @@ def __init__(
The inited MoA module you want to use as the main module.
use_memory (`bool`, defaults to `True`):
Whether the agent has memory.
memory_config (`Optional[dict]`):
The config of memory.
"""
super().__init__(
name=name,
sys_prompt="",
use_memory=use_memory,
memory_config=memory_config,
)
self.moa_module = moa_module # change model init to moa_module

Expand Down
6 changes: 2 additions & 4 deletions examples/conversation_nl2sql/sql_utils.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# -*- coding: utf-8 -*-
"""
Utils and helpers for performing sql querys.
Utils and helpers for performing sql queries.
Referenced from https://github.com/BeachWang/DAIL-SQL.
"""
import sqlite3
Expand Down Expand Up @@ -261,11 +261,10 @@ def is_sql_question_prompt(self, question: str) -> str:
}
return self.sql_prompt.is_sql_question(target)

def generate_prompt(self, x: dict = None) -> dict:
def generate_prompt(self, question: str) -> dict:
"""
Generate prompt given input question
"""
question = x["content"]
target = {
"path_db": self.db_path,
"question": question,
Expand All @@ -277,7 +276,6 @@ def generate_prompt(self, x: dict = None) -> dict:
self.NUM_EXAMPLE * self.scope_factor,
)
prompt_example = []
question = target["question"]
example_prefix = self.question_style.get_example_prefix()
for example in examples:
example_format = self.question_style.format_example(example)
Expand Down
2 changes: 1 addition & 1 deletion examples/conversation_self_organizing/auto-discussion.py
Original file line number Diff line number Diff line change
Expand Up @@ -55,7 +55,7 @@

x = Msg("user", x, role="user")
settings = agent_builder(x)
scenario_participants = extract_scenario_and_participants(settings["content"])
scenario_participants = extract_scenario_and_participants(settings.content)

# set the agents that participant the discussion
agents = [
Expand Down
6 changes: 3 additions & 3 deletions examples/conversation_with_RAG_agents/rag_example.py
Original file line number Diff line number Diff line change
Expand Up @@ -127,15 +127,15 @@ def main() -> None:
# 5. repeat
x = user_agent()
x.role = "user" # to enforce dashscope requirement on roles
if len(x["content"]) == 0 or str(x["content"]).startswith("exit"):
if len(x.content) == 0 or str(x.content).startswith("exit"):
break
speak_list = filter_agents(x.get("content", ""), rag_agent_list)
speak_list = filter_agents(x.content, rag_agent_list)
if len(speak_list) == 0:
guide_response = guide_agent(x)
# Only one agent can be called in the current version,
# we may support multi-agent conversation later
speak_list = filter_agents(
guide_response.get("content", ""),
guide_response.content,
rag_agent_list,
)
agent_name_list = [agent.name for agent in speak_list]
Expand Down
18 changes: 5 additions & 13 deletions examples/conversation_with_mentions/main.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,5 @@
# -*- coding: utf-8 -*-
""" A group chat where user can talk any time implemented by agentscope. """
from loguru import logger
from groupchat_utils import (
select_next_one,
filter_agents,
Expand Down Expand Up @@ -50,18 +49,11 @@ def main() -> None:
speak_list = []
with msghub(agents, announcement=hint):
while True:
try:
x = user(timeout=USER_TIME_TO_SPEAK)
if x.content == "exit":
break
except TimeoutError:
x = {"content": ""}
logger.info(
f"User has not typed text for "
f"{USER_TIME_TO_SPEAK} seconds, skip.",
)

speak_list += filter_agents(x.get("content", ""), npc_agents)
x = user(timeout=USER_TIME_TO_SPEAK)
if x.content == "exit":
break

speak_list += filter_agents(x.content, npc_agents)

if len(speak_list) > 0:
next_agent = speak_list.pop(0)
Expand Down
4 changes: 2 additions & 2 deletions examples/conversation_with_swe-agent/swe_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -197,7 +197,7 @@ def step(self) -> Msg:
# parse and execute action
action = res.parsed.get("action")

obs = self.prase_command(res.parsed["action"])
obs = self.parse_command(res.parsed["action"])
self.speak(
Msg(self.name, "\n====Observation====\n" + obs, role="assistant"),
)
Expand All @@ -214,7 +214,7 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
action_name = msg.content["action"]["name"]
return msg

def prase_command(self, command_call: dict) -> str:
def parse_command(self, command_call: dict) -> str:
command_name = command_call["name"]
command_args = command_call["arguments"]
if command_name == "exit":
Expand Down
5 changes: 3 additions & 2 deletions examples/distributed_parallel_optimization/answerer_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
return Msg(
self.name,
content=f"Unable to load web page [{x.url}].",
role="assistant",
url=x.url,
)
# prepare prompt
Expand All @@ -49,12 +50,12 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
" the following web page:\n\n"
f"{response['html_to_text']}"
f"\n\nBased on the above web page,"
f" please answer my question\n{x.query}",
f" please answer my question\n{x.metadata}",
),
)
# call llm and generate response
response = self.model(prompt).text
msg = Msg(self.name, content=response, url=x.url)
msg = Msg(self.name, content=response, role="assistant", url=x.url)

self.speak(msg)

Expand Down
4 changes: 3 additions & 1 deletion examples/distributed_parallel_optimization/searcher_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -80,11 +80,13 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
Msg(
name=self.name,
content=result,
role="assistant",
url=result["link"],
query=x.content,
metadata=x.content,
)
for result in results
],
role="assistant",
)
self.speak(
Msg(
Expand Down
6 changes: 3 additions & 3 deletions examples/distributed_simulation/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -187,10 +187,10 @@ def run_main_process(
cnt = 0
for r in results:
try:
summ += int(r["content"]["sum"])
cnt += int(r["content"]["cnt"])
summ += int(r.content["sum"])
cnt += int(r.content["cnt"])
except Exception:
logger.error(r["content"])
logger.error(r.content)
et = time.time()
logger.chat(
Msg(
Expand Down
4 changes: 2 additions & 2 deletions examples/distributed_simulation/participant.py
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
"""Generate a random value"""
# generate a response in content
response = self.generate_random_response()
msg = Msg(self.name, content=response)
msg = Msg(self.name, content=response, role="assistant")
return msg


Expand Down Expand Up @@ -148,7 +148,7 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
summ = 0
for r in results:
try:
summ += int(r["content"])
summ += int(r.content)
except Exception as e:
print(e)
return Msg(
Expand Down
8 changes: 4 additions & 4 deletions examples/paper_llm_based_algorithm/src/alg_agents.py
Original file line number Diff line number Diff line change
Expand Up @@ -90,14 +90,14 @@ def invoke_llm_call(
# Update relevant self.cost_metrics
self.cost_metrics["llm_calls"] += 1
self.cost_metrics["prefilling_length_total"] += len(
x_request["content"],
x_request.content,
) + len(dialog_agent.sys_prompt)
self.cost_metrics["decoding_length_total"] += len(x["content"])
self.cost_metrics["decoding_length_total"] += len(x.content)
self.cost_metrics["prefilling_tokens_total"] += num_tokens_from_string(
x_request["content"],
x_request.content,
) + num_tokens_from_string(dialog_agent.sys_prompt)
self.cost_metrics["decoding_tokens_total"] += num_tokens_from_string(
x["content"],
x.content,
)

return x
2 changes: 1 addition & 1 deletion examples/paper_llm_based_algorithm/src/counting.py
Original file line number Diff line number Diff line change
Expand Up @@ -58,7 +58,7 @@ def solve_directly(
for i in range(nsamples):
x = self.invoke_llm_call(x_request, dialog_agent)
candidate_solutions[i] = self.parse_llm_response_counting(
x["content"],
x.content,
) # int

solution = max(
Expand Down
6 changes: 3 additions & 3 deletions examples/paper_llm_based_algorithm/src/rag.py
Original file line number Diff line number Diff line change
Expand Up @@ -134,7 +134,7 @@ def solve(self, request_string: str, question: str) -> dict:
# )
# x_request = request_agent(x=None, content=content)
# lst_x[i] = self.invoke_llm_call(x_request, dialog_agents[i])
# sub_contents = [x["content"] for x in lst_x]
# sub_contents = [x.content for x in lst_x]
# sub_solutions = ["" for _ in range(len(sub_requests))]
# for i in range(len(sub_solutions)):
# ss = self.parse_llm_response_retrieve_relevant_sentences(
Expand All @@ -158,7 +158,7 @@ def solve(self, request_string: str, question: str) -> dict:
x_request = request_agent(x=None, content=content)
x = self.invoke_llm_call(x_request, dialog_agent)
ss = self.parse_llm_response_retrieve_relevant_sentences(
x["content"],
x.content,
)
sub_solutions[i] = ss
sub_latencies[i] = time.time() - time_start
Expand All @@ -183,7 +183,7 @@ def solve(self, request_string: str, question: str) -> dict:
content = self.prompt_generate_final_answer(context, question)
x_request = request_agent(x=None, content=content)
x = self.invoke_llm_call(x_request, dialog_agent)
solution = self.parse_llm_response_generate_final_answer(x["content"])
solution = self.parse_llm_response_generate_final_answer(x.content)
final_step_latency = time.time() - time_start

result = {
Expand Down
2 changes: 1 addition & 1 deletion examples/paper_llm_based_algorithm/src/retrieval.py
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ def solve_directly(
content = self.prompt_retrieval(request_string, question)
x_request = request_agent(x=None, content=content)
x = self.invoke_llm_call(x_request, dialog_agent)
solution = self.parse_llm_response_retrieval(x["content"])
solution = self.parse_llm_response_retrieval(x.content)
return solution

def solve_decomposition(self, request_string: str, question: str) -> dict:
Expand Down
4 changes: 2 additions & 2 deletions examples/paper_llm_based_algorithm/src/sorting.py
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ def solve_directly(
content = self.prompt_sorting(request_string)
x_request = request_agent(x=None, content=content)
x = self.invoke_llm_call(x_request, dialog_agent)
solution = self.parse_llm_response_sorting(x["content"])
solution = self.parse_llm_response_sorting(x.content)
return solution

def merge_two_sorted_lists(
Expand Down Expand Up @@ -90,7 +90,7 @@ def merge_two_sorted_lists(
content = self.prompt_merging(request_string)
x_request = request_agent(x=None, content=content)
x = self.invoke_llm_call(x_request, dialog_agent)
solution = self.parse_llm_response_sorting(x["content"])
solution = self.parse_llm_response_sorting(x.content)

return solution

Expand Down
26 changes: 2 additions & 24 deletions src/agentscope/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -144,7 +144,6 @@ def __init__(
sys_prompt: Optional[str] = None,
model_config_name: str = None,
use_memory: bool = True,
memory_config: Optional[dict] = None,
to_dist: Optional[Union[DistConf, bool]] = False,
) -> None:
r"""Initialize an agent from the given arguments.
Expand All @@ -160,8 +159,6 @@ def __init__(
configuration.
use_memory (`bool`, defaults to `True`):
Whether the agent has memory.
memory_config (`Optional[dict]`):
The config of memory.
to_dist (`Optional[Union[DistConf, bool]]`, default to `False`):
The configurations passed to :py:meth:`to_dist` method. Used in
:py:class:`_AgentMeta`, when this parameter is provided,
Expand Down Expand Up @@ -189,7 +186,6 @@ def __init__(
See :doc:`Tutorial<tutorial/208-distribute>` for detail.
"""
self.name = name
self.memory_config = memory_config
self.sys_prompt = sys_prompt

# TODO: support to receive a ModelWrapper instance
Expand All @@ -200,7 +196,7 @@ def __init__(
)

if use_memory:
self.memory = TemporaryMemory(memory_config)
self.memory = TemporaryMemory()
else:
self.memory = None

Expand Down Expand Up @@ -276,25 +272,7 @@ def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
f'"reply" function.',
)

def load_from_config(self, config: dict) -> None:
"""Load configuration for this agent.

Args:
config (`dict`): model configuration
"""

def export_config(self) -> dict:
"""Return configuration of this agent.

Returns:
The configuration of current agent.
"""
return {}

def load_memory(self, memory: Sequence[dict]) -> None:
r"""Load input memory."""

def __call__(self, *args: Any, **kwargs: Any) -> dict:
def __call__(self, *args: Any, **kwargs: Any) -> Msg:
"""Calling the reply function, and broadcast the generated
response to all audiences if needed."""
res = self.reply(*args, **kwargs)
Expand Down
14 changes: 9 additions & 5 deletions src/agentscope/agents/dialog_agent.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,8 @@
# -*- coding: utf-8 -*-
"""A general dialog agent."""
from typing import Optional, Union, Sequence
from typing import Optional, Union, Sequence, Any

from loguru import logger

from ..message import Msg
from .agent import AgentBase
Expand All @@ -16,7 +18,7 @@ def __init__(
sys_prompt: str,
model_config_name: str,
use_memory: bool = True,
memory_config: Optional[dict] = None,
DavdGao marked this conversation as resolved.
Show resolved Hide resolved
**kwargs: Any,
) -> None:
"""Initialize the dialog agent.

Expand All @@ -31,17 +33,19 @@ def __init__(
configuration.
use_memory (`bool`, defaults to `True`):
Whether the agent has memory.
memory_config (`Optional[dict]`):
The config of memory.
"""
super().__init__(
name=name,
sys_prompt=sys_prompt,
model_config_name=model_config_name,
use_memory=use_memory,
memory_config=memory_config,
)

if kwargs:
logger.warning(
f"Unused keyword arguments are provided: {kwargs}",
)

def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
"""Reply function of the agent. Processes the input data,
generates a prompt using the current dialogue memory and system
Expand Down
Loading