Skip to content

Commit c6a0e47

Browse files
committed
add observation support
1 parent 600c911 commit c6a0e47

File tree

19 files changed

+289
-168
lines changed

19 files changed

+289
-168
lines changed

chain-workflow/src/main/java/com/javaaidev/agenticpatterns/chainworkflow/ChainStepAgent.java

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package com.javaaidev.agenticpatterns.chainworkflow;
22

33
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
4+
import io.micrometer.observation.ObservationRegistry;
45
import java.lang.reflect.Type;
56
import java.util.Map;
67
import org.jspecify.annotations.Nullable;
@@ -10,12 +11,15 @@
1011
public abstract class ChainStepAgent<Req, Res> extends TaskExecutionAgent<Req, Res> implements
1112
Ordered {
1213

13-
protected ChainStepAgent(ChatClient chatClient) {
14-
super(chatClient);
14+
protected ChainStepAgent(ChatClient chatClient,
15+
@Nullable ObservationRegistry observationRegistry) {
16+
super(chatClient, observationRegistry);
1517
}
1618

17-
protected ChainStepAgent(ChatClient chatClient, @Nullable Type responseType) {
18-
super(chatClient, responseType);
19+
protected ChainStepAgent(ChatClient chatClient,
20+
@Nullable Type responseType,
21+
@Nullable ObservationRegistry observationRegistry) {
22+
super(chatClient, responseType, observationRegistry);
1923
}
2024

2125
protected abstract Res call(Req request, Map<String, Object> context,
Lines changed: 20 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,24 +1,29 @@
11
package com.javaaidev.agenticpatterns.chainworkflow;
22

3-
import com.javaaidev.agenticpatterns.taskexecution.NoLLMTaskExecutionAgent;
3+
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
4+
import io.micrometer.observation.ObservationRegistry;
45
import java.lang.reflect.Type;
56
import java.util.ArrayList;
67
import java.util.List;
78
import org.jspecify.annotations.Nullable;
89
import org.springframework.ai.chat.client.ChatClient;
910

1011
public class ChainWorkflowAgent<Request, Response> extends
11-
NoLLMTaskExecutionAgent<Request, Response> {
12+
TaskExecutionAgent<Request, Response> {
1213

1314
private final List<ChainStepAgent<Request, Response>> stepAgents = new ArrayList<>();
1415

15-
protected ChainWorkflowAgent(ChatClient chatClient) {
16-
super(chatClient);
16+
protected ChainWorkflowAgent(
17+
ChatClient chatClient,
18+
@Nullable ObservationRegistry observationRegistry) {
19+
super(chatClient, null, observationRegistry);
1720
}
1821

19-
public ChainWorkflowAgent(ChatClient chatClient,
20-
@Nullable Type responseType) {
21-
super(chatClient, responseType);
22+
public ChainWorkflowAgent(
23+
ChatClient chatClient,
24+
@Nullable Type responseType,
25+
@Nullable ObservationRegistry observationRegistry) {
26+
super(chatClient, responseType, observationRegistry);
2227
}
2328

2429
public void addStep(ChainStepAgent<Request, Response> stepAgent) {
@@ -27,8 +32,16 @@ public void addStep(ChainStepAgent<Request, Response> stepAgent) {
2732

2833
@Override
2934
public Response call(@Nullable Request request) {
35+
return instrumentedCall(request, this::doCall);
36+
}
37+
38+
private Response doCall(@Nullable Request request) {
3039
var chain = new WorkflowChain<>(stepAgents);
3140
return chain.callNext(request, null);
3241
}
3342

43+
@Override
44+
protected String getPromptTemplate() {
45+
return "";
46+
}
3447
}

evaluator-optimizer/src/main/java/com/javaaidev/agenticpatterns/evaluatoroptimizer/EvaluatorOptimizerAgent.java

Lines changed: 48 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
11
package com.javaaidev.agenticpatterns.evaluatoroptimizer;
22

3+
import com.javaaidev.agenticpatterns.taskexecution.NoLLMTaskExecutionAgent;
34
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
5+
import io.micrometer.observation.ObservationRegistry;
6+
import java.lang.reflect.Type;
47
import org.jspecify.annotations.Nullable;
58
import org.slf4j.Logger;
69
import org.slf4j.LoggerFactory;
10+
import org.springframework.ai.chat.client.ChatClient;
711

812
/**
913
* Evaluator-Optimizer Agent, refer to the <a
@@ -12,13 +16,42 @@
1216
* @param <Request>
1317
* @param <Response>
1418
*/
15-
public abstract class EvaluatorOptimizerAgent<Request, Response> {
19+
public abstract class EvaluatorOptimizerAgent<Request, Response> extends
20+
NoLLMTaskExecutionAgent<Request, Response> {
1621

17-
protected TaskExecutionAgent<Request, Response> initialResultAgent = buildInitialResultAgent();
22+
protected ChatClient generationChatClient;
23+
protected ChatClient evaluationChatClient;
24+
25+
protected EvaluatorOptimizerAgent(ChatClient generationChatClient,
26+
ChatClient evaluationChatClient) {
27+
this(generationChatClient, evaluationChatClient, null, null);
28+
}
29+
30+
public EvaluatorOptimizerAgent(ChatClient generationChatClient,
31+
ChatClient evaluationChatClient, @Nullable ObservationRegistry observationRegistry) {
32+
this(generationChatClient, evaluationChatClient, null, observationRegistry);
33+
}
34+
35+
protected EvaluatorOptimizerAgent(ChatClient generationChatClient,
36+
ChatClient evaluationChatClient, @Nullable Type responseType,
37+
@Nullable ObservationRegistry observationRegistry) {
38+
super(responseType, observationRegistry);
39+
this.generationChatClient = generationChatClient;
40+
this.evaluationChatClient = evaluationChatClient;
41+
initAgents();
42+
}
43+
44+
private void initAgents() {
45+
initialResultAgent = buildInitialResultAgent(generationChatClient, observationRegistry);
46+
evaluationAgent = buildEvaluationAgent(evaluationChatClient, observationRegistry);
47+
optimizationAgent = buildOptimizationAgent(generationChatClient, observationRegistry);
48+
}
49+
50+
protected TaskExecutionAgent<Request, Response> initialResultAgent;
1851
@Nullable
19-
protected TaskExecutionAgent<Response, Evaluation> evaluationAgent = buildEvaluationAgent();
52+
protected TaskExecutionAgent<Response, Evaluation> evaluationAgent;
2053
@Nullable
21-
protected TaskExecutionAgent<OptimizationInput<Response>, Response> optimizationAgent = buildOptimizationAgent();
54+
protected TaskExecutionAgent<OptimizationInput<Response>, Response> optimizationAgent;
2255

2356
private static final Logger LOGGER = LoggerFactory.getLogger(EvaluatorOptimizerAgent.class);
2457

@@ -36,23 +69,31 @@ protected int getMaxIterations() {
3669
*
3770
* @return the agent, see {@linkplain TaskExecutionAgent}
3871
*/
39-
protected abstract TaskExecutionAgent<Request, Response> buildInitialResultAgent();
72+
protected abstract TaskExecutionAgent<Request, Response> buildInitialResultAgent(
73+
ChatClient chatClient, @Nullable ObservationRegistry observationRegistry);
4074

4175
/**
4276
* Build the agent to evaluate the result
4377
*
4478
* @return the agent, see {@linkplain TaskExecutionAgent}
4579
*/
46-
protected abstract TaskExecutionAgent<Response, Evaluation> buildEvaluationAgent();
80+
protected abstract TaskExecutionAgent<Response, Evaluation> buildEvaluationAgent(
81+
ChatClient chatClient, @Nullable ObservationRegistry observationRegistry);
4782

4883
/**
4984
* Build the agent to optimize the result
5085
*
5186
* @return the agent, see {@linkplain TaskExecutionAgent}
5287
*/
53-
protected abstract TaskExecutionAgent<OptimizationInput<Response>, Response> buildOptimizationAgent();
88+
protected abstract TaskExecutionAgent<OptimizationInput<Response>, Response> buildOptimizationAgent(
89+
ChatClient chatClient, @Nullable ObservationRegistry observationRegistry);
5490

91+
@Override
5592
public Response call(@Nullable Request request) {
93+
return instrumentedCall(request, this::doCall);
94+
}
95+
96+
private Response doCall(@Nullable Request request) {
5697
var initialResult = initialResultAgent.call(request);
5798
if (evaluationAgent == null || optimizationAgent == null) {
5899
return initialResult;

evaluator-optimizer/src/main/java/com/javaaidev/agenticpatterns/evaluatoroptimizer/PromptBasedEvaluatorOptimizerAgent.java

Lines changed: 28 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
package com.javaaidev.agenticpatterns.evaluatoroptimizer;
22

3-
import com.javaaidev.agenticpatterns.core.TypeResolver;
43
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
4+
import io.micrometer.observation.ObservationRegistry;
55
import java.lang.reflect.Type;
66
import java.util.HashMap;
77
import java.util.Map;
@@ -17,18 +17,18 @@
1717
public abstract class PromptBasedEvaluatorOptimizerAgent<Request, Response> extends
1818
EvaluatorOptimizerAgent<Request, Response> {
1919

20-
@Nullable
21-
protected Type responseType = null;
2220

23-
private void tryResolveType() {
24-
responseType = TypeResolver.resolveType(this.getClass(),
25-
PromptBasedEvaluatorOptimizerAgent.class,
26-
1);
21+
protected PromptBasedEvaluatorOptimizerAgent(ChatClient generationChatClient,
22+
ChatClient evaluationChatClient) {
23+
this(generationChatClient, evaluationChatClient, null, null);
2724
}
2825

29-
protected abstract ChatClient getGenerationChatClient();
30-
31-
protected abstract ChatClient getEvaluationChatClient();
26+
protected PromptBasedEvaluatorOptimizerAgent(ChatClient generationChatClient,
27+
ChatClient evaluationChatClient,
28+
@Nullable Type responseType,
29+
@Nullable ObservationRegistry observationRegistry) {
30+
super(generationChatClient, evaluationChatClient, responseType, observationRegistry);
31+
}
3232

3333
protected abstract String getInitialResultPromptTemplate();
3434

@@ -39,8 +39,9 @@ private void tryResolveType() {
3939

4040
public class GenerateInitialResultAgent extends TaskExecutionAgent<Request, Response> {
4141

42-
public GenerateInitialResultAgent(@Nullable Type responseType) {
43-
super(getGenerationChatClient(), responseType);
42+
public GenerateInitialResultAgent(ChatClient chatClient, @Nullable Type responseType,
43+
@Nullable ObservationRegistry observationRegistry) {
44+
super(chatClient, responseType, observationRegistry);
4445
}
4546

4647
@Override
@@ -55,9 +56,9 @@ protected String getPromptTemplate() {
5556
}
5657

5758
@Override
58-
protected TaskExecutionAgent<Request, Response> buildInitialResultAgent() {
59-
tryResolveType();
60-
return new GenerateInitialResultAgent(responseType);
59+
protected TaskExecutionAgent<Request, Response> buildInitialResultAgent(ChatClient chatClient,
60+
@Nullable ObservationRegistry observationRegistry) {
61+
return new GenerateInitialResultAgent(chatClient, responseType, observationRegistry);
6162
}
6263

6364
protected abstract String getEvaluationPromptTemplate();
@@ -69,9 +70,9 @@ protected TaskExecutionAgent<Request, Response> buildInitialResultAgent() {
6970

7071
public class EvaluateAgent extends TaskExecutionAgent<Response, Evaluation> {
7172

72-
73-
protected EvaluateAgent() {
74-
super(getEvaluationChatClient());
73+
protected EvaluateAgent(ChatClient chatClient,
74+
@Nullable ObservationRegistry observationRegistry) {
75+
super(chatClient, Evaluation.class, observationRegistry);
7576
}
7677

7778
@Override
@@ -86,8 +87,9 @@ protected String getPromptTemplate() {
8687
}
8788

8889
@Override
89-
protected TaskExecutionAgent<Response, Evaluation> buildEvaluationAgent() {
90-
return new EvaluateAgent();
90+
protected TaskExecutionAgent<Response, Evaluation> buildEvaluationAgent(ChatClient chatClient,
91+
@Nullable ObservationRegistry observationRegistry) {
92+
return new EvaluateAgent(chatClient, observationRegistry);
9193
}
9294

9395
protected abstract String getOptimizationPromptTemplate();
@@ -99,8 +101,9 @@ protected TaskExecutionAgent<Response, Evaluation> buildEvaluationAgent() {
99101

100102
public class OptimizeAgent extends TaskExecutionAgent<OptimizationInput<Response>, Response> {
101103

102-
public OptimizeAgent(@Nullable Type responseType) {
103-
super(getGenerationChatClient(), responseType);
104+
public OptimizeAgent(ChatClient chatClient, @Nullable Type responseType,
105+
@Nullable ObservationRegistry observationRegistry) {
106+
super(chatClient, responseType, observationRegistry);
104107
}
105108

106109
@Override
@@ -116,8 +119,8 @@ protected String getPromptTemplate() {
116119
}
117120

118121
@Override
119-
protected TaskExecutionAgent<OptimizationInput<Response>, Response> buildOptimizationAgent() {
120-
tryResolveType();
121-
return new OptimizeAgent(responseType);
122+
protected TaskExecutionAgent<OptimizationInput<Response>, Response> buildOptimizationAgent(
123+
ChatClient chatClient, @Nullable ObservationRegistry observationRegistry) {
124+
return new OptimizeAgent(chatClient, responseType, observationRegistry);
122125
}
123126
}

examples/src/main/java/com/javaaidev/agenticpatterns/examples/chainworkflow/ArticleWritingAgent.java

Lines changed: 19 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@
77
import com.javaaidev.agenticpatterns.examples.chainworkflow.ArticleWritingAgent.ArticleWritingRequest;
88
import com.javaaidev.agenticpatterns.examples.chainworkflow.ArticleWritingAgent.ArticleWritingResponse;
99
import com.javaaidev.agenticpatterns.taskexecution.TaskExecutionAgent;
10+
import io.micrometer.observation.ObservationRegistry;
1011
import java.util.List;
1112
import java.util.Map;
1213
import org.jspecify.annotations.Nullable;
@@ -18,10 +19,12 @@ public class ArticleWritingAgent extends
1819
private final ArticleGenerationAgent articleGenerationAgent;
1920
private final ArticleImprovementChainAgent articleImprovementChainAgent;
2021

21-
protected ArticleWritingAgent(ChatClient chatClient) {
22-
super(chatClient, ArticleWritingResponse.class);
23-
articleGenerationAgent = new ArticleGenerationAgent(chatClient);
24-
articleImprovementChainAgent = new ArticleImprovementChainAgent(chatClient);
22+
protected ArticleWritingAgent(ChatClient chatClient,
23+
@Nullable ObservationRegistry observationRegistry) {
24+
super(chatClient, ArticleWritingResponse.class, observationRegistry);
25+
articleGenerationAgent = new ArticleGenerationAgent(chatClient, observationRegistry);
26+
articleImprovementChainAgent = new ArticleImprovementChainAgent(chatClient,
27+
observationRegistry);
2528
}
2629

2730
@Override
@@ -56,8 +59,9 @@ private record ArticleImprovementResponse(String article) {
5659
private static class ArticleGenerationAgent extends
5760
TaskExecutionAgent<ArticleWritingRequest, ArticleWritingResponse> {
5861

59-
protected ArticleGenerationAgent(ChatClient chatClient) {
60-
super(chatClient, ArticleWritingResponse.class);
62+
protected ArticleGenerationAgent(ChatClient chatClient,
63+
@Nullable ObservationRegistry observationRegistry) {
64+
super(chatClient, ArticleWritingResponse.class, observationRegistry);
6165
}
6266

6367
@Override
@@ -79,8 +83,10 @@ protected String getPromptTemplate() {
7983
private static class ArticleImprovementChainAgent extends
8084
ChainWorkflowAgent<ArticleImprovementRequest, ArticleImprovementResponse> {
8185

82-
protected ArticleImprovementChainAgent(ChatClient chatClient) {
83-
super(chatClient, ArticleImprovementResponse.class);
86+
protected ArticleImprovementChainAgent(
87+
ChatClient chatClient,
88+
@Nullable ObservationRegistry observationRegistry) {
89+
super(chatClient, ArticleImprovementResponse.class, observationRegistry);
8490
initStepAgents();
8591
}
8692

@@ -106,7 +112,8 @@ private void initStepAgents() {
106112
"""
107113
);
108114
for (int i = 0; i < instructions.size(); i++) {
109-
addStep(new ArticleImprovementAgent(chatClient, instructions.get(i), i));
115+
addStep(
116+
new ArticleImprovementAgent(chatClient, observationRegistry, instructions.get(i), i));
110117
}
111118
}
112119
}
@@ -118,8 +125,9 @@ private static class ArticleImprovementAgent extends
118125
private final String instruction;
119126
private final int order;
120127

121-
protected ArticleImprovementAgent(ChatClient chatClient, String instruction, int order) {
122-
super(chatClient, ArticleImprovementResponse.class);
128+
protected ArticleImprovementAgent(ChatClient chatClient,
129+
@Nullable ObservationRegistry observationRegistry, String instruction, int order) {
130+
super(chatClient, ArticleImprovementResponse.class, observationRegistry);
123131
this.instruction = instruction;
124132
this.order = order;
125133
}

examples/src/main/java/com/javaaidev/agenticpatterns/examples/chainworkflow/ArticleWritingConfiguration.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package com.javaaidev.agenticpatterns.examples.chainworkflow;
22

3+
import io.micrometer.observation.ObservationRegistry;
34
import org.springframework.ai.chat.client.ChatClient;
45
import org.springframework.ai.chat.client.advisor.SimpleLoggerAdvisor;
56
import org.springframework.context.annotation.Bean;
@@ -10,7 +11,9 @@ public class ArticleWritingConfiguration {
1011

1112
@Bean
1213
public ArticleWritingAgent articleWritingAgent(ChatClient.Builder chatClientBuilder,
13-
SimpleLoggerAdvisor simpleLoggerAdvisor) {
14-
return new ArticleWritingAgent(chatClientBuilder.defaultAdvisors(simpleLoggerAdvisor).build());
14+
SimpleLoggerAdvisor simpleLoggerAdvisor,
15+
ObservationRegistry observationRegistry) {
16+
return new ArticleWritingAgent(chatClientBuilder.defaultAdvisors(simpleLoggerAdvisor).build(),
17+
observationRegistry);
1518
}
1619
}

0 commit comments

Comments
 (0)