Subagents¶
In the subagent pattern, a main agent creates child subagents to break down and complete a task in parallel.
We support this pattern:
- Create a parent agent.
- Create a child agent, no special syntax needed.
- (Optional) Give the child access to its parent's messages.
from dotenv import load_dotenv
import parallem as pllm
import polars as pl
def subagent_app(orch: pllm.AgentOrchestrator):
collector = []
# Main agent
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()]
# Nested child agent
for i, item in enumerate(places):
with orch.agent(f"subagent-{i}") as subagt:
# Give subagent the parent agent conversation
subconv = subagt.get_msg_state()
subconv.extend(conv)
subconv.ask_llm(
f"Please write 2 paragraphs about {item}.",
tools=[pllm.tools.WebSearchTool()],
)
collector.append(
{
"place": item,
"description": subconv[-1].final_answer,
}
)
return pl.DataFrame(collector)
def aggregation_app(orch: pllm.AgentOrchestrator, df: pl.DataFrame):
all_descriptions = "\n\n".join(df["description"].to_list())
with orch.agent("agg-agent") as agt:
conv = agt.get_msg_state()
conv.ask_llm(
"I like both urban and countryside exploration. Can you pick the top 3 destinations from the choices below? Please give a brief explanation.",
all_descriptions,
)
return conv[-1].final_answer
if __name__ == "__main__":
load_dotenv()
with pllm.resume_directory(".pllm/example/subagents") as orch:
df = subagent_app(orch)
with pl.Config(set_ascii_tables=True):
print(df)
summary = aggregation_app(orch, df)
print(summary)
Output:
[INFO] Resuming with session_id=7
shape: (10, 2)
+-----------+-----------------------------------+
| place | description |
| --- | --- |
| str | str |
+===============================================+
| Paris | Paris is a city of light and l... |
| Tokyo | Tokyo is a city where centurie... |
| New York | New York City, often simply ca... |
| Rome | Rome, the capital of Italy, is... |
| Barcelona | Barcelona sits on the northeas... |
| Istanbul | Istanbul is a city where two c... |
| Bangkok | Bangkok, Thailand's energetic ... |
| Sydney | Sydney is Australia's largest ... |
| Kyoto | Kyoto, in Japan's Kansai regio... |
| Bali | Bali, Indonesia's famed island... |
+-----------+-----------------------------------+
Aggregation¶
After creating subagents, you can aggregate their results.
Output:
Top 3 destinations for a mix of urban and countryside exploration:
- Kyoto, Japan — A city steeped in tradition with easy access to nature: Arashiyama’s bamboo grove, temple gardens, and the Philosopher’s Path let you wander from refined urban culture into serene countryside scenes, all in one trip.
- Sydney, Australia — A world-class city with immediate nature on your doorstep: iconic harbors and beaches (Bondi, Manly) plus coastal trails and nearby national parks give you city vibes and outdoor escapes in one headlining destination.
- Bali, Indonesia — Rich rural landscapes paired with vibrant culture: terraced rice paddies in Ubud, volcanic hikes (Mount Batur), and stunning temples sit alongside beach towns and lively markets, offering both countryside immersion and island-city flavor.
Dynamically creating subagents¶
To create a subagent via a function call, pass the subagent declaration like any other function. Subagents will be created with the names passed into subagent_names.