Agent as Aspect

TagtalLabs
4 min readJul 9, 2024

The traditional AI agent is a piece of code, most likely in modern object-oriented programming languages such as Python.

Traditional AI agent

Aspect-oriented programming is a relatively new method to make software, especially for more adaptive code, sometimes it is called generative programming. AOP could be used to implement AI agents, but nothing related to generative AI itself until Aspect-Oriented Neural Programming.

Aspect-Oriented Neural Programming (AONP) is an innovation on par with Artificial Neural Networks (ANN). ANN focuses on algorithms, with algorithms being the priority and software code merely a form that has never been emphasized. AONP, however, unifies form and function, making the software both the scaffolding and the main body of intelligence, which is the foundation of AGI (Artificial General Intelligence). For the first time, intelligence has a main body. Just like proteins, gene sequences are important, but without the ability to synthesize proteins, genes are useless. The power of genes lies not only in expression but also in self-assembly. If the weights in ANN are the genes of intelligence, AONP is the self-assembly mechanism of intelligence.

In aspect-oriented neural programming, an agent is modeled and programmed as an aspect. The aspects are interconnected or woven together like neurons in neural networks, where natural intelligence originates. Aspects exist at multiple scales within agents themselves and higher-level agents, such as the Aspect of Aspect. Each agent itself has numerous aspects. In this sense, agents are Aspect-Oriented Neural Networks (AONN).

AONN is not just the parameters, but also the actual AI software.

Although Python does not support AspectJ’s AOP syntax, we could simulate it with the decorate pattern in Python. For those unfamiliar with AOP, the code is an example of AOP in Python following AspectJ’s AOP syntax.

class Aspect:
def __init__(self):
self.pointcuts = []
self.advices = []

def pointcut(self, func):
self.pointcuts.append(func)
return func

def advice(self, advice_type):
def decorator(func):
self.advices.append((advice_type, func))
return func
return decorator

def apply(self, target_class):
for pointcut in self.pointcuts:
for attr_name, attr_value in target_class.__dict__.items():
if callable(attr_value) and pointcut(attr_value):
for advice_type, advice in self.advices:
if advice_type == 'before':
attr_value = self._create_wrapper('before', advice, attr_value)
elif advice_type == 'after':
attr_value = self._create_wrapper('after', advice, attr_value)
setattr(target_class, attr_name, attr_value)

def _create_wrapper(self, advice_type, advice, original_func):
def wrapper(*args, **kwargs):
if advice_type == 'before':
advice()
result = original_func(*args, **kwargs)
if advice_type == 'after':
advice()
return result
return wrapper

class LoggingAspect(Aspect):
def __init__(self):
super().__init__()

def all_methods(self, func):
return func.__name__ == self.method_name

@Aspect().advice('before')
def before_advice(self):
print("Before method execution")

@Aspect().advice('after')
def after_advice(self):
print("After method execution")

# Sample target class
class MyClass:
def my_method(self):
print("Executing my_method1")

def my_method2(self):
print("Executing my_method2")

def my_method3(self):
print("Executing my_method3")

Furthermore, we can model an agent with aspect.

class Aspect:
def __init__(self):
pass

def pointcut(self, join_point):
def decorator(func):
def wrapper(*args, **kwargs):
return func(*args, **kwargs)
return wrapper
return decorator

def before_advice(self, join_point):
def decorator(func):
def wrapper(*args, **kwargs):
self.before(join_point)
return func(*args, **kwargs)
return wrapper
return decorator

def after_advice(self, join_point):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
self.after(join_point)
return result
return wrapper
return decorator

def around_advice(self, join_point):
def decorator(func):
def wrapper(*args, **kwargs):
self.before(join_point)
result = func(*args, **kwargs)
self.after(join_point)
return result
return wrapper
return decorator

Pointcut acts in axon or dendrite mode, depending on the direction of information flow. In axon mode, information is from this aspect to another, and vice versa.

So dendrite mode pointcut could be used to observe the environment and axon to take action as what it does in a neuron.

A pointcut is more powerful than a regular object call. It can cross-cut all methods defined in “join_point” and inject the code of advice function or data as a neuron releases chemical transmitters or pulses on muscle cells or other neurons.

class Agent(Aspect):
def __init__(self):
super().__init__()
self.transmitter_to_release = False
self.transmitter_received = False

def act_pointcut(self):
return self.pointcut("axon")

def observe_pointcut(self):
return self.pointcut("dendrite")

def act_advice(self):
def decorator(func):
def wrapper(*args, **kwargs):
return self.transmitter_received
return wrapper
return decorator

def observe_advice(self):
def decorator(func):
def wrapper(*args, **kwargs):
result = func(*args, **kwargs)
self.transmitter_received = result
return result
return wrapper
return decorator
class MotorAgent(Agent):
def __init__(self):
super().__init__()

def act_advice(self):
def decorator(func):
def wrapper(*args, **kwargs):
self.transmitter_received = self.receptor()
if self.transmitter_received:
self.transmitter_to_release = True
else:
self.transmitter_to_release = False
return self.transmitter_to_release
return wrapper
return decorator

def receptor(self):
transmitter_received = False
# Simulate receiving transmitter logic
return transmitter_received
class SensoryAgent(Agent):
def __init__(self):
super().__init__()
class ActionEffector:
def __init__(self):
self.state = False
self.transmitter = False

def receptor(self):
transmitter_received = False
# Simulate receiving transmitter logic
return transmitter_received

def emit(self):
self.transmitter = self.state
return self.transmitter

def contract(self):
self.state = True
# Logic to contract the muscle

def relax(self):
self.state = False
# Logic to relax the muscle

def go(self):
if self.receptor():
self.contract()
else:
self.relax()
c= ActionEffector()
sensory_agent = SensoryAgent()
motor_agent = MotorAgent()

# Apply pointcuts and advices to the action effector's methods
effector_emit = sensory_neuron.dendrite_pointcut()(sensory_neuron.dendrite_advice()(effector.emit))
effector_go = motor_neuron.axon_pointcut()(motor_neuron.axon_advice()(effector.go))

# Simulate the network
actioneffector.state = True # Initial state
actioneffector.transmitter = effector_emit()
print(f"Effector Transmitter: {effector.transmitter}")
effector_go()
print(f"Effector State: {effector.state}")

The original implementation is in Java with AspectJ extension.

https://www.researchgate.net/publication/331274514_Aspect-Oriented_a_Candidate_for_the_Biologically_Inspired_Programming_Paradigm_for_Neural_Networks_and_Evolvable_Software

Sign up to discover human stories that deepen your understanding of the world.

Free

Distraction-free reading. No ads.

Organize your knowledge with lists and highlights.

Tell your story. Find your audience.

Membership

Read member-only stories

Support writers you read most

Earn money for your writing

Listen to audio narrations

Read offline with the Medium app

No responses yet