Skip to content

Commit

Permalink
fix(agent): Disable profile generator -> speed up agent setup (Signif…
Browse files Browse the repository at this point in the history
…icant-Gravitas#7121)

* Add default AutoGPT profile to ai_profile.py & disable profile generator

* Disable custom AI profile generation in agent_protocol_server.py
   - Replace `generate_agent_for_task` by `create_agent`
   - Make `ai_profile` parameter on `create_agent` optional (use default `AIProfile` if not passed)

* Generalize example call in profile_generator.py
   Currently it's specified in an OpenAI-specific format, which might adversely affect performance with other providers.

* Remove dead `AIProfile.api_budget` attribute

* Remove `agent.ai_profile` and `agent.directives` attributes, and replace usages with `agent.state.*`
   This prevents potential state inconsistency between `agent` and `agent.state` when other values are assigned to `agent.ai_profile` and `agent.directives`
  • Loading branch information
Pwuts authored May 31, 2024
1 parent f67c214 commit 16df151
Show file tree
Hide file tree
Showing 8 changed files with 88 additions and 97 deletions.
3 changes: 2 additions & 1 deletion autogpt/autogpt/agent_factory/configurators.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,14 +12,15 @@
def create_agent(
agent_id: str,
task: str,
ai_profile: AIProfile,
app_config: Config,
file_storage: FileStorage,
llm_provider: MultiProvider,
ai_profile: Optional[AIProfile] = None,
directives: Optional[AIDirectives] = None,
) -> Agent:
if not task:
raise ValueError("No task specified for new agent")
ai_profile = ai_profile or AIProfile()
directives = directives or AIDirectives()

agent = _configure_agent(
Expand Down
86 changes: 40 additions & 46 deletions autogpt/autogpt/agent_factory/profile_generator.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,53 +21,48 @@ class AgentProfileGeneratorConfiguration(SystemConfiguration):
model_classification: LanguageModelClassification = UserConfigurable(
default=LanguageModelClassification.SMART_MODEL
)
_example_call: object = [
{
"type": "function",
"function": {
"name": "create_agent",
"arguments": {
"name": "CMOGPT",
"description": (
"a professional digital marketer AI that assists Solopreneurs "
"in growing their businesses by providing "
"world-class expertise in solving marketing problems "
"for SaaS, content products, agencies, and more."
_example_call: object = {
"name": "create_agent",
"arguments": {
"name": "CMOGPT",
"description": (
"a professional digital marketer AI that assists Solopreneurs "
"in growing their businesses by providing "
"world-class expertise in solving marketing problems "
"for SaaS, content products, agencies, and more."
),
"directives": {
"best_practices": [
(
"Engage in effective problem-solving, prioritization, "
"planning, and supporting execution to address your "
"marketing needs as your virtual "
"Chief Marketing Officer."
),
"directives": {
"best_practices": [
(
"Engage in effective problem-solving, prioritization, "
"planning, and supporting execution to address your "
"marketing needs as your virtual "
"Chief Marketing Officer."
),
(
"Provide specific, actionable, and concise advice to "
"help you make informed decisions without the use of "
"platitudes or overly wordy explanations."
),
(
"Identify and prioritize quick wins and cost-effective "
"campaigns that maximize results with minimal time and "
"budget investment."
),
(
"Proactively take the lead in guiding you and offering "
"suggestions when faced with unclear information or "
"uncertainty to ensure your marketing strategy remains "
"on track."
),
],
"constraints": [
"Do not suggest illegal or unethical plans or strategies.",
"Take reasonable budgetary limits into account.",
],
},
},
(
"Provide specific, actionable, and concise advice to "
"help you make informed decisions without the use of "
"platitudes or overly wordy explanations."
),
(
"Identify and prioritize quick wins and cost-effective "
"campaigns that maximize results with minimal time and "
"budget investment."
),
(
"Proactively take the lead in guiding you and offering "
"suggestions when faced with unclear information or "
"uncertainty to ensure your marketing strategy remains "
"on track."
),
],
"constraints": [
"Do not suggest illegal or unethical plans or strategies.",
"Take reasonable budgetary limits into account.",
],
},
}
]
},
}
system_prompt: str = UserConfigurable(
default=(
"Your job is to respond to a user-defined task, given in triple quotes, by "
Expand Down Expand Up @@ -192,7 +187,6 @@ def parse_response_content(
Returns:
The parsed response.
"""
try:
if not response.tool_calls:
Expand Down
4 changes: 1 addition & 3 deletions autogpt/autogpt/agents/agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -104,8 +104,6 @@ def __init__(
super().__init__(settings)

self.llm_provider = llm_provider
self.ai_profile = settings.ai_profile
self.directives = settings.directives
prompt_config = OneShotAgentPromptStrategy.default_configuration.copy(deep=True)
prompt_config.use_functions_api = (
settings.config.use_functions_api
Expand All @@ -116,7 +114,7 @@ def __init__(
self.commands: list[Command] = []

# Components
self.system = SystemComponent(legacy_config, settings.ai_profile)
self.system = SystemComponent()
self.history = ActionHistoryComponent(
settings.history,
self.send_token_limit,
Expand Down
18 changes: 1 addition & 17 deletions autogpt/autogpt/agents/prompt_strategies/one_shot.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,10 +160,7 @@ def build_system_prompt(
+ (self._generate_os_info() if include_os_info else [])
+ [
self.config.body_template.format(
constraints=format_numbered_list(
ai_directives.constraints
+ self._generate_budget_constraint(ai_profile.api_budget)
),
constraints=format_numbered_list(ai_directives.constraints),
resources=format_numbered_list(ai_directives.resources),
commands=self._generate_commands_list(commands),
best_practices=format_numbered_list(ai_directives.best_practices),
Expand Down Expand Up @@ -237,19 +234,6 @@ def _generate_os_info(self) -> list[str]:
)
return [f"The OS you are running on is: {os_info}"]

def _generate_budget_constraint(self, api_budget: float) -> list[str]:
"""Generates the budget information part of the prompt.
Returns:
list[str]: The budget information part of the prompt, or an empty list.
"""
if api_budget > 0.0:
return [
f"It takes money to let you run. "
f"Your API budget is ${api_budget:.3f}"
]
return []

def _generate_commands_list(self, commands: list[CompletionModelFunction]) -> str:
"""Lists the commands available to the agent.
Expand Down
9 changes: 5 additions & 4 deletions autogpt/autogpt/app/agent_protocol_server.py
Original file line number Diff line number Diff line change
Expand Up @@ -33,8 +33,7 @@
from hypercorn.config import Config as HypercornConfig
from sentry_sdk import set_user

from autogpt.agent_factory.configurators import configure_agent_with_state
from autogpt.agent_factory.generators import generate_agent_for_task
from autogpt.agent_factory.configurators import configure_agent_with_state, create_agent
from autogpt.agents.agent_manager import AgentManager
from autogpt.app.utils import is_port_free

Expand Down Expand Up @@ -134,8 +133,10 @@ async def create_task(self, task_request: TaskRequestBody) -> Task:
input=task_request.input,
additional_input=task_request.additional_input,
)
logger.debug(f"Creating agent for task: '{task.input}'")
task_agent = await generate_agent_for_task(
# TODO: re-evaluate performance benefit of task-oriented profiles
# logger.debug(f"Creating agent for task: '{task.input}'")
# task_agent = await generate_agent_for_task(
task_agent = create_agent(
agent_id=task_agent_id(task.task_id),
task=task.input,
app_config=self.app_config,
Expand Down
39 changes: 27 additions & 12 deletions autogpt/autogpt/app/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
is_docker_available,
we_are_running_in_a_docker_container,
)
from forge.config.ai_directives import AIDirectives
from forge.config.ai_profile import AIProfile
from forge.config.config import Config, ConfigBuilder, assert_config_has_openai_api_key
from forge.file_storage import FileStorageBackendName, get_storage
Expand All @@ -31,7 +32,6 @@
from forge.utils.exceptions import AgentTerminated, InvalidAgentResponseError

from autogpt.agent_factory.configurators import configure_agent_with_state, create_agent
from autogpt.agent_factory.profile_generator import generate_agent_profile_for_task
from autogpt.agents.agent_manager import AgentManager
from autogpt.agents.prompt_strategies.one_shot import AssistantThoughts

Expand Down Expand Up @@ -260,15 +260,11 @@ async def run_auto_gpt(
" with as much detail as possible:",
)

ai_profile, task_oriented_ai_directives = await generate_agent_profile_for_task(
task,
app_config=config,
llm_provider=llm_provider,
)
ai_directives = task_oriented_ai_directives
ai_profile = AIProfile()
additional_ai_directives = AIDirectives()
apply_overrides_to_ai_settings(
ai_profile=ai_profile,
directives=ai_directives,
directives=additional_ai_directives,
override_name=override_ai_name,
override_role=override_ai_role,
resources=resources,
Expand All @@ -288,9 +284,12 @@ async def run_auto_gpt(
best_practices,
]
):
ai_profile, ai_directives = await interactively_revise_ai_settings(
(
ai_profile,
additional_ai_directives,
) = await interactively_revise_ai_settings(
ai_profile=ai_profile,
directives=ai_directives,
directives=additional_ai_directives,
app_config=config,
)
else:
Expand All @@ -300,7 +299,7 @@ async def run_auto_gpt(
agent_id=agent_manager.generate_id(ai_profile.ai_name),
task=task,
ai_profile=ai_profile,
directives=ai_directives,
directives=additional_ai_directives,
app_config=config,
file_storage=file_storage,
llm_provider=llm_provider,
Expand All @@ -316,6 +315,22 @@ async def run_auto_gpt(
extra={"preserve_color": True},
)

# TODO: re-evaluate performance benefit of task-oriented profiles
# # Concurrently generate a custom profile for the agent and apply it once done
# def update_agent_directives(
# task: asyncio.Task[tuple[AIProfile, AIDirectives]]
# ):
# logger.debug(f"Updating AIProfile: {task.result()[0]}")
# logger.debug(f"Adding AIDirectives: {task.result()[1]}")
# agent.state.ai_profile = task.result()[0]
# agent.state.directives = agent.state.directives + task.result()[1]

# asyncio.create_task(
# generate_agent_profile_for_task(
# task, app_config=config, llm_provider=llm_provider
# )
# ).add_done_callback(update_agent_directives)

#################
# Run the Agent #
#################
Expand Down Expand Up @@ -445,7 +460,7 @@ async def run_interaction_loop(
"""
# These contain both application config and agent config, so grab them here.
legacy_config = agent.legacy_config
ai_profile = agent.ai_profile
ai_profile = agent.state.ai_profile
logger = logging.getLogger(__name__)

cycle_budget = cycles_remaining = _get_cycle_budget(
Expand Down
11 changes: 0 additions & 11 deletions forge/forge/components/system/system.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,8 +4,6 @@

from forge.agent.protocols import CommandProvider, DirectiveProvider, MessageProvider
from forge.command import Command, command
from forge.config.ai_profile import AIProfile
from forge.config.config import Config
from forge.llm.providers import ChatMessage
from forge.models.json_schema import JSONSchema
from forge.utils.const import FINISH_COMMAND
Expand All @@ -17,16 +15,7 @@
class SystemComponent(DirectiveProvider, MessageProvider, CommandProvider):
"""Component for system messages and commands."""

def __init__(self, config: Config, profile: AIProfile):
self.legacy_config = config
self.profile = profile

def get_constraints(self) -> Iterator[str]:
if self.profile.api_budget > 0.0:
yield (
f"It takes money to let you run. "
f"Your API budget is ${self.profile.api_budget:.3f}"
)
yield "Exclusively use the commands listed below."
yield (
"You can only act proactively, and are unable to start background jobs or "
Expand Down
15 changes: 12 additions & 3 deletions forge/forge/config/ai_profile.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,14 @@
from pydantic import BaseModel, Field

DEFAULT_AI_NAME = "AutoGPT"
DEFAULT_AI_ROLE = (
"a seasoned digital assistant: "
"capable, intelligent, considerate and assertive. "
"You have extensive research and development skills, and you don't shy "
"away from writing some code to solve a problem. "
"You are pragmatic and make the most out of the tools available to you."
)


class AIProfile(BaseModel):
"""
Expand All @@ -12,7 +21,7 @@ class AIProfile(BaseModel):
api_budget (float): The maximum dollar value for API calls (0.0 means infinite)
"""

ai_name: str = ""
ai_role: str = ""
ai_name: str = DEFAULT_AI_NAME
ai_role: str = DEFAULT_AI_ROLE
"""`ai_role` should fit in the following format: `You are {ai_name}, {ai_role}`"""
ai_goals: list[str] = Field(default_factory=list[str])
api_budget: float = 0.0

0 comments on commit 16df151

Please sign in to comment.