refactor: clarify agent pattern names
- Remove redundant workflow suffix from agentic pattern names and related classes - Update documentation to reflect pattern name changes
This commit is contained in:
committed by
Christian Tzolov
parent
1433ff7382
commit
9f8cb92aa9
@@ -55,8 +55,8 @@ Implements a classification system that directs input to specialized followup ta
|
||||
- Content moderation systems
|
||||
- Query optimization based on complexity
|
||||
|
||||
### 4. Orchestrator-Workers Workflow
|
||||
[orchestrator-workers-workflow/](orchestrator-workers-workflow/)
|
||||
### 4. Orchestrator-Workers
|
||||
[orchestrator-workers/](orchestrator-workers/)
|
||||
|
||||
Implements a flexible system where a central LLM orchestrates task decomposition and delegates to specialized worker LLMs.
|
||||
|
||||
@@ -70,8 +70,8 @@ Implements a flexible system where a central LLM orchestrates task decomposition
|
||||
- Multi-source research tasks
|
||||
- Adaptive content creation
|
||||
|
||||
### 5. Evaluator-Optimizer Workflow
|
||||
[evaluator-optimizer-workflow/](evaluator-optimizer-workflow/)
|
||||
### 5. Evaluator-Optimizer
|
||||
[evaluator-optimizer/](evaluator-optimizer/)
|
||||
|
||||
Implements an iterative refinement process where one LLM generates solutions while another provides evaluation and feedback.
|
||||
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
# Evaluator-Optimizer Workflow Pattern
|
||||
# Evaluator-Optimizer Pattern
|
||||
|
||||
This project demonstrates the Evaluator-Optimizer workflow pattern for building effective LLM-based systems, as described in [Anthropic's research on building effective agents](https://www.anthropic.com/research/building-effective-agents).
|
||||
This project demonstrates the Evaluator-Optimizer pattern for building effective LLM-based systems, as described in [Anthropic's research on building effective agents](https://www.anthropic.com/research/building-effective-agents).
|
||||
|
||||

|
||||

|
||||
|
||||
## Overview
|
||||
|
||||
@@ -48,7 +48,7 @@ This pattern is particularly effective when:
|
||||
The implementation uses Spring AI's ChatClient for LLM interactions and consists of:
|
||||
|
||||
```java
|
||||
public class EvaluatorOptimizerWorkflow {
|
||||
public class EvaluatorOptimizer {
|
||||
public RefinedResponse loop(String task) {
|
||||
// 1. Generate initial solution
|
||||
Generation generation = generate(task, context);
|
||||
@@ -68,10 +68,10 @@ public class EvaluatorOptimizerWorkflow {
|
||||
|
||||
```java
|
||||
ChatClient chatClient = // ... initialize chat client
|
||||
EvaluatorOptimizerWorkflow workflow = new EvaluatorOptimizerWorkflow(chatClient);
|
||||
EvaluatorOptimizer agent = new EvaluatorOptimizer(chatClient);
|
||||
|
||||
// Process a task
|
||||
RefinedResponse response = workflow.loop(
|
||||
RefinedResponse response = agent.loop(
|
||||
"Create a Java class implementing a thread-safe counter"
|
||||
);
|
||||
|
||||
@@ -82,11 +82,11 @@ System.out.println("Evolution: " + response.chainOfThought());
|
||||
|
||||
## Customization
|
||||
|
||||
The workflow can be customized through:
|
||||
The pattern can be customized through:
|
||||
|
||||
1. **Custom Prompts**: Provide specialized prompts for generator and evaluator
|
||||
```java
|
||||
workflow = new EvaluatorOptimizerWorkflow(
|
||||
agent = new EvaluatorOptimizer(
|
||||
chatClient,
|
||||
customGeneratorPrompt,
|
||||
customEvaluatorPrompt
|
||||
@@ -10,9 +10,9 @@
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example.spring.ai</groupId>
|
||||
<artifactId>evaluator-optimizer-workflow</artifactId>
|
||||
<artifactId>evaluator-optimizer</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>evaluator-optimizer-workflow</name>
|
||||
<name>evaluator-optimizer</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
@@ -25,10 +25,10 @@
|
||||
</dependency>
|
||||
|
||||
|
||||
<!-- <dependency>
|
||||
<dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-openai-spring-boot-starter</artifactId>
|
||||
</dependency> -->
|
||||
</dependency>
|
||||
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
@@ -36,10 +36,10 @@
|
||||
</dependency> -->
|
||||
|
||||
|
||||
<dependency>
|
||||
<!-- <dependency>
|
||||
<groupId>org.springframework.ai</groupId>
|
||||
<artifactId>spring-ai-ollama-spring-boot-starter</artifactId>
|
||||
</dependency>
|
||||
</dependency> -->
|
||||
|
||||
<dependency>
|
||||
<groupId>org.springframework.boot</groupId>
|
||||
@@ -16,7 +16,7 @@
|
||||
*/
|
||||
package com.example.agentic;
|
||||
|
||||
import com.example.agentic.EvaluatorOptimizerWorkflow.RefinedResponse;
|
||||
import com.example.agentic.EvaluatorOptimizer.RefinedResponse;
|
||||
|
||||
import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.boot.CommandLineRunner;
|
||||
@@ -25,7 +25,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// EVALUATION WORKFLOW
|
||||
// EVALUATOR-OPTIMIZER
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@SpringBootApplication
|
||||
@@ -39,7 +39,7 @@ public class Application {
|
||||
public CommandLineRunner commandLineRunner(ChatClient.Builder chatClientBuilder) {
|
||||
var chatClient = chatClientBuilder.build();
|
||||
return args -> {
|
||||
RefinedResponse refinedResponse = new EvaluatorOptimizerWorkflow(chatClient).loop("""
|
||||
RefinedResponse refinedResponse = new EvaluatorOptimizer(chatClient).loop("""
|
||||
<user input>
|
||||
Implement a Stack in Java with:
|
||||
1. push(x)
|
||||
@@ -47,7 +47,6 @@ public class Application {
|
||||
3. getMin()
|
||||
All operations should be O(1).
|
||||
All inner fields should be private and when used should be prefixed with 'this.'.
|
||||
Add inline code documentation.
|
||||
</user input>
|
||||
""");
|
||||
|
||||
@@ -74,7 +74,7 @@ import org.springframework.util.Assert;
|
||||
* effective agents</a>
|
||||
*/
|
||||
@SuppressWarnings("null")
|
||||
public class EvaluatorOptimizerWorkflow {
|
||||
public class EvaluatorOptimizer {
|
||||
|
||||
public static final String DEFAULT_GENERATOR_PROMPT = """
|
||||
Your goal is to complete the task based on the input. If there are feedback
|
||||
@@ -101,6 +101,7 @@ public class EvaluatorOptimizerWorkflow {
|
||||
|
||||
public static final String DEFAULT_EVALUATOR_PROMPT = """
|
||||
Evaluate this code implementation for correctness, time complexity, and best practices.
|
||||
Ensure the code have proper javadoc documentation.
|
||||
Respond with EXACTLY this JSON format on a single line:
|
||||
|
||||
{"evaluation":"PASS, NEEDS_IMPROVEMENT, or FAIL", "feedback":"Your feedback here"}
|
||||
@@ -150,11 +151,11 @@ public class EvaluatorOptimizerWorkflow {
|
||||
|
||||
private final String evaluatorPrompt;
|
||||
|
||||
public EvaluatorOptimizerWorkflow(ChatClient chatClient) {
|
||||
public EvaluatorOptimizer(ChatClient chatClient) {
|
||||
this(chatClient, DEFAULT_GENERATOR_PROMPT, DEFAULT_EVALUATOR_PROMPT);
|
||||
}
|
||||
|
||||
public EvaluatorOptimizerWorkflow(ChatClient chatClient, String generatorPrompt, String evaluatorPrompt) {
|
||||
public EvaluatorOptimizer(ChatClient chatClient, String generatorPrompt, String evaluatorPrompt) {
|
||||
Assert.notNull(chatClient, "ChatClient must not be null");
|
||||
Assert.hasText(generatorPrompt, "Generator prompt must not be empty");
|
||||
Assert.hasText(evaluatorPrompt, "Evaluator prompt must not be empty");
|
||||
@@ -27,7 +27,7 @@ This pattern is particularly effective for:
|
||||
The implementation uses Spring AI's ChatClient for LLM interactions and consists of:
|
||||
|
||||
```java
|
||||
public class OrchestratorWorkersWorkflow {
|
||||
public class OrchestratorWorkers {
|
||||
public WorkerResponse process(String taskDescription) {
|
||||
// 1. Orchestrator analyzes task and determines subtasks
|
||||
OrchestratorResponse orchestratorResponse = // ...
|
||||
@@ -45,10 +45,10 @@ public class OrchestratorWorkersWorkflow {
|
||||
|
||||
```java
|
||||
ChatClient chatClient = // ... initialize chat client
|
||||
OrchestratorWorkersWorkflow workflow = new OrchestratorWorkersWorkflow(chatClient);
|
||||
OrchestratorWorkers agent = new OrchestratorWorkers(chatClient);
|
||||
|
||||
// Process a task
|
||||
WorkerResponse response = workflow.process(
|
||||
WorkerResponse response = agent.process(
|
||||
"Generate both technical and user-friendly documentation for a REST API endpoint"
|
||||
);
|
||||
|
||||
@@ -59,11 +59,11 @@ System.out.println("Worker Outputs: " + response.workerResponses());
|
||||
|
||||
## Customization
|
||||
|
||||
The workflow can be customized through:
|
||||
The pattern can be customized through:
|
||||
|
||||
1. **Custom Prompts**: Provide specialized prompts for orchestrator and workers
|
||||
```java
|
||||
workflow = new OrchestratorWorkersWorkflow(
|
||||
agent = new OrchestratorWorkers(
|
||||
chatClient,
|
||||
customOrchestratorPrompt,
|
||||
customWorkerPrompt
|
||||
@@ -10,9 +10,9 @@
|
||||
<relativePath /> <!-- lookup parent from repository -->
|
||||
</parent>
|
||||
<groupId>com.example.spring.ai</groupId>
|
||||
<artifactId>orchestrator-workers-workflow</artifactId>
|
||||
<artifactId>orchestrator-workers</artifactId>
|
||||
<version>0.0.1-SNAPSHOT</version>
|
||||
<name>orchestrator-workers-workflow</name>
|
||||
<name>orchestrator-workers</name>
|
||||
<description>Demo project for Spring Boot</description>
|
||||
<properties>
|
||||
<java.version>17</java.version>
|
||||
@@ -23,7 +23,7 @@ import org.springframework.boot.autoconfigure.SpringBootApplication;
|
||||
import org.springframework.context.annotation.Bean;
|
||||
|
||||
// ------------------------------------------------------------
|
||||
// ORCHESTRATOR WORKFLOW
|
||||
// ORCHESTRATOR WORKERS
|
||||
// ------------------------------------------------------------
|
||||
|
||||
@SpringBootApplication
|
||||
@@ -38,7 +38,7 @@ public class Application {
|
||||
var chatClient = chatClientBuilder.build();
|
||||
return args -> {
|
||||
|
||||
new OrchestratorWorkersWorkflow(chatClient)
|
||||
new OrchestratorWorkers(chatClient)
|
||||
.process("Write a product description for a new eco-friendly water bottle");
|
||||
|
||||
};
|
||||
@@ -21,9 +21,9 @@ import org.springframework.ai.chat.client.ChatClient;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Workflow: <b>Orchestrator-workers</b>
|
||||
* Pattern: <b>Orchestrator-workers</b>
|
||||
* <p/>
|
||||
* In this workflow, a central LLM (the orchestrator) dynamically breaks down
|
||||
* In this pattern, a central LLM (the orchestrator) dynamically breaks down
|
||||
* complex tasks into subtasks,
|
||||
* delegates them to worker LLMs, and uses a synthesizer to combine their
|
||||
* results. The orchestrator analyzes
|
||||
@@ -41,7 +41,7 @@ import org.springframework.util.Assert;
|
||||
* result</li>
|
||||
* </ul>
|
||||
* <p/>
|
||||
* When to use: This workflow is well-suited for complex tasks where you can't
|
||||
* When to use: This pattern is well-suited for complex tasks where you can't
|
||||
* predict the subtasks needed upfront.
|
||||
* For example:
|
||||
* <ul>
|
||||
@@ -64,7 +64,7 @@ import org.springframework.util.Assert;
|
||||
* "https://www.anthropic.com/research/building-effective-agents">Building
|
||||
* effective agents</a>
|
||||
*/
|
||||
public class OrchestratorWorkersWorkflow {
|
||||
public class OrchestratorWorkers {
|
||||
|
||||
private final ChatClient chatClient;
|
||||
private final String orchestratorPrompt;
|
||||
@@ -135,22 +135,22 @@ public class OrchestratorWorkersWorkflow {
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new OrchestratorWorkersWorkflow with default prompts.
|
||||
* Creates a new OrchestratorWorkers with default prompts.
|
||||
*
|
||||
* @param chatClient The ChatClient to use for LLM interactions
|
||||
*/
|
||||
public OrchestratorWorkersWorkflow(ChatClient chatClient) {
|
||||
public OrchestratorWorkers(ChatClient chatClient) {
|
||||
this(chatClient, DEFAULT_ORCHESTRATOR_PROMPT, DEFAULT_WORKER_PROMPT);
|
||||
}
|
||||
|
||||
/**
|
||||
* Creates a new OrchestratorWorkersWorkflow with custom prompts.
|
||||
* Creates a new OrchestratorWorkers with custom prompts.
|
||||
*
|
||||
* @param chatClient The ChatClient to use for LLM interactions
|
||||
* @param orchestratorPrompt Custom prompt for the orchestrator LLM
|
||||
* @param workerPrompt Custom prompt for the worker LLMs
|
||||
*/
|
||||
public OrchestratorWorkersWorkflow(ChatClient chatClient, String orchestratorPrompt, String workerPrompt) {
|
||||
public OrchestratorWorkers(ChatClient chatClient, String orchestratorPrompt, String workerPrompt) {
|
||||
Assert.notNull(chatClient, "ChatClient must not be null");
|
||||
Assert.hasText(orchestratorPrompt, "Orchestrator prompt must not be empty");
|
||||
Assert.hasText(workerPrompt, "Worker prompt must not be empty");
|
||||
@@ -161,7 +161,7 @@ public class OrchestratorWorkersWorkflow {
|
||||
}
|
||||
|
||||
/**
|
||||
* Processes a task using the orchestrator-workers workflow pattern.
|
||||
* Processes a task using the orchestrator-workers pattern.
|
||||
* First, the orchestrator analyzes the task and breaks it down into subtasks.
|
||||
* Then, workers execute each subtask in parallel.
|
||||
* Finally, the results are combined into a single response.
|
||||
@@ -17,8 +17,8 @@
|
||||
<module>chain-workflow</module>
|
||||
<module>parallelization-worflow</module>
|
||||
<module>routing-workflow</module>
|
||||
<module>orchestrator-workers-workflow</module>
|
||||
<module>evaluator-optimizer-workflow</module>
|
||||
<module>orchestrator-workers</module>
|
||||
<module>evaluator-optimizer</module>
|
||||
</modules>
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user