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

Refactor Distributed Modules #18

Merged
merged 15 commits into from
Feb 1, 2024
Merged
8 changes: 0 additions & 8 deletions docs/sphinx_doc/source/agentscope.agents.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,3 @@ dict_dialog_agent module
:members:
:undoc-members:
:show-inheritance:

rpc_dialog_agent module
-------------------------------

.. automodule:: agentscope.agents.dict_dialog_agent
:members:
:undoc-members:
:show-inheritance:
1 change: 0 additions & 1 deletion docs/sphinx_doc/source/tutorial/201-agent.md
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,6 @@ Below is a table summarizing the functionality of some of the key agents availab
| Agent Type | Description | Typical Use Cases |
| -------------- | ------------------------------------------------------------ | ------------------------------------------------------------ |
| `AgentBase` | Serves as the superclass for all agents, providing essential attributes and methods. | The foundation for building any custom agent. |
| `RpcAgentBase` | Executes remote procedure calls in distributed mode. | The foundation for building any custom agent in distributed mode. |
| `DialogAgent` | Manages dialogues by understanding context and generating coherent responses. | Customer service bots, virtual assistants. |
| `UserAgent` | Interacts with the user to collect input, generating messages that may include URLs or additional specifics based on required keys. | Collecting user input for agents |
| *More to Come* | AgentScope is continuously expanding its pool with more specialized agents for diverse applications. | |
Expand Down
42 changes: 22 additions & 20 deletions docs/sphinx_doc/source/tutorial/208-distribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,39 +45,35 @@ A-->C

Please follow the steps below to deploy your application distributedly.

### Write your agents
### Convert your agents
pan-x-c marked this conversation as resolved.
Show resolved Hide resolved

To use distributed functionality, your agent class needs to inherit from `RpcAgentBase`.
`RpcAgentBase` requires several additional parameters compared to `AgentBase` during initialization.
`AgentBase` provided the `to_dist` method to convert the agent into a distributed version.
`to_dist` requires several parameters.

- `host`: the hostname or IP address of the machine where the agent runs, defaults to `localhost`.
- `port`: the port of this agent's RPC server, defaults to `80`.
- `launch_server`: whether to launch an RPC server locally, defaults to `True`.
- `local_mode`: set to `True` if all agents run on the same machine, defaults to `True`.

But don't worry, `RpcAgentBase` shares the same interface as `AgentBase`, you only need to implement the `reply` method. You can even copy the `reply` method of an `AgentBase` subclass and use it in `RpcAgentBase`.
- `lazy_launch`: if set to `True`, only launch the server when the agent is called.

### Run in multi-process mode

AgentScope supports deployment in multi-process mode, where each agent is a sub-process of the application's main process, and all agents run on the same machine.
Its usage is very similar to single-process mode. The only difference lies in the initialization phase.
The usage is exactly the same as single process mode, and you only need to call the `to_dist` method after initialization.

Suppose you have classes `A` and `B`, both of which inherit from `RpcAgentBase`.
You can run the application in multi-process mode by passing in an additional parameter `port`, the other parts are completely the same as the single-process mode.
Suppose you have classes `A` and `B`, both of which inherit from `AgentBase`.

```python
# import packages

a = A(
name="A",
...,
port=12001, # port is required, other fields like host, launch_server and local_mode use the default value
)
).to_dist()
pan-x-c marked this conversation as resolved.
Show resolved Hide resolved
b = B(
name="B",
...,
port=12002, # port is required
)
).to_dist()

x = None
while x is None or x.content != 'exit':
Expand All @@ -93,11 +89,13 @@ AgentScope also supports to run agents on multiple machines. In this case, you n
# import packages

server_a = RpcAgentServerLauncher(
name="A",
...,
agent_class=A,
agent_kwargs={
"name": "A"
...
},
host=ip_a,
port=12001,
local_mode=False,
)
server_a.launch()
server_a.wait_until_terminate()
Expand All @@ -110,11 +108,13 @@ Please make sure that the two machines can access each other using the IP addres
# import packages

server_b = RpcAgentServerLauncher(
name="B",
...,
agent_class=B,
agent_kwargs={
"name": "B",
...
},
host=ip_b,
port=12001,
local_mode=False,
)
server_b.launch()
server_b.wait_until_terminate()
Expand All @@ -127,14 +127,16 @@ Then, you can run the application's main process on any machine that can access

a = A(
name="A",
...,
...
).to_dist(
host=ip_a,
port=12001,
launch_server=False,
)
b = B(
name="B",
...,
...
).to_dist(
host=ip_b,
port=12002,
launch_server=False,
Expand Down
60 changes: 34 additions & 26 deletions examples/distributed/distributed_debate.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

import agentscope
from agentscope.msghub import msghub
from agentscope.agents.rpc_dialog_agent import RpcDialogAgent
from agentscope.agents.dialog_agent import DialogAgent
from agentscope.agents.rpc_agent import RpcAgentServerLauncher
from agentscope.message import Msg
from agentscope.utils.logging_utils import logger
Expand Down Expand Up @@ -69,11 +69,10 @@ def setup_server(parsed_args: argparse.Namespace) -> None:
host = getattr(parsed_args, f"{parsed_args.role}_host")
port = getattr(parsed_args, f"{parsed_args.role}_port")
server_launcher = RpcAgentServerLauncher(
agent_class=DialogAgent,
agent_kwargs=config,
host=host,
port=port,
local_mode=False,
agent_class=RpcDialogAgent,
**config,
)
server_launcher.launch()
server_launcher.wait_until_terminate()
Expand All @@ -84,37 +83,46 @@ def run_main_process(parsed_args: argparse.Namespace) -> None:
agentscope.init(
model_configs="configs/model_configs.json",
)
pro_agent = RpcDialogAgent(
name="Pro",
host=parsed_args.pro_host,
port=parsed_args.pro_port,
launch_server=False,
)
con_agent = RpcDialogAgent(
name="Con",
host=parsed_args.con_host,
port=parsed_args.con_port,
launch_server=False,
)
judge_agent = RpcDialogAgent(
name="Judge",
host=parsed_args.judge_host,
port=parsed_args.judge_port,
launch_server=False,
)
with open(
pan-x-c marked this conversation as resolved.
Show resolved Hide resolved
"configs/debate_agent_configs.json",
"r",
encoding="utf-8",
) as f:
configs = json.load(f)
pro_agent = DialogAgent(
**configs["pro"],
).to_dist(
host=parsed_args.pro_host,
port=parsed_args.pro_port,
launch_server=False,
)
con_agent = DialogAgent(
**configs["con"],
).to_dist(
host=parsed_args.con_host,
port=parsed_args.con_port,
launch_server=False,
)
judge_agent = DialogAgent(
**configs["judge"],
).to_dist(
host=parsed_args.judge_host,
port=parsed_args.judge_port,
launch_server=False,
)
participants = [pro_agent, con_agent, judge_agent]
hint = Msg(name="System", content=ANNOUNCEMENT)
x = None
with msghub(participants=participants, announcement=hint):
for _ in range(3):
pro_resp = pro_agent(x)
logger.chat(pro_resp.update_value())
logger.chat(pro_resp)
con_resp = con_agent(pro_resp)
logger.chat(con_resp.update_value())
logger.chat(con_resp)
x = judge_agent(con_resp)
logger.chat(x.update_value())
logger.chat(x)
x = judge_agent(x)
logger.chat(x.update_value())
logger.chat(x)


if __name__ == "__main__":
Expand Down
25 changes: 14 additions & 11 deletions examples/distributed/distributed_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
""" An example of distributed dialog """

import argparse
import time
from loguru import logger

import agentscope
from agentscope.agents.user_agent import UserAgent
from agentscope.agents.rpc_dialog_agent import RpcDialogAgent
from agentscope.agents.dialog_agent import DialogAgent
from agentscope.agents.rpc_agent import RpcAgentServerLauncher


Expand Down Expand Up @@ -38,14 +37,15 @@ def setup_assistant_server(assistant_host: str, assistant_port: int) -> None:
model_configs="configs/model_configs.json",
)
assistant_server_launcher = RpcAgentServerLauncher(
name="Assitant",
agent_class=RpcDialogAgent,
agent_class=DialogAgent,
agent_kwargs={
"name": "Assitant",
"sys_prompt": "You are a helpful assistant.",
"model": "gpt-3.5-turbo",
"use_memory": True,
},
host=assistant_host,
port=assistant_port,
sys_prompt="You are a helpful assistant.",
model="gpt-3.5-turbo",
use_memory=True,
local_mode=False,
)
assistant_server_launcher.launch()
assistant_server_launcher.wait_until_terminate()
Expand All @@ -56,8 +56,12 @@ def run_main_process(assistant_host: str, assistant_port: int) -> None:
agentscope.init(
model_configs="configs/model_configs.json",
)
assistant_agent = RpcDialogAgent(
assistant_agent = DialogAgent(
name="Assistant",
sys_prompt="You are a helpful assistant.",
model="gpt-3.5-turbo",
use_memory=True,
).to_dist(
host=assistant_host,
port=assistant_port,
launch_server=False,
Expand All @@ -73,8 +77,7 @@ def run_main_process(assistant_host: str, assistant_port: int) -> None:
msg = user_agent()
while not msg.content.endswith("exit"):
msg = assistant_agent(msg)
logger.chat(msg.update_value())
time.sleep(0.5)
logger.chat(msg)
msg = user_agent(msg)


Expand Down
25 changes: 11 additions & 14 deletions notebook/distributed_debate.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -84,31 +84,28 @@
"outputs": [],
"source": [
"import agentscope\n",
"from agentscope.agents.rpc_dialog_agent import RpcDialogAgent\n",
"from agentscope.agents.dialog_agent import DialogAgent\n",
"\n",
"agentscope.init(model_configs=model_configs)\n",
"\n",
"pro_agent = RpcDialogAgent(\n",
"pro_agent = DialogAgent(\n",
" name=\"Pro\",\n",
" port=12001,\n",
" model=\"gpt-3.5-turbo\",\n",
" use_memory=True,\n",
" sys_prompt=\"Assume the role of a debater who is arguing in favor of the proposition that AGI (Artificial General Intelligence) can be achieved using the GPT model framework. Construct a coherent and persuasive argument, including scientific, technological, and theoretical evidence, to support the statement that GPT models are a viable path to AGI. Highlight the advancements in language understanding, adaptability, and scalability of GPT models as key factors in progressing towards AGI.\",\n",
")\n",
"con_agent = RpcDialogAgent(\n",
").to_dist()\n",
"con_agent = DialogAgent(\n",
" name=\"Con\",\n",
" port=12002,\n",
" model=\"gpt-3.5-turbo\",\n",
" use_memory=True,\n",
" sys_prompt=\"Assume the role of a debater who is arguing against the proposition that AGI can be achieved using the GPT model framework. Construct a coherent and persuasive argument, including scientific, technological, and theoretical evidence, to support the statement that GPT models, while impressive, are insufficient for reaching AGI. Discuss the limitations of GPT models such as lack of understanding, consciousness, ethical reasoning, and general problem-solving abilities that are essential for true AGI.\",\n",
")\n",
"judge_agent = RpcDialogAgent(\n",
").to_dist()\n",
"judge_agent = DialogAgent(\n",
" name=\"Judge\",\n",
" port=12003,\n",
" model=\"gpt-3.5-turbo\",\n",
" use_memory=True,\n",
" sys_prompt=\"Assume the role of an impartial judge in a debate where the affirmative side argues that AGI can be achieved using the GPT model framework, and the negative side contests this. Listen to both sides' arguments and provide an analytical judgment on which side presented a more compelling and reasonable case. Consider the strength of the evidence, the persuasiveness of the reasoning, and the overall coherence of the arguments presented by each side.\"\n",
")"
").to_dist()"
]
},
{
Expand Down Expand Up @@ -153,13 +150,13 @@
"with msghub(participants=participants, announcement=hint):\n",
" for _ in range(3):\n",
" pro_resp = pro_agent(x)\n",
" logger.chat(pro_resp.update_value())\n",
" logger.chat(pro_resp)\n",
" con_resp = con_agent(pro_resp)\n",
" logger.chat(con_resp.update_value())\n",
" logger.chat(con_resp)\n",
" x = judge_agent(con_resp)\n",
" logger.chat(x.update_value())\n",
" logger.chat(x)\n",
" x = judge_agent(x)\n",
" logger.chat(x.update_value())\n"
" logger.chat(x)\n"
]
},
{
Expand Down
10 changes: 4 additions & 6 deletions notebook/distributed_dialog.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -80,19 +80,18 @@
"source": [
"import agentscope\n",
"from agentscope.agents.user_agent import UserAgent\n",
"from agentscope.agents.rpc_dialog_agent import RpcDialogAgent\n",
"from agentscope.agents.dialog_agent import DialogAgent\n",
"\n",
"agentscope.init(\n",
" model_configs=model_configs\n",
")\n",
"\n",
"assistant_agent = RpcDialogAgent(\n",
"assistant_agent = DialogAgent(\n",
" name=\"Assistant\",\n",
" port=12010,\n",
" sys_prompt=\"You are a helpful assistant.\",\n",
" model=\"gpt-3.5-turbo\",\n",
" use_memory=True,\n",
")\n",
").to_dist()\n",
"user_agent = UserAgent(\n",
" name=\"User\",\n",
")"
Expand All @@ -119,8 +118,7 @@
"msg = user_agent()\n",
"while not msg.content.endswith(\"exit\"):\n",
" msg = assistant_agent(msg)\n",
" logger.chat(msg.update_value())\n",
" time.sleep(0.5)\n",
" logger.chat(msg)\n",
" msg = user_agent(msg)"
]
}
Expand Down
Loading
Loading