[FEAT][MatrixSwarm]

pull/761/head
Kye Gomez 3 months ago
parent e06652ed8b
commit 37894599c2

@ -188,6 +188,7 @@ nav:
- TaskQueueSwarm: "swarms/structs/taskqueue_swarm.md" - TaskQueueSwarm: "swarms/structs/taskqueue_swarm.md"
- SwarmRearrange: "swarms/structs/swarm_rearrange.md" - SwarmRearrange: "swarms/structs/swarm_rearrange.md"
- MultiAgentRouter: "swarms/structs/multi_agent_router.md" - MultiAgentRouter: "swarms/structs/multi_agent_router.md"
- MatrixSwarm: "swarms/structs/matrix_swarm.md"
- Various Execution Methods: "swarms/structs/various_execution_methods.md" - Various Execution Methods: "swarms/structs/various_execution_methods.md"
- Workflows: - Workflows:
- ConcurrentWorkflow: "swarms/structs/concurrentworkflow.md" - ConcurrentWorkflow: "swarms/structs/concurrentworkflow.md"

@ -0,0 +1,247 @@
# MatrixSwarm
The `MatrixSwarm` class provides a framework for managing and operating on matrices of AI agents, enabling matrix-like operations similar to linear algebra. This allows for complex agent interactions and parallel processing capabilities.
## Overview
`MatrixSwarm` treats AI agents as elements in a matrix, allowing for operations like addition, multiplication, and transposition. This approach enables sophisticated agent orchestration and parallel processing patterns.
## Installation
```bash
pip3 install -U swarms
```
## Basic Usage
```python
from swarms import Agent
from swarms.matrix import MatrixSwarm
# Create a 2x2 matrix of agents
agents = [
[Agent(agent_name="Agent-0-0"), Agent(agent_name="Agent-0-1")],
[Agent(agent_name="Agent-1-0"), Agent(agent_name="Agent-1-1")]
]
# Initialize the matrix
matrix = MatrixSwarm(agents)
```
## Class Constructor
```python
def __init__(self, agents: List[List[Agent]])
```
### Parameters
- `agents` (`List[List[Agent]]`): A 2D list of Agent instances representing the matrix.
### Raises
- `ValueError`: If the input is not a valid 2D list of Agent instances.
## Methods
### transpose()
Transposes the matrix of agents by swapping rows and columns.
```python
def transpose(self) -> MatrixSwarm
```
#### Returns
- `MatrixSwarm`: A new MatrixSwarm instance with transposed dimensions.
---
### add(other)
Performs element-wise addition of two agent matrices.
```python
def add(self, other: MatrixSwarm) -> MatrixSwarm
```
#### Parameters
- `other` (`MatrixSwarm`): Another MatrixSwarm instance to add.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm resulting from the addition.
#### Raises
- `ValueError`: If matrix dimensions are incompatible.
---
### scalar_multiply(scalar)
Scales the matrix by duplicating agents along rows.
```python
def scalar_multiply(self, scalar: int) -> MatrixSwarm
```
#### Parameters
- `scalar` (`int`): The multiplication factor.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm with scaled dimensions.
---
### multiply(other, inputs)
Performs matrix multiplication (dot product) between two agent matrices.
```python
def multiply(self, other: MatrixSwarm, inputs: List[str]) -> List[List[AgentOutput]]
```
#### Parameters
- `other` (`MatrixSwarm`): The second MatrixSwarm for multiplication.
- `inputs` (`List[str]`): Input queries for the agents.
#### Returns
- `List[List[AgentOutput]]`: Matrix of operation results.
#### Raises
- `ValueError`: If matrix dimensions are incompatible for multiplication.
---
### subtract(other)
Performs element-wise subtraction of two agent matrices.
```python
def subtract(self, other: MatrixSwarm) -> MatrixSwarm
```
#### Parameters
- `other` (`MatrixSwarm`): Another MatrixSwarm to subtract.
#### Returns
- `MatrixSwarm`: A new MatrixSwarm resulting from the subtraction.
---
### identity(size)
Creates an identity matrix of agents.
```python
def identity(self, size: int) -> MatrixSwarm
```
#### Parameters
- `size` (`int`): Size of the identity matrix (NxN).
#### Returns
- `MatrixSwarm`: An identity MatrixSwarm.
---
### determinant()
Computes the determinant of a square agent matrix.
```python
def determinant(self) -> Any
```
#### Returns
- `Any`: The determinant result.
#### Raises
- `ValueError`: If the matrix is not square.
---
### save_to_file(path)
Saves the matrix structure and metadata to a JSON file.
```python
def save_to_file(self, path: str) -> None
```
#### Parameters
- `path` (`str`): File path for saving the matrix data.
## Extended Example
Here's a comprehensive example demonstrating various MatrixSwarm operations:
```python
from swarms import Agent
from swarms.matrix import MatrixSwarm
# Create agents with specific configurations
agents = [
[
Agent(
agent_name=f"Agent-{i}-{j}",
system_prompt="Your system prompt here",
model_name="gpt-4",
max_loops=1,
verbose=True
) for j in range(2)
] for i in range(2)
]
# Initialize matrix
matrix = MatrixSwarm(agents)
# Example operations
transposed = matrix.transpose()
scaled = matrix.scalar_multiply(2)
# Run operations with inputs
inputs = ["Query 1", "Query 2"]
results = matrix.multiply(transposed, inputs)
# Save results
matrix.save_to_file("matrix_results.json")
```
## Output Schema
The `AgentOutput` class defines the structure for operation results:
```python
class AgentOutput(BaseModel):
agent_name: str
input_query: str
output_result: Any
metadata: dict
```
## Best Practices
1. **Initialization**
- Ensure all agents in the matrix are properly configured before initialization
- Validate matrix dimensions for your use case
2. **Operation Performance**
- Consider computational costs for large matrices
- Use appropriate batch sizes for inputs
3. **Error Handling**
- Implement proper error handling for agent operations
- Validate inputs before matrix operations
4. **Resource Management**
- Monitor agent resource usage in large matrices
- Implement proper cleanup procedures
## Limitations
- Matrix operations are constrained by the underlying agent capabilities
- Performance may vary based on agent configuration and complexity
- Resource usage scales with matrix dimensions
## See Also
- [Swarms Documentation](https://github.com/kyegomez/swarms)
- [Agent Class Reference](https://github.com/kyegomez/swarms/tree/main/swarms)

@ -33,7 +33,7 @@ Main class for routing tasks to different swarm types.
| `flow` | str | The flow of the swarm. | | `flow` | str | The flow of the swarm. |
| `return_json` | bool | Flag to enable/disable returning the result in JSON format. | | `return_json` | bool | Flag to enable/disable returning the result in JSON format. |
| `auto_generate_prompts` | bool | Flag to enable/disable auto generation of prompts. | | `auto_generate_prompts` | bool | Flag to enable/disable auto generation of prompts. |
| `swarm` | Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow] | Instantiated swarm object. | | `swarm` | Union[AgentRearrange, MixtureOfAgents, SpreadSheetSwarm, SequentialWorkflow, ConcurrentWorkflow, GroupChat, MultiAgentRouter] | Instantiated swarm object. |
| `logs` | List[SwarmLog] | List of log entries captured during operations. | | `logs` | List[SwarmLog] | List of log entries captured during operations. |
#### Methods: #### Methods:
@ -271,6 +271,39 @@ result = concurrent_router.run("Conduct a comprehensive market analysis for Prod
``` ```
### GroupChat
Use Case: Simulating a group chat with multiple agents.
```python
group_chat_router = SwarmRouter(
name="GroupChat",
description="Simulate a group chat with multiple agents",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type="GroupChat"
)
result = group_chat_router.run("Conduct a comprehensive market analysis for Product X")
```
### MultiAgentRouter
Use Case: Simulating a group chat with multiple agents.
```python
multi_agent_router = SwarmRouter(
name="MultiAgentRouter",
description="Simulate a group chat with multiple agents",
max_loops=1,
agents=[financial_analyst, market_researcher, competitor_analyst],
swarm_type="MultiAgentRouter"
)
result = multi_agent_router.run("Conduct a comprehensive market analysis for Product X")
```
### Auto Select (Experimental) ### Auto Select (Experimental)
Autonomously selects the right swarm by conducting vector search on your input task or name or description or all 3. Autonomously selects the right swarm by conducting vector search on your input task or name or description or all 3.

@ -161,7 +161,7 @@ print(result)
We're excited to see how you leverage Swarms-Memory in your projects! Join our community on Discord to share your experiences, ask questions, and stay updated on the latest developments. We're excited to see how you leverage Swarms-Memory in your projects! Join our community on Discord to share your experiences, ask questions, and stay updated on the latest developments.
- **🐦 Twitter**: [Follow us on Twitter](https://twitter.com/swarms_platform) - **🐦 Twitter**: [Follow us on Twitter](https://twitter.com/swarms_platform)
- **📢 Discord**: [Join the Agora Discord](https://discord.gg/agora) - **📢 Discord**: [Join the Agora Discord](https://discord.gg/jM3Z6M9uMq)
- **Swarms Platform**: [Visit our website](https://swarms.ai) - **Swarms Platform**: [Visit our website](https://swarms.ai)
- **📙 Documentation**: [Read the Docs](https://docs.swarms.ai) - **📙 Documentation**: [Read the Docs](https://docs.swarms.ai)

@ -1,216 +0,0 @@
from swarms.structs.matrix_swarm import MatrixSwarm, AgentOutput
from swarms import Agent
def create_test_matrix(rows: int, cols: int) -> MatrixSwarm:
"""Helper function to create a test agent matrix"""
agents = [
[
Agent(
agent_name=f"TestAgent-{i}-{j}",
system_prompt="Test prompt",
)
for j in range(cols)
]
for i in range(rows)
]
return MatrixSwarm(agents)
def test_init():
"""Test MatrixSwarm initialization"""
# Test valid initialization
matrix = create_test_matrix(2, 2)
assert isinstance(matrix, MatrixSwarm)
assert len(matrix.agents) == 2
assert len(matrix.agents[0]) == 2
# Test invalid initialization
try:
MatrixSwarm([[1, 2], [3, 4]]) # Non-agent elements
assert False, "Should raise ValueError"
except ValueError:
pass
try:
MatrixSwarm([]) # Empty matrix
assert False, "Should raise ValueError"
except ValueError:
pass
def test_transpose():
"""Test matrix transpose operation"""
matrix = create_test_matrix(2, 3)
transposed = matrix.transpose()
assert len(transposed.agents) == 3 # Original cols become rows
assert len(transposed.agents[0]) == 2 # Original rows become cols
# Verify agent positions
for i in range(2):
for j in range(3):
assert (
matrix.agents[i][j].agent_name
== transposed.agents[j][i].agent_name
)
def test_add():
"""Test matrix addition"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.add(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
# Test incompatible dimensions
matrix3 = create_test_matrix(2, 3)
try:
matrix1.add(matrix3)
assert False, "Should raise ValueError"
except ValueError:
pass
def test_scalar_multiply():
"""Test scalar multiplication"""
matrix = create_test_matrix(2, 2)
scalar = 3
result = matrix.scalar_multiply(scalar)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2 * scalar
# Verify agent duplication
for i in range(len(result.agents)):
for j in range(0, len(result.agents[0]), scalar):
original_agent = matrix.agents[i][j // scalar]
for k in range(scalar):
assert (
result.agents[i][j + k].agent_name
== original_agent.agent_name
)
def test_multiply():
"""Test matrix multiplication"""
matrix1 = create_test_matrix(2, 3)
matrix2 = create_test_matrix(3, 2)
inputs = ["test query 1", "test query 2"]
result = matrix1.multiply(matrix2, inputs)
assert len(result) == 2 # Number of rows in first matrix
assert len(result[0]) == 2 # Number of columns in second matrix
# Verify output structure
for row in result:
for output in row:
assert isinstance(output, AgentOutput)
assert isinstance(output.input_query, str)
assert isinstance(output.metadata, dict)
def test_subtract():
"""Test matrix subtraction"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.subtract(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
def test_identity():
"""Test identity matrix creation"""
matrix = create_test_matrix(3, 3)
identity = matrix.identity(3)
assert len(identity.agents) == 3
assert len(identity.agents[0]) == 3
# Verify diagonal elements are from original matrix
for i in range(3):
assert (
identity.agents[i][i].agent_name
== matrix.agents[i][i].agent_name
)
# Verify non-diagonal elements are zero agents
for j in range(3):
if i != j:
assert identity.agents[i][j].agent_name.startswith(
"Zero-Agent"
)
def test_determinant():
"""Test determinant calculation"""
# Test 1x1 matrix
matrix1 = create_test_matrix(1, 1)
det1 = matrix1.determinant()
assert det1 is not None
# Test 2x2 matrix
matrix2 = create_test_matrix(2, 2)
det2 = matrix2.determinant()
assert det2 is not None
# Test non-square matrix
matrix3 = create_test_matrix(2, 3)
try:
matrix3.determinant()
assert False, "Should raise ValueError"
except ValueError:
pass
def test_save_to_file(tmp_path):
"""Test saving matrix to file"""
import os
matrix = create_test_matrix(2, 2)
file_path = os.path.join(tmp_path, "test_matrix.json")
matrix.save_to_file(file_path)
assert os.path.exists(file_path)
# Verify file contents
import json
with open(file_path, "r") as f:
data = json.load(f)
assert "agents" in data
assert "outputs" in data
assert len(data["agents"]) == 2
assert len(data["agents"][0]) == 2
def run_all_tests():
"""Run all test functions"""
test_functions = [
test_init,
test_transpose,
test_add,
test_scalar_multiply,
test_multiply,
test_subtract,
test_identity,
test_determinant,
]
for test_func in test_functions:
try:
test_func()
print(f"{test_func.__name__} passed")
except AssertionError as e:
print(f"{test_func.__name__} failed: {str(e)}")
except Exception as e:
print(
f"{test_func.__name__} failed with exception: {str(e)}"
)
if __name__ == "__main__":
run_all_tests()

@ -0,0 +1,217 @@
from swarms.structs.matrix_swarm import MatrixSwarm, AgentOutput
from swarms import Agent
def create_test_matrix(rows: int, cols: int) -> MatrixSwarm:
"""Helper function to create a test agent matrix"""
agents = [
[
Agent(
agent_name=f"TestAgent-{i}-{j}",
model_name="gpt-4o",
system_prompt="Test prompt",
)
for j in range(cols)
]
for i in range(rows)
]
return MatrixSwarm(agents)
def test_init():
"""Test MatrixSwarm initialization"""
# Test valid initialization
matrix = create_test_matrix(2, 2)
assert isinstance(matrix, MatrixSwarm)
assert len(matrix.agents) == 2
assert len(matrix.agents[0]) == 2
# Test invalid initialization
try:
MatrixSwarm([[1, 2], [3, 4]]) # Non-agent elements
assert False, "Should raise ValueError"
except ValueError:
pass
try:
MatrixSwarm([]) # Empty matrix
assert False, "Should raise ValueError"
except ValueError:
pass
def test_transpose():
"""Test matrix transpose operation"""
matrix = create_test_matrix(2, 3)
transposed = matrix.transpose()
assert len(transposed.agents) == 3 # Original cols become rows
assert len(transposed.agents[0]) == 2 # Original rows become cols
# Verify agent positions
for i in range(2):
for j in range(3):
assert (
matrix.agents[i][j].agent_name
== transposed.agents[j][i].agent_name
)
def test_add():
"""Test matrix addition"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.add(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
# Test incompatible dimensions
matrix3 = create_test_matrix(2, 3)
try:
matrix1.add(matrix3)
assert False, "Should raise ValueError"
except ValueError:
pass
def test_scalar_multiply():
"""Test scalar multiplication"""
matrix = create_test_matrix(2, 2)
scalar = 3
result = matrix.scalar_multiply(scalar)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2 * scalar
# Verify agent duplication
for i in range(len(result.agents)):
for j in range(0, len(result.agents[0]), scalar):
original_agent = matrix.agents[i][j // scalar]
for k in range(scalar):
assert (
result.agents[i][j + k].agent_name
== original_agent.agent_name
)
def test_multiply():
"""Test matrix multiplication"""
matrix1 = create_test_matrix(2, 3)
matrix2 = create_test_matrix(3, 2)
inputs = ["test query 1", "test query 2"]
result = matrix1.multiply(matrix2, inputs)
assert len(result) == 2 # Number of rows in first matrix
assert len(result[0]) == 2 # Number of columns in second matrix
# Verify output structure
for row in result:
for output in row:
assert isinstance(output, AgentOutput)
assert isinstance(output.input_query, str)
assert isinstance(output.metadata, dict)
def test_subtract():
"""Test matrix subtraction"""
matrix1 = create_test_matrix(2, 2)
matrix2 = create_test_matrix(2, 2)
result = matrix1.subtract(matrix2)
assert len(result.agents) == 2
assert len(result.agents[0]) == 2
def test_identity():
"""Test identity matrix creation"""
matrix = create_test_matrix(3, 3)
identity = matrix.identity(3)
assert len(identity.agents) == 3
assert len(identity.agents[0]) == 3
# Verify diagonal elements are from original matrix
for i in range(3):
assert (
identity.agents[i][i].agent_name
== matrix.agents[i][i].agent_name
)
# Verify non-diagonal elements are zero agents
for j in range(3):
if i != j:
assert identity.agents[i][j].agent_name.startswith(
"Zero-Agent"
)
def test_determinant():
"""Test determinant calculation"""
# Test 1x1 matrix
matrix1 = create_test_matrix(1, 1)
det1 = matrix1.determinant()
assert det1 is not None
# Test 2x2 matrix
matrix2 = create_test_matrix(2, 2)
det2 = matrix2.determinant()
assert det2 is not None
# Test non-square matrix
matrix3 = create_test_matrix(2, 3)
try:
matrix3.determinant()
assert False, "Should raise ValueError"
except ValueError:
pass
def test_save_to_file(tmp_path):
"""Test saving matrix to file"""
import os
matrix = create_test_matrix(2, 2)
file_path = os.path.join(tmp_path, "test_matrix.json")
matrix.save_to_file(file_path)
assert os.path.exists(file_path)
# Verify file contents
import json
with open(file_path, "r") as f:
data = json.load(f)
assert "agents" in data
assert "outputs" in data
assert len(data["agents"]) == 2
assert len(data["agents"][0]) == 2
def run_all_tests():
"""Run all test functions"""
test_functions = [
test_init,
test_transpose,
test_add,
test_scalar_multiply,
test_multiply,
test_subtract,
test_identity,
test_determinant,
]
for test_func in test_functions:
try:
test_func()
print(f"{test_func.__name__} passed")
except AssertionError as e:
print(f"{test_func.__name__} failed: {str(e)}")
except Exception as e:
print(
f"{test_func.__name__} failed with exception: {str(e)}"
)
if __name__ == "__main__":
run_all_tests()
Loading…
Cancel
Save