[BUG][HierarchicalSwarm.prepare_worker_agents][multi_agent_prompt_improvements appends to system_prompt after the LLM is built, so it never reaches the model and piles up]
Summary
HierarchicalSwarm(multi_agent_prompt_improvements=True) does nothing the model can see. It appends about 9 KB of collaboration preamble and team roster to each worker's system_prompt, but it does so after the worker's LLM has been built, so the text never appears in the request. The append is also permanent and cumulative on the caller's own Agent objects: every HierarchicalSwarm built over the same workers adds another copy. Nothing raises and nothing is logged.
This is the third copy of the defect fixed for SequentialWorkflow in #2035 and for SwarmRouter in #2048.
Reproduction
Offline, with litellm.completion stubbed so the check sees the request that would actually go to the provider:
from types import SimpleNamespace
import swarms.utils.litellm_wrapper as lw
from swarms import Agent, HierarchicalSwarm
from swarms.prompts.multi_agent_collab_prompt import MULTI_AGENT_COLLAB_PROMPT_TWO
sent = []
def fake_completion(**params):
sent.append(params["messages"])
msg = SimpleNamespace(content="WORKER_ANSWER", tool_calls=None, role="assistant")
return SimpleNamespace(choices=[SimpleNamespace(message=msg, finish_reason="stop")], usage=None)
lw.completion = fake_completion
director = lambda: Agent(agent_name="Director", model_name="gpt-5.4", print_on=False)
worker = Agent(agent_name="Researcher", system_prompt="You research.", model_name="gpt-5.4", max_loops=1, print_on=False)
print("worker.system_prompt:", len(worker.system_prompt), "chars before")
swarm = HierarchicalSwarm(agents=[worker], multi_agent_prompt_improvements=True, director=director())
print(" after one HierarchicalSwarm(...):", len(worker.system_prompt), "chars")
HierarchicalSwarm(agents=[worker], multi_agent_prompt_improvements=True, director=director())
print(" after a second:", len(worker.system_prompt), "chars")
swarm.call_single_agent("Researcher", "Find three facts about Mars.")
request = sent[-1]
print("roles sent to the model:", [m["role"] for m in request])
print("collaboration preamble in the request:",
any(MULTI_AGENT_COLLAB_PROMPT_TWO.strip()[:80] in str(m["content"]) for m in request))On master (04c8e97d):
worker.system_prompt: 13 chars before
after one HierarchicalSwarm(...): 9121 chars
after a second: 18229 chars
roles sent to the model: ['system', 'user']
collaboration preamble in the request: FalseExpected: the preamble reaches the request, and the caller's agent is left unchanged.
Root cause
swarms/structs/hiearchical_swarm.py:221-230, called from init_swarm() at :243-244:
def prepare_worker_agents(self):
for agent in self.agents:
prompt = MULTI_AGENT_COLLAB_PROMPT_TWO + self.list_worker_agents()
if hasattr(agent, "system_prompt"):
agent.system_prompt += promptWorkers are built by the caller before they reach the swarm. Agent.__init__ builds the LiteLLM client, which bakes the system prompt into its own message list at construction time. Agent._transcript_from_memory then skips system rows because "the LLM wrapper supplies it". After construction, nothing reads agent.system_prompt again, so the append is dead text. It is only ever visible if something later rebuilds the LLM, at which point every accumulated copy arrives at once.
Expected fix
Deliver the preamble the way #2035 and #2048 did: as a per-call system turn, without touching the caller's agent. HierarchicalSwarm already builds each worker's messages in _worker_run_payload (:393-399), so the preamble can be prepended there, and prepare_worker_agents together with its call in init_swarm can be deleted. AgentRearrange._messages_for already delivers its collab_prompt this way.
A nested swarm whose run() takes no messages would not receive the preamble. It does not receive it today either: the attribute this code sets on it is never read.
Source: kyegomez/swarms