Subagents¶
In the subagent pattern, a main agent creates child subagents to break down and complete a task in parallel.
This pattern is supported by parallem:
- Create a parent agent.
- Within the parent block, create a child agent. (No special syntax required.)
- (Optional) Give the child access to its parent's messages.
from dotenv import load_dotenv
import parallem as pllm
def subagent_app(orch: pllm.AgentOrchestrator):
with orch.agent("main-agent") as agt:
conv = agt.get_msg_state()
conv.ask_llm(
"Please name 10 tourist destinations, separated by commas, with no explanation."
)
places = [x.strip() for x in conv[-1].final_answer.split(",") if x.strip()]
print(places)
# Subagent pattern: simply create another agent from within the agent
# No special syntax required.
descriptions = []
for i, item in enumerate(places):
with orch.agent(f"subagent-{i}") as subagt:
subconv = subagt.get_msg_state()
subconv.extend(conv) # Give subagent the parent agent conversation
subconv.ask_llm(
f"Please write 2 paragraphs about {item}.",
tools=[pllm.tools.WebSearchTool()],
)
descriptions.append(subconv[-1])
for i, desc in enumerate(descriptions):
print(f"{i + 1}. {desc.final_answer[:40]}...")
if __name__ == "__main__":
load_dotenv()
with pllm.resume_directory(
".pllm/example/subagents",
provider="openai",
strategy="concurrent",
) as orch:
subagent_app(orch)
[INFO] Resuming with session_id=5
['Paris', 'Tokyo', 'New York', 'Rome', 'Barcelona', 'Istanbul', 'Bangkok', 'Sydney', 'Kyoto', 'Bali']
1. Paris is a city of light and layers, whe...
2. Tokyo is a city where centuries of tradi...
3. New York City, often simply called New Y...
4. Rome, the capital of Italy, is a living ...
5. Barcelona sits on the northeastern coast...
6. Istanbul is a city where two continents ...
7. Bangkok, Thailand's energetic capital, s...
8. Sydney is Australia's largest city, fame...
9. Kyoto, in Japan's Kansai region, long se...
10. Bali, Indonesia's famed island, lies bet...
Dynamically creating subagents¶
You may want the parent to create a subagent via a function call.
Simply pass in your subagent function as a function call (like any regular function).
When ask_functions is called, ParaLLeM will automatically create the necessary subagents using the names passed into subagent_names.
import parallem as pllm
from dotenv import load_dotenv
def city_summary_agent(agt: pllm.AgentContext, city: str) -> str:
"""Creates an up-to-date summary of a city as a travel destination."""
conv = agt.get_msg_state()
conv.ask_llm(f"Write one concise paragraph about {city} as a travel destination.")
return conv[-1].final_answer
def planner_agent(agt: pllm.AgentContext):
# Parent agent
conv = agt.get_msg_state()
conv.ask_llm(
"Generate summaries of 3 popular travel destinations.",
tools=pllm.to_tool_schema([city_summary_agent]),
)
# ask_functions creates subagents on the fly
fc_outs = conv.ask_functions(
city_summary_agent=city_summary_agent,
subagent_names=["city-agent-1", "city-agent-2", "city-agent-3"],
)
conv.ask_llm(
"Combine these city summaries into a ranked list.",
*fc_outs,
)
print(conv[-1].final_answer)
if __name__ == "__main__":
load_dotenv()
with pllm.resume_directory(
".pllm/example/subagent-dynamic", dashboard=True
) as orch:
with orch.agent("planner") as agt:
planner_agent(agt)