Skip to content

顺序模板工作流智能体

Supported in ADKPython v0.1.0Typescript v0.2.0Go v0.1.0Java v0.2.0

SequentialAgent 类是一个模板工作流智能体,它按照列表指定的顺序执行其子智能体。当你希望以固定的严格顺序执行时,请使用 SequentialAgent。与其他模板工作流一样,SequentialAgent 对象的执行不由 AI 模型控制,其子智能体的执行方式是确定性的。顺序执行集中指定的子智能体可能使用也可能不使用 AI 模型,但这些子智能体的整体执行最终由你定义的 SequentialAgent 对象管理。

备选方案:基于图的工作流

从 ADK 2.0 开始,模板工作流已被更灵活的工作流结构所取代,包括基于图的工作流动态工作流

示例场景

假设你想构建一个能够总结任何网页的智能体,使用两个工具:获取页面内容总结页面。由于智能体必须在调用总结页面之前始终先调用获取页面内容,你可以使用 SequentialAgent 类来构建你的智能体。

与其他工作流智能体一样,SequentialAgent 不是由 LLM 驱动的,因此它的执行方式是确定性的。也就是说,工作流智能体只关注它们的执行方式(即按顺序),而不是它们的内部逻辑;工作流智能体的工具或子智能体可能使用也可能不使用 LLM。

工作原理

当调用 SequentialAgentrun_async() 方法时,它执行以下操作:

Sequential Agent

共享调用上下文

SequentialAgent 将相同的 InvocationContext 传递给其每个子智能体。这意味着它们都共享相同的会话状态,包括临时(temp:)命名空间,使得在单轮次内的步骤之间传递数据变得容易。

完整示例:代码开发流水线

  • 代码编写智能体: 一个根据规范生成初始代码的 LLM 智能体。
  • 代码审查智能体: 一个审查生成代码中的错误、风格问题和最佳实践遵循情况的 LLM 智能体。它接收代码编写智能体的输出。
  • 代码重构智能体: 一个接收已审查代码和审查意见,并对其进行重构以提高质量和解决问题的 LLM 智能体。

使用 SequentialAgent 可以轻松定义此执行流程,如下面的代码片段所示:

SequentialAgent(sub_agents=[CodeWriterAgent, CodeReviewerAgent, CodeRefactorerAgent])

这确保了代码以严格、可靠的顺序被编写、然后审查、最后重构。每个子智能体的输出通过输出键存储在状态中传递给下一个子智能体

代码
from google.adk.agents.sequential_agent import SequentialAgent
from google.adk.agents.llm_agent import LlmAgent

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

# --- 1. 定义每个流水线阶段的子智能体 ---

# Code Writer Agent
# 从用户查询中获取初始规格并写代码。
code_writer_agent = LlmAgent(
    name="CodeWriterAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are a Python Code Generator.
    Based *only* on the user's request, write Python code that fulfills the requirement.
    Output *only* the complete Python code block, enclosed in triple backticks (```python ... ```).
    Do not add any other text before or after the code block.
    """,
    description="Writes initial Python code based on a specification.",
    output_key="generated_code"
)

# Code Reviewer Agent
# 从上一个智能体生成的代码中获取代码并提供反馈。
code_reviewer_agent = LlmAgent(
    name="CodeReviewerAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are an expert Python Code Reviewer.
    Your task is to provide constructive feedback on the provided code.

    **Code to Review:**
    ```python
    {generated_code}
    ```

    **Review Criteria:**
    1.  **Correctness:** Does the code work as intended? Are there logic errors?
    2.  **Readability:** Is the code clear and easy to understand? Follows PEP 8 style guidelines?
    3.  **Efficiency:** Is the code reasonably efficient? Any obvious performance bottlenecks?
    4.  **Edge Cases:** Does the code handle potential edge cases or invalid inputs gracefully?
    5.  **Best Practices:** Does the code follow common Python best practices?

    **Output:**
    Provide your feedback as a concise, bulleted list. Focus on the most important points for improvement.
    If the code is excellent and requires no changes, simply state: "No major issues found."
    Output *only* the review comments or the "No major issues" statement.
    """,
    description="Reviews code and provides feedback.",
    output_key="review_comments"
)


# Code Refactorer Agent
# 从原始代码和评论中获取评论并重构代码。
code_refactorer_agent = LlmAgent(
    name="CodeRefactorerAgent",
    model=GEMINI_MODEL,
    instruction="""
    You are a Python Code Refactoring AI.
    Your goal is to improve the given Python code based on the provided review comments.

    **Original Code:**
    ```python
    {generated_code}
    ```

    **Review Comments:**
    {review_comments}

    **Task:**
    Carefully apply the suggestions from the review comments to refactor the original code.
    If the review comments state "No major issues found," return the original code unchanged.
    Ensure the final code is complete, functional, and includes necessary imports and docstrings.

    **Output:**
    Output *only* the final, refactored Python code block, enclosed in triple backticks (```python ... ```).
    Do not add any other text before or after the code block.
    """,
    description="Refactors code based on review comments.",
    output_key="refactored_code"
)


# --- 2. Create the SequentialAgent ---
# This agent orchestrates the pipeline by running the sub_agents in order.
code_pipeline_agent = SequentialAgent(
    name="CodePipelineAgent",
    sub_agents=[code_writer_agent, code_reviewer_agent, code_refactorer_agent],
    description="Executes a sequence of code writing, reviewing, and refactoring.",
)

root_agent = code_pipeline_agent
// Part of agent.ts --> Follow https://adk.dev/get-started/ to learn the setup

// --- 1. Define Sub-Agents for Each Pipeline Stage ---

// Code Writer Agent
// Takes the initial specification (from user query) and writes code.
const codeWriterAgent = new LlmAgent({
    name: "CodeWriterAgent",
    model: GEMINI_MODEL,
    instruction: `You are a Python Code Generator.
Based *only* on the user's request, write Python code that fulfills the requirement.
Output *only* the complete Python code block, enclosed in triple backticks (\`\`\`python ... \`\`\`).
Do not add any other text before or after the code block.
`,
    description: "Writes initial Python code based on a specification.",
    outputKey: "generated_code" // Stores output in state['generated_code']
});

// Code Reviewer Agent
// Takes the code generated by the previous agent (read from state) and provides feedback.
const codeReviewerAgent = new LlmAgent({
    name: "CodeReviewerAgent",
    model: GEMINI_MODEL,
    instruction: `You are an expert Python Code Reviewer.
    Your task is to provide constructive feedback on the provided code.

    **Code to Review:**
    \`\`\`python
    {generated_code}
    \`\`\`

**Review Criteria:**
1.  **Correctness:** Does the code work as intended? Are there logic errors?
2.  **Readability:** Is the code clear and easy to understand? Follows PEP 8 style guidelines?
3.  **Efficiency:** Is the code reasonably efficient? Any obvious performance bottlenecks?
4.  **Edge Cases:** Does the code handle potential edge cases or invalid inputs gracefully?
5.  **Best Practices:** Does the code follow common Python best practices?

**Output:**
Provide your feedback as a concise, bulleted list. Focus on the most important points for improvement.
If the code is excellent and requires no changes, simply state: "No major issues found."
Output *only* the review comments or the "No major issues" statement.
`,
    description: "Reviews code and provides feedback.",
    outputKey: "review_comments", // Stores output in state['review_comments']
});


// Code Refactorer Agent
// Takes the original code and the review comments (read from state) and refactors the code.
const codeRefactorerAgent = new LlmAgent({
    name: "CodeRefactorerAgent",
    model: GEMINI_MODEL,
    instruction: `You are a Python Code Refactoring AI.
Your goal is to improve the given Python code based on the provided review comments.

  **Original Code:**
  \`\`\`python
  {generated_code}
  \`\`\`

  **Review Comments:**
  {review_comments}

**Task:**
Carefully apply the suggestions from the review comments to refactor the original code.
If the review comments state "No major issues found," return the original code unchanged.
Ensure the final code is complete, functional, and includes necessary imports and docstrings.

**Output:**
Output *only* the final, refactored Python code block, enclosed in triple backticks (\`\`\`python ... \`\`\`).
Do not add any other text before or after the code block.
`,
    description: "Refactors code based on review comments.",
    outputKey: "refactored_code", // Stores output in state['refactored_code']
});


// --- 2. Create the SequentialAgent ---
// This agent orchestrates the pipeline by running the sub_agents in order.
const rootAgent = new SequentialAgent({
    name: "CodePipelineAgent",
    subAgents: [codeWriterAgent, codeReviewerAgent, codeRefactorerAgent],
    description: "Executes a sequence of code writing, reviewing, and refactoring.",
    // The agents will run in the order provided: Writer -> Reviewer -> Refactorer
});
    model, err := gemini.NewModel(ctx, modelName, &genai.ClientConfig{})
    if err != nil {
        return fmt.Errorf("failed to create model: %v", err)
    }

    codeWriterAgent, err := llmagent.New(llmagent.Config{
        Name:        "CodeWriterAgent",
        Model:       model,
        Description: "Writes initial Go code based on a specification.",
        Instruction: `You are a Go Code Generator.
Based *only* on the user's request, write Go code that fulfills the requirement.
Output *only* the complete Go code block, enclosed in triple backticks ('''go ... ''').
Do not add any other text before or after the code block.`,
        OutputKey: "generated_code",
    })
    if err != nil {
        return fmt.Errorf("failed to create code writer agent: %v", err)
    }

    codeReviewerAgent, err := llmagent.New(llmagent.Config{
        Name:        "CodeReviewerAgent",
        Model:       model,
        Description: "Reviews code and provides feedback.",
        Instruction: `You are an expert Go Code Reviewer.
Your task is to provide constructive feedback on the provided code.

**Code to Review:**
'''go
{generated_code}
'''

**Review Criteria:**
1.  **Correctness:** Does the code work as intended? Are there logic errors?
2.  **Readability:** Is the code clear and easy to understand? Follows Go style guidelines?
3.  **Idiomatic Go:** Does the code use Go's features in a natural and standard way?
4.  **Edge Cases:** Does the code handle potential edge cases or invalid inputs gracefully?
5.  **Best Practices:** Does the code follow common Go best practices?

**Output:**
Provide your feedback as a concise, bulleted list. Focus on the most important points for improvement.
If the code is excellent and requires no changes, simply state: "No major issues found."
Output *only* the review comments or the "No major issues" statement.`,
        OutputKey: "review_comments",
    })
    if err != nil {
        return fmt.Errorf("failed to create code reviewer agent: %v", err)
    }

    codeRefactorerAgent, err := llmagent.New(llmagent.Config{
        Name:        "CodeRefactorerAgent",
        Model:       model,
        Description: "Refactors code based on review comments.",
        Instruction: `You are a Go Code Refactoring AI.
Your goal is to improve the given Go code based on the provided review comments.

**Original Code:**
'''go
{generated_code}
'''

**Review Comments:**
{review_comments}

**Task:**
Carefully apply the suggestions from the review comments to refactor the original code.
If the review comments state "No major issues found," return the original code unchanged.
Ensure the final code is complete, functional, and includes necessary imports.

**Output:**
Output *only* the final, refactored Go code block, enclosed in triple backticks ('''go ... ''').
Do not add any other text before or after the code block.`,
        OutputKey: "refactored_code",
    })
    if err != nil {
        return fmt.Errorf("failed to create code refactorer agent: %v", err)
    }

    codePipelineAgent, err := sequentialagent.New(sequentialagent.Config{
        AgentConfig: agent.Config{
            Name:        appName,
            Description: "Executes a sequence of code writing, reviewing, and refactoring.",
            SubAgents: []agent.Agent{
                codeWriterAgent,
                codeReviewerAgent,
                codeRefactorerAgent,
            },
        },
    })
    if err != nil {
        return fmt.Errorf("failed to create sequential agent: %v", err)
    }
import com.google.adk.agents.LlmAgent;
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.genai.types.Content;
import com.google.genai.types.Part;
import io.reactivex.rxjava3.core.Flowable;

public class SequentialAgentExample {

  private static final String APP_NAME = "CodePipelineAgent";
  private static final String USER_ID = "test_user_456";
  private static final String MODEL_NAME = "gemini-2.0-flash";

  public static void main(String[] args) {
    SequentialAgentExample sequentialAgentExample = new SequentialAgentExample();
    sequentialAgentExample.runAgent(
        "Write a Java function to calculate the factorial of a number.");
  }

  public void runAgent(String prompt) {

    LlmAgent codeWriterAgent =
        LlmAgent.builder()
            .model(MODEL_NAME)
            .name("CodeWriterAgent")
            .description("Writes initial Java code based on a specification.")
            .instruction(
                """
                You are a Java Code Generator.
                Based *only* on the user's request, write Java code that fulfills the requirement.
                Output *only* the complete Java code block, enclosed in triple backticks (```java ... ```).
                Do not add any other text before or after the code block.
                """)
            .outputKey("generated_code")
            .build();

    LlmAgent codeReviewerAgent =
        LlmAgent.builder()
            .model(MODEL_NAME)
            .name("CodeReviewerAgent")
            .description("Reviews code and provides feedback.")
            .instruction(
                """
                    You are an expert Java Code Reviewer.
                    Your task is to provide constructive feedback on the provided code.

                    **Code to Review:**
                    ```java
                    {generated_code}
                    ```

                    **Review Criteria:**
                    1.  **Correctness:** Does the code work as intended? Are there logic errors?
                    2.  **Readability:** Is the code clear and easy to understand? Follows Java style guidelines?
                    3.  **Efficiency:** Is the code reasonably efficient? Any obvious performance bottlenecks?
                    4.  **Edge Cases:** Does the code handle potential edge cases or invalid inputs gracefully?
                    5.  **Best Practices:** Does the code follow common Java best practices?

                    **Output:**
                    Provide your feedback as a concise, bulleted list. Focus on the most important points for improvement.
                    If the code is excellent and requires no changes, simply state: "No major issues found."
                    Output *only* the review comments or the "No major issues" statement.
                """)
            .outputKey("review_comments")
            .build();

    LlmAgent codeRefactorerAgent =
        LlmAgent.builder()
            .model(MODEL_NAME)
            .name("CodeRefactorerAgent")
            .description("Refactors code based on review comments.")
            .instruction(
                """
                You are a Java Code Refactoring AI.
                Your goal is to improve the given Java code based on the provided review comments.

                  **Original Code:**
                  ```java
                  {generated_code}
                  ```

                  **Review Comments:**
                  {review_comments}

                **Task:**
                Carefully apply the suggestions from the review comments to refactor the original code.
                If the review comments state "No major issues found," return the original code unchanged.
                Ensure the final code is complete, functional, and includes necessary imports and docstrings.

                **Output:**
                Output *only* the final, refactored Java code block, enclosed in triple backticks (```java ... ```).
                Do not add any other text before or after the code block.
                """)
            .outputKey("refactored_code")
            .build();

    SequentialAgent codePipelineAgent =
        SequentialAgent.builder()
            .name(APP_NAME)
            .description("Executes a sequence of code writing, reviewing, and refactoring.")
            // The agents will run in the order provided: Writer -> Reviewer -> Refactorer
            .subAgents(codeWriterAgent, codeReviewerAgent, codeRefactorerAgent)
            .build();

    // Create an InMemoryRunner
    InMemoryRunner runner = new InMemoryRunner(codePipelineAgent, 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(prompt));

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

    // Stream event response
    eventStream.blockingForEach(
        event -> {
          if (event.finalResponse()) {
            System.out.println(event.stringifyContent());
          }
        });
  }
}