-
Notifications
You must be signed in to change notification settings - Fork 348
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Co-authored-by: panxuchen <[email protected]> Co-authored-by: gaoheyang <[email protected]> Co-authored-by: chenyushuo <[email protected]>
- Loading branch information
1 parent
7befaf8
commit 282244e
Showing
82 changed files
with
8,751 additions
and
2,234 deletions.
There are no files selected for viewing
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
685 changes: 369 additions & 316 deletions
685
docs/sphinx_doc/zh_CN/source/tutorial/208-distribute.md
Large diffs are not rendered by default.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
``` |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 |
14 changes: 14 additions & 0 deletions
14
examples/environments/auction_simulation/configs/model_configs.json
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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 | ||
} | ||
} | ||
] |
Oops, something went wrong.