크리스마스를 저장하는 Microsoft의 에이전트 프레임워크
소개
완벽한 크리스마스 선물을 찾는 것은 스트레스가 될 수 있습니다. 선물 아이디어를 브레인스토밍하고, 매장 간 가격을 비교하고, 모든 것이 제 시간에 도착하는지 확인하는 과정에서 연말연시 쇼핑은 순식간에 부담스러워집니다. 함께 일하는 전문 AI 에이전트에게 이러한 작업을 위임할 수 있다면 어떨까요? 이 게시물에서는 Microsoft의 에이전트 프레임워크를 사용하여 각 에이전트가 선물 아이디어 생성부터 가격 비교까지 워크플로를 통해 조정되는 특정 작업을 전문으로 하는 다중 에이전트 시스템을 구축하는 방법을 살펴보겠습니다.
축제 기술 달력 2025

이 프로젝트는 연휴 기간 동안 기술을 기념하는 멋진 커뮤니티 이벤트인 Festive Tech Calendar 2025 세션의 일부입니다. Sessionize에서 이벤트에 대한 자세한 내용을 확인할 수 있습니다.
Microsoft의 에이전트 프레임워크란 무엇입니까?
에이전트 프레임워크는 AI 에이전트 및 다중 에이전트 시스템을 구축, 조정 및 배포하기 위한 Microsoft의 솔루션입니다. 이는 순차적으로, 동시에 또는 핸드오프 패턴을 통해 작업할 수 있는 에이전트를 생성하기 위한 유연한 기반을 제공합니다. 이 프레임워크는 OpenAI, Azure OpenAI 및 Microsoft Foundry 모델을 지원하므로 매우 다양합니다.
주요 기능은 다음과 같습니다:
- 다중 에이전트 오케스트레이션: 그룹 채팅, 순차, 동시 및 핸드오프 패턴
- 플러그인 생태계: 기본 기능, OpenAPI 및 MCP(모델 컨텍스트 프로토콜)로 확장
- 워크플로 지원: 실행기와 에지를 사용하여 복잡한 에이전트 파이프라인 구축
전제 조건
코드를 살펴보기 전에 다음 사항을 확인하세요.
- .NET 9
- Azure OpenAI 액세스(또는 OpenAI API 키)
- 비주얼 스튜디오 또는 비주얼 스튜디오 코드
필수 패키지를 설치합니다(미리보기에서는 --prerelease 플래그가 필요합니다).
dotnet add package Microsoft.Agents.AI.OpenAI --prerelease
dotnet add package Microsoft.Agents.AI.Workflows --prerelease
dotnet add package Azure.AI.OpenAI
dotnet add package Azure.Identity
dotnet add package Azure.AI.Agents.Persistent --prerelease
선물 쇼핑 에이전트
우리의 크리스마스 선물 찾기는 함께 일하는 세 명의 전문 에이전트로 구성됩니다.
- 선물 아이디어 에이전트 - 받는 사람의 프로필을 기반으로 창의적인 선물 제안 생성
- 가격 비교 에이전트 - 여러 매장에서 가장 좋은 가격을 찾아줍니다.
- 요약 에이전트 - 최종 권장 사항을 컴파일합니다.
모델
에이전트 파이프라인을 통해 흐를 데이터 모델을 정의하는 것부터 시작해 보겠습니다.
public class GiftRecipient
{
public string Name { get; set; } = string.Empty;
public int Age { get; set; }
public List<string> Interests { get; set; } = [];
public decimal Budget { get; set; }
}
public class GiftIdea
{
public string Name { get; set; } = string.Empty;
public string Description { get; set; } = string.Empty;
public string Category { get; set; } = string.Empty;
public decimal EstimatedPrice { get; set; }
}
public class PriceResult
{
public string GiftName { get; set; } = string.Empty;
public string Store { get; set; } = string.Empty;
public decimal Price { get; set; }
public string Url { get; set; } = string.Empty;
}
public class GiftRecommendation
{
public GiftIdea Gift { get; set; } = new();
public List<PriceResult> Prices { get; set; } = [];
public PriceResult? BestDeal { get; set; }
}
에이전트 구축
에이전트 프레임워크의 장점은 전문 에이전트를 생성하는 것이 얼마나 쉬운가입니다. 각 에이전트는 전문 지식을 정의하는 특정 시스템 프롬프트가 있는 단순한 ChatClientAgent입니다.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
public static class ChristmasAgentFactory
{
public static AIAgent CreateGiftIdeaAgent(IChatClient chatClient)
{
return new ChatClientAgent(
chatClient,
@"You are a creative Christmas gift advisor. When given information about a person
(age, interests, budget), you suggest thoughtful and personalized gift ideas.
For each suggestion, provide:
- Gift name
- Brief description of why it's a good fit
- Category (Electronics, Books, Fashion, Home, Experience, etc.)
- Estimated price range
Always suggest 3-5 gift options within the specified budget.
Format your response as a structured list.");
}
public static AIAgent CreatePriceComparisonAgent(IChatClient chatClient)
{
return new ChatClientAgent(
chatClient,
@"You are a price comparison specialist. Given a list of gift ideas,
you research and compare prices from different online retailers.
For each gift, provide:
- Store name (Amazon, Best Buy, Target, Walmart, etc.)
- Current price
- Any available discounts or deals
Always highlight the best deal for each item.
Consider shipping costs and delivery times for Christmas.");
}
public static AIAgent CreateSummaryAgent(IChatClient chatClient)
{
return new ChatClientAgent(
chatClient,
@"You are a gift recommendation summarizer. Take the gift ideas and price
comparisons and create a final recommendation report.
Your summary should:
- Rank gifts by value (quality vs price)
- Highlight the top pick with reasoning
- Include total cost estimate
- Add any tips for holiday shopping
Make the summary cheerful and festive!");
}
}
워크플로 만들기
이제 에이전트를 순차적인 워크플로에 연결하는 재미있는 부분이 나옵니다. 에이전트 프레임워크는 에이전트를 다양한 패턴으로 구성하기 위해 WorkflowBuilder 및 AgentWorkflowBuilder를 제공합니다.
public static class ChristmasGiftWorkflow
{
public static async Task RunAsync()
{
// Set up the Azure OpenAI client
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")
?? throw new InvalidOperationException("AZURE_OPENAI_ENDPOINT is not set.");
var deploymentName = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME")
?? "gpt-4o-mini";
var chatClient = new AzureOpenAIClient(
new Uri(endpoint),
new DefaultAzureCredential())
.GetChatClient(deploymentName)
.AsIChatClient();
// Create our specialized agents
AIAgent giftIdeaAgent = ChristmasAgentFactory.CreateGiftIdeaAgent(chatClient);
AIAgent priceAgent = ChristmasAgentFactory.CreatePriceComparisonAgent(chatClient);
AIAgent summaryAgent = ChristmasAgentFactory.CreateSummaryAgent(chatClient);
// Build a sequential workflow: Ideas -> Prices -> Summary
var workflow = AgentWorkflowBuilder.BuildSequential(
"ChristmasGiftFinder",
[giftIdeaAgent, priceAgent, summaryAgent]);
// Define our gift recipient
var recipient = new GiftRecipient
{
Name = "Mom",
Age = 55,
Interests = ["gardening", "cooking", "reading", "yoga"],
Budget = 100
};
var prompt = $@"Find Christmas gifts for {recipient.Name},
age {recipient.Age}, who enjoys {string.Join(", ", recipient.Interests)}.
Budget: ${recipient.Budget}";
// Execute the workflow with streaming
await using StreamingRun run = await InProcessExecution.StreamAsync(
workflow,
new ChatMessage(ChatRole.User, prompt));
// Send the turn token to start processing
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
// Watch for workflow events
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
if (evt is AgentRunUpdateEvent agentUpdate)
{
Console.Write(agentUpdate.Data);
}
else if (evt is WorkflowOutputEvent outputEvent)
{
Console.WriteLine("\n🎄 Final Recommendations:");
Console.WriteLine(outputEvent.Data);
}
}
}
}
동시에 에이전트 실행
여러 사람에게 줄 선물을 동시에 검색하고 싶다면 어떻게 해야 할까요? 에이전트 프레임워크는 동시 실행을 지원하며 이는 다음 시나리오에 적합합니다.
public static async Task FindGiftsForEveryoneAsync(IChatClient chatClient, List<GiftRecipient> recipients)
{
// Create an agent for each recipient
var agents = recipients.Select(r => new ChatClientAgent(
chatClient,
$@"Find the perfect Christmas gift for {r.Name} (age {r.Age}),
who loves {string.Join(", ", r.Interests)}. Budget: ${r.Budget}.
Provide one well-researched recommendation with price."
)).ToList();
// Build a concurrent workflow - all agents run in parallel
var workflow = AgentWorkflowBuilder.BuildConcurrent(
"FamilyGiftFinder",
agents);
await using StreamingRun run = await InProcessExecution.StreamAsync(
workflow,
new ChatMessage(ChatRole.User, "Find gifts now!"));
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
await foreach (WorkflowEvent evt in run.WatchStreamAsync())
{
if (evt is WorkflowOutputEvent output)
{
Console.WriteLine("🎁 All gift recommendations ready!");
Console.WriteLine(output.Data);
}
}
}
더 많은 제어를 위한 맞춤형 실행기보다 복잡한 시나리오의 경우 워크플로를 세밀하게 제어할 수 있는 사용자 지정 실행기를 만들 수 있습니다.
public sealed class GiftValidatorExecutor : Executor<List<ChatMessage>, List<ChatMessage>>
{
public GiftValidatorExecutor() : base("GiftValidator") { }
public override async ValueTask<List<ChatMessage>> HandleAsync(
List<ChatMessage> messages,
IWorkflowContext context,
CancellationToken cancellationToken = default)
{
var lastMessage = messages.LastOrDefault()?.Text ?? "";
// Validate that suggestions are within budget
if (lastMessage.Contains("over budget", StringComparison.OrdinalIgnoreCase))
{
Console.WriteLine("⚠️ Some suggestions exceeded budget, filtering...");
// Add validation logic here
}
Console.WriteLine("✅ Gift suggestions validated!");
return messages;
}
}
그런 다음 이 실행자를 워크플로에 삽입할 수 있습니다.
var validator = new GiftValidatorExecutor();
var workflow = new WorkflowBuilder(giftIdeaAgent)
.AddEdge(giftIdeaAgent, validator)
.AddEdge(validator, priceAgent)
.AddEdge(priceAgent, summaryAgent)
.WithOutputFrom(summaryAgent)
.Build();
Bing Grounding으로 실제 웹 검색 추가
지금까지 에이전트는 AI 모델의 지식을 기반으로 응답을 생성합니다. 하지만 실제 제품 가격과 재고 여부를 웹에서 검색하고 싶다면 어떻게 해야 할까요? Bing Search를 통한 접지가 필요한 곳입니다. 이는 에이전트가 응답을 생성할 때 실시간 공개 웹 데이터를 통합할 수 있도록 해주는 Microsoft Foundry(이전의 Azure AI Foundry)에서 사용할 수 있는 도구입니다.
먼저 Azure Portal에서 Bing Search를 통한 접지 리소스를 만들어야 합니다. AI 프로젝트와 동일한 리소스 그룹에 만들어야 합니다.
Bing Search를 사용하여 접지 설정
Bing Search를 통한 Grounding의 장점은 Azure AI 에이전트와 직접 통합된다는 것입니다. 에이전트는 사용자의 쿼리를 기반으로 검색 도구를 언제 사용할지 결정하고, 웹을 검색하고, 그 결과를 바탕으로 근거 있는 응답을 생성합니다.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
public static class BingGroundingSetup
{
public static async Task<PersistentAgent> CreateAgentWithBingGroundingAsync(
string projectEndpoint,
string modelDeploymentName,
string bingConnectionId)
{
// Create the Persistent Agents client
var agentClient = new PersistentAgentsClient(projectEndpoint, new DefaultAzureCredential());
// Configure the Bing Grounding tool
var bingGroundingTool = new BingGroundingToolDefinition(
new BingGroundingSearchToolParameters(
[new BingGroundingSearchConfiguration(bingConnectionId)]
)
);
// Create the agent with Bing Grounding enabled
var agent = await agentClient.Administration.CreateAgentAsync(
model: modelDeploymentName,
name: "ChristmasPriceHunter",
instructions: @"You are a Christmas gift price comparison specialist.
When given gift ideas, use Bing to search for:
- Current prices at major retailers (Amazon, Best Buy, Target, Walmart)
- Available discounts and holiday deals
- Shipping times to ensure delivery before Christmas
Always provide URLs to the products you find.
Highlight the best deals and recommend where to buy.",
tools: [bingGroundingTool]
);
return agent;
}
}
실제 검색으로 가격비교 에이전트 만들기
이제 웹에서 실제 제품 정보를 검색하는 완전한 가격 비교 에이전트를 만들어 보겠습니다.
using Azure.AI.Agents.Persistent;
using Azure.Identity;
public class ChristmasPriceAgent
{
private readonly PersistentAgentsClient _client;
private readonly string _modelDeployment;
private readonly string _bingConnectionId;
public ChristmasPriceAgent(string projectEndpoint, string modelDeployment, string bingConnectionId)
{
_client = new PersistentAgentsClient(projectEndpoint, new DefaultAzureCredential());
_modelDeployment = modelDeployment;
_bingConnectionId = bingConnectionId;
}
public async Task<string> FindGiftPricesAsync(string giftIdeas)
{
// Create agent with Bing Grounding
var bingTool = new BingGroundingToolDefinition(
new BingGroundingSearchToolParameters(
[new BingGroundingSearchConfiguration(_bingConnectionId)]
)
);
var agent = await _client.Administration.CreateAgentAsync(
model: _modelDeployment,
name: "PriceHunter",
instructions: @"Search the web for current prices on the given gift ideas.
For each gift, find prices from at least 2-3 different stores.
Include direct links to the products.
Note any Christmas sales or discounts available.",
tools: [bingTool]
);
try
{
// Create a thread for the conversation
var thread = await _client.Threads.CreateThreadAsync();
// Add the gift ideas as a message
await _client.Messages.CreateMessageAsync(
thread.Id,
MessageRole.User,
$"Find current prices for these gift ideas: {giftIdeas}"
);
// Run the agent
var run = await _client.Runs.CreateRunAsync(thread.Id, agent.Id);
// Wait for completion
do
{
await Task.Delay(500);
run = await _client.Runs.GetRunAsync(thread.Id, run.Id);
}
while (run.Status == RunStatus.Queued || run.Status == RunStatus.InProgress);
// Get the response
var messages = _client.Messages.GetMessages(thread.Id);
var response = messages
.Where(m => m.Role == MessageRole.Agent)
.SelectMany(m => m.ContentItems)
.OfType<MessageTextContent>()
.FirstOrDefault();
// Clean up
await _client.Threads.DeleteThreadAsync(thread.Id);
return response?.Text ?? "No results found.";
}
finally
{
// Clean up the agent
await _client.Administration.DeleteAgentAsync(agent.Id);
}
}
}
Bing Grounding을 작업 흐름에 통합
전체 선물 찾기 워크플로에서 Bing 기반 가격 에이전트를 사용하는 방법은 다음과 같습니다.
public static async Task RunWithBingGroundingAsync()
{
var projectEndpoint = Environment.GetEnvironmentVariable("PROJECT_ENDPOINT")!;
var modelDeployment = Environment.GetEnvironmentVariable("MODEL_DEPLOYMENT_NAME") ?? "gpt-4o";
var bingConnectionId = Environment.GetEnvironmentVariable("BING_CONNECTION_ID")!;
// Connection ID format: /subscriptions/{sub}/resourceGroups/{rg}/providers/Microsoft.CognitiveServices/accounts/{account}/projects/{project}/connections/{connection}
Console.WriteLine("🔍 Searching the web for real prices with Bing Grounding...\n");
var priceAgent = new ChristmasPriceAgent(projectEndpoint, modelDeployment, bingConnectionId);
// First, generate gift ideas (could come from another agent)
var giftIdeas = "1. Milwaukee cordless drill set, 2. Weber portable grill, 3. Carhartt beanie";
// Search for real prices
var priceResults = await priceAgent.FindGiftPricesAsync(giftIdeas);
Console.WriteLine("📊 Price Comparison Results:");
Console.WriteLine(priceResults);
Console.WriteLine("\n🎁 Happy Shopping! 🎁");
}
Bing 결과에서 인용 처리
Bing Search를 통한 접지의 중요한 측면 중 하나는 응답에 소스 웹 사이트에 대한 링크가 포함된 인용이 포함된다는 것입니다. 이를 추출하고 표시하는 방법은 다음과 같습니다.
public static void ProcessBingGroundingResponse(IEnumerable<PersistentThreadMessage> messages)
{
foreach (var message in messages.Where(m => m.Role == MessageRole.Agent))
{
foreach (var content in message.ContentItems)
{
if (content is MessageTextContent textContent)
{
var response = textContent.Text;
// Process URL citations
if (textContent.Annotations != null)
{
foreach (var annotation in textContent.Annotations)
{
if (annotation is MessageTextUriCitationAnnotation uriAnnotation)
{
// Replace citation placeholder with markdown link
response = response.Replace(
uriAnnotation.Text,
$" [{uriAnnotation.UriCitation.Title}]({uriAnnotation.UriCitation.Uri})"
);
}
}
}
Console.WriteLine(response);
}
}
}
}
이제 가격 비교 에이전트가 실행되면 Bing Search를 통한 접지를 사용하여 실제 제품 목록, 현재 가격 및 라이브 웹에서 사용 가능한 거래를 찾습니다. 에이전트는 쿼리를 기반으로 언제 검색할지 자동으로 결정하고 적절한 인용과 함께 근거 있는 응답을 반환합니다.
완전한 프로그램
Program.cs에서 모든 것이 하나로 합쳐지는 방법은 다음과 같습니다.
using Azure.AI.OpenAI;
using Azure.Identity;
using Microsoft.Agents.AI;
using Microsoft.Agents.AI.Workflows;
using Microsoft.Extensions.AI;
Console.WriteLine("🎄 Christmas Gift Finder - Powered by AI Agents 🎄\n");
var endpoint = Environment.GetEnvironmentVariable("AZURE_OPENAI_ENDPOINT")!;
var deployment = Environment.GetEnvironmentVariable("AZURE_OPENAI_DEPLOYMENT_NAME") ?? "gpt-4o-mini";
var chatClient = new AzureOpenAIClient(new Uri(endpoint), new DefaultAzureCredential())
.GetChatClient(deployment)
.AsIChatClient();
// Create the agent team
var ideaAgent = ChristmasAgentFactory.CreateGiftIdeaAgent(chatClient);
var priceAgent = ChristmasAgentFactory.CreatePriceComparisonAgent(chatClient);
var summaryAgent = ChristmasAgentFactory.CreateSummaryAgent(chatClient);
// Build the workflow
var workflow = AgentWorkflowBuilder.BuildSequential(
"ChristmasGiftWorkflow",
[ideaAgent, priceAgent, summaryAgent]);
Console.Write("Who are you shopping for? ");
var recipientName = Console.ReadLine() ?? "Someone special";
Console.Write("What are their interests? ");
var interests = Console.ReadLine() ?? "general";
Console.Write("What's your budget? $");
var budget = Console.ReadLine() ?? "50";
var prompt = $"Find Christmas gifts for {recipientName} who enjoys {interests}. Budget: ${budget}";
Console.WriteLine("\n🔍 Searching for the perfect gifts...\n");
await using var run = await InProcessExecution.StreamAsync(
workflow,
new ChatMessage(ChatRole.User, prompt));
await run.TrySendMessageAsync(new TurnToken(emitEvents: true));
await foreach (var evt in run.WatchStreamAsync())
{
switch (evt)
{
case AgentRunUpdateEvent update:
Console.Write(update.Update.Text);
break;
case WorkflowOutputEvent output:
Console.WriteLine("\n\n🎁 Happy Shopping! 🎁");
break;
}
}
결론
Microsoft의 에이전트 프레임워크를 사용하면 각 에이전트가 특정 작업을 전문으로 하는 다중 에이전트 시스템을 놀라울 정도로 쉽게 구축할 수 있습니다. 워크플로를 통해 이러한 에이전트를 조정함으로써 구조적이고 효율적인 방식으로 크리스마스 쇼핑과 같은 복잡한 문제를 해결할 수 있습니다.
이를 더욱 강력하게 만드는 것은 도구를 통해 실제 기능을 추가할 수 있는 능력입니다. Microsoft Foundry의 Grounding with Bing Search를 통합함으로써 당사의 가격 비교 에이전트는 실제로 웹에서 현재 가격, 거래 및 가용성을 검색할 수 있습니다. 이를 통해 간단한 AI 챗봇을 적절한 인용을 통해 진정으로 유용한 쇼핑 도우미로 탈바꿈시킬 수 있습니다.
순차, 동시 및 핸드오프 패턴에 대한 프레임워크의 지원은 사용자의 정확한 요구 사항에 맞는 에이전트 시스템을 설계할 수 있음을 의미합니다. 선물 찾기, 여행 계획 또는 기타 다단계 작업 등 무엇이든 에이전트 프레임워크는 이를 실현하는 데 필요한 구성 요소를 제공합니다.이번 휴가철에는 AI 에이전트에게 연구를 맡기고 선물 포장에 집중하고 가족과 함께 즐거운 시간을 보내세요!
소스 코드
이 게시물에 표시된 개념은 공식 Agent Framework 샘플을 기반으로 합니다. Microsoft Agent Framework GitHub 리포지토리에서 더 많은 예제를 탐색할 수 있습니다.
즐거운 휴일 보내시고 즐거운 코딩하세요! 🎄