@@ -10,6 +10,7 @@ For this exercise, you need some environment variables from prior exercises. If
10
10
11
11
``` azurecli
12
12
export RESOURCE_GROUP=<resource-group>
13
+ export DB_SERVER_NAME=<server-name>
13
14
export OPENAI_RESOURCE_NAME=OpenAISpringAI
14
15
export AZURE_OPENAI_ENDPOINT=$(az cognitiveservices account show \
15
16
--resource-group $RESOURCE_GROUP \
@@ -23,6 +24,12 @@ export AZURE_OPENAI_API_KEY=$(az cognitiveservices account keys list \
23
24
--query "key1" \
24
25
--output tsv \
25
26
| tr -d '\r')
27
+ export PGHOST=$(az postgres flexible-server show \
28
+ --resource-group $RESOURCE_GROUP \
29
+ --name $DB_SERVER_NAME \
30
+ --query fullyQualifiedDomainName \
31
+ --output tsv \
32
+ | tr -d '\r')
26
33
```
27
34
28
35
### Create the BlogWriterService
@@ -83,138 +90,6 @@ public class BlogWriterService {
83
90
* 4. Refine the draft based on feedback
84
91
* 5. Repeat until approved or max iterations reached
85
92
*
86
- * @param topic The blog post topic
87
- * @return A refined blog post with a maximum of 10 sentences
88
- */
89
- public String generateBlogPost (String topic ) {
90
- logger. info(" Starting blog generation for topic: {}" , topic);
91
-
92
- // PHASE 1: WRITER AGENT
93
- // Prompt the Writer agent to generate the initial blog draft
94
- String initialPrompt = String . format(" " "
95
- You are a professional blog writer. Write a well-structured, engaging blog post about " % s" .
96
- The post should have a clear introduction, body paragraphs, and conclusion.
97
- Include relevant examples and maintain a conversational yet professional tone.
98
-
99
- IMPORTANT FORMATTING REQUIREMENTS:
100
- 1. Format as plain text only (no Markdown, HTML, or special formatting)
101
- 2. Use simple ASCII characters only
102
- 3. For the title, simply put it on the first line and use ALL CAPS instead of " #" symbols
103
- 4. Separate paragraphs with blank lines
104
- 5. The blog post must be concise and contain NO MORE THAN 10 SENTENCES total.
105
- " " " , topic);
106
-
107
- // Using Spring AI's fluent API to send the prompt and get the response
108
- logger. info(" Sending initial draft generation prompt to AI model" );
109
- String draft = chatClient. prompt()
110
- .user(initialPrompt) // Creates a UserMessage with the prompt
111
- .call() // Executes the AI call
112
- .content(); // Extracts the content from the response
113
- logger. info(" Initial draft successfully generated for topic: {}" , topic);
114
-
115
- // PHASE 2: EVALUATION & REFINEMENT LOOP
116
- // Setup for the iterative improvement process
117
- boolean approved = false ;
118
- int iteration = 1 ;
119
- boolean forceFirstIteration = true ; // Force at least one round of feedback to demonstrate the pattern
120
-
121
- // Continue until we reach max iterations or get approval (but always do at least one iteration)
122
- while ((! approved && iteration <= MAX_ITERATIONS ) || forceFirstIteration) {
123
- logger. info(" Starting iteration {} of blog refinement" , iteration);
124
-
125
- // PHASE 2A: EDITOR AGENT
126
- // Prompt the Editor agent to evaluate the current draft
127
- String evalPrompt = String . format(" " "
128
- You are a critical blog editor with extremely high standards. Evaluate the following blog draft and respond with either:
129
- PASS - if the draft is exceptional, well-written, engaging, and complete
130
- NEEDS_IMPROVEMENT - followed by specific, actionable feedback on what to improve
131
-
132
- Focus on:
133
- - Clarity and flow of ideas
134
- - Engagement and reader interest
135
- - Professional yet conversational tone
136
- - Structure and organization
137
- - Strict adherence to the 10-sentence maximum length requirement
138
-
139
- IMPORTANT EVALUATION RULES:
140
- 1. The blog MUST have no more than 10 sentences total. Count the sentences carefully.
141
- 2. For the first iteration, ALWAYS respond with NEEDS_IMPROVEMENT regardless of quality.
142
- 3. Be extremely thorough in your evaluation and provide detailed feedback.
143
- 4. If the draft exceeds 10 sentences, it must receive a NEEDS_IMPROVEMENT rating.
144
- 5. Even well-written drafts should receive suggestions for improvement in early iterations.
145
-
146
- Draft:
147
- %s
148
- " " " , draft);
149
-
150
- // Send the evaluation prompt to the AI model
151
- logger. info(" Sending draft for editorial evaluation (iteration: {})" , iteration);
152
- String evaluation = chatClient. prompt()
153
- .user(evalPrompt)
154
- .call()
155
- .content();
156
-
157
- // After first iteration, remove the force flag
158
- if (forceFirstIteration) {
159
- forceFirstIteration = false ;
160
- }
161
-
162
- // Check if the Editor agent approves the draft
163
- if (evaluation. toUpperCase(). contains(" PASS" ) && iteration > 1 ) { // Only allow PASS after first iteration
164
- // Draft is approved, exit the loop
165
- approved = true ;
166
- logger. info(" Draft approved by editor on iteration {}" , iteration);
167
- } else {
168
- // Draft needs improvement, extract the specific feedback
169
- String feedback = extractFeedback(evaluation);
170
- logger. info(" Editor feedback received (iteration {}): {}" , iteration, feedback);
171
-
172
- // PHASE 2B: WRITER AGENT (REFINEMENT)
173
- // Prompt the Writer agent to refine the draft based on the feedback
174
- String refinePrompt = String . format(" " "
175
- You are a blog writer. Improve the following blog draft based on this editorial feedback:
176
-
177
- Feedback: %s
178
-
179
- Current Draft:
180
- %s
181
-
182
- IMPORTANT REQUIREMENTS:
183
- 1. The final blog post MUST NOT exceed 10 sentences total.
184
- 2. Maintain a clear introduction, body, and conclusion structure.
185
- 3. Keep formatting as plain text only (NO Markdown, HTML, or special formatting)
186
- 4. For the title, use ALL CAPS instead of any special formatting
187
- 5. Separate paragraphs with blank lines
188
- 6. Use only simple ASCII characters
189
- 7. Provide the complete improved version while addressing the feedback.
190
- 8. Count your sentences carefully before submitting.
191
- " " " , feedback, draft);
192
-
193
- // Send the refinement prompt to the AI model
194
- logger. info(" Requesting draft revision based on feedback (iteration: {})" , iteration);
195
- draft = chatClient. prompt()
196
- .user(refinePrompt)
197
- .call()
198
- .content();
199
- logger. info(" Revised draft received for iteration {}" , iteration);
200
- }
201
- iteration++ ;
202
- }
203
-
204
- // PHASE 3: FINALIZATION
205
- // Return the final draft, either approved or after reaching max iterations
206
- if (! approved) {
207
- logger. warn(" Maximum iterations ({}) reached without editor approval" , MAX_ITERATIONS );
208
- } else {
209
- logger. info(" Blog post generation completed successfully for topic: {}" , topic);
210
- }
211
-
212
- return draft;
213
- }
214
-
215
- /**
216
- * Enhanced version of generateBlogPost that also returns metadata about the generation process.
217
- *
218
93
* This method ensures at least one feedback-improvement cycle occurs to demonstrate
219
94
* the full evaluator-optimizer pattern in action, regardless of initial draft quality.
220
95
*
0 commit comments