Skip to content

Parallel agents

ParallelAgent 是一種工作流程 agent,能夠同時執行其子 agent。這對於可獨立執行的任務來說,能大幅加快工作流程的速度。

當你遇到以下情境時,請使用 ParallelAgent:若你的場景以速度為優先,且包含獨立且資源密集的任務,ParallelAgent 能有效促進高效的平行執行。當子 agent 之間沒有相依關係時,這些任務可以同時執行,大幅縮短整體處理時間。

如同其他工作流程 agentParallelAgent 並非由大型語言模型 (LLM) 驅動,因此其執行方式是確定性的。不過,工作流程 agent 只負責執行(例如:平行執行子 agent),而不涉及其內部邏輯;工作流程 agent 的工具或子 agent 可能會,也可能不會使用大型語言模型 (LLM)。

範例

這種方法特別適合多來源資料擷取或大量運算等操作,在這些情境下,平行化能帶來顯著的效能提升。重要的是,這種策略假設同時執行的 agent 之間不需要共用狀態或直接資訊交換

運作方式

當呼叫 ParallelAgentrun_async() 方法時:

  1. 同時執行:同時啟動 sub_agents 清單中每一個子 agent 的 run_async() 方法。這代表所有 agent 幾乎在同一時間開始執行。
  2. 獨立分支: 每個子 agent 都在自己的執行分支中運作。在執行期間,這些分支之間不會自動共用對話歷史或狀態。
  3. 結果收集: ParallelAgent 會管理平行執行,並通常提供一種方式讓你在所有子 agent 完成後存取各自的結果(例如:透過結果清單或事件)。結果的順序可能不是確定性的。

獨立執行與狀態管理

務必理解,ParallelAgent 內的子 agent 是獨立執行的。如果你需要這些 agent 之間進行通訊或資料共享,必須自行實作。可能的做法包括:

  • 共用 InvocationContext 你可以將共用的 InvocationContext 物件傳遞給每個子 agent。這個物件可以作為共用的資料儲存區。不過,你需要謹慎管理對這個共用 context 的同時存取(例如:使用鎖定機制),以避免競爭條件。
  • 外部狀態管理: 使用外部資料庫、訊息佇列或其他機制來管理共用狀態,並協助 agent 之間的通訊。
  • 後處理: 收集每個分支的結果,然後實作協調資料的邏輯。

Parallel Agent

完整範例:平行網路研究

想像你要同時研究多個主題:

  1. 研究員 Agent 1: 一個 LlmAgent,負責研究「再生能源來源」。
  2. 研究員 Agent 2: 一個 LlmAgent,負責研究「電動車技術」。
  3. 研究員 Agent 3: 一個 LlmAgent,負責研究「碳捕捉方法」。

    ParallelAgent(sub_agents=[ResearcherAgent1, ResearcherAgent2, ResearcherAgent3])
    

這些研究任務彼此獨立。使用 ParallelAgent 可以讓它們同時執行(平行執行),與依序執行相比,有機會大幅縮短整體研究所需的時間。每個 agent 執行完畢後,其結果會分別被收集。

Full Code
 # Part of agent.py --> Follow https://google.github.io/adk-docs/get-started/quickstart/ to learn the setup
 # --- 1. Define Researcher Sub-Agents (to run in parallel) ---

 # Researcher 1: Renewable Energy
 researcher_agent_1 = LlmAgent(
     name="RenewableEnergyResearcher",
     model=GEMINI_MODEL,
     instruction="""You are an AI Research Assistant specializing in energy.
 Research the latest advancements in 'renewable energy sources'.
 Use the Google Search tool provided.
 Summarize your key findings concisely (1-2 sentences).
 Output *only* the summary.
 """,
     description="Researches renewable energy sources.",
     tools=[google_search],
     # Store result in state for the merger agent
     output_key="renewable_energy_result"
 )

 # Researcher 2: Electric Vehicles
 researcher_agent_2 = LlmAgent(
     name="EVResearcher",
     model=GEMINI_MODEL,
     instruction="""You are an AI Research Assistant specializing in transportation.
 Research the latest developments in 'electric vehicle technology'.
 Use the Google Search tool provided.
 Summarize your key findings concisely (1-2 sentences).
 Output *only* the summary.
 """,
     description="Researches electric vehicle technology.",
     tools=[google_search],
     # Store result in state for the merger agent
     output_key="ev_technology_result"
 )

 # Researcher 3: Carbon Capture
 researcher_agent_3 = LlmAgent(
     name="CarbonCaptureResearcher",
     model=GEMINI_MODEL,
     instruction="""You are an AI Research Assistant specializing in climate solutions.
 Research the current state of 'carbon capture methods'.
 Use the Google Search tool provided.
 Summarize your key findings concisely (1-2 sentences).
 Output *only* the summary.
 """,
     description="Researches carbon capture methods.",
     tools=[google_search],
     # Store result in state for the merger agent
     output_key="carbon_capture_result"
 )

 # --- 2. Create the ParallelAgent (Runs researchers concurrently) ---
 # This agent orchestrates the concurrent execution of the researchers.
 # It finishes once all researchers have completed and stored their results in state.
 parallel_research_agent = ParallelAgent(
     name="ParallelWebResearchAgent",
     sub_agents=[researcher_agent_1, researcher_agent_2, researcher_agent_3],
     description="Runs multiple research agents in parallel to gather information."
 )

 # --- 3. Define the Merger Agent (Runs *after* the parallel agents) ---
 # This agent takes the results stored in the session state by the parallel agents
 # and synthesizes them into a single, structured response with attributions.
 merger_agent = LlmAgent(
     name="SynthesisAgent",
     model=GEMINI_MODEL,  # Or potentially a more powerful model if needed for synthesis
     instruction="""You are an AI Assistant responsible for combining research findings into a structured report.

 Your primary task is to synthesize the following research summaries, clearly attributing findings to their source areas. Structure your response using headings for each topic. Ensure the report is coherent and integrates the key points smoothly.

 **Crucially: Your entire response MUST be grounded *exclusively* on the information provided in the 'Input Summaries' below. Do NOT add any external knowledge, facts, or details not present in these specific summaries.**

 **Input Summaries:**

 *   **Renewable Energy:**
     {renewable_energy_result}

 *   **Electric Vehicles:**
     {ev_technology_result}

 *   **Carbon Capture:**
     {carbon_capture_result}

 **Output Format:**

 ## Summary of Recent Sustainable Technology Advancements

 ### Renewable Energy Findings
 (Based on RenewableEnergyResearcher's findings)
 [Synthesize and elaborate *only* on the renewable energy input summary provided above.]

 ### Electric Vehicle Findings
 (Based on EVResearcher's findings)
 [Synthesize and elaborate *only* on the EV input summary provided above.]

 ### Carbon Capture Findings
 (Based on CarbonCaptureResearcher's findings)
 [Synthesize and elaborate *only* on the carbon capture input summary provided above.]

 ### Overall Conclusion
 [Provide a brief (1-2 sentence) concluding statement that connects *only* the findings presented above.]

 Output *only* the structured report following this format. Do not include introductory or concluding phrases outside this structure, and strictly adhere to using only the provided input summary content.
 """,
     description="Combines research findings from parallel agents into a structured, cited report, strictly grounded on provided inputs.",
     # No tools needed for merging
     # No output_key needed here, as its direct response is the final output of the sequence
 )


 # --- 4. Create the SequentialAgent (Orchestrates the overall flow) ---
 # This is the main agent that will be run. It first executes the ParallelAgent
 # to populate the state, and then executes the MergerAgent to produce the final output.
 sequential_pipeline_agent = SequentialAgent(
     name="ResearchAndSynthesisPipeline",
     # Run parallel research first, then merge
     sub_agents=[parallel_research_agent, merger_agent],
     description="Coordinates parallel research and synthesizes the results."
 )

 root_agent = sequential_pipeline_agent
 import com.google.adk.agents.LlmAgent;
 import com.google.adk.agents.ParallelAgent;
 import com.google.adk.agents.SequentialAgent;
 import com.google.adk.events.Event;
 import com.google.adk.runner.InMemoryRunner;
 import com.google.adk.sessions.Session;
 import com.google.adk.tools.GoogleSearchTool;
 import com.google.genai.types.Content;
 import com.google.genai.types.Part;
 import io.reactivex.rxjava3.core.Flowable;

 public class ParallelResearchPipeline {

   private static final String APP_NAME = "parallel_research_app";
   private static final String USER_ID = "research_user_01";
   private static final String GEMINI_MODEL = "gemini-2.0-flash";

   // Assume google_search is an instance of the GoogleSearchTool
   private static final GoogleSearchTool googleSearchTool = new GoogleSearchTool();

   public static void main(String[] args) {
     String query = "Summarize recent sustainable tech advancements.";
     SequentialAgent sequentialPipelineAgent = initAgent();
     runAgent(sequentialPipelineAgent, query);
   }

   public static SequentialAgent initAgent() {
     // --- 1. Define Researcher Sub-Agents (to run in parallel) ---
     // Researcher 1: Renewable Energy
     LlmAgent researcherAgent1 = LlmAgent.builder()
         .name("RenewableEnergyResearcher")
         .model(GEMINI_MODEL)
         .instruction("""
                     You are an AI Research Assistant specializing in energy.
                     Research the latest advancements in 'renewable energy sources'.
                     Use the Google Search tool provided.
                     Summarize your key findings concisely (1-2 sentences).
                     Output *only* the summary.
                     """)
         .description("Researches renewable energy sources.")
         .tools(googleSearchTool)
         .outputKey("renewable_energy_result") // Store result in state
         .build();

     // Researcher 2: Electric Vehicles
     LlmAgent researcherAgent2 = LlmAgent.builder()
         .name("EVResearcher")
         .model(GEMINI_MODEL)
         .instruction("""
                     You are an AI Research Assistant specializing in transportation.
                     Research the latest developments in 'electric vehicle technology'.
                     Use the Google Search tool provided.
                     Summarize your key findings concisely (1-2 sentences).
                     Output *only* the summary.
                     """)
         .description("Researches electric vehicle technology.")
         .tools(googleSearchTool)
         .outputKey("ev_technology_result") // Store result in state
         .build();

     // Researcher 3: Carbon Capture
     LlmAgent researcherAgent3 = LlmAgent.builder()
         .name("CarbonCaptureResearcher")
         .model(GEMINI_MODEL)
         .instruction("""
                     You are an AI Research Assistant specializing in climate solutions.
                     Research the current state of 'carbon capture methods'.
                     Use the Google Search tool provided.
                     Summarize your key findings concisely (1-2 sentences).
                     Output *only* the summary.
                     """)
         .description("Researches carbon capture methods.")
         .tools(googleSearchTool)
         .outputKey("carbon_capture_result") // Store result in state
         .build();

     // --- 2. Create the ParallelAgent (Runs researchers concurrently) ---
     // This agent orchestrates the concurrent execution of the researchers.
     // It finishes once all researchers have completed and stored their results in state.
     ParallelAgent parallelResearchAgent =
         ParallelAgent.builder()
             .name("ParallelWebResearchAgent")
             .subAgents(researcherAgent1, researcherAgent2, researcherAgent3)
             .description("Runs multiple research agents in parallel to gather information.")
             .build();

     // --- 3. Define the Merger Agent (Runs *after* the parallel agents) ---
     // This agent takes the results stored in the session state by the parallel agents
     // and synthesizes them into a single, structured response with attributions.
     LlmAgent mergerAgent =
         LlmAgent.builder()
             .name("SynthesisAgent")
             .model(GEMINI_MODEL)
             .instruction(
                 """
                       You are an AI Assistant responsible for combining research findings into a structured report.
                       Your primary task is to synthesize the following research summaries, clearly attributing findings to their source areas. Structure your response using headings for each topic. Ensure the report is coherent and integrates the key points smoothly.
                       **Crucially: Your entire response MUST be grounded *exclusively* on the information provided in the 'Input Summaries' below. Do NOT add any external knowledge, facts, or details not present in these specific summaries.**
                       **Input Summaries:**

                       *   **Renewable Energy:**
                           {renewable_energy_result}

                       *   **Electric Vehicles:**
                           {ev_technology_result}

                       *   **Carbon Capture:**
                           {carbon_capture_result}

                       **Output Format:**

                       ## Summary of Recent Sustainable Technology Advancements

                       ### Renewable Energy Findings
                       (Based on RenewableEnergyResearcher's findings)
                       [Synthesize and elaborate *only* on the renewable energy input summary provided above.]

                       ### Electric Vehicle Findings
                       (Based on EVResearcher's findings)
                       [Synthesize and elaborate *only* on the EV input summary provided above.]

                       ### Carbon Capture Findings
                       (Based on CarbonCaptureResearcher's findings)
                       [Synthesize and elaborate *only* on the carbon capture input summary provided above.]

                       ### Overall Conclusion
                       [Provide a brief (1-2 sentence) concluding statement that connects *only* the findings presented above.]

                       Output *only* the structured report following this format. Do not include introductory or concluding phrases outside this structure, and strictly adhere to using only the provided input summary content.
                       """)
             .description(
                 "Combines research findings from parallel agents into a structured, cited report, strictly grounded on provided inputs.")
             // No tools needed for merging
             // No output_key needed here, as its direct response is the final output of the sequence
             .build();

     // --- 4. Create the SequentialAgent (Orchestrates the overall flow) ---
     // This is the main agent that will be run. It first executes the ParallelAgent
     // to populate the state, and then executes the MergerAgent to produce the final output.
     SequentialAgent sequentialPipelineAgent =
         SequentialAgent.builder()
             .name("ResearchAndSynthesisPipeline")
             // Run parallel research first, then merge
             .subAgents(parallelResearchAgent, mergerAgent)
             .description("Coordinates parallel research and synthesizes the results.")
             .build();

     return sequentialPipelineAgent;
   }

   public static void runAgent(SequentialAgent sequentialPipelineAgent, String query) {
     // Create an InMemoryRunner
     InMemoryRunner runner = new InMemoryRunner(sequentialPipelineAgent, APP_NAME);
     // InMemoryRunner automatically creates a session service. Create a session using the service
     Session session = runner.sessionService().createSession(APP_NAME, USER_ID).blockingGet();
     Content userMessage = Content.fromParts(Part.fromText(query));

     // Run the agent
     Flowable<Event> eventStream = runner.runAsync(USER_ID, session.id(), userMessage);

     // Stream event response
     eventStream.blockingForEach(
         event -> {
           if (event.finalResponse()) {
             System.out.printf("Event Author: %s \n Event Response: %s \n\n\n", event.author(), event.stringifyContent());
           }
         });
   }
 }