Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add environment modules #378

Merged
merged 197 commits into from
Oct 28, 2024
Merged

Add environment modules #378

merged 197 commits into from
Oct 28, 2024

Conversation

pan-x-c
Copy link
Collaborator

@pan-x-c pan-x-c commented Aug 2, 2024

Description

Add Environment Modules (Env and its sub-classes)

Env is a key concept of AgentScope, representing global data shared among agents.

Each env has name and value, and multiple envs can be organized into a tree structure, where each env can have multiple children envs and one parent env.

Different implementations of envs may have different event functions, which are marked by @event_func.
Users can bind EventListener to specific event functions, and the listener will be activated when the event function is called.

Similar to AgentBase sub-classes, Env sub-classes also support the to_dist call, and the parameter is the same as AgentBase.

Decouple distribution-related functions from other AgentScope modules

Move to_dist into RpcMeta

RpcMeta is a meta-class that integrates all to_dist related methods/parameters.
Now, to_dist function/parameter can be used directly if the class is a subclass of RpcMeta.
The original to_dist and _AgentMeta is removed.

Extend RpcAgent into RpcObject

RpcObject is an enhanced version of RpcAgent, and can be used to represent any object (unlike RpcAgent which can only represent Agent)
Users can call any public methods or get any attributes on the RpcObject, and the RpcObject will forward the request to the real object running in the RPC server.
The original RpcAgent is removed.

Add @async_func and AsyncResult to replace the reply and Placeholder

Because the RpcObject supports calling any public methods and returns any results, the old Placeholder cannot cover this complex scenario. Therefore, @async_func and AsyncResult are added.

Functions decorated with @async_func will automatically return AsyncResult objects in distributed mode.
The usage of AsyncResult is the same as Placeholder, which is instantiated only when its internal objects are accessed.
AsyncResult can be used to represent any type of data, not just Msg.
The original PlaceholderMessage is removed.

Through the above modification, the agent and message modules are decoupled from the distributed mode.
Note that the user interface of the distributed mode is unchanged, all modifications above are completely hidden from the user, and all previous distributed examples can be run without any modification.

Add Guess Two Third of the Average Game example

The code of "Very Large-Scale Multi-Agent Simulation in AgentScope" is released under examples/paper_large_scale_simulation

Checklist

Please check the following items before code is ready to be reviewed.

  • Code has passed all tests
  • Docstrings have been added/updated in Google Style
  • Documentation has been updated
  • Code is ready for review

@pan-x-c pan-x-c added the feature label Aug 2, 2024
Copy link
Collaborator

@DavdGao DavdGao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

  1. Move the environment modules into examples like what rag and react did before, and we should consider to merge it into the library when it's ready.
  2. Will it enter an infinite loop? For example, agentA and agentB subscribe to the locations of each other and trigger each other, leading to an endless actions cycle.

agentA move ==> agentB listen ==> agent B move ==> agentA listen ==> agentB move ....

Copy link
Collaborator

@xieyxclack xieyxclack left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM. Please refer to inline comments

src/agentscope/environment/env.py Show resolved Hide resolved
src/agentscope/environment/env.py Show resolved Hide resolved
src/agentscope/environment/env.py Outdated Show resolved Hide resolved
src/agentscope/environment/event.py Outdated Show resolved Hide resolved
src/agentscope/memory/temporary_memory.py Show resolved Hide resolved
src/agentscope/message/msg.py Show resolved Hide resolved
src/agentscope/rpc/rpc_meta.py Show resolved Hide resolved
src/agentscope/server/launcher.py Outdated Show resolved Hide resolved
@pan-x-c
Copy link
Collaborator Author

pan-x-c commented Oct 22, 2024

To be discussed

  1. the name of distributed functions. In the current version, async_func/sync_func may be confused with async in Python asyncio. unblocking_func / blocking_func may be a better name.
  2. the old agent_id is renamed to oid (a short version of object_id), which may cause misunderstandings and incompatibility with legacy code. However, here we really need an id field for all objects, not just agents.

Copy link
Collaborator

@DavdGao DavdGao left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Some of my concerns in this PR:

  1. The planned deprecation of placeholder may be too extensive. Consider this alternative: create a Mixin class that blocks certain remote function calls (e.g., a configurable reply). This way, the message class (and the env modules) can inherit from it, maintaining the functionality of placeholders without causing confusion in return types from an agent (AsyncResult or Msg).
class RemoteMixin:
    
    _enable: bool = False

    __remote_attrs__ = []

    def __getattr__(self, name):
        if _enable and name in self.__remote_attrs__:
            # ...
        else:
            super().__getattr__(name)

class Msg(RemoteMixin):
    __remote_attrs__ = ['reply', 'observe', 'xxx']
    """Functions/attrs need to be executed/obtained from remote."""

    # ...
  1. If feasible, try not to use metaclasses for functionality implementation. They can be challenging for developers to understand.

  2. I believe the agent should be the framework's core. Thus, the design of the environment module should align with the agent's settings, not vice versa. For instance, the agent's identity should be independent of the environment and distribution modules.

src/agentscope/server/launcher.py Outdated Show resolved Hide resolved
src/agentscope/server/launcher.py Outdated Show resolved Hide resolved
@pan-x-c pan-x-c merged commit 282244e into modelscope:main Oct 28, 2024
14 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

Successfully merging this pull request may close these issues.

7 participants