Skip to content

Commit

Permalink
Add environment modules (#378)
Browse files Browse the repository at this point in the history
Co-authored-by: panxuchen <[email protected]>
Co-authored-by: gaoheyang <[email protected]>
Co-authored-by: chenyushuo <[email protected]>
  • Loading branch information
4 people authored Oct 28, 2024
1 parent 7befaf8 commit 282244e
Show file tree
Hide file tree
Showing 82 changed files with 8,751 additions and 2,234 deletions.
678 changes: 360 additions & 318 deletions docs/sphinx_doc/en/source/tutorial/208-distribute.md

Large diffs are not rendered by default.

1 change: 1 addition & 0 deletions docs/sphinx_doc/zh_CN/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,7 @@ AgentScope 文档
agentscope.service
agentscope.rpc
agentscope.server
agentscope.environment
agentscope.web
agentscope.prompt
agentscope.utils
685 changes: 369 additions & 316 deletions docs/sphinx_doc/zh_CN/source/tutorial/208-distribute.md

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion examples/distributed_parallel_optimization/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -53,7 +53,7 @@ def parse_args() -> argparse.Namespace:
model_config_name="my_model",
)
if args.use_dist:
answerer = answerer.to_dist(lazy_launch=False)
answerer = answerer.to_dist()
answerers.append(answerer)

user_agent = UserAgent()
Expand Down
2 changes: 1 addition & 1 deletion examples/distributed_simulation/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -196,7 +196,7 @@ def run_main_process(
Msg(
name="Moderator",
role="assistant",
content=f"The average value is {summ/cnt} [takes {et-st} s]",
content=f"The average value is {summ / cnt} [takes {et - st} s]",
),
)

Expand Down
55 changes: 55 additions & 0 deletions examples/environments/auction_simulation/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,55 @@
# Simple Auction Simulation

This is a simple example of auction simulation to show the environment module of AgentScope.

## Background

This example simulates the following scenario:

Some bidders, each carrying their own money, participate in an auction. After the bidding for an item begins, they decide whether to bid a higher price after hearing the bids of others. When no one places a bid after the waiting time has elapsed, the auctioneer announces the auction results.

## How to Run

```shell
cd examples/environments/auction_simulation
python main.py
```

You can also set the following arguments:

- `bidder-num`: the number of bidders who participate in the auction.
- `agent-type`: `random` or `llm`, the agent type of bidders.
- `waiting-time`: the waiting time for the auctioneer to decide the winner.
- `use-dist`: whether to use the distributed version. (You have to shut down the simulation manually in the distributed version.)

The following is sample output:

```log
Auction: Auction starts!
Listener: Notifying the bidder bidder_0...
Listener: Notifying the bidder bidder_1...
Listener: Notifying the bidder bidder_2...
Listener: Notifying the bidder bidder_3...
Listener: Notifying the bidder bidder_4...
bidder_1: Bid 34 for oil_painting
Listener: Bidder bidder_1 bids 34 for oil_painting. Notifying Bidder bidder_0
Listener: Bidder bidder_1 bids 34 for oil_painting. Notifying Bidder bidder_2
Listener: Bidder bidder_1 bids 34 for oil_painting. Notifying Bidder bidder_3
Listener: Bidder bidder_1 bids 34 for oil_painting. Notifying Bidder bidder_4
...
bidder_1: Bid 88 for oil_painting
Listener: Bidder bidder_1 bids 88 for oil_painting. Notifying Bidder bidder_0
bidder_0: Bid 53 for oil_painting
Listener: Bidder bidder_1 bids 88 for oil_painting. Notifying Bidder bidder_2
Listener: Bidder bidder_1 bids 88 for oil_painting. Notifying Bidder bidder_3
Listener: Bidder bidder_1 bids 88 for oil_painting. Notifying Bidder bidder_4
bidder_3: Not bid for oil_painting
bidder_0: Not bid for oil_painting
bidder_3: Bid 35 for oil_painting
bidder_4: Bid 21 for oil_painting
bidder_0: Not bid for oil_painting
bidder_1: Bid 26 for oil_painting
bidder_2: Not bid for oil_painting
Auction: Auction ends!
Auction: oil_painting is sold to bidder_1 for 88
```
156 changes: 156 additions & 0 deletions examples/environments/auction_simulation/agents.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,156 @@
# -*- coding: utf-8 -*-
"""The agents used to simulate an auction."""
import random
import re
import time
from typing import Optional, Sequence, Union

from env import Item

from loguru import logger
from agentscope.agents import AgentBase
from agentscope.message import Msg


class RandomBidder(AgentBase):
"""A fake bidder agent who bids randomly."""

def __init__(
self,
name: str,
money: int = 100,
not_bid_ratio: float = 0.5,
sleep_time: float = 1.0,
) -> None:
"""Initialize the bidder agent."""
super().__init__(name=name)
self.money = money
self.not_bid_ratio = not_bid_ratio
self.sleep_time = sleep_time

def generate_random_response(self, start: int = 0) -> Optional[int]:
"""Generate a random bid or not to bid."""
time.sleep(random.random() * self.sleep_time)
if random.random() < self.not_bid_ratio:
return None
return random.randint(start, self.money)

def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
"""Generate a random value"""
item = Item.from_dict(x.content["item"])
# generate a random bid or not to bid
response = self.generate_random_response(item.opening_price)
if response is None:
self.speak(
Msg(
self.name,
content=f"Not bid for {item.name}",
role="assistant",
),
)
return Msg(self.name, content=None, role="assistant")
else:
self.speak(
Msg(
self.name,
content=f"Bid {response} for {item.name}",
role="assistant",
),
)
msg = Msg(self.name, content=response, role="assistant")
return msg


class Bidder(AgentBase):
"""The bidder agent."""

def __init__(
self,
name: str,
model_config_name: str,
money: int = 100,
) -> None:
"""Initialize the bidder agent."""
super().__init__(
name=name,
model_config_name=model_config_name,
use_memory=True,
)
self.money = money
self.prompt = Msg(
name="system",
role="system",
content="You are a bidder. You will be given an item. "
f"You have {self.money} money. "
"Please consider whether to bid for the item. "
"If you want to bid, please provide the bid value "
"(an integer between 1 and your money). "
"If you don't want to bid, please provide 0.",
)

def parse_value(self, txt: str) -> Optional[int]:
"""Parse the bid from the response."""
numbers = re.findall(r"\d+", txt)
if len(numbers) == 0:
logger.warning(
f"Fail to parse value from [{txt}], use not bidding instead.",
)
return None
elif int(numbers[-1]) > self.money:
logger.warning(
f"Try to bid more than {self.money}, "
f"use {self.money} instead.",
)
return self.money
else:
return int(numbers[-1]) if numbers[-1] != "0" else None

def reply(self, x: Optional[Union[Msg, Sequence[Msg]]] = None) -> Msg:
"""Generate a value by LLM"""

if self.memory:
self.memory.add(x)

item = Item.from_dict(x.content["item"])
bidder_name = x.content.get("bidder_name", None)
prev_bid = x.content.get("bid", None)
content = (
f"The item is {item.name} and "
f"the opening price is {item.opening_price}."
)
if bidder_name and prev_bid:
content += f"\n{bidder_name} bid {prev_bid} for the item."
bid_info = Msg("assistant", content=content, role="assistant")

# prepare prompt
prompt = self.model.format(
self.prompt,
self.memory.get_memory(),
bid_info,
)

# call llm and generate response
response = self.model(prompt).text
bid = self.parse_value(response)
msg = Msg(self.name, bid, role="assistant")
if response is None:
self.speak(
Msg(
self.name,
content=f"Not bid for {item.name}",
role="assistant",
),
)
else:
self.speak(
Msg(
self.name,
content=f"Bid {response} for {item.name}",
role="assistant",
),
)
# Record the message in memory
if self.memory:
self.memory.add(msg)

return msg
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
[
{
"config_name": "model",
"model_type": "openai_chat",
"model_name": "path-to-your-model-dir",
"api_key": "EMPTY",
"client_args": {
"base_url": "http://localhost:8083/v1"
},
"generate_args": {
"temperature": 1.0
}
}
]
Loading

0 comments on commit 282244e

Please sign in to comment.