Overview¶
The goal of Creamas is to aid in development, research and teaching of agent-based systems which exhibit
creative behaviour. Creamas is built on top of
aiomas, from which the basic agent and container
(Environment
in Creamas) are subclassed. The container provides a communication route (RPC) between
agents. If you need to know more about how the low level communication works, see aiomas documentation.
Agents And Environments¶
Agents (CreativeAgent
) in Creamas focus on building artifacts
and evaluating them. Each agent belongs to Environment
, which serves
as a communication route between the agents. Environment can also hold other information
shared by the agents or, e.g., provide means for the agents to communicate only with nearby
agents in a 2D-grid. Agents are created by handling the environment as the first
initialization parameter.
from creamas.core import CreativeAgent, Environment
# Create environment to tcp://localhost:5555/
env = Environment.create(('localhost', 5555))
# Create agent with address tcp://localhost:5555/0
a1 = CreativeAgent(env)
# Create agent with address tcp://localhost:5555/1
a2 = CreativeAgent(env)
The fundamental design principle guiding the development of Creamas is that
agents create artifacts (Artifact
) in some domain(s) and
evaluate them. Most of the functionality is geared towards this goal.
However, Creamas does not take a stand on the design of the multi-agent systems or individual agents and is quite agnostic considering the agent implementations. Therefore, Creamas can be used to develop arbitrary agent societies, but you might want to take a look at aiomas if you do not need any of the additional functionality provided by Creamas.
Communication Between the Agents¶
Communication between the agents in one of the key interests in multi-agent systems.
In Creamas, agents can expose their own functions as services to other agents by using
expose()
decorator (originating from aiomas library). An agent wishing to communicate
with another agent connects to the remote agent and calls the exposed function
remotely. To this end they have to know the other agent’s (tcp) address.
Note
Agents derived from CreativeAgent
are
supposed to store addresses of other agents in their
connections
.
Consider a following simple multiply()
service an agent AgentA has:
import creamas
class AgentA(creamas.CreativeAgent):
@creamas.expose
async def multiply(self, int1, int2):
return int1 * int2
Now, another agent, AgentB, knowing that AgentA’s address is addr
can then use AgentA’s multiply
service by connecting to AgentA through
its environment.
import random
import creamas
class AgentB(creamas.CreativeAgent):
def __init__(self, *args, **kwargs):
super().__init__(*args, **kwargs)
self.int1 = random.randint(0, 100)
self.int2 = random.randint(0, 100)
async def complex_computation(self, addr):
remote_agent_A = await self.env.connect(addr)
value = await remote_agent_A.multiply(self.int1, self.int2)
# do something with the value
return value
Importantly, the agents do not have to reside in the same environment or even on the same machine, i.e. you can connect to any agent or environment as long as you know the address of the specific agent in the environment. However, the remote agent and its environment have to be implemented using classes derived from aiomas library, like Creamas agent classes and environments do.
Note
Connecting to an agent and calling an exposed function are done asynchronously using await keyword before the function call. Any method using await has to have async keyword at the start of its function definition.
Creating and Analyzing Agent Connections¶
Studying varying social network structures in creative agent systems is one of
the main purposes Creamas exists. To generate agent connections and to analyze
them, Creamas has some built-in support for integration with
NetworkX graph library.
These functionalities are found from creamas.nx
module. The main
functions are connections_from_graph()
and
graph_from_connections()
. They allow priming agent-to-agent
connections with varying properties and analyzing them easily using NetworkX
graph structures.
Evaluating Artifacts¶
Exchanging artifacts, and information about them, is an eminent functionality for agents in Creamas. An agent can ask other agent’s opinions about its own artifacts or other artifacts it has seen. This allows the agent to accumulate knowledge about the artifact preferences of other agents, which may alter the agent’s own behavior.
Method ask_opinion()
offers
a shortcut to ask an opinion about an artifact from a remote agent.
# This is a toy example. Code won't work off the shelf as the agents don't
# have any evaluation methods, which we will see in the next section.
from creamas.core import Artifact
# Create some artifact.
ar = Artifact()
# first evaluate it yourself
ev = a1.evaluate(ar)
# ask other agent's opinion (evaluation) of it
remote_addr = a1.connections[0]
ret = a1.ask_opinion(remote_addr, ar)
# get a1's current attitude towards a2
att = a1.get_attitude(remote_addr)
# get difference between evaluations
diff = abs(ev - ret)
# if evaluations are very similar, become friendlier with the agent
if diff < 0.2:
a1.set_attitude(a2.addr, att + 0.1)
# if evaluations are very different, dislike the agent
if diff > 0.8
a1.set_attitude(a2.addr, att - 0.1)
Iterative Simulation¶
Creamas provides an easy to use Simulation
which can be used to run iterative simulations using agents’ act()
.
Simulations can be created directly or they can be given an environment at
initialization time. See Using Simulation for details.
Voting and Other Social Choice Functions¶
Creamas offers some basic social choice/social decision making behavior for agents in the form of voting. Agents can publish their own artifacts as candidates. These candidates can then be collected and voted upon. Optionally, agents can validate each others candidates, i.e. exercise veto power on them, before voting takes place. See Voting for details.
Support for Multiple Cores and Distributed Systems¶
Creamas has inherent support for using multiple cores on a single machine and
distributing your environments on multiple nodes, e.g., on a computing cluster.
However, these functionalities are not yet fully tested, but have been used in
several systems and platforms effectively. Multiprocessing functionality is in
mp
-module (see Multiprocessing), and distributing the environments on several
nodes is in ds
-module (see Distributed Systems).
If you want to learn more about multiprocessing and distributed system support in Creamas, read an overview of them: Multiprocessing and Distributed Systems.