Skip to content

Commit

Permalink
update docstring and tutorial of rpc agent
Browse files Browse the repository at this point in the history
  • Loading branch information
pan-x-c committed Jan 25, 2024
1 parent 7c3100d commit c768864
Show file tree
Hide file tree
Showing 10 changed files with 121 additions and 81 deletions.
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
37 changes: 22 additions & 15 deletions docs/sphinx_doc/source/tutorial/208-distribute.md
Original file line number Diff line number Diff line change
Expand Up @@ -45,36 +45,35 @@ A-->C

Please follow the steps below to deploy your application distributedly.

### Write your agents
### Convert your agents

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.
The usage is exactly the same as single process mode, and you only need to ensure that the agents used are instances of `RpcAgentBase` subclasses.
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`.
Suppose you have classes `A` and `B`, both of which inherit from `AgentBase`.

```python
# import packages

a = A(
name="A",
...,
)
).to_dist()
b = B(
name="B",
...,
)
).to_dist()

x = None
while x is None or x.content != 'exit':
Expand All @@ -90,8 +89,11 @@ 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,
Expand All @@ -107,8 +109,11 @@ 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,
Expand All @@ -124,14 +129,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
10 changes: 5 additions & 5 deletions examples/distributed/distributed_debate.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,11 +69,11 @@ 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=DialogAgent,
**config,
)
server_launcher.launch()
server_launcher.wait_until_terminate()
Expand All @@ -86,21 +86,21 @@ def run_main_process(parsed_args: argparse.Namespace) -> None:
)
pro_agent = DialogAgent(
name="Pro",
).to_distributed(
).to_dist(
host=parsed_args.pro_host,
port=parsed_args.pro_port,
launch_server=False,
)
con_agent = DialogAgent(
name="Con",
).to_distributed(
).to_dist(
host=parsed_args.con_host,
port=parsed_args.con_port,
launch_server=False,
)
judge_agent = DialogAgent(
name="Judge",
).to_distributed(
).to_dist(
host=parsed_args.judge_host,
port=parsed_args.judge_port,
launch_server=False,
Expand Down
9 changes: 4 additions & 5 deletions examples/distributed/distributed_dialog.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@
""" An example of distributed dialog """

import argparse
import time
from loguru import logger

import agentscope
Expand Down Expand Up @@ -41,13 +40,14 @@ def setup_assistant_server(assistant_host: str, assistant_port: int) -> None:
agent_class=DialogAgent,
agent_kwargs={
"name": "Assitant",
"host": assistant_host,
"port": assistant_port,
"sys_prompt": "You are a helpful assistant.",
"model": "gpt-3.5-turbo",
"use_memory": True,
"local_mode": False,
},
host=assistant_host,
port=assistant_port,
local_mode=False,
)
assistant_server_launcher.launch()
assistant_server_launcher.wait_until_terminate()
Expand All @@ -60,7 +60,7 @@ def run_main_process(assistant_host: str, assistant_port: int) -> None:
)
assistant_agent = DialogAgent(
name="Assistant",
).to_distributed(
).to_dist(
host=assistant_host,
port=assistant_port,
launch_server=False,
Expand All @@ -77,7 +77,6 @@ def run_main_process(assistant_host: str, assistant_port: int) -> None:
while not msg.content.endswith("exit"):
msg = assistant_agent(msg)
logger.chat(msg)
time.sleep(0.5)
msg = user_agent(msg)


Expand Down
6 changes: 3 additions & 3 deletions notebook/distributed_debate.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -93,19 +93,19 @@
" 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",
").to_distributed()\n",
").to_dist()\n",
"con_agent = DialogAgent(\n",
" name=\"Con\",\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",
").to_distributed()\n",
").to_dist()\n",
"judge_agent = DialogAgent(\n",
" name=\"Judge\",\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_distributed()"
").to_dist()"
]
},
{
Expand Down
3 changes: 1 addition & 2 deletions notebook/distributed_dialog.ipynb
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@
" sys_prompt=\"You are a helpful assistant.\",\n",
" model=\"gpt-3.5-turbo\",\n",
" use_memory=True,\n",
").to_distributed()\n",
").to_dist()\n",
"user_agent = UserAgent(\n",
" name=\"User\",\n",
")"
Expand Down Expand Up @@ -119,7 +119,6 @@
"while not msg.content.endswith(\"exit\"):\n",
" msg = assistant_agent(msg)\n",
" logger.chat(msg)\n",
" time.sleep(0.5)\n",
" msg = user_agent(msg)"
]
}
Expand Down
24 changes: 22 additions & 2 deletions src/agentscope/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -182,7 +182,7 @@ def _broadcast_to_audience(self, x: dict) -> None:
for agent in self._audience:
agent.observe(x)

def to_distributed(
def to_dist(
self,
host: str = "localhost",
port: int = None,
Expand All @@ -192,7 +192,27 @@ def to_distributed(
local_mode: bool = True,
lazy_launch: bool = True,
) -> AgentBase:
"""Convert current agent instance into a distributed version"""
"""Convert current agent instance into a distributed version.
Args:
host (`str`, defaults to `"localhost"`):
Hostname of the rpc agent server.
port (`int`, defaults to `None`):
Port of the rpc agent server.
max_pool_size (`int`, defaults to `100`):
Max number of task results that the server can accommodate.
max_timeout_seconds (`int`, defaults to `1800`):
Timeout for task results.
local_mode (`bool`, defaults to `True`):
Whether the started rpc server only listens to local
requests.
lazy_launch (`bool`, defaults to `True`):
Only launch the server when the agent is called.
Returns:
`AgentBase`: the wrapped agent instance with distributed
functionality
"""
from .rpc_agent import RpcAgent

if issubclass(self.__class__, RpcAgent):
Expand Down
Loading

0 comments on commit c768864

Please sign in to comment.