Saltar a contenido

Agentes paralelos

Soportado en ADKPython v0.1.0Typescript v0.2.0Go v0.1.0Java v0.2.0

El ParallelAgent es un agente de flujo de trabajo que ejecuta sus sub-agentes concurrentemente. Esto acelera dramáticamente los flujos de trabajo donde las tareas pueden realizarse de manera independiente.

Usa ParallelAgent cuando: Para escenarios que priorizan la velocidad e involucran tareas independientes e intensivas en recursos, un ParallelAgent facilita la ejecución paralela eficiente. Cuando los sub-agentes operan sin dependencias, sus tareas pueden realizarse concurrentemente, reduciendo significativamente el tiempo total de procesamiento.

Al igual que con otros agentes de flujo de trabajo, el ParallelAgent no está impulsado por un LLM, y por lo tanto es determinista en cómo se ejecuta. Dicho esto, los agentes de flujo de trabajo solo se preocupan por su ejecución (es decir, ejecutar sub-agentes en paralelo), y no por su lógica interna; las herramientas o sub-agentes de un agente de flujo de trabajo pueden o no utilizar LLMs.

Ejemplo

Este enfoque es particularmente beneficioso para operaciones como la recuperación de datos de múltiples fuentes o cálculos pesados, donde la paralelización produce ganancias sustanciales de rendimiento. Importante destacar que esta estrategia asume que no hay necesidad inherente de estado compartido o intercambio directo de información entre los agentes que se ejecutan concurrentemente.

Cómo funciona

Cuando se llama al método run_async() del ParallelAgent:

  1. Ejecución Concurrente: Inicia el método run_async() de cada sub-agente presente en la lista sub_agents concurrentemente. Esto significa que todos los agentes comienzan a ejecutarse (aproximadamente) al mismo tiempo.
  2. Ramas Independientes: Cada sub-agente opera en su propia rama de ejecución. No hay compartición automática del historial de conversación o estado entre estas ramas durante la ejecución.
  3. Recolección de Resultados: El ParallelAgent gestiona la ejecución paralela y, típicamente, proporciona una forma de acceder a los resultados de cada sub-agente después de que hayan completado (por ejemplo, a través de una lista de resultados o eventos). El orden de los resultados puede no ser determinista.

Ejecución Independiente y Gestión del Estado

Es crucial entender que los sub-agentes dentro de un ParallelAgent se ejecutan independientemente. Si necesitas comunicación o compartición de datos entre estos agentes, debes implementarlo explícitamente. Los enfoques posibles incluyen:

  • InvocationContext Compartido: Podrías pasar un objeto InvocationContext compartido a cada sub-agente. Este objeto podría actuar como un almacén de datos compartido. Sin embargo, necesitarías gestionar el acceso concurrente a este contexto compartido cuidadosamente (por ejemplo, usando bloqueos) para evitar condiciones de carrera.
  • Gestión de Estado Externa: Usa una base de datos externa, cola de mensajes u otro mecanismo para gestionar el estado compartido y facilitar la comunicación entre agentes.
  • Post-Procesamiento: Recolecta resultados de cada rama, y luego implementa lógica para coordinar datos posteriormente.

Parallel Agent

Ejemplo Completo: Investigación Web Paralela

Imagina investigar múltiples temas simultáneamente:

  1. Agente Investigador 1: Un LlmAgent que investiga "fuentes de energía renovable."
  2. Agente Investigador 2: Un LlmAgent que investiga "tecnología de vehículos eléctricos."
  3. Agente Investigador 3: Un LlmAgent que investiga "métodos de captura de carbono."

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

Estas tareas de investigación son independientes. Usar un ParallelAgent les permite ejecutarse concurrentemente, potencialmente reduciendo el tiempo total de investigación significativamente en comparación con ejecutarlas secuencialmente. Los resultados de cada agente se recolectarían por separado después de que terminen.

Código Completo
 from google.adk.agents.parallel_agent import ParallelAgent
 from google.adk.agents.llm_agent import LlmAgent
 from google.adk.agents.sequential_agent import SequentialAgent
 from google.adk.tools import google_search

 # --- Constants ---
 GEMINI_MODEL = "gemini-2.5-flash"

 # --- 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
 // Part of agent.ts --> Follow https://google.github.io/adk-docs/get-started/quickstart/ to learn the setup
 // --- 1. Define Researcher Sub-Agents (to run in parallel) ---

 const researchTools = [GOOGLE_SEARCH];

 // Researcher 1: Renewable Energy
 const researcherAgent1 = new 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: researchTools,
     // Store result in state for the merger agent
     outputKey: "renewable_energy_result"
 });

 // Researcher 2: Electric Vehicles
 const researcherAgent2 = new 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: researchTools,
     // Store result in state for the merger agent
     outputKey: "ev_technology_result"
 });

 // Researcher 3: Carbon Capture
 const researcherAgent3 = new 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: researchTools,
     // Store result in state for the merger agent
     outputKey: "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.
 const parallelResearchAgent = new ParallelAgent({
     name: "ParallelWebResearchAgent",
     subAgents: [researcherAgent1, researcherAgent2, researcherAgent3],
     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.
 const mergerAgent = new 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.
 const rootAgent = new SequentialAgent({
     name: "ResearchAndSynthesisPipeline",
     // Run parallel research first, then merge
     subAgents: [parallelResearchAgent, mergerAgent],
     description: "Coordinates parallel research and synthesizes the results."
 });
    model, err := gemini.NewModel(ctx, modelName, &genai.ClientConfig{})
    if err != nil {
        return fmt.Errorf("failed to create model: %v", err)
    }

    // --- 1. Define Researcher Sub-Agents (to run in parallel) ---
    researcher1, err := llmagent.New(llmagent.Config{
        Name:  "RenewableEnergyResearcher",
        Model: 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.",
        OutputKey:   "renewable_energy_result",
    })
    if err != nil {
        return err
    }
    researcher2, err := llmagent.New(llmagent.Config{
        Name:  "EVResearcher",
        Model: 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.",
        OutputKey:   "ev_technology_result",
    })
    if err != nil {
        return err
    }
    researcher3, err := llmagent.New(llmagent.Config{
        Name:  "CarbonCaptureResearcher",
        Model: 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.",
        OutputKey:   "carbon_capture_result",
    })
    if err != nil {
        return err
    }

    // --- 2. Create the ParallelAgent (Runs researchers concurrently) ---
    parallelResearchAgent, err := parallelagent.New(parallelagent.Config{
        AgentConfig: agent.Config{
            Name:        "ParallelWebResearchAgent",
            Description: "Runs multiple research agents in parallel to gather information.",
            SubAgents:   []agent.Agent{researcher1, researcher2, researcher3},
        },
    })
    if err != nil {
        return fmt.Errorf("failed to create parallel agent: %v", err)
    }

    // --- 3. Define the Merger Agent (Runs *after* the parallel agents) ---
    synthesisAgent, err := llmagent.New(llmagent.Config{
        Name:  "SynthesisAgent",
        Model: 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.",
    })
    if err != nil {
        return fmt.Errorf("failed to create synthesis agent: %v", err)
    }

    // --- 4. Create the SequentialAgent (Orchestrates the overall flow) ---
    pipeline, err := sequentialagent.New(sequentialagent.Config{
        AgentConfig: agent.Config{
            Name:        "ResearchAndSynthesisPipeline",
            Description: "Coordinates parallel research and synthesizes the results.",
            SubAgents:   []agent.Agent{parallelResearchAgent, synthesisAgent},
        },
    })
    if err != nil {
        return fmt.Errorf("failed to create sequential agent pipeline: %v", err)
    }
 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());
           }
         });
   }
 }