-
Notifications
You must be signed in to change notification settings - Fork 7
Agent Aggregate
The AgentAggregate
class is a core component of an AI agent system. It implements several interfaces (AgentInterface
, HasLinkedAgentsInterface
, HasLinkedToolsInterface
, HasLinkedContextSourcesInterface
) and serves as an aggregate root for an AI agent.
Key functionalities include:
- Storing and managing an underlying
Agent
object - Managing associations with other entities like tools, other agents, and context sources
- Handling agent metadata, including memory, prompts, and configuration
- Providing a unified interface to access agent properties and associated entities
The class uses composition to wrap an Agent
object and extends its functionality by managing various associations and metadata.
In addition to the core functionality previously described, the AgentAggregate system also includes advanced output formatting and tool execution control through interceptors. Specifically:
- OutputFormatterInterceptor: Allows for custom formatting of the agent's output based on predefined schemas or DTO classes.
- ToolExecutorInterceptor: Provides control over whether to return tool execution results immediately or continue processing.
a) Creating a Chatbot Agent:
$chatbotAgent = new AgentAggregate(
agent: new Agent(
key: 'chatbot',
name: 'Customer Support Bot',
description: 'AI assistant for customer inquiries',
instruction: 'Provide helpful responses to customer questions.'
)
);
$chatbotAgent->addAssociation(new Model(model: 'gpt-4'));
$chatbotAgent->addAssociation(new ToolLink(name: 'database_query'));
b) Setting up a Data Analysis Agent:
$dataAnalysisAgent = new AgentAggregate(
agent: new Agent(
key: 'data_analyst',
name: 'Data Insights Generator',
description: 'AI for analyzing complex datasets',
instruction: 'Analyze data and provide insightful summaries.'
)
);
$dataAnalysisAgent->addAssociation(new Model(model: 'gpt-4-32k'));
$dataAnalysisAgent->addMetadata(new SolutionMetadata(
type: MetadataType::Configuration,
key: 'max_tokens',
content: 8000
));
c) Creating a Multi-Agent System:
$masterAgent = new AgentAggregate(
agent: new Agent(
key: 'master',
name: 'Task Coordinator',
description: 'Coordinates multiple specialized agents',
instruction: 'Delegate tasks to appropriate sub-agents.'
)
);
$masterAgent->addAssociation(new AgentLink(name: 'chatbot', outputSchema: ChatbotResponse::class));
$masterAgent->addAssociation(new AgentLink(name: 'data_analyst', outputSchema: AnalysisResult::class));
d) Implementing a Context-Aware Agent:
$contextAwareAgent = new AgentAggregate(
agent: new Agent(
key: 'context_aware',
name: 'Contextual Assistant',
description: 'Provides responses based on context',
instruction: 'Use context sources to inform your responses.'
)
);
$contextAwareAgent->addAssociation(new ContextSourceLink(name: 'user_history'));
$contextAwareAgent->addAssociation(new ContextSourceLink(name: 'product_catalog'));
e) Creating a Learning Agent with Memory:
$learningAgent = new AgentAggregate(
agent: new Agent(
key: 'learner',
name: 'Adaptive AI',
description: 'Agent that learns and adapts from interactions',
instruction: 'Learn from interactions and improve responses over time.'
)
);
$learningAgent->addMetadata(new SolutionMetadata(
type: MetadataType::Memory,
key: 'past_interactions',
content: 'Remember key points from previous conversations.'
));
f) Creating an Agent with Structured Output:
$structuredOutputAgent = new AgentAggregate(
agent: new Agent(
key: 'structured_output',
name: 'JSON Response Generator',
description: 'Generates responses in a specific JSON format',
instruction: 'Provide information in the required JSON structure.'
)
);
$structuredOutputAgent->addMetadata(new OutputFormatter(
new JsonSchemaFormatter($schemaMapper)->withJsonSchema(CustomerInfoResponse::class)
));
class CustomerInfoResponse {
public function __construct(
public string $name,
public int $age,
public string $email
) {}
}
g) Creating a Tool-Focused Agent:
$toolFocusedAgent = new AgentAggregate(
agent: new Agent(
key: 'tool_executor',
name: 'Direct Tool Executor',
description: 'Executes tools and returns results directly',
instruction: 'Execute the appropriate tool and return its result immediately.'
)
);
$toolFocusedAgent->addMetadata(new ReturnToolResult());
$toolFocusedAgent->addAssociation(new ToolLink(name: 'data_retriever'));
$toolFocusedAgent->addAssociation(new ToolLink(name: 'calculation_performer'));
The AgentAggregate
class doesn't have direct configuration options, but it manages configuration through metadata. Some key configuration options include:
a) Model Configuration:
- Default: None (must be explicitly set)
- Example:
$agent->addAssociation(new Model(model: 'gpt-4'));
b) Memory Configuration:
- Default: Empty array
- Example:
$agent->addMetadata(new SolutionMetadata(
type: MetadataType::Memory,
key: 'important_fact',
content: 'Always greet the user politely.'
));
c) Prompt Configuration:
- Default: Empty array
- Example:
$agent->addMetadata(new SolutionMetadata(
type: MetadataType::Prompt,
key: 'greeting',
content: 'Hello! How can I assist you today?'
));
d) General Configuration:
- Default: Empty array
- Example:
$agent->addMetadata(new SolutionMetadata(
type: MetadataType::Configuration,
key: 'max_tokens',
content: 150
));
e) Output Formatter Configuration:
- Default: None (standard output)
- Purpose: Defines how the agent's output should be formatted
- Example:
use LLM\Agents\Solution\Metadata\OutputFormatter;
use LLM\Agents\LLM\Output\JsonSchemaFormatter;
$agent->addMetadata(new OutputFormatter(
new JsonSchemaFormatter($schemaMapper)->withJsonSchema(ResponseDTO::class)
));
This configuration tells the agent to format its output according to the ResponseDTO
class structure.
f) Return Tool Result Configuration:
- Default: false (continue processing after tool execution)
- Purpose: Determines whether to return the tool execution result immediately
- Example:
use LLM\Agents\Solution\Metadata\ReturnToolResult;
$agent->addMetadata(new ReturnToolResult());
When this option is set, the agent will immediately return the result of a tool execution instead of continuing to process it.
a) Agent:
- Purpose: Represents the core agent entity with basic properties.
- Interaction:
AgentAggregate
wraps anAgent
object and extends its functionality.
b) Solution:
- Purpose: Base class for various types of solutions (Model, ToolLink, AgentLink, etc.).
- Interaction:
AgentAggregate
manages associations of differentSolution
subtypes.
c) Model:
- Purpose: Represents the language model used by the agent.
- Interaction:
AgentAggregate
ensures only oneModel
is associated with the agent.
d) ToolLink:
- Purpose: Represents a tool that the agent can use.
- Interaction:
AgentAggregate
manages a collection ofToolLink
objects.
e) AgentLink:
- Purpose: Represents a link to another agent.
- Interaction:
AgentAggregate
manages links to other agents throughAgentLink
objects.
f) ContextSourceLink:
- Purpose: Represents a source of context information for the agent.
- Interaction:
AgentAggregate
manages context sources throughContextSourceLink
objects.
g) SolutionMetadata:
- Purpose: Stores metadata for the agent (memory, prompts, configuration).
- Interaction:
AgentAggregate
managesSolutionMetadata
objects to store various types of metadata.
h) OutputFormatterInterceptor:
- Purpose: Formats the agent's output according to specified schemas or DTOs.
- Interaction: Intercepts the agent's response and applies the configured formatting before returning.
i) ToolExecutorInterceptor:
- Purpose: Controls the flow of execution when tools are called by the agent.
- Interaction: Intercepts tool calls, executes them, and either returns the result immediately or allows further processing based on configuration.
Here's a Mermaid class diagram illustrating the relationships between AgentAggregate
and its related classes:
classDiagram
class AgentAggregate {
-Agent agent
-array associations
+getKey() string
+getName() string
+getDescription() string
+getInstruction() string
+getTools() array
+getContextSources() array
+getAgents() array
+getModel() Model
+getMemory() array
+getPrompts() array
+getConfiguration() array
+addAssociation(Solution)
+addMetadata(SolutionMetadata)
}
class Agent {
+string key
+string name
+string description
+string instruction
+bool isActive
}
class Solution {
+string name
+SolutionType type
+string description
}
class Model {
+string model
}
class ToolLink {
+getName() string
}
class AgentLink {
+getName() string
+string outputSchema
}
class ContextSourceLink {
+getName() string
}
class SolutionMetadata {
+MetadataType type
+string key
+mixed content
}
class OutputFormatterInterceptor {
+execute(ExecutionInput, InterceptorHandler) Execution
}
class ToolExecutorInterceptor {
+execute(ExecutionInput, InterceptorHandler) Execution
}
class ExecutorInterceptorInterface {
<<interface>>
+execute(ExecutionInput, InterceptorHandler) Execution
}
AgentAggregate "1" --* "1" Agent
AgentAggregate "1" --o "*" Solution
Solution <|-- Model
Solution <|-- ToolLink
Solution <|-- AgentLink
Solution <|-- ContextSourceLink
AgentAggregate "1" --o "*" SolutionMetadata
Agent "1" --o "*" SolutionMetadata
ExecutorInterceptorInterface <|.. OutputFormatterInterceptor
ExecutorInterceptorInterface <|.. ToolExecutorInterceptor
AgentAggregate ..> OutputFormatterInterceptor : configures
AgentAggregate ..> ToolExecutorInterceptor : configures
This diagram illustrates the relationships between AgentAggregate
and its related classes:
-
AgentAggregate
contains oneAgent
instance. -
AgentAggregate
can have multipleSolution
instances (includingModel
,ToolLink
,AgentLink
, andContextSourceLink
). - Both
AgentAggregate
andAgent
can have multipleSolutionMetadata
instances. -
Model
,ToolLink
,AgentLink
, andContextSourceLink
inherit fromSolution
.