Multiple Agent Workflow Fails to Automatically Parallelize Tasks

Status Closed — not planned
Maintainer reply None cached
Activity 12 comments · opened Aug 13, 2025 · closed Jan 8, 2026

Bug Description
when asking claude to do a task using multiple agents, even if specifying a number to use, the exact same pattern emerges - claude agrees and then proceeds with working using only one agent, and you need to stop him and instruct again to launch multiple agents - and only then it will comply

Environment Info

  • Platform: darwin
  • Terminal: cursor
  • Version: 1.0.77
  • Feedback ID: de424c7c-c0b5-414e-9e4e-f50fc16951bc

Errors

[]

View original on GitHub ↗

12 Comments

danieliser · 1 year ago

Just tweeted about this last night, try this in your prompt @ivg-design.

Run multiple Task invocations in a SINGLE message

I had 5 parallel agents succesfully build out a spec together

<img width="2400" height="552" alt="Image" src="https://github.com/user-attachments/assets/b9756324-1d29-4471-900a-9e9368838edd" />

The spec was requested to be parsed into groups of tasks that could be paralleled without issues. Each list of tasks was accomplished by a single sub-agent (can also just use Task() for each as well).

Results were super promising. The code generated worked 99%, only a few small issues had to be ironed out across multiple systems.

notque · 1 year ago

It's hard to get them to consistently run in parallel. I've found asking for parallel gives me the least likely response to them being run. Better results are from "at the same time" and other variations. But it's not consistent.

It works more often when you use a coordinator agent for some reason.

ivg-design · 1 year ago

i was never able to get one agent to supervise multiple others - - how would you even do it? I've tried to have a custom Supervisor but it never runs in parallel - only sequentially - i could not even get this custom agents stuff to work - only the multiple prompts to get 4-5 agents working on a task....

github-actions[bot] · 1 year ago

Found 3 possible duplicate issues:

  1. https://github.com/anthropics/claude-code/issues/5032
  2. https://github.com/anthropics/claude-code/issues/5703
  3. https://github.com/anthropics/claude-code/issues/2148

This issue will be automatically closed as a duplicate in 3 days.

  • If your issue is a duplicate, please close it and 👍 the existing issue instead
  • To prevent auto-closure, add a comment or 👎 this comment

🤖 Generated with Claude Code

ivg-design · 1 year ago

this is not the same as other issues - in my instance a direct command 100% of the time fails to start multiple agents!

lukemmtt · 1 year ago

I've been looking into a variant of this issue involving task tool agents (rather than pre-defined sub-agents); I came upon some interesting findings.

Similar to your case, I've found that Claude Code _rarely_ succeeds in running Task Tool agents in parallel the first time, even when explicitly asked. If I interrupt Claude Code and ask it to try again, it almost always succeeds though. This got me thinking:

I drilled Claude Code on the topic—asking it what it was actually invoking in both the successful case (i.e. successful parallel execution) and unsuccessful case (sequential execution); from what I've learned, I'm quite confident that the issue is simply one of Claude _not having a clear and definitive understanding of the correct syntax for 'parallel execution'_.

tl;dr: I suspect that the solution, at least until Anthropic fixes this, is to instruct Claude Code more precisely. i.e. instead of saying 'Run multiple agents in parallel', perhaps we should ask it to "invoke multiple agents in the same <function_calls> block. This is very similar to what @danieliser mentioned above in suggesting "Run multiple Task invocations in a SINGLE message"; but "single message" still leaves the actual invocation syntax up to interpretation, whereas mentioning function_calls avoids all ambiguity.

Full deep dive inside this 'details' block:
<details><summary>Full Technical exploration of Claude Code invocations</summary>

Specifically, here's what it says it passes to the system when task tool agents get invoked sequentially:

### Message 1:

<function_calls>
  <invoke name="Task">
    <parameter name="subagent_type">general-purpose</antml:parameter>
    <parameter name="description">Search project files</antml:parameter>
    <parameter name="prompt">Search for Python files in the codebase</antml:parameter>
  </antml:invoke>
</antml:function_calls>

Wait for results, then send Message 2...

### Message 2:

<function_calls>
  <invoke name="Task">
    <parameter name="subagent_type">general-purpose</antml:parameter>
    <parameter name="description">List project configuration</antml:parameter>
    <parameter name="prompt">List configuration files in the project</antml:parameter>
  </antml:invoke>
</antml:function_calls>

And here's what it says it passes to the system when task tool agents get invoked in parallel:

### Single Message:

<function_calls>
  <invoke name="Task">
    <parameter name="subagent_type">general-purpose</antml:parameter>
    <parameter name="description">Search project files</antml:parameter>
    <parameter name="prompt">Search for Python files in the codebase</antml:parameter>
  </antml:invoke>
  <invoke name="Task">
    <parameter name="subagent_type">general-purpose</antml:parameter>
    <parameter name="description">List project configuration</antml:parameter>
    <parameter name="prompt">List configuration files in the project</antml:parameter>
  </antml:invoke>
</antml:function_calls>

In light of this, I wondered why Claude Code is so often failing to use the required 'parallel invocation' syntax, so I asked it to explain the system instructions on the matter, and it said the specific instruction (verified in the full system instruction dump here is:

You have the capability to call multiple tools in a single response. When multiple independent pieces of information are requested, batch your tool calls together for optimal performance.

So, my speculation is: perhaps it doesn't actually "know" the proper syntax—so when you say "in parallel", it's passing multiple messages / function_call invocations one after another, thinking they'll run in parallel, but they don't.

In other words, Claude Code doesn't understand its own system. It sets out 'thinking' it can invoke multiple messages or multiple <function_calls> blocks one after another, but the system immediately cuts it off once it sees a <function_calls> block—even if Claude Code wasn't finished "talking".

</details>

ww2283 · 11 months ago

thanks @lukemmtt for the observation.

I thus created this hook that can be used for automatic parallel spawning if used as a PostToolUse watching for TodoWrite. It's quite reliable (the code block formatting is a bit broken here but you will know how to fix it easily from your end).

#!/usr/bin/env python3
import json
import sys
import os
import logging
import hashlib

# --- Logging Configuration ---
LOG_FILE = "/tmp/claude_supervisor.log"
STATE_FILE = "/tmp/claude_todo_hook.state" 

logging.basicConfig(
    level=logging.INFO,
    format='%(asctime)s - %(levelname)s - %(message)s',
    filename=LOG_FILE,
    filemode='a'
)

def main():
    logging.info("--- Supervisor PostToolUse Hook Triggered (Self-Reflection Prompter) ---")
    try:
        hook_input = json.load(sys.stdin)
        
        if hook_input.get("tool_name") != "TodoWrite":
            sys.exit(0)

        tool_input_data = hook_input.get("tool_input", {})
        todo_objects = tool_input_data.get("todos", [])

        if not todo_objects:
            logging.info("TodoWrite called, but 'todos' list is empty. Exiting.")
            sys.exit(0)

        tasks_to_process_content = [task.get("content", "") for task in todo_objects]
        todo_content_full = "\n".join(tasks_to_process_content)
        
        current_hash = hashlib.md5(todo_content_full.encode()).hexdigest()
        last_hash = ""
        if os.path.exists(STATE_FILE):
            with open(STATE_FILE, 'r') as f:
                last_hash = f.read().strip()
        
        if current_hash == last_hash:
            logging.info("Todo list has not changed. Skipping reflection prompt.")
            sys.exit(0)
            
        logging.info("New todo list detected. Injecting reflection prompt.")
        
        # MODIFIED: The prompt now includes specific syntax instructions.
        reflection_prompt = """
**Supervisor's Prompt: Review and Parallelize the Plan**

The initial plan has been drafted. Now, **think** to optimize its execution.

1.  **Analyze Dependencies**: Critically review the list of tasks.
2.  **Group for Parallelism**: Identify any tasks that are independent and can be executed concurrently. Group them into a parallel stage.
3.  **Format for Parallel Execution**: To run a group of tasks in parallel, you **must** place multiple `<invoke name="Task">` calls inside a **single** `<function_calls>` block in your response.

Reminder of example format for running two tasks in parallel:
```xml
<function_calls>
  <invoke name="Task">
    <parameter name="description">First parallel task...</parameter>
    <parameter name="prompt">Details for the first task...</parameter>
  </invoke>
  <invoke name="Task">
    <parameter name="description">Second parallel task...</parameter>
    <parameter name="prompt">Details for the second task...</parameter>
  </invoke>
</function_calls>

Please present your analysis of parallel stages and then proceed with the first stage using the correct format.
"""

response = {
"hookSpecificOutput": {
"hookEventName": "PostToolUse",
"additionalContext": reflection_prompt
}
}

logging.info("Injecting context to trigger self-reflection and parallelization.")
print(json.dumps(response), flush=True)

with open(STATE_FILE, 'w') as f:
f.write(current_hash)
logging.info(f"Updated state file with new hash: {current_hash}")

except Exception as e:
logging.exception("An unexpected error occurred in the Supervisor hook.")

sys.exit(0)

if __name__ == "__main__":
main()

ty13r · 11 months ago

You're Absolutely Right!

<img width="902" height="437" alt="Image" src="https://github.com/user-attachments/assets/bf8ad290-cc18-4c5f-8922-1135460fcb58" />

<img width="904" height="864" alt="Image" src="https://github.com/user-attachments/assets/3cfa9c1e-9f67-4018-a82f-271bbe97f61d" />

Same issue - closed ticket - https://github.com/anthropics/claude-code/issues/7406#issuecomment-3276053762

villesau · 11 months ago

This seems to work for me relatively consistently: Parallelize the tasks and run them in sub-agents simultaneously all at the same time.

github-actions[bot] · 8 months ago

This issue has been inactive for 30 days. If the issue is still occurring, please comment to let us know. Otherwise, this issue will be automatically closed in 30 days for housekeeping purposes.

github-actions[bot] · 7 months ago

This issue has been automatically closed due to 60 days of inactivity. If you're still experiencing this issue, please open a new issue with updated information.

github-actions[bot] · 7 months ago

This issue has been automatically locked since it was closed and has not had any activity for 7 days. If you're experiencing a similar issue, please file a new issue and reference this one if it's relevant.