agent multi step reasoning update

pull/839/head
Kye Gomez 4 weeks ago
parent 048a47931e
commit c43180de14

@ -1,20 +1,16 @@
from swarms.structs.agent import Agent from swarms.structs.agent import Agent
from swarms.prompts.finance_agent_sys_prompt import (
FINANCIAL_AGENT_SYS_PROMPT,
)
# Initialize the agent # Initialize the agent
agent = Agent( agent = Agent(
agent_name="Financial-Analysis-Agent", agent_name="Financial-Analysis-Agent",
agent_description="Personal finance advisor agent", agent_description="Personal finance advisor agent",
system_prompt=FINANCIAL_AGENT_SYS_PROMPT, max_loops=4,
max_loops=2,
model_name="gpt-4o-mini", model_name="gpt-4o-mini",
dynamic_temperature_enabled=True, dynamic_temperature_enabled=True,
interactive=False, interactive=False,
output_type="dict", output_type="all",
) )
print( agent.run("Conduct an analysis of the best real undervalued ETFs")
agent.run("Conduct an analysis of the best real undervalued ETFs") # print(out)
) # print(type(out))

@ -0,0 +1,48 @@
def generate_reasoning_prompt(max_loops: int) -> str:
# You are a deliberate, step-by-step reasoning agent designed to solve complex problems
# through iterative reasoning loops.
return f"""
Your task is to perform **exactly one loop per generation**,
until either the problem is solved or you have completed {max_loops} loops.
## Instructions:
- In this generation, perform loop number {{current_loop}} out of {max_loops}.
- **Do not perform more than one loop in a single generation.**
- Use the **maximum token budget** available to explore, reason, and reflect.
- Output must **end** with:
- `### End of Loop {{current_loop}}`
- **Do not proceed to loop {{current_loop + 1}}** unless explicitly prompted again.
## Loop Structure (per generation):
1. **Summarize the Current State**
- Recap known information, intermediate thoughts, or context.
2. **Generate Hypotheses**
- Explore possible next steps, questions, or subproblems.
3. **Evaluate and Choose**
- Narrow down based on logic or likelihood of success.
4. **Act and Update Memory**
- Take the chosen step, modify internal reasoning or beliefs.
5. **Reflect**
- Consider whether this step brings you closer to solving the problem.
- Suggest whether to continue, backtrack, or finalize.
## Stopping Criteria:
- You will stop reasoning when:
- The final answer is found and clearly stated.
- {max_loops} loops have been completed.
- You conclude that continued reasoning won't help.
In the final loop (loop {max_loops}), output your final solution as:
**Final Answer:**
Be methodical, reflective, and token-efficient. Use all available room to think in detail.
Do not rush to conclusions. Each loop is isolated and should be treated as its own generation.
"""

@ -0,0 +1,41 @@
REACT_SYS_PROMPT = """You are a thoughtful and methodical AI agent. You solve problems through careful reasoning and by using external tools when needed. You use a "Thought → Action → Observation" loop, repeating as many times as needed to build your understanding and solve the problem. Your goal is not just to answer correctly, but to demonstrate clear reasoning and adaptability.
Follow this structure:
---
Question: [The users input]
Thought 1: Understand the question. What is being asked? Break it down into sub-parts. What knowledge or information might be required?
Thought 2: Form a plan. Decide what steps to take. Which facts should be recalled? Which need to be looked up? Which tools should be used?
Action 1: [Use a tool, such as Search[query], Lookup[entity], Calculator[expression], or even Plan[...] if you need to set subgoals]
Observation 1: [The result from the tool]
Thought 3: Reflect on the observation. What did you learn? What do you now know or still not know? Update your plan if needed.
Action 2: [Next tool or operation]
Observation 2: [...]
...
[Repeat Thought Action Observation as needed]
Thought N: You now have all the necessary information. Synthesize what you know. Reconstruct the answer clearly, and justify it.
Action N: Finish[final_answer]
---
Guidelines for Reasoning:
- Always **start by interpreting the problem carefully.**
- If the question is complex, **break it into parts** and tackle each.
- **Think before you act.** Plan actions deliberately, not reflexively.
- Use **search engines** or **lookup tools** for facts, definitions, or current events.
- Use a **calculator** for numerical operations.
- Use **Reflection** steps if your observations are unclear, surprising, or contradictory.
- Don't rush to finish — **reasoning is more important than speed.**
- When concluding, make sure your **answer is fully supported** by earlier steps.
"""

@ -65,6 +65,8 @@ from swarms.utils.litellm_tokenizer import count_tokens
from swarms.utils.litellm_wrapper import LiteLLM from swarms.utils.litellm_wrapper import LiteLLM
from swarms.utils.pdf_to_text import pdf_to_text from swarms.utils.pdf_to_text import pdf_to_text
from swarms.utils.str_to_dict import str_to_dict from swarms.utils.str_to_dict import str_to_dict
from swarms.prompts.react_base_prompt import REACT_SYS_PROMPT
from swarms.prompts.max_loop_prompt import generate_reasoning_prompt
# Utils # Utils
@ -302,7 +304,7 @@ class Agent:
saved_state_path: Optional[str] = None, saved_state_path: Optional[str] = None,
autosave: Optional[bool] = False, autosave: Optional[bool] = False,
context_length: Optional[int] = 8192, context_length: Optional[int] = 8192,
user_name: Optional[str] = "Human:", user_name: Optional[str] = "Human",
self_healing_enabled: Optional[bool] = False, self_healing_enabled: Optional[bool] = False,
code_interpreter: Optional[bool] = False, code_interpreter: Optional[bool] = False,
multi_modal: Optional[bool] = None, multi_modal: Optional[bool] = None,
@ -396,6 +398,7 @@ class Agent:
mcp_servers: MCPServerSseParams = None, mcp_servers: MCPServerSseParams = None,
mcp_url: str = None, mcp_url: str = None,
mcp_urls: List[str] = None, mcp_urls: List[str] = None,
react_on: bool = False,
*args, *args,
**kwargs, **kwargs,
): ):
@ -518,12 +521,13 @@ class Agent:
self.mcp_servers = mcp_servers self.mcp_servers = mcp_servers
self.mcp_url = mcp_url self.mcp_url = mcp_url
self.mcp_urls = mcp_urls self.mcp_urls = mcp_urls
self.react_on = react_on
self._cached_llm = ( self._cached_llm = (
None # Add this line to cache the LLM instance None # Add this line to cache the LLM instance
) )
self.short_memory = self.short_memory_init() # self.short_memory = self.short_memory_init()
# Initialize the feedback # Initialize the feedback
self.feedback = [] self.feedback = []
@ -555,6 +559,16 @@ class Agent:
if self.mcp_url or self.mcp_servers is not None: if self.mcp_url or self.mcp_servers is not None:
self.add_mcp_tools_to_memory() self.add_mcp_tools_to_memory()
if self.react_on is True:
self.system_prompt += REACT_SYS_PROMPT
if len(self.max_loops) > 1:
self.system_prompt += generate_reasoning_prompt(
self.max_loops
)
self.short_memory = self.short_memory_init()
def short_memory_init(self): def short_memory_init(self):
if ( if (
self.agent_name is not None self.agent_name is not None
@ -575,33 +589,6 @@ class Agent:
return self.short_memory return self.short_memory
def init_handling(self):
# Define tasks as pairs of (function, condition)
# Each task will only run if its condition is True
self.setup_config()
if exists(self.docs_folder):
self.get_docs_from_doc_folders()
if exists(self.tools):
self.handle_tool_init()
if exists(self.tool_schema) or exists(self.list_base_models):
self.handle_tool_schema_ops()
if exists(self.sop) or exists(self.sop_list):
self.handle_sop_ops()
# Run sequential operations after all concurrent tasks are done
# self.agent_output = self.agent_output_model()
log_agent_data(self.to_dict())
if self.llm is None:
self.llm = self.llm_handling()
if self.mcp_url or self.mcp_servers is not None:
self.add_mcp_tools_to_memory()
def agent_output_model(self): def agent_output_model(self):
# Many steps # Many steps
id = agent_id() id = agent_id()
@ -1021,24 +1008,13 @@ class Agent:
agent(task="What is the capital of France?", img="path/to/image.jpg", is_last=True) agent(task="What is the capital of France?", img="path/to/image.jpg", is_last=True)
""" """
try: try:
# 1. Batch process initial setup
setup_tasks = [
lambda: self.check_if_no_prompt_then_autogenerate(
task
),
lambda: self.short_memory.add(
role=self.user_name, content=task
),
lambda: (
self.plan(task) if self.plan_enabled else None
),
]
# Execute setup tasks concurrently self.check_if_no_prompt_then_autogenerate(task)
with ThreadPoolExecutor(
max_workers=len(setup_tasks) self.short_memory.add(role=self.user_name, content=task)
) as executor:
executor.map(lambda f: f(), setup_tasks) if self.plan_enabled:
self.plan(task)
# Set the loop count # Set the loop count
loop_count = 0 loop_count = 0
@ -1068,10 +1044,18 @@ class Agent:
): ):
loop_count += 1 loop_count += 1
# self.short_memory.add( if len(self.max_loops) > 1:
# role=f"{self.agent_name}", self.short_memory.add(
# content=f"Internal Reasoning Loop: {loop_count} of {self.max_loops}", role=self.agent_name,
# ) content=f"Current Internal Reasoning Loop: {loop_count}/{self.max_loops}",
)
# If it is the final loop, then add the final loop message
if loop_count == self.max_loops:
self.short_memory.add(
role=self.agent_name,
content=f"🎉 Final Internal Reasoning Loop: {loop_count}/{self.max_loops} Prepare your comprehensive response.",
)
# Dynamic temperature # Dynamic temperature
if self.dynamic_temperature_enabled is True: if self.dynamic_temperature_enabled is True:
@ -1148,7 +1132,11 @@ class Agent:
self.streaming_on, self.streaming_on,
) )
out = self.llm.run(out) out = self.call_llm(task=out)
self.short_memory.add(
role=self.agent_name, content=out
)
if self.no_print is False: if self.no_print is False:
agent_print( agent_print(
@ -1158,10 +1146,6 @@ class Agent:
self.streaming_on, self.streaming_on,
) )
self.short_memory.add(
role=self.agent_name, content=out
)
self.sentiment_and_evaluator(response) self.sentiment_and_evaluator(response)
success = True # Mark as successful to exit the retry loop success = True # Mark as successful to exit the retry loop
@ -1219,7 +1203,7 @@ class Agent:
break break
self.short_memory.add( self.short_memory.add(
role="User", content=user_input role=self.user_name, content=user_input
) )
if self.loop_interval: if self.loop_interval:
@ -1233,21 +1217,10 @@ class Agent:
self.save() self.save()
# log_agent_data(self.to_dict()) log_agent_data(self.to_dict())
# if self.autosave is True:
# self.save()
# 14. Batch final operations
final_tasks = [
lambda: log_agent_data(self.to_dict()),
lambda: self.save() if self.autosave else None,
]
with ThreadPoolExecutor( if self.autosave:
max_workers=len(final_tasks) self.save()
) as executor:
executor.map(lambda f: f(), final_tasks)
return history_output_formatter( return history_output_formatter(
self.short_memory, type=self.output_type self.short_memory, type=self.output_type

Loading…
Cancel
Save