mirror of
https://github.com/aljazceru/Auto-GPT.git
synced 2025-12-18 06:24:20 +01:00
feat(agent): Component-based Agents (#7054)
This incremental re-architecture unifies Agent code and plugins, so everything is component-based. ## Breaking changes - Removed command categories and `DISABLED_COMMAND_CATEGORIES` environment variable. Use `DISABLED_COMMANDS` environment variable to disable individual commands. - Changed `command` decorator; old-style commands are no longer supported. Implement `CommandProvider` on components instead. - Removed `CommandRegistry`, now all commands are provided by components implementing `CommandProvider`. - Removed `prompt_config` from `AgentSettings`. - Removed plugin support: old plugins will no longer be loaded and executed. - Removed `PromptScratchpad`, it was used by plugins and is no longer needed. - Changed `ThoughtProcessOutput` from tuple to pydantic `BaseModel`. ## Other changes - Created `AgentComponent`, protocols and logic to execute them. - `BaseAgent` and `Agent` is now composed of components. - Moved some logic from `BaseAgent` to `Agent`. - Moved agent features and commands to components. - Removed check if the same operation is about to be executed twice in a row. - Removed file logging from `FileManagerComponent` (formerly `AgentFileManagerMixin`) - Updated tests - Added docs See [Introduction](https://github.com/kcze/AutoGPT/blob/kpczerwinski/open-440-modular-agents/docs/content/AutoGPT/component%20agent/introduction.md) for more information.
This commit is contained in:
committed by
GitHub
parent
6ff02677d2
commit
a74548d3cd
166
docs/content/AutoGPT/component agent/protocols.md
Normal file
166
docs/content/AutoGPT/component agent/protocols.md
Normal file
@@ -0,0 +1,166 @@
|
||||
# ⚙️ Protocols
|
||||
|
||||
Protocols are *interfaces* implemented by [Components](./components.md) used to group related functionality. Each protocol needs to be handled explicitly by the agent at some point of the execution. We provide a comprehensive list of built-in protocols that are already handled in the built-in `Agent`, so when you inherit from the base agent all built-in protocols will work!
|
||||
|
||||
**Protocols are listed in the order of the default execution.**
|
||||
|
||||
## Order-independent protocols
|
||||
|
||||
Components implementing exclusively order-independent protocols can added in any order, including in-between ordered protocols.
|
||||
|
||||
### `DirectiveProvider`
|
||||
|
||||
Yields constraints, resources and best practices for the agent. This has no direct impact on other protocols; is purely informational and will be passed to a llm when the prompt is built.
|
||||
|
||||
```py
|
||||
class DirectiveProvider(AgentComponent):
|
||||
def get_constraints(self) -> Iterator[str]:
|
||||
return iter([])
|
||||
|
||||
def get_resources(self) -> Iterator[str]:
|
||||
return iter([])
|
||||
|
||||
def get_best_practices(self) -> Iterator[str]:
|
||||
return iter([])
|
||||
```
|
||||
|
||||
**Example** A web-search component can provide a resource information. Keep in mind that this actually doesn't allow the agent to access the internet. To do this a relevant `Command` needs to be provided.
|
||||
|
||||
```py
|
||||
class WebSearchComponent(DirectiveProvider):
|
||||
def get_resources(self) -> Iterator[str]:
|
||||
yield "Internet access for searches and information gathering."
|
||||
# We can skip "get_constraints" and "get_best_practices" if they aren't needed
|
||||
```
|
||||
|
||||
### `CommandProvider`
|
||||
|
||||
Provides a command that can be executed by the agent.
|
||||
|
||||
```py
|
||||
class CommandProvider(AgentComponent):
|
||||
def get_commands(self) -> Iterator[Command]:
|
||||
...
|
||||
```
|
||||
|
||||
The easiest way to provide a command is to use `command` decorator on a component method and then yield the method. Each command needs a name, description and a parameter schema using `JSONSchema`. By default method name is used as a command name, and first part of docstring for the description (before `Args:` or `Returns:`) and schema can be provided in the decorator.
|
||||
|
||||
**Example** Calculator component that can perform multiplication. Agent is able to call this command if it's relevant to a current task and will see the returned result.
|
||||
|
||||
```py
|
||||
from autogpt.agents.components import Component
|
||||
from autogpt.agents.protocols import CommandProvider
|
||||
from autogpt.core.utils.json_schema import JSONSchema
|
||||
from autogpt.utils.command_decorator import command
|
||||
|
||||
|
||||
class CalculatorComponent(CommandProvider):
|
||||
get_commands(self) -> Iterator[Command]:
|
||||
yield self.multiply
|
||||
|
||||
@command(parameters={
|
||||
"a": JSONSchema(
|
||||
type=JSONSchema.Type.INTEGER,
|
||||
description="The first number",
|
||||
required=True,
|
||||
),
|
||||
"b": JSONSchema(
|
||||
type=JSONSchema.Type.INTEGER,
|
||||
description="The second number",
|
||||
required=True,
|
||||
)})
|
||||
def multiply(self, a: int, b: int) -> str:
|
||||
"""
|
||||
Multiplies two numbers.
|
||||
|
||||
Args:
|
||||
a: First number
|
||||
b: Second number
|
||||
|
||||
Returns:
|
||||
Result of multiplication
|
||||
"""
|
||||
return str(a * b)
|
||||
```
|
||||
|
||||
The agent will be able to call this command, named `multiply` with two arguments and will receive the result. The command description will be: `Multiplies two numbers.`
|
||||
|
||||
To learn more about commands see [🛠️ Commands](./commands.md).
|
||||
|
||||
## Order-dependent protocols
|
||||
|
||||
The order of components implementing order-dependent protocols is important.
|
||||
Some components may depend on the results of components before them.
|
||||
|
||||
### `MessageProvider`
|
||||
|
||||
Yields messages that will be added to the agent's prompt. You can use either `ChatMessage.user()`: this will interpreted as a user-sent message or `ChatMessage.system()`: that will be more important.
|
||||
|
||||
```py
|
||||
class MessageProvider(AgentComponent):
|
||||
def get_messages(self) -> Iterator[ChatMessage]:
|
||||
...
|
||||
```
|
||||
|
||||
**Example** Component that provides a message to the agent's prompt.
|
||||
|
||||
```py
|
||||
class HelloComponent(MessageProvider):
|
||||
def get_messages(self) -> Iterator[ChatMessage]:
|
||||
yield ChatMessage.user("Hello World!")
|
||||
```
|
||||
|
||||
### `AfterParse`
|
||||
|
||||
Protocol called after the response is parsed.
|
||||
|
||||
```py
|
||||
class AfterParse(AgentComponent):
|
||||
def after_parse(self, response: ThoughtProcessOutput) -> None:
|
||||
...
|
||||
```
|
||||
|
||||
**Example** Component that logs the response after it's parsed.
|
||||
|
||||
```py
|
||||
class LoggerComponent(AfterParse):
|
||||
def after_parse(self, response: ThoughtProcessOutput) -> None:
|
||||
logger.info(f"Response: {response}")
|
||||
```
|
||||
|
||||
### `ExecutionFailure`
|
||||
|
||||
Protocol called when the execution of the command fails.
|
||||
|
||||
```py
|
||||
class ExecutionFailure(AgentComponent):
|
||||
@abstractmethod
|
||||
def execution_failure(self, error: Exception) -> None:
|
||||
...
|
||||
```
|
||||
|
||||
**Example** Component that logs the error when the command fails.
|
||||
|
||||
```py
|
||||
class LoggerComponent(ExecutionFailure):
|
||||
def execution_failure(self, error: Exception) -> None:
|
||||
logger.error(f"Command execution failed: {error}")
|
||||
```
|
||||
|
||||
### `AfterExecute`
|
||||
|
||||
Protocol called after the command is successfully executed by the agent.
|
||||
|
||||
```py
|
||||
class AfterExecute(AgentComponent):
|
||||
def after_execute(self, result: ActionResult) -> None:
|
||||
...
|
||||
```
|
||||
|
||||
**Example** Component that logs the result after the command is executed.
|
||||
|
||||
```py
|
||||
class LoggerComponent(AfterExecute):
|
||||
def after_execute(self, result: ActionResult) -> None:
|
||||
logger.info(f"Result: {result}")
|
||||
```
|
||||
Reference in New Issue
Block a user