Skip to content

Commit

Permalink
Support to serialize message objects in AgentScope and remove unused …
Browse files Browse the repository at this point in the history
…arguments. (modelscope#388)

---------

Co-authored-by: qbc <[email protected]>
  • Loading branch information
DavdGao and qbc2016 authored Aug 27, 2024
1 parent a265d3f commit bc2e24b
Show file tree
Hide file tree
Showing 47 changed files with 849 additions and 502 deletions.
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,
**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

0 comments on commit bc2e24b

Please sign in to comment.