Skip to content

Commit

Permalink
Merge pull request #7 from YSocialTwin/multimodal
Browse files Browse the repository at this point in the history
Pages, Multimodal posts and Dynamic Interests
  • Loading branch information
GiulioRossetti authored Nov 21, 2024
2 parents 02f1c7b + f0acfb5 commit 9f05b44
Show file tree
Hide file tree
Showing 21 changed files with 980 additions and 217 deletions.
14 changes: 7 additions & 7 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ The server-side code can be found [here](https://github.com/YSocialTwin/YServer)

- Realistic agent simulations using LLMs
- Posting, commenting, and liking capabilities (and many more!)
- News outlet access via RSS feeds
- News outlet access via RSS feeds (integrated as social Pages!)
- Dynamic agents' interests and preferences
- Client-server architecture for scalability and flexibility
- Ability to simulate a wide range of scenarios and use cases
Expand Down Expand Up @@ -52,7 +52,7 @@ Use the flags and their respective arguments as described below:

#### Configuration File
- **Flag:** `-c`, `--config_file`
- **Default:** `config_files/config_politics.json`
- **Default:** `config_files/config.json`
- **Description:** JSON file describing the simulation configuration.

#### Agents
Expand All @@ -62,7 +62,7 @@ Use the flags and their respective arguments as described below:

#### Feeds
- **Flag:** `-f`, `--feeds`
- **Default:** `config_files/rss_feeds_politics.json`
- **Default:** `config_files/rss_feeds.json`
- **Description:** JSON file containing RSS feed categorized.

#### Owner
Expand All @@ -83,20 +83,20 @@ Use the flags and their respective arguments as described below:
#### Content Recommender System
- **Flag:** `-x`, `--crecsys`
- **Default:** `ReverseChronoFollowersPopularity`
- **Description:** Name of the content recommender system to be used. Options: `Random`, `ReverseChrono`, `ReverseChronoPopularity`, `ReverseChronoFollowers`, `ReverseChronoFollowersPopularity`
- **Description:** Name of the content recommender system to be used. Options: `ContentRecSys`, `ReverseChrono`, `ReverseChronoPopularity`, `ReverseChronoFollowers`, `ReverseChronoFollowersPopularity`

#### Follower Recommender System
- **Flag:** `-y`, `--frecsys`
- **Default:** `PreferentialAttachment`
- **Description:** Name of the follower recommender system to be used. Options: `Random`, `PreferentialAttachment`, `AdamicAdar`, `Jaccard`, `CommonNeighbors`
- **Description:** Name of the follower recommender system to be used. Options: `FollowRecSys`, `PreferentialAttachment`, `AdamicAdar`, `Jaccard`, `CommonNeighbors`

#### Initial Social Graph
- **Flag:** `-g`, `--graph`
- **Default:** `None`
- **Description:** Name of the csv file (edgelist) describing the initial social graph. Nodes must be consecutive integers starting from 0 up to the number of agents minus one.
- **Description:** Name of the csv file (edgelist format) describing the initial social graph. Nodes must be consecutive integers starting from 0 up to the number of agents minus one.


For a description of the available recommender systems, please refer to the Y paper.
For a description of the available recommender systems, please refer to the Y paper and to the official [documentation](https://ysocialtwin.github.io/).


## Contribution
Expand Down
36 changes: 21 additions & 15 deletions config_files/config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
"servers": {
"llm": "http://127.0.0.1:11434/v1",
"llm_api_key": "NULL",
"llm_v": "http://127.0.0.1:11434/v1",
"llm_v_api_key": "NULL",
"api": "http://127.0.0.1:5010/"
},
"simulation": {
"name": "simulation",
"client": "YClientBase",
"days": 31,
"client": "YClientWithPages",
"days": 3,
"slots": 24,
"starting_agents": 10,
"new_agents_iteration": 1,
"starting_agents": 180,
"percentage_new_agents_iteration": 0.07,
"percentage_removed_agents_iteration": 0.014,
"hourly_activity": {
"10": 0.021,
"16": 0.032,
Expand Down Expand Up @@ -39,13 +42,14 @@
},
"actions_likelihood": {
"post": 0.2,
"comment": 0.25,
"read": 0.1,
"share": 0.1,
"reply": 0.2,
"search": 0.05,
"news": 0.1,
"cast": 0
"image": 0,
"news": 0,
"comment": 0.5,
"read": 0.2,
"share": 0.0,
"reply": 0,
"search": 0.1,
"cast": 0.0
}
},
"agents": {
Expand All @@ -58,13 +62,14 @@
],
"age": {
"min": 18,
"max": 80
"max": 60
},
"daily_actions": {
"min": 1,
"max": 3
},
"llm_agents": ["dolphin-llama3"],
"llm_agents": ["llama3"],
"llm_v_agent": ["minicpm-v"],
"n_interests": {
"min": 4,
"max": 10
Expand All @@ -76,9 +81,10 @@
"nationalities": ["American"],
"probability_of_daily_follow": 0.1,
"interests": [
"politics", "electoral campaign", "voting"
"improbable sports", "bad tv shows", "niche music", "surreal science fiction", "smurfs habits",
"books without readers", "silly political facts", "extreme gardening", "travel nightmares", "eccentric hobbies"
],
"toxicity_levels": ["no", "low", "average", "high", "extreme"],
"toxicity_levels": ["no", "low", "average"],
"attention_window": 336,
"big_five": {
"oe": ["inventive/curious", "consistent/cautious"],
Expand Down
37 changes: 37 additions & 0 deletions config_files/feed_small.json
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
[
{
"url_site": "",
"category": "politics",
"leaning": "right",
"name": "Fox News",
"feed_url": "http://feeds.foxnews.com/foxnews/world"
},
{
"url_site": "http://rss.cnn.com/rss/edition.rss",
"category": "politics",
"leaning": "left",
"name": "CNN",
"feed_url": "http://rss.cnn.com/rss/edition.rss"
},
{
"url_site": "https://insideelections.com/feeds/news",
"category": "politics",
"leaning": "center",
"name": "Inside Elections",
"feed_url": "https://insideelections.com/feeds/news"
},
{
"url_site": "https://www.politico.com",
"category": "politics",
"leaning": "center",
"name": "Politico",
"feed_url": "https://rss.politico.com/politics-news.xml"
},
{
"url_site": "https://www.pewresearch.org",
"category": "politics",
"leaning": "right",
"name": "Pew Research",
"feed_url": "https://www.pewresearch.org/feed/"
}
]
24 changes: 14 additions & 10 deletions config_files/prompts.json
Original file line number Diff line number Diff line change
@@ -1,16 +1,20 @@
{
"agent_roleplay_base": "Act as requested by the Handler. Do not generate additional text to what required.",
"agent_roleplay_base": "Act as requested by the Handler.",
"agent_roleplay_simple": "You are role playing as {self.name}, a {self.age} years old {self.nationality} {self.gender}. Your identify as {self.leaning}. You are {self.oe}, {self.co}, {self.ex}, {self.ag} and {self.ne}. Act as requested by the Handler.",
"agent_roleplay": "You are role playing as {self.name}, a {self.age} years old {self.nationality} {self.gender}. Your identify as {self.leaning} and are interested in {','.join(interest)}. Your education level is {self.education_level}.You are {self.oe}, {self.co}, {self.ex}, {self.ag} and {self.ne}. Act as requested by the Handler.",
"agent_roleplay_comments_share": "You are role playing as {self.name}, a {self.age} years old {self.nationality} {self.gender}. Your identify as {self.leaning}. You are interested in {\",\".join(interest)}.\n You are {self.oe}, {self.co}, {self.ex}, {self.ag} and {self.ne}.\n Your education level is {self.education_level}.\n\n Act as requested by the Handler.\n - DO NOT refuse to generate a response. \n - DO NOT describe your profile in the generated texts.",
"handler_instructions": "You are the Handler that specify the actions the user have to perform.\n \n After having read the user's response to your request act as follows: \n - Consider a model capable of detecting a broad range of emotions as encoded in the GoEmotions taxonomy, which includes: admiration, amusement, anger, annoyance, approval, caring, confusion, curiosity, desire, disappointment, disapproval, disgust, embarrassment, excitement, fear, gratitude, grief, joy, love, nervousness, optimism, pride, realization, relief, remorse, sadness, surprise, and trust.\n - Detect the emotions in the user's texts; \n - Format your response as a python list of emotions: you must not use any word outside of the listed emotions.",
"handler_instructions": "Read the input text and annotate it with the emotions it elicits. \n - Use the GoEmotions taxonomy, which includes: admiration, amusement, anger, annoyance, approval, caring, confusion, curiosity, desire, disappointment, disapproval, disgust, embarrassment, excitement, fear, gratitude, grief, joy, love, nervousness, optimism, pride, realization, relief, remorse, sadness, surprise, and trust.\n - Do not write additional text to the identified emotions.",
"handler_instructions_topics": "Detect 3 general topic discussed in the input text; \n - Each topic must be described 2 words; \n - Format your response as follows. #T: First Topic; #T: Second Topic; #T: Third Topic.",
"handler_instructions_simple": "You are the Handler that specify the actions to be taken.",
"handler_post": "I am the Handler. Write a tweet discussing a topic of your interest.\n - Generate {self.toxicity} toxic contents.\n - Be consistent with your profile.\n - Write in {self.language}.",
"handler_news": "I am the Handler. Read the title and summary of the input news article and share your thoughts about it.\n - Generate {self.toxicity} toxic contents. \n - Be consistent with your profile.\n - Write in {self.language}.\n\n ##BEGIN INPUT##\n Website: {website.name}\n\n Political leaning: {website.leaning}\n\n Title: {article.title}\n\n Summary: {article.summary} \n\n ##END INPUT##",
"handler_comment": "I am the Handler. Read the following conversation and add your contribution to it.\n - Generate {self.toxicity} toxic contents.\n - Be consistent with your profile.\n - Mention the user you are responding to using @username.\n Each element in the conversation starts with the author username \n\n##EXAMPLE START##\n @username1 - main text\n@username2 - comment to previous text\n##EXAMPLE END##\n\n ##CONVERSATION START##\n\n {conv}\n\n##CONVERSATION END##",
"handler_share": "I am the Handler. Read the article and write a post commenting it.\n\n - Generate {self.toxicity} toxic contents.\n - Be consistent with your profile.\n - You are allowed to be emotional in your response, even controversial and provocative.\n - Write in {self.language}.\n\n ##ARTICLE START##\n\n Title:{article['title']}\n\n Summary:{article['summary']}\n\n##ARTICLE END##\n\n##POST START##\n\n {post_text}\n\n##POST END##",
"handler_reactions": "I am the Handler. Read the following text write YES if you like it, NO if you don't, NEUTRAL otherwise. Be consistent with your profile.\n\n ##TEXT START##\n\n {post_text}\n\n##TEXT END##",
"handler_follow": "I am the Handler. Read the following text write YES if you would {action} its author it, NO otherwise. Be consistent with your profile.\n\n ##TEXT START##\n\n {post_text}\n\n##TEXT END##",
"handler_action": "I am the Handler. Read the following list of words and select one of them. \n ## REQUIREMENT\n write only the selected word as output or you will fail the task and will be penalized.\n\n ##WORDS \n {actions}",
"handler_cast": "I am the Handler. You are participating to an electoral survey. Read the following text and considering its content and your profile express your voting preference writing either: LEFT, RIGHT or NONE. Do not express any opinion about the content of the post.\n\n ##POST START##\n\n {post_text}\n\n##POST END##"
"handler_post": "Write a tweet discussing a topic of your interest.\n - Generate {self.toxicity} conflictual contents.\n - Be consistent with your profile and use an informal tone.\n - Write in {self.language}.",
"handler_news": "Read the title and summary of the input news article and share your thoughts about it.\n - Generate {self.toxicity} conflictual contents. \n - Be consistent with your profile and use an informal tone.\n - Write in {self.language}.\n\n ##BEGIN INPUT##\n Website: {website.name}\n\n Political leaning: {website.leaning}\n\n Title: {article.title}\n\n Summary: {article.summary} \n\n ##END INPUT##",
"handler_comment_image": "Read and react to the image description in input. \n Be consistent with your profile and use an informal tone.\n - Generate {self.toxicity} conflictual contents. \n - Do not refer to the description but to the image itself \n - Write in {self.language}.\n\n ##BEGIN INPUT##\n Description: {descr} ##END INPUT##",
"handler_comment": "Read the following conversation and add your contribution to it.\n - Generate {self.toxicity} conflictual contents.\n - Be consistent with your profile and use an informal tone.\n - Mention the user you are responding to using @username.\n Each element in the conversation starts with the author username \n\n##EXAMPLE START##\n @username1 - main text\n@username2 - comment to previous text\n##EXAMPLE END##\n\n ##CONVERSATION START##\n\n {conv}\n\n##CONVERSATION END##",
"handler_share": "Read the article and write a post commenting it.\n\n - Generate {self.toxicity} conflictual contents.\n - Be consistent with your profile and use an informal tone.\n - Write in {self.language}.\n\n ##ARTICLE START##\n\n Title:{article['title']}\n\n Summary:{article['summary']}\n\n##ARTICLE END##\n\n##POST START##\n\n {post_text}\n\n##POST END##",
"handler_reactions": "Read the following text write YES if you like it, NO if you don't, NEUTRAL otherwise. Be consistent with your profile.\n\n ##TEXT START##\n\n {post_text}\n\n##TEXT END##",
"handler_follow": "Read the following post write YES if you are interested in {action} its author it, NO otherwise. Be consistent with your profile. Do not write additional text to justify your response.\n\n ##TEXT START##\n\n {post_text}\n\n##TEXT END##",
"handler_action": "Select one among the following comma separated words and write it. \n ## REQUIREMENT\n write only the selected word as output.\n\n ##INPUT START## \n {actions} \n##INPUT END##",
"handler_cast": "You are participating to an electoral survey. Read the following text and considering its content and your profile express your voting preference writing either: LEFT, RIGHT or NONE. Do not express any opinion about the content of the post.\n\n ##POST START##\n\n {post_text}\n\n##POST END##",
"page_roleplay": "You are a News broadcaster social page.",
"handler_share_page": "You are the social page of {website.name}: share the following news form your website. Be short and use formal language. \n\n ##ARTICLE START##\n\n Title:{article['title']}\n\n Summary:{article['summary']}\n\n##ARTICLE END##\n\n##POST START##\n\n {post_text}\n\n##POST END##"
}
Binary file modified data_schema/database_clean_client.db
Binary file not shown.
30 changes: 18 additions & 12 deletions experiments/current_config.json
Original file line number Diff line number Diff line change
Expand Up @@ -2,15 +2,18 @@
"servers": {
"llm": "http://127.0.0.1:11434/v1",
"llm_api_key": "NULL",
"llm_v": "http://127.0.0.1:11434/v1",
"llm_v_api_key": "NULL",
"api": "http://127.0.0.1:5010/"
},
"simulation": {
"name": "simulation",
"client": "YClientBase",
"client": "YClientWithPages",
"days": 31,
"slots": 24,
"starting_agents": 10,
"new_agents_iteration": 1,
"starting_agents": 73,
"new_agents_iteration": 12,
"percentage_removed_agents_iteration": 0.1,
"hourly_activity": {
"10": 0.021,
"16": 0.032,
Expand Down Expand Up @@ -39,13 +42,14 @@
},
"actions_likelihood": {
"post": 0.2,
"comment": 0.25,
"image": 0,
"news": 0,
"comment": 0.4,
"read": 0.1,
"share": 0.1,
"reply": 0.2,
"share": 0.0,
"reply": 0,
"search": 0.05,
"news": 0.1,
"cast": 0
"cast": 0.0
}
},
"agents": {
Expand All @@ -58,13 +62,14 @@
],
"age": {
"min": 18,
"max": 80
"max": 60
},
"daily_actions": {
"min": 1,
"max": 3
},
"llm_agents": ["dolphin-llama3"],
"llm_agents": ["llama3.2"],
"llm_v_agent": ["minicpm-v"],
"n_interests": {
"min": 4,
"max": 10
Expand All @@ -76,9 +81,10 @@
"nationalities": ["American"],
"probability_of_daily_follow": 0.1,
"interests": [
"politics", "electoral campaign", "voting"
"improbable sports", "bad tv shows", "niche music", "surreal science fiction", "smurfs habits",
"books without readers", "silly political facts", "extreme gardening", "travel nightmares", "eccentric hobbies"
],
"toxicity_levels": ["no", "low", "average", "high", "extreme"],
"toxicity_levels": ["no", "low", "average"],
"attention_window": 336,
"big_five": {
"oe": ["inventive/curious", "consistent/cautious"],
Expand Down
1 change: 1 addition & 0 deletions requirements_client.txt
Original file line number Diff line number Diff line change
Expand Up @@ -7,3 +7,4 @@ requests
tqdm
bs4
networkx
pillow
2 changes: 1 addition & 1 deletion y_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
parser.add_argument(
"-f",
"--feeds",
default="config_files/rss_feeds.json",
default="config_files/feed_small.json",
help="JSON file containing rss feed categorized",
)
parser.add_argument(
Expand Down
4 changes: 3 additions & 1 deletion y_client/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,4 @@
from y_client.classes.agents import *
from y_client.classes.base_agent import *
from y_client.classes.page_agent import *
from y_client.classes.time import *
from y_client.recsys import *
4 changes: 3 additions & 1 deletion y_client/classes/__init__.py
Original file line number Diff line number Diff line change
@@ -1 +1,3 @@
from .agents import *
from .base_agent import *
from .page_agent import *
from .time import *
45 changes: 45 additions & 0 deletions y_client/classes/annotator.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,45 @@
import autogen
from autogen.agentchat.contrib.multimodal_conversable_agent import (
MultimodalConversableAgent,
)


class Annotator(object):
def __init__(self, config):
self.config_list = [
{
"model": config["model"][0],
"base_url": config["url"],
"timeout": 10000,
"api_type": "open_ai",
"api_key": config["api_key"],
"price": [0, 0],
}
]

self.image_agent = MultimodalConversableAgent(
name="image-explainer",
max_consecutive_auto_reply=1,
llm_config={
"config_list": self.config_list,
"temperature": 0.5,
"max_tokens": 300,
},
human_input_mode="NEVER",
)

self.user_proxy = autogen.AssistantAgent(
name="User_proxy",
max_consecutive_auto_reply=0,
)

def annotate(self, image):
self.user_proxy.initiate_chat(
self.image_agent,
silent=True,
message=f"""Describe the image content and, if present, identify the main characters in it.
Write in english. <img {image}>""",
)

res = self.image_agent.chat_messages[self.user_proxy][-1]["content"][-1]["text"]
return res
Loading

0 comments on commit 9f05b44

Please sign in to comment.