Skip to content

Commit 5278498

Browse files
authored
pull base content,head:wwlpublishsync,into:204cce7b31ec95f51eefa781b050b2054145f995fd40ddece39ce713435d4c6d-live
2 parents 2496d14 + 739c8f0 commit 5278498

File tree

341 files changed

+5675
-5548
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

341 files changed

+5675
-5548
lines changed

learn-pr/azure/build-enterprise-ai-agents-with-java-spring/includes/7-exercise-agent-ai-development.md

Lines changed: 9 additions & 137 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ For this exercise, you need some environment variables from prior exercises. If
1010

1111
```azurecli
1212
export RESOURCE_GROUP=<resource-group>
13+
export DB_SERVER_NAME=<server-name>
1314
export OPENAI_RESOURCE_NAME=OpenAISpringAI
1415
export AZURE_OPENAI_ENDPOINT=$(az cognitiveservices account show \
1516
--resource-group $RESOURCE_GROUP \
@@ -23,6 +24,12 @@ export AZURE_OPENAI_API_KEY=$(az cognitiveservices account keys list \
2324
--query "key1" \
2425
--output tsv \
2526
| 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')
2633
```
2734

2835
### Create the BlogWriterService
@@ -83,138 +90,6 @@ public class BlogWriterService {
8390
* 4. Refine the draft based on feedback
8491
* 5. Repeat until approved or max iterations reached
8592
*
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-
*
21893
* This method ensures at least one feedback-improvement cycle occurs to demonstrate
21994
* the full evaluator-optimizer pattern in action, regardless of initial draft quality.
22095
*
@@ -499,13 +374,10 @@ public class BlogWriterService {
499374

500375
This implementation includes the following key features:
501376

502-
- Basic blog generation. The `generateBlogPost` method:
503-
- Creates a well-structured blog post on a given topic.
377+
- Blog generation with metadata. The `generateBlogPostWithMetadata` method:
378+
- Creates a well-structured blog post on a given topic with detailed metadata about the generation process.
504379
- Uses an iterative refinement process with Writer and Editor agents.
505380
- Enforces a 10-sentence maximum length.
506-
507-
- Enhanced metadata generation. The `generateBlogPostWithMetadata` method:
508-
- Extends the basic functionality to capture detailed metadata about the generation process.
509381
- Tracks iterations, approval status, token usage, and editor feedback history.
510382
- Returns all information in a structured `BlogGenerationResult` object.
511383

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.introduction
3+
title: Introduction
4+
metadata:
5+
title: Introduction
6+
description: "Introduction."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 1
12+
content: |
13+
[!include[](includes/1-introduction.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.create-user
3+
title: Perform basic User Management tasks
4+
metadata:
5+
title: Perform basic User Management tasks
6+
description: "Perform labs to learn about creating users and assigning them access rights."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 15
12+
content: |
13+
[!include[](includes/2-create-user.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.create-group
3+
title: Perform basic Group Management tasks
4+
metadata:
5+
title: Perform basic Group Management tasks
6+
description: "Perform labs to create groups, assign users, and grant access."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 15
12+
content: |
13+
[!include[](includes/3-create-group.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.configure-password-protection
3+
title: Perform basic Password Protection tasks
4+
metadata:
5+
title: Perform basic Password Protection tasks
6+
description: "Perform an interactive lab to configure and enable password protection features."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 5
12+
content: |
13+
[!include[](includes/4-configure-password-protect.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.configure-password-reset
3+
title: Perform basic Self-Service Password Reset (SSPR) tasks
4+
metadata:
5+
title: Perform basic Self-Service Password Reset (SSPR) tasks
6+
description: "Perform this interactive lab to enable and configure basics features of SSPR."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 5
12+
content: |
13+
[!include[](includes/5-configure-password-reset.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.add-multifactor-authentication
3+
title: Perform basic Multifactor Authentication tasks
4+
metadata:
5+
title: Perform basic Multifactor Authentication tasks
6+
description: "Perform the lab to enable multifactor authentication to protect users and company data."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 10
12+
content: |
13+
[!include[](includes/6-add-multifactor-authentication.md)]
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.create-conditional-access-policy
3+
title: Perform basic Conditional Access policy tasks
4+
metadata:
5+
title: Perform basic Conditional Access policy tasks
6+
description: "Perform the lab to explore creating and evaluating the impact of Conditional Access policies."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 10
12+
content: |
13+
[!include[](includes/7-create-conditional-access-policy.md)]
Lines changed: 60 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,60 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.knowledge-check
3+
title: Knowledge check
4+
metadata:
5+
title: Knowledge check
6+
description: "Check your knowledge."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 3
12+
content: |
13+
[!include[](includes/8-knowledge-check.md)]
14+
quiz:
15+
title: "Check your knowledge"
16+
questions:
17+
- content: "The goal is to create a new user in Microsoft Entra ID. What is the first step to take?"
18+
choices:
19+
- content: "Browse to Identity > Users > All users."
20+
isCorrect: false
21+
explanation: "Incorrect. This is the second step after signing in to the Microsoft Entra admin center."
22+
- content: "Select New user > Create new user."
23+
isCorrect: false
24+
explanation: "Incorrect. This is the third step after browsing to the All users page."
25+
- content: "Sign in to the Microsoft Entra admin center as at least a User Administrator."
26+
isCorrect: true
27+
explanation: "Correct. The first step is to sign in to the Microsoft Entra admin center with the appropriate role."
28+
- content: "What is the first step to add a license to a user in Microsoft Entra ID?"
29+
choices:
30+
- content: "Sign in to the Microsoft 365 admin center as at least a License Administrator."
31+
isCorrect: true
32+
explanation: "Correct. The first step is to sign in to the Microsoft 365 admin center with the appropriate administrative role."
33+
- content: "Navigate to Billing > Licenses."
34+
isCorrect: false
35+
explanation: "Incorrect. This is the second step. The first step is to sign in to the Microsoft 365 admin center."
36+
- content: "Select the license to assign."
37+
isCorrect: false
38+
explanation: "Incorrect. This is the third step. The first step is to sign in to the Microsoft 365 admin center."
39+
- content: "An identity and access administrator needs to invite an external user to collaborate on a project. What is the first step to take?"
40+
choices:
41+
- content: "Send an email invitation directly from the admin's email client."
42+
isCorrect: false
43+
explanation: "Incorrect. Invitations should be sent through the Microsoft Entra admin center to ensure proper tracking and management."
44+
- content: "Sign in to the Microsoft Entra admin center as at least a User Administrator."
45+
isCorrect: true
46+
explanation: "Correct. The first step is to sign in to the Microsoft Entra admin center with the necessary permissions to invite external users."
47+
- content: "Create a new user account for the external user."
48+
isCorrect: false
49+
explanation: "Incorrect. There is no need to create a new user account; instead, invite the external user to use their existing account."
50+
- content: "An identity and access admin needs to assign a role to a user in Microsoft Entra. What is the first step to take?"
51+
choices:
52+
- content: "Sign in to the Microsoft Entra admin center."
53+
isCorrect: true
54+
explanation: "Correct. The first step in assigning a role in Microsoft Entra is to sign in to the Microsoft Entra admin center."
55+
- content: "Navigate to the Azure portal."
56+
isCorrect: false
57+
explanation: "Incorrect. Role assignments in Microsoft Entra are managed through the Microsoft Entra admin center, not the Azure portal."
58+
- content: "Create a new user account."
59+
isCorrect: false
60+
explanation: "Incorrect. Creating a new user account isn't the first step in assigning a role. Sign in to the Microsoft Entra admin center first."
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
### YamlMime:ModuleUnit
2+
uid: learn.wwl.get-started-identity-access-labs.summary-resources
3+
title: Summary and resources
4+
metadata:
5+
title: Summary and resources
6+
description: "Summary and resources."
7+
ms.date: 03/29/2025
8+
author: wwlpublish
9+
ms.author: roberts
10+
ms.topic: unit
11+
durationInMinutes: 1
12+
content: |
13+
[!include[](includes/9-summary-resources.md)]

0 commit comments

Comments
 (0)