<?xml version="1.0" encoding="utf-8" standalone="yes"?><rss version="2.0" xmlns:atom="http://www.w3.org/2005/Atom" xmlns:content="http://purl.org/rss/1.0/modules/content/"><channel><title>The .NET Blog</title><link>https://thedotnetblog.com/ko/</link><description>Articles, tutorials and insights from the .NET community.</description><generator>Hugo</generator><language>ko</language><managingEditor>@thedotnetblog (The .NET Blog)</managingEditor><webMaster>@thedotnetblog</webMaster><lastBuildDate>Mon, 14 Sep 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/ko/index.xml" rel="self" type="application/rss+xml"/><item><title>NDC Oslo 2026</title><link>https://thedotnetblog.com/ko/events/ndc-oslo-2026/</link><pubDate>Mon, 14 Sep 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/events/ndc-oslo-2026/</guid><description>유럽 최대의 개발자 컨퍼런스 중 하나 — Oslo Spektrum에서 5일간의 워크숍, 세션, 네트워킹. 150명 이상의 발표자와 160개 세션.</description><content:encoded>&lt;p&gt;&lt;strong&gt;NDC Oslo 2026&lt;/strong&gt;은 &lt;strong&gt;2026년 9월 14일~18일&lt;/strong&gt; 노르웨이 오슬로의 &lt;strong&gt;Oslo Spektrum&lt;/strong&gt;에서 개최됩니다.&lt;/p&gt;
&lt;p&gt;NDC Oslo는 유럽에서 가장 크고 존경받는 개발자 컨퍼런스 중 하나로, .NET, 클라우드, 보안, 아키텍처, AI 등 다양한 주제를 다룹니다. 2026년 에디션은 현재 예약 단계에 있으며, 대규모 라인업이 구성되고 있습니다.&lt;/p&gt;
&lt;h2 id="숫자로-보기"&gt;숫자로 보기&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;160개 세션&lt;/strong&gt; (예약 중)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;150명 발표자&lt;/strong&gt; (예약 중)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;15개 워크숍&lt;/strong&gt; (예약 중)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;5일간&lt;/strong&gt; — 워크숍 + 컨퍼런스&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="확정-발표자"&gt;확정 발표자&lt;/h2&gt;
&lt;p&gt;발표자 목록이 구성되고 있으며, 확정된 이름은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Nick Chapsas&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Maddy Montaquila&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Troy Hunt&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Kevlin Henney&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Venkat Subramaniam&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Jeff Fritz&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Philippe De Ryck&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Nhlanhla Lucky Nkosi&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Aleksander Stensby&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="티켓"&gt;티켓&lt;/h2&gt;
&lt;p&gt;Early Bird 티켓이 판매 중 — Early Bird 혜택은 &lt;strong&gt;2026년 5월 22일&lt;/strong&gt;에 종료됩니다.&lt;/p&gt;
&lt;p&gt;CFP (Call for Papers)도 진행 중입니다.&lt;/p&gt;
&lt;h2 id="2026년-다른-ndc-이벤트"&gt;2026년 다른 NDC 이벤트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;NDC Sydney — 2026년 4월 22일~24일&lt;/li&gt;
&lt;li&gt;NDC Toronto — 2026년 5월 5일~8일&lt;/li&gt;
&lt;li&gt;NDC Copenhagen — 2026년 6월 1일~4일&lt;/li&gt;
&lt;li&gt;NDC AI — 2026년 6월 8일~10일&lt;/li&gt;
&lt;li&gt;NDC TechTown — 2026년 9월 21일~24일&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="링크"&gt;링크&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/"&gt;이벤트 웹사이트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/tickets"&gt;티켓&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/call-for-papers"&gt;Call for Papers&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://ndcoslo.com/speakers"&gt;발표자&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>.NET Day Switzerland 2026</title><link>https://thedotnetblog.com/ko/events/dotnet-day-switzerland-2026/</link><pubDate>Tue, 25 Aug 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/events/dotnet-day-switzerland-2026/</guid><description>.NET 개발자, 아키텍트, 전문가를 위한 비영리 커뮤니티 컨퍼런스 — .NET, C#, ASP.NET Core, Azure 등을 다루며 — 취리히에서 개최됩니다.</description><content:encoded>&lt;p&gt;&lt;strong&gt;.NET Day Switzerland 2026&lt;/strong&gt;은 &lt;strong&gt;2026년 8월 25일&lt;/strong&gt; &lt;strong&gt;Arena Cinemas Sihlcity&lt;/strong&gt;(Kalanderplatz 8, 8045 취리히)에서 개최됩니다.&lt;/p&gt;
&lt;p&gt;개발자, 아키텍트, 전문가가 .NET, C#, ASP.NET Core, Azure 등 Microsoft 개발 생태계 전반에 대해 논의하는 독립적인 비영리 커뮤니티 컨퍼런스입니다. 모든 발표자와 스태프는 자원봉사로 참여하며, 티켓 판매 잉여금은 자선 단체 또는 스위스 .NET 커뮤니티에 기부됩니다.&lt;/p&gt;
&lt;h2 id="참가자-혜택"&gt;참가자 혜택&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;국제 전문가의 고품질 세션&lt;/li&gt;
&lt;li&gt;다른 참가자와의 네트워킹&lt;/li&gt;
&lt;li&gt;휴식 시간, 점심, 아페로 중 음식과 음료&lt;/li&gt;
&lt;li&gt;스폰서 교류를 통한 커리어 기회&lt;/li&gt;
&lt;li&gt;휴식 시간에 발표자와 직접 대화&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="티켓"&gt;티켓&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;종류&lt;/th&gt;
&lt;th&gt;가격&lt;/th&gt;
&lt;th&gt;판매 현황&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;Very Early Bird (4월 1일–30일)&lt;/td&gt;
&lt;td&gt;299 CHF&lt;/td&gt;
&lt;td&gt;최대 100매&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Early Bird&lt;/td&gt;
&lt;td&gt;399 CHF&lt;/td&gt;
&lt;td&gt;최대 100매&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;일반&lt;/td&gt;
&lt;td&gt;449 CHF&lt;/td&gt;
&lt;td&gt;매진 시까지&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;발표자와 일정은 아직 발표되지 않았습니다 — 발표자 모집은 &lt;a href="https://sessionize.com/net-day-switzerland-2026/"&gt;Sessionize&lt;/a&gt;에서 진행 중입니다.&lt;/p&gt;
&lt;h2 id="주최자"&gt;주최자&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://twitter.com/FabianGosebrink"&gt;Fabian Gosebrink&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/manumeyer1"&gt;Manuel Meyer&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://twitter.com/gassmannt"&gt;Thomas Gassmann&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="링크"&gt;링크&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://dotnetday.ch/"&gt;이벤트 웹사이트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="http://eepurl.com/dDoFEn"&gt;뉴스레터 구독&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;</content:encoded></item><item><title>SDD Conference 2026</title><link>https://thedotnetblog.com/ko/events/sdd-conference-2026/</link><pubDate>Mon, 11 May 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/events/sdd-conference-2026/</guid><description>런던 Barbican Centre에서 열리는 5일간의 소프트웨어 개발 컨퍼런스 — 78개 세션과 14개 워크숍으로 아키텍처, .NET, AI, Azure, DevOps 등을 다룹니다.</description><content:encoded>&lt;p&gt;&lt;strong&gt;SDD 2026&lt;/strong&gt;은 &lt;strong&gt;2026년 5월 11일~15일&lt;/strong&gt; &lt;strong&gt;런던의 Barbican Centre&lt;/strong&gt;에서 개최됩니다. 3일간의 핵심 컨퍼런스는 화요일부터 목요일까지이며, 월요일과 금요일에는 선택적 전일 워크숍이 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;78개 세션&lt;/strong&gt;과 &lt;strong&gt;14개 워크숍&lt;/strong&gt;을 갖춘 유럽에서 가장 알찬 개발자 컨퍼런스 중 하나입니다.&lt;/p&gt;
&lt;h2 id="주제"&gt;주제&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;아키텍처적 사고&lt;/li&gt;
&lt;li&gt;C# 13에서의 함수형 코드&lt;/li&gt;
&lt;li&gt;서버리스 디자인&lt;/li&gt;
&lt;li&gt;시맨틱 AI&lt;/li&gt;
&lt;li&gt;Azure Kubernetes Services&lt;/li&gt;
&lt;li&gt;린 DevOps 전략&lt;/li&gt;
&lt;li&gt;모델 컨텍스트 프로토콜 (MCP)&lt;/li&gt;
&lt;li&gt;.NET에서의 에이전틱 AI&lt;/li&gt;
&lt;li&gt;모놀리스 리팩토링&lt;/li&gt;
&lt;li&gt;LLM으로 더 빠르게 코딩&lt;/li&gt;
&lt;li&gt;포스트 양자 세계의 암호학&lt;/li&gt;
&lt;li&gt;로컬 퍼스트 개발&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="발표자"&gt;발표자&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Kevlin Henney&lt;/strong&gt;, &lt;strong&gt;Neal Ford&lt;/strong&gt;, &lt;strong&gt;Sander Hoogendoorn&lt;/strong&gt;, &lt;strong&gt;Andrew Clymer&lt;/strong&gt;, &lt;strong&gt;Jacqui Read&lt;/strong&gt;, &lt;strong&gt;Christian Weyer&lt;/strong&gt;, &lt;strong&gt;Jeff Prosise&lt;/strong&gt;, &lt;strong&gt;Jules May&lt;/strong&gt;, &lt;strong&gt;Oliver Sturm&lt;/strong&gt;, &lt;strong&gt;Raju Gandhi&lt;/strong&gt;를 포함한 세계적 수준의 라인업.&lt;/p&gt;
&lt;h2 id="티켓-및-정보"&gt;티켓 및 정보&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/"&gt;이벤트 웹사이트&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddvault.s3.amazonaws.com/assets/SDD_2026_schedule.pdf"&gt;전체 어젠다 PDF&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://sddconf.com/register"&gt;등록 옵션&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;SDD 2025 참가자의 98%가 전체 경험을 좋음, 매우 좋음 또는 우수로 평가했습니다.&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps MCP 서버 4월 업데이트: WIQL 쿼리, PAT 인증, 실험적 MCP Apps</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/</link><pubDate>Mon, 27 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/</guid><description>Azure DevOps MCP 서버가 WIQL 기반 work item 쿼리, Personal Access Token 인증, MCP 어노테이션, 그리고 일반 워크플로우를 재사용 가능한 도구로 패키징하는 실험적 MCP Apps 기능을 받았습니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/azure-devops-mcp-server-april-2026-wiql-pat-apps/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Azure DevOps MCP 서버가 계속 개선되고 있습니다. Dan Hellem의 4월 업데이트는 로컬 및 원격 서버 모두를 다룹니다.&lt;/p&gt;
&lt;h2 id="wiql-쿼리-지원"&gt;WIQL 쿼리 지원&lt;/h2&gt;
&lt;p&gt;새로운 &lt;code&gt;wit_query_by_wiql&lt;/code&gt; 도구로 MCP 클라이언트에서 직접 Work Item Query Language 쿼리를 실행할 수 있습니다.&lt;/p&gt;
&lt;h2 id="personal-access-tokens"&gt;Personal Access Tokens&lt;/h2&gt;
&lt;p&gt;로컬 서버에서 PAT 인증 — 대화형 인증이 불가능한 통합 시나리오에 중요합니다.&lt;/p&gt;
&lt;h2 id="mcp-어노테이션"&gt;MCP 어노테이션&lt;/h2&gt;
&lt;p&gt;읽기 전용, 파괴적, 오픈 월드 도구를 위한 메타데이터 태그 — 에이전트 신뢰성의 기반.&lt;/p&gt;
&lt;h2 id="wiki-도구-통합"&gt;Wiki 도구 통합&lt;/h2&gt;
&lt;p&gt;5개의 별도 wiki 도구 → 2개의 더 강력한 도구. 도구가 적을수록 LLM 성능이 향상됩니다.&lt;/p&gt;
&lt;h2 id="실험적-mcp-apps"&gt;실험적: MCP Apps&lt;/h2&gt;
&lt;p&gt;MCP 서버 환경 내의 패키징된 워크플로우. 방향은 맞습니다.&lt;/p&gt;
&lt;p&gt;Dan Hellem의 원본 포스트: &lt;a href="https://devblogs.microsoft.com/devops/azure-devops-mcp-server-april-update/"&gt;Azure DevOps MCP Server April Update&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>SQL Server 2025: 에이전트 준비 데이터베이스 — 하나의 엔진에서 보안, 백업, MCP</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/</link><pubDate>Sun, 26 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/</guid><description>Polyglot Tax 시리즈의 마지막 편은 어려운 프로덕션 문제를 다룹니다: 관계형, JSON, 그래프, 벡터 데이터 전반에 걸친 통합 Row-Level Security, 그리고 MCP 통합.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/sql-server-2025-agent-ready-security-mcp/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Aditya Badramraju의 Polyglot Tax 시리즈를 많은 관심으로 팔로우해왔습니다. 파트 4는 이 아키텍처를 프로덕션에서 신뢰할지 실제로 결정하는 부분으로 시리즈를 마무리합니다.&lt;/p&gt;
&lt;h2 id="모든-데이터-모델을-위한-단일-보안-모델"&gt;모든 데이터 모델을 위한 단일 보안 모델&lt;/h2&gt;
&lt;p&gt;하나의 Row-Level Security 정책으로 모든 데이터 모델을 커버. 감사인에게 하나의 정책, 하나의 증명.&lt;/p&gt;
&lt;h2 id="통합-백업--원자적-복구"&gt;통합 백업 = 원자적 복구&lt;/h2&gt;
&lt;p&gt;폴리글롯 스택에서 5개 데이터베이스의 특정 시점 복구를 조율하는 것은 일관성 악몽입니다. 하나의 데이터베이스로는 정의상 원자적입니다.&lt;/p&gt;
&lt;h2 id="mcp-통합-수동-코딩된-미들웨어-없이"&gt;MCP 통합: 수동 코딩된 미들웨어 없이&lt;/h2&gt;
&lt;p&gt;SQL Server 2025는 SQL MCP 서버를 직접 지원합니다. 에이전트가 도구를 호출하면, 엔진이 자동으로 테넌트 격리와 컬럼 마스킹을 강제합니다.&lt;/p&gt;
&lt;p&gt;Aditya Badramraju의 원본 포스트: &lt;a href="https://devblogs.microsoft.com/azure-sql/the-polyglot-tax-part-4/"&gt;The Polyglot Tax – Part 4&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>.NET 10이 Ubuntu 26.04 LTS에 탑재됐다 — 새로운 것들</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/</guid><description>Ubuntu 26.04 LTS (Resolute Raccoon)가 .NET 10을 일급 도구체인으로 탑재했습니다. Native AOT, Chiseled 컨테이너, Linux 7.0.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원문을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-ubuntu-2604-resolute-raccoon-net10/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Ubuntu LTS의 날입니다. &lt;a href="https://canonical.com/blog/canonical-releases-ubuntu-26-04-lts-resolute-raccoon"&gt;Ubuntu 26.04 (Resolute Raccoon)&lt;/a&gt;이 오늘 출시됐으며, 모든 Ubuntu LTS처럼 최신 .NET LTS — 이번에는 &lt;a href="https://devblogs.microsoft.com/dotnet/whats-new-for-dotnet-in-ubuntu-2604/"&gt;.NET 10&lt;/a&gt; — 을 탑재합니다.&lt;/p&gt;
&lt;h2 id="net-10을-두-명령으로-설치"&gt;.NET 10을 두 명령으로 설치&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt update
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sudo apt install dotnet-sdk-10.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;.NET은 &lt;a href="https://ubuntu.com/toolchains"&gt;Ubuntu에서 공식 지원하는 도구체인&lt;/a&gt; 중 하나입니다.&lt;/p&gt;
&lt;h2 id="컨테이너--noble을--resolute로-업데이트"&gt;컨테이너: &lt;code&gt;-noble&lt;/code&gt;을 &lt;code&gt;-resolute&lt;/code&gt;로 업데이트&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;sed -i &lt;span class="s2"&gt;&amp;#34;s/noble/resolute/g&amp;#34;&lt;/span&gt; Dockerfile
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="native-aot-3ms-시작-14mb-바이너리"&gt;Native AOT: 3ms 시작, 1.4MB 바이너리&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y dotnet-sdk-aot-10.0 clang
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet publish app.cs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 1.4MB 네이티브 바이너리, 3ms 시작&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;콜드 스타트 시간이 중요한 클라우드 네이티브 워크로드 — Functions, 컨테이너, 서버리스 — 에서 진정한 게임 체인저입니다.&lt;/p&gt;
&lt;h2 id="net-8-또는-9가-필요한가요"&gt;.NET 8 또는 9가 필요한가요?&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y software-properties-common
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;add-apt-repository ppa:dotnet/backports
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;apt install -y dotnet-sdk-8.0
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/whats-new-for-dotnet-in-ubuntu-2604/"&gt;전체 게시물&lt;/a&gt;에서 cgroup v2, 포스트-퀀텀 암호화, Linux 7.0에 대한 자세한 내용을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Agent Framework의 CodeAct: 에이전트 지연 시간을 절반으로 줄이는 방법</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/</guid><description>CodeAct는 다단계 도구 체인을 단일 샌드박스 코드 블록으로 압축합니다 — 지연 시간 52% 감소, 토큰 사용량 64% 감소. 에이전트에 미치는 영향과 사용 시기를 알아보세요.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동으로 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/codeact-agent-framework-hyperlight-50-percent-faster/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;모든 에이전트 프로젝트에서 트레이스를 보며 &amp;ldquo;왜 이렇게 오래 걸리는 거야?&amp;ldquo;라고 생각하는 순간이 있습니다. 모델은 괜찮고, 도구도 작동합니다. 하지만 한 번에 계산할 수 있는 결과를 위해 일곱 번의 왕복이 발생합니다.&lt;/p&gt;
&lt;p&gt;이것이 바로 CodeAct가 해결하는 문제입니다. &lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;Agent Framework 팀이 새 &lt;code&gt;agent-framework-hyperlight&lt;/code&gt; 패키지를 통해 알파 지원을 출시&lt;/a&gt;했습니다.&lt;/p&gt;
&lt;h2 id="codeact란"&gt;CodeAct란?&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://arxiv.org/abs/2402.01030"&gt;CodeAct 패턴&lt;/a&gt;은 우아하게 단순합니다. 모델에 도구 목록을 주고 하나씩 호출하게 하는 대신, 단일 &lt;code&gt;execute_code&lt;/code&gt; 도구를 주고 &lt;em&gt;전체 계획&lt;/em&gt;을 짧은 Python 프로그램으로 표현하게 합니다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;방식&lt;/th&gt;
&lt;th&gt;시간&lt;/th&gt;
&lt;th&gt;토큰&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;기존 방식&lt;/td&gt;
&lt;td&gt;27.81초&lt;/td&gt;
&lt;td&gt;6,890&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CodeAct&lt;/td&gt;
&lt;td&gt;13.23초&lt;/td&gt;
&lt;td&gt;2,489&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;개선&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;52.4%&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;63.9%&lt;/strong&gt;&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="보안-hyperlight-마이크로-vm"&gt;보안: Hyperlight 마이크로 VM&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;agent-framework-hyperlight&lt;/code&gt; 패키지는 &lt;a href="https://github.com/hyperlight-dev/hyperlight"&gt;Hyperlight&lt;/a&gt; 마이크로 VM을 사용합니다. 각 &lt;code&gt;execute_code&lt;/code&gt; 호출은 자체 새로운 마이크로 VM을 받습니다. 시작 시간은 밀리초 단위입니다. 격리는 사실상 무료입니다.&lt;/p&gt;
&lt;p&gt;도구는 계속 호스트에서 실행됩니다. 모델이 생성한 &lt;em&gt;글루 코드&lt;/em&gt;는 샌드박스에서 실행됩니다. 올바른 분리입니다.&lt;/p&gt;
&lt;h2 id="최소-설정"&gt;최소 설정&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework_hyperlight&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nd"&gt;@tool&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;def&lt;/span&gt; &lt;span class="nf"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="o"&gt;-&amp;gt;&lt;/span&gt; &lt;span class="nb"&gt;dict&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="nb"&gt;float&lt;/span&gt; &lt;span class="o"&gt;|&lt;/span&gt; &lt;span class="nb"&gt;str&lt;/span&gt;&lt;span class="p"&gt;]:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;&amp;#34;&amp;#34;Return the current weather for a city.&amp;#34;&amp;#34;&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;city&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;city&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;temperature_c&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="mf"&gt;21.5&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;conditions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;partly cloudy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;codeact&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HyperlightCodeActProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_weather&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;approval_mode&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;never_require&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Agent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;CodeActAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;context_providers&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;codeact&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="codeact-사용-시기-그리고-사용하지-않을-때"&gt;CodeAct 사용 시기 (그리고 사용하지 않을 때)&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;CodeAct를 사용하는 경우:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;많은 소규모 도구 호출을 연결하는 작업 (조회, 조인, 계산)&lt;/li&gt;
&lt;li&gt;지연 시간과 토큰 비용이 중요한 경우&lt;/li&gt;
&lt;li&gt;모델 생성 코드에 강력한 격리가 필요한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;strong&gt;기존 도구 호출을 사용하는 경우:&lt;/strong&gt;&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;에이전트가 턴당 한두 번만 도구를 호출하는 경우&lt;/li&gt;
&lt;li&gt;각 호출에 개별 승인이 필요한 부작용이 있는 경우&lt;/li&gt;
&lt;li&gt;도구 설명이 부족하거나 모호한 경우&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="지금-시도해보세요"&gt;지금 시도해보세요&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install agent-framework-hyperlight --pre
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/agent-framework/codeact-with-hyperlight/"&gt;Agent Framework 블로그의 전체 게시물&lt;/a&gt;에서 심층적인 내용을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 이제 .mcpb — 런타임 없이 설치하기</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/</guid><description>Azure MCP Server가 MCP Bundle(.mcpb)로 제공됩니다 — 다운로드하고 Claude Desktop에 드래그하면 끝. Node.js, Python, .NET 불필요.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원문을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-mcpb-no-runtime-install/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;MCP 서버 설정에서 번거로웠던 것이 무엇인지 아시나요? 런타임이 필요했습니다. npm 버전에는 Node.js, pip/uvx에는 Python, dotnet 버전에는 .NET SDK.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;Azure MCP Server가 이를 바꿨습니다&lt;/a&gt;. 이제 &lt;code&gt;.mcpb&lt;/code&gt; — MCP Bundle — 로 제공되며 설정은 드래그 앤 드롭입니다.&lt;/p&gt;
&lt;h2 id="mcp-bundle이란"&gt;MCP Bundle이란?&lt;/h2&gt;
&lt;p&gt;VS Code 확장(&lt;code&gt;.vsix&lt;/code&gt;)이나 브라우저 확장(&lt;code&gt;.crx&lt;/code&gt;)처럼 생각하세요. 단, MCP 서버용입니다. &lt;code&gt;.mcpb&lt;/code&gt; 파일은 서버 바이너리와 모든 종속성을 포함한 독립적인 ZIP 아카이브입니다.&lt;/p&gt;
&lt;h2 id="설치-방법"&gt;설치 방법&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1. 플랫폼용 번들 다운로드&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server"&gt;GitHub Releases 페이지&lt;/a&gt;에서 OS와 아키텍처에 맞는 &lt;code&gt;.mcpb&lt;/code&gt; 파일을 다운로드합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;2. Claude Desktop에 설치&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;가장 쉬운 방법: 확장 설정 페이지(&lt;code&gt;☰ → 파일 → 설정 → 확장&lt;/code&gt;)가 열린 상태에서 &lt;code&gt;.mcpb&lt;/code&gt; 파일을 Claude Desktop 창에 드래그 앤 드롭합니다. 서버 세부 정보를 확인하고 설치를 클릭합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;3. Azure 인증&lt;/strong&gt;&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;az login
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;끝입니다. Azure MCP Server는 기존 Azure 자격 증명을 사용합니다.&lt;/p&gt;
&lt;h2 id="할-수-있는-것"&gt;할 수 있는 것&lt;/h2&gt;
&lt;p&gt;AI 클라이언트에서 직접 100개 이상의 Azure 서비스 도구에 접근:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;Cosmos DB, Storage, Key Vault, App Service, Foundry 쿼리 및 관리&lt;/li&gt;
&lt;li&gt;모든 작업을 위한 &lt;code&gt;az&lt;/code&gt; CLI 명령 생성&lt;/li&gt;
&lt;li&gt;Bicep 및 Terraform 템플릿 생성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="시작하기"&gt;시작하기&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;다운로드&lt;/strong&gt;: &lt;a href="https://github.com/microsoft/mcp/releases?q=Azure.Mcp.Server-"&gt;GitHub Releases&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;저장소&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp"&gt;aka.ms/azmcp&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문서&lt;/strong&gt;: &lt;a href="https://aka.ms/azmcp/docs"&gt;aka.ms/azmcp/docs&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-mcp-server-mcpb-support/"&gt;전체 게시물&lt;/a&gt;을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure SDK 2026년 4월: AI Foundry 2.0과 .NET 개발자가 알아야 할 것들</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/</guid><description>2026년 4월 Azure SDK 릴리스는 중요한 breaking changes가 포함된 Azure.AI.Projects 2.0.0 안정 버전, Cosmos DB 치명적 보안 수정, 그리고 .NET을 위한 새로운 Provisioning 라이브러리를 제공합니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/azure-sdk-april-2026-ai-foundry-2-stable/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;월간 SDK 릴리스는 종종 무시하기 쉽습니다. 이번에는 주목할 몇 가지가 있습니다.&lt;/p&gt;
&lt;h2 id="azureaiprojects-200--의미있는-breaking-changes"&gt;Azure.AI.Projects 2.0.0 — 의미있는 Breaking Changes&lt;/h2&gt;
&lt;p&gt;네임스페이스 분리, 타입 이름 변경, 불리언 속성의 일관된 &lt;code&gt;Is*&lt;/code&gt; 규칙.&lt;/p&gt;
&lt;h2 id="cosmos-db-java-치명적-보안-수정-rce"&gt;Cosmos DB Java: 치명적 보안 수정 (RCE)&lt;/h2&gt;
&lt;p&gt;버전 4.79.0에서 &lt;strong&gt;원격 코드 실행 취약점 (CWE-502)&lt;/strong&gt; 치명적 수정. 즉시 업데이트하세요.&lt;/p&gt;
&lt;h2 id="net을-위한-새-provisioning-라이브러리"&gt;.NET을 위한 새 Provisioning 라이브러리&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/Azure.Provisioning.Network/1.0.0"&gt;Azure.Provisioning.Network 1.0.0&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://www.nuget.org/packages/Azure.Provisioning.PrivateDns/1.0.0"&gt;Azure.Provisioning.PrivateDns 1.0.0&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;원본 포스트: &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-sdk-release-april-2026/"&gt;Azure SDK Release (April 2026)&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>GPT-5.5가 Azure Foundry에 출시됐다 — .NET 개발자가 알아야 할 것들</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/</guid><description>GPT-5.5가 Microsoft Foundry에서 일반 출시됐습니다. GPT-5에서 5.5로의 발전, 실제로 무엇이 개선됐는지, 오늘 에이전트에서 사용하는 방법.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원문을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/gpt-55-foundry-ga-what-dotnet-developers-need-to-know/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Microsoft가 &lt;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;GPT-5.5가 Microsoft Foundry에서 일반 출시됐다고 발표했습니다&lt;/a&gt;. Azure에서 에이전트를 구축해 왔다면, 이것이 기다리던 업데이트입니다.&lt;/p&gt;
&lt;h2 id="gpt-5-발전-과정"&gt;GPT-5 발전 과정&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-5&lt;/strong&gt;: 추론과 속도를 단일 시스템으로 통합&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.4&lt;/strong&gt;: 더 강력한 다단계 추론, 기업용 초기 에이전트 기능&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-5.5&lt;/strong&gt;: 더 깊은 장문맥 추론, 더 신뢰할 수 있는 에이전트 실행, 향상된 토큰 효율성&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="실제로-무엇이-바뀌었나"&gt;실제로 무엇이 바뀌었나&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;향상된 에이전트 코딩&lt;/strong&gt;: GPT-5.5는 대규모 코드베이스 전체에서 컨텍스트를 유지하고, 아키텍처 수준 오류를 진단하며, 테스트 요구사항을 예측합니다. 수정이 &lt;em&gt;다른 무엇에&lt;/em&gt; 영향을 미치는지 행동 전에 추론합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;토큰 효율성&lt;/strong&gt;: 더 적은 토큰과 더 적은 재시도로 더 높은 품질의 출력. 프로덕션 배포에서 비용과 지연이 직접 감소합니다.&lt;/p&gt;
&lt;h2 id="가격"&gt;가격&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;모델&lt;/th&gt;
&lt;th&gt;입력 ($/M tokens)&lt;/th&gt;
&lt;th&gt;캐시 입력&lt;/th&gt;
&lt;th&gt;출력 ($/M tokens)&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5&lt;/td&gt;
&lt;td&gt;$5.00&lt;/td&gt;
&lt;td&gt;$0.50&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.5 Pro&lt;/td&gt;
&lt;td&gt;$30.00&lt;/td&gt;
&lt;td&gt;$3.00&lt;/td&gt;
&lt;td&gt;$180.00&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="foundry가-중요한-이유"&gt;Foundry가 중요한 이유&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service를 사용하면 YAML로 에이전트를 정의하거나 Microsoft Agent Framework, GitHub Copilot SDK, LangGraph 또는 OpenAI Agents SDK와 연결할 수 있습니다. 영구 파일시스템, 별도의 Microsoft Entra 아이덴티티, 제로 스케일 가격으로 격리된 호스팅 에이전트로 실행합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;aiProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.5&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;당신은 유용한 어시스턴트입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;내에이전트&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;a href="https://azure.microsoft.com/en-us/blog/openais-gpt-5-5-in-microsoft-foundry-frontier-intelligence-on-an-enterprise-ready-platform/"&gt;전체 발표&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.118: Copilot CLI에 세션 이름, 모델 배지, TypeScript 7.0 나이틀리 옵트인 추가</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/</guid><description>Visual Studio Code 1.118은 Copilot CLI 개선에 집중한 릴리스 — 세션 명명, 모델 배지, 자동 모델 선택, TypeScript 7.0 나이틀리 옵트인.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 포스트는 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-118-copilot-cli-session-names-model-badge/"&gt;여기&lt;/a&gt;를 클릭하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_118"&gt;Visual Studio Code 1.118&lt;/a&gt;은 작지만 집중된 릴리스입니다 — 주로 Copilot CLI 개선에 관한 것이지만 몇 가지 주목할 점이 있습니다.&lt;/p&gt;
&lt;h2 id="copilot-cli-세션에-진짜-이름-붙기"&gt;Copilot CLI: 세션에 진짜 이름 붙기&lt;/h2&gt;
&lt;p&gt;Copilot CLI SDK 세션 타이틀 API가 이제 세션 이름의 진실 소스로 사용됩니다. 자동 생성된 레이블 대신 SDK의 실제 이름이 표시됩니다.&lt;/p&gt;
&lt;h2 id="키보드-단축키로-세션-빠르게-전환"&gt;키보드 단축키로 세션 빠르게 전환&lt;/h2&gt;
&lt;p&gt;Agents 앱에 이제 &lt;code&gt;Ctrl+1&lt;/code&gt;, &lt;code&gt;Ctrl+2&lt;/code&gt; 등의 세션 전환 키가 바인딩되었습니다.&lt;/p&gt;
&lt;h2 id="채팅에-모델-배지-표시"&gt;채팅에 모델 배지 표시&lt;/h2&gt;
&lt;p&gt;채팅 패널의 Copilot CLI 응답에 이제 모델 배지가 표시됩니다 — 각 요청을 어떤 모델이 처리했는지 한눈에 볼 수 있습니다.&lt;/p&gt;
&lt;h2 id="copilot-cli에-자동-모델-선택"&gt;Copilot CLI에 자동 모델 선택&lt;/h2&gt;
&lt;p&gt;자동 모델 선택 기능이 이제 Copilot CLI 에이전트에서도 작동합니다.&lt;/p&gt;
&lt;h2 id="typescript-70-나이틀리-옵트인"&gt;TypeScript 7.0 나이틀리 옵트인&lt;/h2&gt;
&lt;p&gt;이제 VS Code 설정에서 직접 TypeScript 7.0 나이틀리 테스트에 옵트인할 수 있습니다. TypeScript 7.0은 대규모 릴리스입니다(&lt;a href="https://devblogs.microsoft.com/typescript/announcing-typescript-7-0-beta/"&gt;베타가 며칠 전 출시&lt;/a&gt;).&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_118"&gt;전체 릴리스 노트&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>당신의 에이전트는 어디서 기억하나요? 채팅 기록 저장소 실용 가이드</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</link><pubDate>Sat, 25 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/</guid><description>서비스 관리형 vs 클라이언트 관리형? 선형 vs 분기형? AI 에이전트가 실제로 무엇을 할 수 있는지 결정하는 아키텍처 결정 — C#과 Python 코드 예제 포함.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원문을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/chat-history-storage-patterns-agent-framework/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;AI 에이전트를 구축할 때 대부분의 에너지를 모델, 도구, 프롬프트에 씁니다. &lt;em&gt;대화 기록이 어디에 저장되는가&lt;/em&gt;라는 질문은 구현 세부사항처럼 보이지만, 실제로 가장 중요한 아키텍처 결정 중 하나입니다.&lt;/p&gt;
&lt;p&gt;이 결정은 사용자가 대화를 분기할 수 있는지, 응답을 취소할 수 있는지, 재시작 후 세션을 재개할 수 있는지, 그리고 데이터가 인프라를 벗어나는지를 결정합니다. &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;Agent Framework 팀이 심층 분석을 공개했습니다&lt;/a&gt;.&lt;/p&gt;
&lt;h2 id="두-가지-기본-패턴"&gt;두 가지 기본 패턴&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;서비스 관리형&lt;/strong&gt;: AI 서비스가 대화 상태를 저장합니다. 앱은 참조를 유지하고 서비스가 각 요청에 관련 기록을 자동으로 포함시킵니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;클라이언트 관리형&lt;/strong&gt;: 앱이 전체 기록을 유지하고 각 요청마다 관련 메시지를 보냅니다. 서비스는 무상태입니다. 모든 것을 제어합니다.&lt;/p&gt;
&lt;h2 id="agent-framework의-추상화-방식"&gt;Agent Framework의 추상화 방식&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;내 이름은 Alice입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;내 이름이 뭔가요?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_session&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;first&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;내 이름은 Alice입니다.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;second&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;내 이름이 뭔가요?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="공급자-빠른-참조"&gt;공급자 빠른 참조&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;공급자&lt;/th&gt;
&lt;th&gt;저장 위치&lt;/th&gt;
&lt;th&gt;모델&lt;/th&gt;
&lt;th&gt;압축&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;OpenAI/Azure Chat Completions&lt;/td&gt;
&lt;td&gt;클라이언트&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;당신&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Foundry Agent Service&lt;/td&gt;
&lt;td&gt;서비스&lt;/td&gt;
&lt;td&gt;선형&lt;/td&gt;
&lt;td&gt;서비스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Responses API (기본값)&lt;/td&gt;
&lt;td&gt;서비스&lt;/td&gt;
&lt;td&gt;분기형&lt;/td&gt;
&lt;td&gt;서비스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Anthropic Claude, Ollama&lt;/td&gt;
&lt;td&gt;클라이언트&lt;/td&gt;
&lt;td&gt;N/A&lt;/td&gt;
&lt;td&gt;당신&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="선택-방법"&gt;선택 방법&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;분기 또는 &amp;ldquo;취소&amp;rdquo; 기능이 필요한가?&lt;/strong&gt; → 서비스 관리형 Responses API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 주권이 필요한가?&lt;/strong&gt; → 데이터베이스 백엔드가 있는 클라이언트 관리형&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단순 챗봇인가?&lt;/strong&gt; → 서비스 관리형 선형으로 충분&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;전체 의사결정 트리를 보려면 &lt;a href="https://devblogs.microsoft.com/agent-framework/chat-history-storage-patterns-in-microsoft-agent-framework/"&gt;전체 게시물&lt;/a&gt;을 읽어보세요.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2: Bun 지원, 더 나은 컨테이너, 그리고 적은 디버깅 마찰</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/</link><pubDate>Fri, 24 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/</guid><description>Aspire 13.2은 Vite 앱에 일급 Bun 지원을 추가하고, Yarn 안정성을 수정하며, 로컬 개발 동작을 더 예측 가능하게 만드는 컨테이너 개선 사항을 제공합니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/aspire-132-bun-container-enhancements/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;.NET 백엔드와 JavaScript 프론트엔드를 Aspire에서 구축하고 있다면, 13.2는 조용히 하루를 더 나게 만드는 업데이트입니다.&lt;/p&gt;
&lt;h2 id="bun이-이제-일급-시민입니다"&gt;Bun이 이제 일급 시민입니다&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withBun&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;팀이 이미 Bun을 사용한다면, Aspire는 더 이상 역류를 강요하지 않습니다.&lt;/p&gt;
&lt;h2 id="yarn이-더-안정적으로"&gt;Yarn이 더 안정적으로&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;withYarn()&lt;/code&gt;과 &lt;code&gt;addViteApp()&lt;/code&gt;에서 신비한 실패가 줄어듭니다.&lt;/p&gt;
&lt;h2 id="컨테이너-개선"&gt;컨테이너 개선&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;ImagePullPolicy.Never&lt;/code&gt;로 레지스트리 없이 로컬 이미지 사용. PostgreSQL 18+ 데이터 볼륨이 이제 올바르게 작동합니다.&lt;/p&gt;
&lt;h2 id="디버깅-개선"&gt;디버깅 개선&lt;/h2&gt;
&lt;p&gt;코어 타입에 &lt;code&gt;DebuggerDisplayAttribute&lt;/code&gt;, &lt;code&gt;WaitFor&lt;/code&gt;의 개선된 오류 메시지, 올바른 타이밍에 발화하는 &lt;code&gt;BeforeResourceStartedEvent&lt;/code&gt;.&lt;/p&gt;
&lt;p&gt;David Pine의 원본 포스트: &lt;a href="https://devblogs.microsoft.com/aspire/aspire-bun-support-and-container-enhancements/"&gt;Aspire 13.2: Bun Support and Container Enhancements&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>Foundry Toolboxes: AI 에이전트 도구를 위한 단일 엔드포인트</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/</guid><description>Microsoft Foundry가 Toolboxes를 공개 프리뷰로 출시했습니다. AI 에이전트 도구를 단일 MCP 호환 엔드포인트를 통해 관리하고 노출하는 방법입니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동으로 번역되었습니다. 원본 버전을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-toolboxes-curate-manage-tools-ai-agents/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;직접 겪기 전까지는 사소해 보이는 문제가 있다: 조직이 여러 AI 에이전트를 구축하고, 각 에이전트는 도구가 필요하며, 각 팀은 처음부터 다시 구성한다. 같은 웹 검색 통합, 같은 Azure AI Search 설정, 같은 GitHub MCP 서버 연결 — 하지만 다른 저장소에, 다른 팀이, 다른 자격증명으로, 공유 거버넌스 없이.&lt;/p&gt;
&lt;p&gt;Microsoft Foundry가 공개 프리뷰로 &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;Toolboxes&lt;/a&gt;를 출시했으며, 이는 그 문제에 대한 직접적인 해답이다.&lt;/p&gt;
&lt;h2 id="toolbox란"&gt;Toolbox란&lt;/h2&gt;
&lt;p&gt;Toolbox는 Foundry에서 한 번 정의하고 단일 MCP 호환 엔드포인트를 통해 노출하는 명명된 재사용 가능한 도구 번들이다. MCP를 사용하는 모든 에이전트 런타임이 소비할 수 있다 — Foundry Agents에 종속되지 않는다.&lt;/p&gt;
&lt;p&gt;제안은 간단하다: &lt;strong&gt;build once, consume anywhere&lt;/strong&gt;. 도구를 정의하고, 인증을 중앙에서 설정하고 (OAuth 패스스루, Entra 관리 ID), 엔드포인트를 게시한다. 그 도구가 필요한 각 에이전트는 엔드포인트에 연결하면 모두 가져온다.&lt;/p&gt;
&lt;h2 id="4개의-기둥-오늘-2개-사용-가능"&gt;4개의 기둥 (오늘 2개 사용 가능)&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;기둥&lt;/th&gt;
&lt;th&gt;상태&lt;/th&gt;
&lt;th&gt;기능&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Discover&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;출시 예정&lt;/td&gt;
&lt;td&gt;수동 검색 없이 승인된 도구 발견&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Build&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;사용 가능&lt;/td&gt;
&lt;td&gt;도구를 재사용 가능한 번들로 구성&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Consume&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;사용 가능&lt;/td&gt;
&lt;td&gt;단일 MCP 엔드포인트가 모든 도구 노출&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Govern&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;출시 예정&lt;/td&gt;
&lt;td&gt;모든 도구 호출의 중앙 인증 + 가시성&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="실제-예시"&gt;실제 예시&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.identity&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="nn"&gt;os&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;FOUNDRY_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;toolbox_version&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;beta&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;toolboxes&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_toolbox_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;toolbox_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;customer-feedback-triaging-toolbox&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;문서를 검색하고 GitHub 이슈에 응답&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;web_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;description&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;공개 문서 검색&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_search&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;index_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;internal-docs&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;mcp_server&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;server_url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://your-github-mcp-server.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;게시 후 Foundry는 통합 엔드포인트를 제공한다. 한 번 연결하면 모든 도구를 사용할 수 있다.&lt;/p&gt;
&lt;h2 id="foundry-agents에-종속되지-않는다"&gt;Foundry Agents에 종속되지 않는다&lt;/h2&gt;
&lt;p&gt;Toolboxes는 Foundry에서 &lt;strong&gt;생성·관리&lt;/strong&gt;되지만 소비 면은 오픈 MCP 프로토콜이다. Microsoft Agent Framework나 LangGraph로 만든 커스텀 에이전트, GitHub Copilot 및 기타 MCP 지원 IDE에서 사용할 수 있다.&lt;/p&gt;
&lt;h2 id="지금-왜-중요한가"&gt;지금 왜 중요한가&lt;/h2&gt;
&lt;p&gt;멀티 에이전트 물결이 프로덕션에 도달하고 있다. 새로운 에이전트마다 중복 설정, 오래된 자격증명, 일관성 없는 동작의 새로운 표면이 생긴다. Build + Consume 기반은 중앙화를 시작하기에 충분하다. Govern 기둥이 출시되면 전체 에이전트 플리트에 완전히 관찰 가능하고 중앙 제어되는 도구 계층을 갖게 된다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;아직 초기 단계다 — 공개 프리뷰, Python SDK 우선, Discover와 Govern은 예정되어 있다. 하지만 모델은 견고하고, MCP 네이티브 설계는 이미 구축 중인 도구와 함께 작동한다는 것을 의미한다. &lt;a href="https://devblogs.microsoft.com/foundry/introducing-toolboxes-in-foundry/"&gt;공식 발표&lt;/a&gt;를 확인해 시작해보자.&lt;/p&gt;</content:encoded></item><item><title>Python, TypeScript, .NET으로 azd 훅 작성하기: 셸 스크립트와의 작별</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/</guid><description>Azure Developer CLI가 이제 Python, JavaScript, TypeScript, .NET으로 훅 작성을 지원합니다. 마이그레이션 스크립트 하나 때문에 Bash로 전환할 필요가 없어집니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동으로 번역되었습니다. 원본 버전을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-hooks-python-javascript-typescript-dotnet/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;완전히 .NET으로 구성된 프로젝트에서 azd 훅을 위해 Bash 스크립트를 작성해야 했던 경험이 있다면, 그 불편함을 잘 알 것이다. 프로젝트의 모든 것이 C#인데, 왜 pre-provisioning 단계 하나 때문에 셸 문법으로 전환해야 하는가.&lt;/p&gt;
&lt;p&gt;그 불만이 이제 공식적으로 해결됐다. Azure Developer CLI가 &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-multi-language-hooks/"&gt;훅의 멀티 언어 지원을 출시&lt;/a&gt;했으며, 기대했던 것만큼 훌륭하다.&lt;/p&gt;
&lt;h2 id="훅이란"&gt;훅이란&lt;/h2&gt;
&lt;p&gt;훅은 &lt;code&gt;azd&lt;/code&gt; 라이프사이클의 핵심 지점에서 실행되는 스크립트다 — 프로비저닝 전, 배포 후 등. &lt;code&gt;azure.yaml&lt;/code&gt;에 정의되며 CLI를 수정하지 않고 커스텀 로직을 주입할 수 있게 해준다.&lt;/p&gt;
&lt;p&gt;기존에는 Bash와 PowerShell만 지원됐다. 이제 &lt;strong&gt;Python, JavaScript, TypeScript 또는 .NET&lt;/strong&gt;을 사용할 수 있으며, &lt;code&gt;azd&lt;/code&gt;가 나머지를 자동으로 처리한다.&lt;/p&gt;
&lt;h2 id="감지-방식"&gt;감지 방식&lt;/h2&gt;
&lt;p&gt;훅을 파일로 가리키기만 하면 &lt;code&gt;azd&lt;/code&gt;가 파일 확장자에서 언어를 추론한다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/setup.py&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postdeploy&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/seed.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/migrate.cs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;추가 설정이 필요 없다. 확장자가 모호한 경우 &lt;code&gt;kind: python&lt;/code&gt; (또는 해당 언어)을 명시적으로 지정할 수 있다.&lt;/p&gt;
&lt;h2 id="언어별-주요-세부-사항"&gt;언어별 주요 세부 사항&lt;/h2&gt;
&lt;h3 id="python"&gt;Python&lt;/h3&gt;
&lt;p&gt;스크립트 옆 (또는 상위 디렉토리)에 &lt;code&gt;requirements.txt&lt;/code&gt;나 &lt;code&gt;pyproject.toml&lt;/code&gt;을 놓으면 &lt;code&gt;azd&lt;/code&gt;가 자동으로 가상 환경을 생성하고 의존성을 설치한 후 스크립트를 실행한다.&lt;/p&gt;
&lt;h3 id="javascript와-typescript"&gt;JavaScript와 TypeScript&lt;/h3&gt;
&lt;p&gt;같은 패턴 — 스크립트 근처에 &lt;code&gt;package.json&lt;/code&gt;을 두면 &lt;code&gt;azd&lt;/code&gt;가 먼저 &lt;code&gt;npm install&lt;/code&gt;을 실행한다. TypeScript의 경우 컴파일 단계나 &lt;code&gt;tsconfig.json&lt;/code&gt; 없이 &lt;code&gt;npx tsx&lt;/code&gt;를 사용한다.&lt;/p&gt;
&lt;h3 id="net"&gt;.NET&lt;/h3&gt;
&lt;p&gt;두 가지 모드 지원:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;프로젝트 모드&lt;/strong&gt;: 스크립트 옆에 &lt;code&gt;.csproj&lt;/code&gt;가 있으면 &lt;code&gt;azd&lt;/code&gt;가 자동으로 &lt;code&gt;dotnet restore&lt;/code&gt;와 &lt;code&gt;dotnet build&lt;/code&gt;를 실행한다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;단일 파일 모드&lt;/strong&gt;: .NET 10+에서 독립 &lt;code&gt;.cs&lt;/code&gt; 파일을 &lt;code&gt;dotnet run script.cs&lt;/code&gt;로 직접 실행 가능하다. 프로젝트 파일 불필요.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="실행기별-설정"&gt;실행기별 설정&lt;/h2&gt;
&lt;p&gt;각 언어는 선택적 &lt;code&gt;config&lt;/code&gt; 블록을 지원한다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-yaml" data-lang="yaml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;hooks&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;preprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/setup.ts&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;packageManager&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;pnpm&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;postprovision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;run&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;./hooks/migrate.cs&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;config&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;configuration&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;Release&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="nt"&gt;framework&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;&lt;span class="w"&gt; &lt;/span&gt;&lt;span class="l"&gt;net10.0&lt;/span&gt;&lt;span class="w"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="net-개발자에게-중요한-이유"&gt;.NET 개발자에게 중요한 이유&lt;/h2&gt;
&lt;p&gt;훅은 azd 기반 프로젝트에서 언어 전환을 강제하는 마지막 장소였다. 이제 앱 코드, 인프라 스크립트, 라이프사이클 훅을 포함한 전체 배포 파이프라인이 하나의 언어로 살 수 있다. 기존 .NET 유틸리티를 훅에서 재사용하고, 공유 라이브러리를 참조하고, 셸 스크립트 유지보수에서 해방될 수 있다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;작은 변화처럼 보이지만 azd 일상 워크플로우에서 많은 마찰을 제거하는 변화 중 하나다. 훅의 멀티 언어 지원은 지금 바로 사용 가능하다 — &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-multi-language-hooks/"&gt;공식 게시물&lt;/a&gt;에서 전체 문서를 확인해 보자.&lt;/p&gt;</content:encoded></item><item><title>Windows App Dev CLI v0.3: 터미널에서 F5 디버그와 에이전트를 위한 UI 자동화</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/</guid><description>Windows App Development CLI v0.3는 터미널에서 디버그 실행을 위한 winapp run, UI 자동화를 위한 winapp ui, 그리고 패키지 앱에서 dotnet run을 동작하게 하는 NuGet 패키지를 제공합니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동으로 번역되었습니다. 원본을 보려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/windows-app-dev-cli-v03-run-ui-automation/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Visual Studio의 F5 경험은 훌륭합니다. 하지만 CI 파이프라인, 자동화 워크플로우, 또는 AI 에이전트가 테스트를 수행할 때 패키지된 Windows 앱을 시작하고 디버그하기 위해 VS를 열어야 한다면 너무 번거롭습니다.&lt;/p&gt;
&lt;p&gt;Windows App Development CLI v0.3이 &lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;출시&lt;/a&gt;되었으며, 두 가지 핵심 기능으로 이를 직접 해결합니다: &lt;code&gt;winapp run&lt;/code&gt;과 &lt;code&gt;winapp ui&lt;/code&gt;.&lt;/p&gt;
&lt;h2 id="winapp-run-어디서나-f5"&gt;winapp run: 어디서나 F5&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;winapp run&lt;/code&gt;은 언패키지된 앱 폴더와 매니페스트를 받아, VS가 디버그 시작 시 수행하는 모든 작업을 실행합니다: 루스 패키지 등록, 앱 시작, 재배포 간 &lt;code&gt;LocalState&lt;/code&gt; 보존.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 앱을 빌드한 다음 패키지 앱으로 실행&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winapp run ./bin/Debug
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;WinUI, WPF, WinForms, Console, Avalonia 등에서 동작합니다. 모드는 개발자와 자동화 워크플로우 모두를 위해 설계되었습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--detach&lt;/code&gt;&lt;/strong&gt;: 시작 후 즉시 터미널에 제어권을 반환합니다. CI/자동화에 적합합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--unregister-on-exit&lt;/code&gt;&lt;/strong&gt;: 앱 종료 시 등록된 패키지를 정리합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;--debug-output&lt;/code&gt;&lt;/strong&gt;: &lt;code&gt;OutputDebugString&lt;/code&gt; 메시지와 예외를 실시간으로 캡처합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="새로운-nuget-패키지-패키지-앱을-위한-dotnet-run"&gt;새로운 NuGet 패키지: 패키지 앱을 위한 dotnet run&lt;/h2&gt;
&lt;p&gt;.NET 개발자를 위한 새로운 NuGet 패키지가 있습니다: &lt;code&gt;Microsoft.Windows.SDK.BuildTools.WinApp&lt;/code&gt;. 설치 후 &lt;code&gt;dotnet run&lt;/code&gt;이 전체 이너 루프를 처리합니다: 빌드, 루스 레이아웃 패키지 준비, Windows 등록 및 시작 — 모두 한 단계로.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winapp init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Windows.SDK.BuildTools.WinApp
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="winapp-ui-커맨드-라인에서-ui-자동화"&gt;winapp ui: 커맨드 라인에서 UI 자동화&lt;/h2&gt;
&lt;p&gt;이것이 에이전트 시나리오를 여는 기능입니다. &lt;code&gt;winapp ui&lt;/code&gt;는 터미널에서 실행 중인 모든 Windows 앱(WPF, WinForms, Win32, Electron, WinUI3)에 대한 완전한 UI 자동화 액세스를 제공합니다.&lt;/p&gt;
&lt;p&gt;가능한 작업:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 최상위 창 나열&lt;/li&gt;
&lt;li&gt;창의 전체 UI 자동화 트리 탐색&lt;/li&gt;
&lt;li&gt;이름, 유형 또는 자동화 ID로 요소 검색&lt;/li&gt;
&lt;li&gt;클릭, 호출 및 값 설정&lt;/li&gt;
&lt;li&gt;스크린샷 캡처&lt;/li&gt;
&lt;li&gt;요소 나타날 때까지 대기 — 테스트 동기화에 이상적&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;&lt;code&gt;winapp ui&lt;/code&gt;와 &lt;code&gt;winapp run&lt;/code&gt;을 결합하면 터미널에서 완전한 빌드 → 시작 → 검증 워크플로우가 가능합니다. 에이전트가 앱을 실행하고, UI 상태를 검사하고, 프로그래밍 방식으로 상호작용하여 결과를 검증할 수 있습니다.&lt;/p&gt;
&lt;h2 id="기타-새로운-기능"&gt;기타 새로운 기능&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp unregister&lt;/code&gt;&lt;/strong&gt;: 완료 후 사이드로드된 패키지를 제거합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;winapp manifest add-alias&lt;/code&gt;&lt;/strong&gt;: 터미널에서 이름으로 앱을 시작하는 별칭을 추가합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;탭 자동완성&lt;/strong&gt;: 단일 명령으로 PowerShell 완성을 구성합니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="설치-방법"&gt;설치 방법&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;winget install Microsoft.WinAppCli
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 또는&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;npm install -g @microsoft/winappcli
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;CLI는 공개 미리 보기 중입니다. 전체 문서는 &lt;a href="https://github.com/microsoft/WinAppCli"&gt;GitHub 저장소&lt;/a&gt;를, 모든 세부 정보는 &lt;a href="https://devblogs.microsoft.com/ifdef-windows/windows-app-development-cli-v0-3-new-run-and-ui-commands-plus-dotnet-run-support-for-packaged-apps/"&gt;원본 발표&lt;/a&gt;를 참조하세요.&lt;/p&gt;</content:encoded></item><item><title>하루 68분을 코드 재설명에 낭비하고 있나요? 해결책이 있습니다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/</link><pubDate>Thu, 23 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/</guid><description>컨텍스트 로트는 현실입니다 — AI 에이전트는 30턴 후에 길을 잃고, 매시간 컴팩션 세금을 냅니다. auto-memory는 GitHub Copilot CLI에 수천 개의 토큰을 소모하지 않고 외과적인 기억을 제공합니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/auto-memory-stop-re-explaining-code-to-copilot/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;Copilot 세션이 &lt;code&gt;/compact&lt;/code&gt;에 도달하여 에이전트가 무엇을 하고 있었는지 완전히 잊어버리는 순간을 아시나요? 다음 5분 동안 파일 구조, 실패한 테스트, 이미 시도한 세 가지 접근 방식을 다시 설명합니다. 그리고 또 일어납니다.&lt;/p&gt;
&lt;p&gt;Desi Villanueva가 측정했습니다: &lt;strong&gt;하루 68분&lt;/strong&gt; — 재오리엔테이션에만. 코드 작성도 아니고, PR 리뷰도 아니고, AI가 이미 알고 있던 것들을 다시 알려주는 데만.&lt;/p&gt;
&lt;h2 id="컨텍스트-윈도우의-거짓말"&gt;컨텍스트 윈도우의 거짓말&lt;/h2&gt;
&lt;p&gt;실제 계산: 200K 총 컨텍스트에서 MCP 도구 65K, 인스트럭션 파일 10K를 빼면, &lt;strong&gt;한 글자 입력 전에 이미 125K만 남습니다&lt;/strong&gt;. LLM은 60% 용량에서 벽에 부딪히므로, 실효 한계는 &lt;strong&gt;45K 토큰&lt;/strong&gt;입니다.&lt;/p&gt;
&lt;h2 id="컴팩션-세금"&gt;컴팩션 세금&lt;/h2&gt;
&lt;p&gt;잔인한 부분: &lt;strong&gt;기억은 이미 존재합니다.&lt;/strong&gt; Copilot CLI는 &lt;code&gt;~/.copilot/session-store.db&lt;/code&gt;에 모든 세션을 기록합니다. 에이전트가 읽지 못할 뿐입니다.&lt;/p&gt;
&lt;h2 id="auto-memory-리콜-레이어-메모리-시스템이-아님"&gt;auto-memory: 리콜 레이어, 메모리 시스템이 아님&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;pip install auto-memory
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;~1,900줄의 Python. 의존성 없음. 30초 설치.&lt;/p&gt;
&lt;p&gt;grep 결과로 컨텍스트를 범람시키는 대신, &lt;strong&gt;10,000 토큰이 아닌 50 토큰&lt;/strong&gt;으로 정말 중요한 것에 대한 외과적 접근을 제공합니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;컨텍스트 로트는 실제 아키텍처 제약입니다. auto-memory는 에이전트에게 저렴하고 정확한 리콜 메커니즘을 제공하여 이를 우회합니다.&lt;/p&gt;
&lt;p&gt;확인해보세요: &lt;a href="https://github.com/dezgit2025/auto-memory"&gt;GitHub의 auto-memory&lt;/a&gt;. Desi Villanueva의 원본 포스트: &lt;a href="https://devblogs.microsoft.com/all-things-azure/i-wasted-68-minutes-a-day-re-explaining-my-code-then-i-built-auto-memory/"&gt;I Wasted 68 Minutes a Day&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>지금 바로 패치하세요: .NET 10.0.7 OOB 보안 업데이트 (ASP.NET Core Data Protection)</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/</link><pubDate>Wed, 22 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/</guid><description>.NET 10.0.7은 Microsoft.AspNetCore.DataProtection의 보안 취약점을 수정하는 비정기 릴리스 — 관리된 인증 암호화기가 잘못된 바이트에서 HMAC을 계산하여 권한 상승이 발생할 수 있었습니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본 버전은 &lt;a href="https://thedotnetblog.com/posts/emiliano-montesdeoca/dotnet-10-0-7-oob-security-patch-data-protection/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;이 업데이트는 선택 사항이 아닙니다. 애플리케이션이 &lt;code&gt;Microsoft.AspNetCore.DataProtection&lt;/code&gt;을 사용한다면 10.0.7로 업데이트해야 합니다.&lt;/p&gt;
&lt;h2 id="무슨-일이-있었나요"&gt;무슨 일이 있었나요&lt;/h2&gt;
&lt;p&gt;Patch Tuesday &lt;code&gt;.NET 10.0.6&lt;/code&gt; 릴리스 후 일부 사용자가 복호화 실패를 보고했습니다. 조사 중 &lt;strong&gt;CVE-2026-40372&lt;/strong&gt;가 발견되었습니다: HMAC 검증 태그가 &lt;strong&gt;잘못된 바이트&lt;/strong&gt;에서 계산되어 권한 상승으로 이어질 수 있었습니다.&lt;/p&gt;
&lt;h2 id="수정-방법"&gt;수정 방법&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.AspNetCore.DataProtection --version 10.0.7
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그런 다음 애플리케이션을 &lt;strong&gt;재빌드하고 재배포&lt;/strong&gt;하세요.&lt;/p&gt;
&lt;p&gt;Rahul Bhandari의 원본 발표: &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-10-0-7-oob-security-update/"&gt;.NET 10.0.7 Out-of-Band Security Update&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>azd + GitHub Copilot: AI 기반 프로젝트 설정과 스마트 오류 해결</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/</guid><description>Azure Developer CLI가 GitHub Copilot과 통합되어 프로젝트 인프라를 생성하고 배포 오류를 해결합니다 — 터미널을 벗어날 필요 없이.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 영어 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-copilot-integration-ai-setup-troubleshooting/"&gt;여기&lt;/a&gt;에서 확인할 수 있습니다.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;기존 앱을 Azure에 배포하려고 할 때, 빈 &lt;code&gt;azure.yaml&lt;/code&gt; 파일을 보며 Express API가 Container Apps를 써야 할지 App Service를 써야 할지 떠올리려 했던 경험 있으신가요? 그런 순간이 이제 훨씬 짧아집니다.&lt;/p&gt;
&lt;p&gt;Azure Developer CLI(&lt;code&gt;azd&lt;/code&gt;)가 GitHub Copilot과 두 가지 방식으로 통합되었습니다: &lt;code&gt;azd init&lt;/code&gt; 실행 시 AI 지원 프로젝트 스캐폴딩, 그리고 배포 실패 시 지능형 오류 트러블슈팅. 두 기능 모두 터미널 안에서 완전히 동작합니다 — 딱 원하는 방식입니다.&lt;/p&gt;
&lt;h2 id="azd-init에서-copilot-설정"&gt;azd init에서 Copilot 설정&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd init&lt;/code&gt;을 실행하면 이제 &amp;ldquo;Set up with GitHub Copilot (Preview)&amp;rdquo; 옵션이 나타납니다. 선택하면 Copilot이 코드베이스를 분석하여 실제 코드를 기반으로 &lt;code&gt;azure.yaml&lt;/code&gt;, 인프라 템플릿, Bicep 모듈을 생성합니다.&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd init
# 선택: &amp;#34;Set up with GitHub Copilot (Preview)&amp;#34;
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;필요한 것들:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;azd 1.23.11 이상&lt;/strong&gt; — &lt;code&gt;azd version&lt;/code&gt;으로 확인하거나 &lt;code&gt;azd update&lt;/code&gt;로 업데이트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;활성 GitHub Copilot 구독&lt;/strong&gt; (Individual, Business 또는 Enterprise)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub CLI (&lt;code&gt;gh&lt;/code&gt;)&lt;/strong&gt; — 필요 시 &lt;code&gt;azd&lt;/code&gt;가 로그인을 요청함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;정말 유용한 점은 양방향으로 동작한다는 것입니다. 처음부터 빌드한다면? Copilot이 처음부터 올바른 Azure 서비스를 설정하도록 도와줍니다. 배포하고 싶은 기존 앱이 있다면? Copilot을 그쪽으로 지향하면 코드 구조를 바꾸지 않고도 설정을 생성해 줍니다.&lt;/p&gt;
&lt;h3 id="실제로-무엇을-하나"&gt;실제로 무엇을 하나&lt;/h3&gt;
&lt;p&gt;PostgreSQL 의존성이 있는 Node.js Express API가 있다고 합시다. Container Apps와 App Service 중 무엇을 선택할지 수동으로 결정하고 Bicep을 처음부터 작성하는 대신, Copilot이 스택을 감지하고 다음을 생성합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;올바른 &lt;code&gt;language&lt;/code&gt;, &lt;code&gt;host&lt;/code&gt;, &lt;code&gt;build&lt;/code&gt; 설정이 담긴 &lt;code&gt;azure.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;Azure Container Apps를 위한 Bicep 모듈&lt;/li&gt;
&lt;li&gt;Azure Database for PostgreSQL을 위한 Bicep 모듈&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 무언가를 변경하기 전에 사전 검사를 실행합니다 — git 작업 디렉토리가 깨끗한지 확인하고, MCP 서버 도구 동의를 미리 요청합니다. 무엇이 바뀌는지 정확히 알고 난 뒤에만 진행됩니다.&lt;/p&gt;
&lt;h2 id="copilot-기반-오류-트러블슈팅"&gt;Copilot 기반 오류 트러블슈팅&lt;/h2&gt;
&lt;p&gt;배포 오류는 피할 수 없습니다. 누락된 파라미터, 권한 문제, SKU 가용성 문제 — 그리고 오류 메시지는 정작 필요한 것을 알려주지 않습니다: &lt;em&gt;어떻게 고치는가&lt;/em&gt;.&lt;/p&gt;
&lt;p&gt;Copilot 없이는: 오류 복사 → 문서 검색 → 관련 없는 Stack Overflow 답변 3개 읽기 → &lt;code&gt;az&lt;/code&gt; CLI 명령어 실행 → 다시 시도하며 기도. &lt;code&gt;azd&lt;/code&gt;에 Copilot이 통합되면 이 루프가 사라집니다. &lt;code&gt;azd&lt;/code&gt; 명령이 실패하면 즉시 4가지 옵션을 제공합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Explain&lt;/strong&gt; — 무엇이 잘못됐는지 알기 쉬운 설명&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Guidance&lt;/strong&gt; — 수정을 위한 단계별 지침&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Diagnose and Guide&lt;/strong&gt; — 완전한 분석 + Copilot이 수정 적용 (승인 후) + 선택적 재시도&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skip&lt;/strong&gt; — 직접 처리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;핵심: Copilot은 이미 프로젝트, 실패한 명령, 오류 세부 정보의 컨텍스트를 갖고 있습니다. 제안은 &lt;em&gt;여러분의 상황&lt;/em&gt;에 맞게 구체적입니다.&lt;/p&gt;
&lt;h3 id="기본-동작-설정"&gt;기본 동작 설정&lt;/h3&gt;
&lt;p&gt;항상 같은 옵션을 선택한다면, 인터랙티브 프롬프트를 건너뛸 수 있습니다:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config set copilot.errorHandling.category troubleshoot
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;값: &lt;code&gt;explain&lt;/code&gt;, &lt;code&gt;guidance&lt;/code&gt;, &lt;code&gt;troubleshoot&lt;/code&gt;, &lt;code&gt;fix&lt;/code&gt;, &lt;code&gt;skip&lt;/code&gt;. 자동 수정 및 재시도도 활성화할 수 있습니다:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config set copilot.errorHandling.fix allow
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;언제든지 인터랙티브 모드로 되돌리기:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;azd config unset copilot.errorHandling.category
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd update&lt;/code&gt;로 최신 버전을 받고 다음 프로젝트에서 &lt;code&gt;azd init&lt;/code&gt;을 써보세요. 진정한 가치를 주는 Copilot 통합입니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-copilot-integration/"&gt;원문 발표를 여기서 읽어보세요&lt;/a&gt;.&lt;/p&gt;</content:encoded></item><item><title>C#와 .NET Native AOT로 Node.js 네이티브 애드온 작성하기</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/</link><pubDate>Tue, 21 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/</guid><description>C# Dev Kit 팀이 C++로 작성된 Node.js 애드온을 .NET Native AOT로 교체했습니다 — 결과는 더 깔끔하고 안전하며, .NET SDK만 있으면 됩니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 영어 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/nodejs-addons-csharp-native-aot/"&gt;여기&lt;/a&gt;에서 확인할 수 있습니다.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;제가 좋아하는 시나리오입니다. .NET 도구를 개발하는 팀이 C++로 작성하고 &lt;code&gt;node-gyp&lt;/code&gt;으로 컴파일하는 네이티브 Node.js 애드온을 사용하고 있었습니다. 동작했습니다. 하지만 팀원 누구도 직접 건드리지 않을 패키지를 빌드하기 위해 모든 개발자 기기에 Python(그것도 구버전)을 설치해야 했습니다.&lt;/p&gt;
&lt;p&gt;그래서 매우 합리적인 질문을 했습니다: .NET SDK가 이미 설치되어 있는데, 왜 C++를 쓰는 걸까요?&lt;/p&gt;
&lt;p&gt;답은 Native AOT였고, 결과는 정말 우아합니다.&lt;/p&gt;
&lt;h2 id="기본-아이디어"&gt;기본 아이디어&lt;/h2&gt;
&lt;p&gt;Node.js 네이티브 애드온은 Node.js가 런타임에 로드할 수 있는 공유 라이브러리(Windows의 &lt;code&gt;.dll&lt;/code&gt;, Linux의 &lt;code&gt;.so&lt;/code&gt;, macOS의 &lt;code&gt;.dylib&lt;/code&gt;)입니다. 인터페이스는 &lt;a href="https://nodejs.org/api/n-api.html"&gt;N-API&lt;/a&gt;—안정적이고 ABI 호환 가능한 C API입니다. N-API는 라이브러리가 어떤 언어로 만들어졌는지 신경 쓰지 않고, 올바른 심볼을 내보내는지만 확인합니다.&lt;/p&gt;
&lt;p&gt;.NET Native AOT는 정확히 그것을 만들 수 있습니다. C# 코드를 임의의 진입점을 가진 네이티브 공유 라이브러리로 미리 컴파일합니다. 이것이 전부입니다.&lt;/p&gt;
&lt;h2 id="프로젝트-설정"&gt;프로젝트 설정&lt;/h2&gt;
&lt;p&gt;프로젝트 파일은 최소화됩니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;Project&lt;/span&gt; &lt;span class="na"&gt;Sdk=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Microsoft.NET.Sdk&amp;#34;&lt;/span&gt;&lt;span class="nt"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;TargetFramework&amp;gt;&lt;/span&gt;net10.0&lt;span class="nt"&gt;&amp;lt;/TargetFramework&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;PublishAot&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/PublishAot&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;AllowUnsafeBlocks&amp;gt;&lt;/span&gt;true&lt;span class="nt"&gt;&amp;lt;/AllowUnsafeBlocks&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;lt;/PropertyGroup&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;/Project&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;PublishAot&lt;/code&gt;은 &lt;code&gt;dotnet publish&lt;/code&gt; 시 공유 라이브러리를 생성하도록 SDK에 지시합니다. &lt;code&gt;AllowUnsafeBlocks&lt;/code&gt;는 함수 포인터와 고정 버퍼를 사용하는 N-API interop에 필요합니다.&lt;/p&gt;
&lt;h2 id="진입점-내보내기"&gt;진입점 내보내기&lt;/h2&gt;
&lt;p&gt;Node.js는 라이브러리가 &lt;code&gt;napi_register_module_v1&lt;/code&gt;을 내보낼 것을 기대합니다. C#에서는 &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt;가 정확히 그 역할을 합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kd"&gt;unsafe&lt;/span&gt; &lt;span class="kd"&gt;partial&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;RegistryAddon&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [UnmanagedCallersOnly(
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; EntryPoint = &amp;#34;napi_register_module_v1&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; CallConvs = [typeof(CallConvCdecl)]&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;Init&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;RegisterFunction&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;readStringValue&amp;#34;&lt;/span&gt;&lt;span class="n"&gt;u8&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;&amp;amp;&lt;/span&gt;&lt;span class="n"&gt;ReadStringValue&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;exports&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;주목할 점들: &lt;code&gt;nint&lt;/code&gt;는 네이티브 크기 정수로 &lt;code&gt;intptr_t&lt;/code&gt;의 관리형 등가물입니다. &lt;code&gt;u8&lt;/code&gt; 접미사는 UTF-8 문자열 리터럴을 담은 &lt;code&gt;ReadOnlySpan&amp;lt;byte&amp;gt;&lt;/code&gt;를 생성하여 인코딩 할당 없이 N-API에 직접 전달됩니다. &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt;는 Node.js가 찾는 정확한 진입점 이름으로 메서드를 내보냅니다.&lt;/p&gt;
&lt;h2 id="n-api를-호스트-프로세스에-대해-해석하기"&gt;N-API를 호스트 프로세스에 대해 해석하기&lt;/h2&gt;
&lt;p&gt;N-API 함수는 별도의 라이브러리가 아닌 &lt;code&gt;node.exe&lt;/code&gt; 자체에서 내보냅니다. 따라서 무언가에 링크하는 대신, 시작 시 실행 중인 프로세스에 대해 해석합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="k"&gt;void&lt;/span&gt; &lt;span class="n"&gt;Initialize&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;NativeLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;SetDllImportResolver&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;System&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Reflection&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Assembly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetExecutingAssembly&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ResolveDllImport&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;ResolveDllImport&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;libraryName&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Assembly&lt;/span&gt; &lt;span class="n"&gt;assembly&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;DllImportSearchPath&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;searchPath&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;libraryName&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;NativeLibrary&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetMainProgramHandle&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이를 통해 P/Invoke 선언이 &lt;code&gt;[LibraryImport]&lt;/code&gt;와 소스 생성 마샬링으로 올바르게 동작합니다.&lt;/p&gt;
&lt;h2 id="실제-내보낸-함수"&gt;실제 내보낸 함수&lt;/h2&gt;
&lt;p&gt;그들이 구현한 레지스트리 읽기 함수:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[UnmanagedCallersOnly(CallConvs = [typeof(CallConvCdecl)]&lt;/span&gt;&lt;span class="p"&gt;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;ReadStringValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;nint&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;try&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;keyPath&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetStringArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;valueName&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;GetStringArg&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;info&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="m"&gt;1&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyPath&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;||&lt;/span&gt; &lt;span class="n"&gt;valueName&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ThrowError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Expected two string arguments: keyPath, valueName&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;var&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;Registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CurrentUser&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;OpenSubKey&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;keyPath&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;writable&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;key&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;GetValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;valueName&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;CreateString&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="k"&gt;value&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;GetUndefined&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;catch&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Exception&lt;/span&gt; &lt;span class="n"&gt;ex&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ThrowError&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;env&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;$&amp;#34;Registry read failed: {ex.Message}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;try/catch&lt;/code&gt;에 대한 중요한 참고사항: &lt;code&gt;[UnmanagedCallersOnly]&lt;/code&gt; 메서드에서 처리되지 않은 예외는 호스트 프로세스를 충돌시킵니다. 항상 예외를 잡아 &lt;code&gt;ThrowError&lt;/code&gt;를 통해 JavaScript에 전달하세요.&lt;/p&gt;
&lt;h2 id="typescript에서-호출하기"&gt;TypeScript에서 호출하기&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="kr"&gt;require&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s1"&gt;&amp;#39;./native/win32-x64/RegistryAddon.node&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="kr"&gt;as&lt;/span&gt; &lt;span class="nx"&gt;RegistryAddon&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;sdkPath&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="nx"&gt;registry&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;readStringValue&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s1"&gt;&amp;#39;SOFTWARE\\dotnet\\Setup\\InstalledVersions\\x64\\sdk&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;InstallLocation&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;TypeScript → C#, Python 없음, C++ 없음.&lt;/p&gt;
&lt;h2 id="얻은-것"&gt;얻은 것&lt;/h2&gt;
&lt;p&gt;즉각적인 승리는 기여자 경험이었습니다: 특정 Python 버전이 더 이상 필요 없고, &lt;code&gt;yarn install&lt;/code&gt;은 Node.js와 .NET SDK만으로 동작합니다. CI 파이프라인도 단순해졌습니다. 성능은 C++ 구현과 비슷했습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;C# Dev Kit 팀은 Python/C++ 복잡성을 팀 모두가 이미 작성하고 디버그할 줄 아는 깔끔한 C# 코드로 대체했습니다. 모든 문자열 마샬링 헬퍼를 포함한 전체 안내는 &lt;a href="https://devblogs.microsoft.com/dotnet/writing-nodejs-addons-with-dotnet-native-aot/"&gt;.NET 블로그 원문&lt;/a&gt;을 참고하세요.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.117: 에이전트가 전용 Git 브랜치를 갖게 됐다, 완전 찬성이다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</link><pubDate>Sun, 19 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/</guid><description>VS Code 1.117이 에이전트 세션을 위한 worktree 격리, 영구 Autopilot 모드, 서브에이전트 지원을 제공합니다. 에이전트 코딩 워크플로가 훨씬 더 현실적이 됐습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-117-agents-autopilot-worktrees/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;&amp;ldquo;AI 어시스턴트&amp;quot;와 &amp;ldquo;AI 팀원&amp;rdquo; 사이의 경계가 계속 얇아지고 있다. VS Code 1.117이 출시됐고 &lt;a href="https://code.visualstudio.com/updates/v1_117"&gt;전체 릴리스 노트&lt;/a&gt;는 내용이 가득하지만, 이야기는 분명하다: 에이전트가 개발 워크플로의 일등 시민이 되고 있다.&lt;/p&gt;
&lt;p&gt;진짜 중요한 것들을 정리했다.&lt;/p&gt;
&lt;h2 id="autopilot-모드가-드디어-설정을-기억한다"&gt;Autopilot 모드가 드디어 설정을 기억한다&lt;/h2&gt;
&lt;p&gt;이전에는 새 세션을 시작할 때마다 Autopilot을 다시 활성화해야 했다. 짜증났다. 이제 권한 모드가 세션 간에 유지되고, 기본값도 설정할 수 있다.&lt;/p&gt;
&lt;p&gt;Agent Host는 세 가지 세션 설정을 지원한다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Default&lt;/strong&gt; — 도구가 실행 전에 확인을 요청&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Bypass&lt;/strong&gt; — 모든 것을 자동 승인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Autopilot&lt;/strong&gt; — 완전 자율, 스스로 질문에 답하고 계속 진행&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;마이그레이션, Docker, CI와 함께 새 .NET 프로젝트를 스캐폴딩하고 있다면 — Autopilot으로 한 번 설정하고 잊어버리면 된다. 그 설정이 유지된다.&lt;/p&gt;
&lt;h2 id="에이전트-세션을-위한-worktree와-git-격리"&gt;에이전트 세션을 위한 worktree와 git 격리&lt;/h2&gt;
&lt;p&gt;이게 핵심이다. 에이전트 세션이 이제 완전한 worktree와 git 격리를 지원한다. 에이전트가 작업을 수행할 때 자체 브랜치와 작업 디렉토리를 갖게 된다는 뜻이다. 메인 브랜치는 전혀 영향을 받지 않는다.&lt;/p&gt;
&lt;p&gt;더 좋은 건 — Copilot CLI가 이 worktree 세션에 의미 있는 브랜치 이름을 생성해준다. 더 이상 &lt;code&gt;agent-session-abc123&lt;/code&gt; 같은 이름은 없다. 에이전트가 실제로 무엇을 하고 있는지 설명하는 이름을 받게 된다.&lt;/p&gt;
&lt;p&gt;여러 피처 브랜치를 관리하거나 긴 스캐폴딩 작업이 실행되는 동안 버그를 수정하는 .NET 개발자에게 이건 게임 체인저다. 한 worktree에서 에이전트가 API 컨트롤러를 빌드하는 동안 다른 worktree에서 서비스 레이어 문제를 디버깅할 수 있다. 충돌 없음. 스태시 없음. 혼란 없음.&lt;/p&gt;
&lt;h2 id="서브에이전트와-에이전트-팀"&gt;서브에이전트와 에이전트 팀&lt;/h2&gt;
&lt;p&gt;Agent Host Protocol이 이제 서브에이전트를 지원한다. 에이전트가 작업의 일부를 처리하기 위해 다른 에이전트를 생성할 수 있다. 위임이라고 생각하면 된다 — 메인 에이전트가 조율하고, 전문 에이전트가 각 부분을 담당한다.&lt;/p&gt;
&lt;p&gt;아직 초기 단계지만 .NET 워크플로에 대한 잠재력은 분명하다. 한 에이전트가 EF Core 마이그레이션을 처리하고 다른 에이전트가 통합 테스트를 설정하는 모습을 상상해보라. 아직 완전히 도달하지는 않았지만, 프로토콜 지원이 지금 들어왔다는 것은 도구가 빠르게 따라올 것이라는 뜻이다.&lt;/p&gt;
&lt;h2 id="에이전트가-입력을-보낼-때-터미널-출력이-자동으로-포함"&gt;에이전트가 입력을 보낼 때 터미널 출력이 자동으로 포함&lt;/h2&gt;
&lt;p&gt;작지만 의미 있다. 에이전트가 터미널에 입력을 보내면 터미널 출력이 이제 자동으로 컨텍스트에 포함된다. 이전에는 에이전트가 무슨 일이 일어났는지 읽기 위해 추가 턴이 필요했다.&lt;/p&gt;
&lt;p&gt;에이전트가 &lt;code&gt;dotnet build&lt;/code&gt;를 실행하고, 실패하고, 에러를 보기 위해 또 한 번 왕복하는 걸 본 적이 있다면 — 그 마찰이 사라졌다. 출력을 즉시 보고 반응한다.&lt;/p&gt;
&lt;h2 id="macos-agents-앱-자동-업데이트"&gt;macOS Agents 앱 자동 업데이트&lt;/h2&gt;
&lt;p&gt;macOS의 독립형 Agents 앱이 이제 자동 업데이트된다. 더 이상 새 버전을 수동으로 다운로드할 필요가 없다. 그냥 최신 상태를 유지한다.&lt;/p&gt;
&lt;h2 id="알아둘-만한-작은-것들"&gt;알아둘 만한 작은 것들&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;package.json 호버&lt;/strong&gt;가 이제 설치된 버전과 최신 사용 가능 버전을 모두 표시한다. .NET 프로젝트와 함께 npm 도구를 관리하는 경우 유용하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;JSDoc 주석의 이미지&lt;/strong&gt;가 호버와 자동완성에서 올바르게 렌더링된다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI 세션&lt;/strong&gt;이 VS Code에서 생성됐는지 외부에서 생성됐는지 표시한다 — 터미널 간에 이동할 때 편리하다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Copilot CLI, Claude Code, Gemini CLI&lt;/strong&gt;가 셸 타입으로 인식된다. 에디터가 무엇을 실행하고 있는지 알고 있다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="핵심-정리"&gt;핵심 정리&lt;/h2&gt;
&lt;p&gt;VS Code 1.117은 화려한 기능 나열이 아니다. 인프라다. Worktree 격리, 영구 권한, 서브에이전트 프로토콜 — 이것들은 에이전트가 코드를 건드리지 않으면서 실제 병렬 작업을 처리하는 워크플로를 위한 기반이다.&lt;/p&gt;
&lt;p&gt;.NET으로 개발하면서 아직 에이전트 워크플로에 뛰어들지 않았다면, 솔직히 지금이 시작할 때다.&lt;/p&gt;</content:encoded></item><item><title>Azure에서의 AI 실험이 돈을 태우고 있다 — 해결 방법은 이것이다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/</guid><description>Azure의 AI 워크로드는 빠르게 비용이 증가할 수 있습니다. 개발 속도를 늦추지 않으면서 비용을 통제하는 데 실제로 효과가 있는 방법에 대해 이야기해 봅시다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/cloud-cost-optimization-ai-workloads-azure/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;지금 Azure에서 AI 기반 앱을 구축하고 있다면, 아마 한 가지 눈치챈 게 있을 겁니다: 클라우드 청구서가 예전과 다르게 보인다는 것입니다. 단순히 높아진 게 아니라 — 이상해졌습니다. 들쭉날쭉하고, 예측하기 어렵습니다.&lt;/p&gt;
&lt;p&gt;Microsoft가 &lt;a href="https://azure.microsoft.com/en-us/blog/cloud-cost-optimization-principles-that-still-matter/"&gt;여전히 중요한 클라우드 비용 최적화 원칙&lt;/a&gt;에 대한 훌륭한 글을 방금 게시했는데, 솔직히 이보다 더 좋은 타이밍은 없었을 겁니다. AI 워크로드가 비용에 관한 게임의 규칙을 바꿔놓았으니까요.&lt;/p&gt;
&lt;h2 id="ai-워크로드가-다른-이유"&gt;AI 워크로드가 다른 이유&lt;/h2&gt;
&lt;p&gt;핵심은 이겁니다. 전통적인 .NET 워크로드는 비교적 예측 가능합니다. App Service 티어를 알고, SQL DTU를 알고, 월별 지출을 꽤 정확하게 추정할 수 있습니다. AI 워크로드는요? 그렇지 않습니다.&lt;/p&gt;
&lt;p&gt;어떤 모델이 맞는지 여러 모델을 테스트하고 있습니다. 파인튜닝을 위해 GPU 지원 인프라를 올리고 있습니다. 프롬프트 길이와 사용자 행동에 따라 토큰 소비가 크게 달라지는 Azure OpenAI API를 호출하고 있습니다. 모든 실험에는 실제 비용이 들고, 올바른 접근 방식을 찾기까지 수십 번을 실행해야 할 수도 있습니다.&lt;/p&gt;
&lt;p&gt;이 예측 불가능성이 바로 비용 최적화가 중요한 이유입니다 — 나중에 생각할 것이 아니라, 첫날부터.&lt;/p&gt;
&lt;h2 id="관리-vs-최적화--차이를-알아야-합니다"&gt;관리 vs. 최적화 — 차이를 알아야 합니다&lt;/h2&gt;
&lt;p&gt;기사에서 개발자들이 간과하는 것 같은 구분이 있습니다: 비용 &lt;em&gt;관리&lt;/em&gt;와 비용 &lt;em&gt;최적화&lt;/em&gt;에는 차이가 있다는 것입니다.&lt;/p&gt;
&lt;p&gt;관리는 추적과 보고입니다. Azure Cost Management에서 예산을 설정하고, 알림을 받고, 대시보드를 봅니다. 이건 기본 중의 기본입니다.&lt;/p&gt;
&lt;p&gt;최적화는 실제로 결정을 내리는 곳입니다. 정말 S3 티어가 필요한 건지, S1으로 부하를 감당할 수 있는 건지? 항상 켜져 있는 컴퓨트 인스턴스가 주말에 놀고 있지는 않은지? 학습 작업에 스팟 인스턴스를 사용할 수는 없는지?&lt;/p&gt;
&lt;p&gt;.NET 개발자로서 우리는 코드에 집중하고 인프라 결정은 &amp;ldquo;운영팀&amp;quot;에 맡기는 경향이 있습니다. 하지만 Azure에 배포하고 있다면, 그 결정은 여러분의 결정이기도 합니다.&lt;/p&gt;
&lt;h2 id="실제로-효과가-있는-것"&gt;실제로 효과가 있는 것&lt;/h2&gt;
&lt;p&gt;기사와 제 개인적인 경험을 바탕으로, 실제로 차이를 만드는 것들입니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;무엇에 얼마를 쓰고 있는지 파악하세요.&lt;/strong&gt; 리소스에 태그를 달아주세요. 진심입니다. 어떤 프로젝트나 실험이 예산을 잡아먹고 있는지 구분할 수 없다면, 아무것도 최적화할 수 없습니다. 적절한 태깅이 된 Azure Cost Management가 가장 좋은 친구입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;실험하기 전에 가드레일을 설정하세요.&lt;/strong&gt; Azure Policy를 사용해 dev/test 환경에서 비싼 SKU를 제한하세요. Azure OpenAI 배포에 지출 한도를 설정하세요. 누군가가 주말 동안 GPU 클러스터를 켜둔 채 놔뒀다는 걸 청구서가 도착하고 나서야 알게 되는 일은 없어야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;지속적으로 적정 규모를 유지하세요.&lt;/strong&gt; 프로토타이핑 중에 선택한 그 VM? 프로덕션에는 아마 맞지 않을 겁니다. Azure Advisor가 추천을 해줍니다 — 실제로 살펴보세요. 1년에 한 번이 아니라 매달 검토하세요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;라이프사이클을 생각하세요.&lt;/strong&gt; 개발 리소스는 종료되어야 합니다. 테스트 환경이 24시간 돌아갈 필요는 없습니다. 자동 종료 정책을 사용하세요. AI 워크로드의 경우 특히, 컴퓨트를 계속 켜두는 대신 실행당 과금되는 서버리스 옵션을 고려하세요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;비용만이 아닌 가치를 측정하세요.&lt;/strong&gt; 이건 잊기 쉽습니다. 비용은 더 들지만 훨씬 더 나은 결과를 제공하는 모델이 올바른 선택일 수 있습니다. 목표는 가장 적게 쓰는 것이 아니라 — 똑똑하게 쓰는 것입니다.&lt;/p&gt;
&lt;h2 id="핵심-요약"&gt;핵심 요약&lt;/h2&gt;
&lt;p&gt;클라우드 비용 최적화는 일회성 정리가 아닙니다. 습관입니다. AI 워크로드로 인해 지출이 그 어느 때보다 예측하기 어려워진 지금, 이 습관을 일찍 들이면 나중에 고통스러운 깜짝 놀랄 일을 방지할 수 있습니다.&lt;/p&gt;
&lt;p&gt;Azure에서 구축하는 .NET 개발자라면, 클라우드 청구서를 코드 다루듯 대하기 시작하세요 — 정기적으로 리뷰하고, 지저분해지면 리팩토링하고, 비용을 이해하지 않은 채 절대 배포하지 마세요.&lt;/p&gt;</content:encoded></item><item><title>Foundry의 RFT가 더 저렴하고 스마트해졌습니다 — 변경된 내용 정리</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/</guid><description>Microsoft Foundry가 이번 달 세 가지 RFT 업데이트를 출시했습니다: o4-mini 글로벌 트레이닝, 새로운 GPT-4.1 모델 그레이더, 그리고 디버깅 시간을 크게 줄여줄 모범 사례 가이드.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-fine-tuning-april-2026-rft-graders/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;파인튜닝된 모델에 의존하는 .NET 앱을 개발하고 있다면, 이번 달 Foundry 업데이트에 주목할 필요가 있습니다. Reinforcement Fine-Tuning이 더 접근하기 쉬워지고 비용이 크게 낮아졌습니다.&lt;/p&gt;
&lt;p&gt;자세한 내용은 &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-foundry-finetune-april-2026/"&gt;공식 발표&lt;/a&gt;에 있지만, 여기서 실용적인 요약을 정리해 드리겠습니다.&lt;/p&gt;
&lt;h2 id="o4-mini-글로벌-트레이닝"&gt;o4-mini 글로벌 트레이닝&lt;/h2&gt;
&lt;p&gt;o4-mini는 추론 중심 및 에이전트 워크로드에 가장 적합한 모델입니다. 큰 소식: 이제 13개 이상의 Azure 리전에서 파인튜닝 작업을 시작할 수 있으며, Standard 트레이닝 대비 토큰당 트레이닝 비용이 더 낮습니다. 동일한 인프라, 동일한 품질, 더 넓은 범위.&lt;/p&gt;
&lt;p&gt;팀이 여러 지역에 분산되어 있다면 이것은 중요합니다. 더 이상 트레이닝을 위해 소수의 리전에 묶여 있을 필요가 없습니다.&lt;/p&gt;
&lt;p&gt;글로벌 트레이닝 작업을 시작하는 REST API 호출은 다음과 같습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;curl -X POST &lt;span class="s2"&gt;&amp;#34;https://&amp;lt;your-resource&amp;gt;.openai.azure.com/openai/fine_tuning/jobs?api-version=2025-04-01-preview&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H &lt;span class="s2"&gt;&amp;#34;Content-Type: application/json&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -H &lt;span class="s2"&gt;&amp;#34;api-key: &lt;/span&gt;&lt;span class="nv"&gt;$AZURE_OPENAI_API_KEY&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;&lt;/span&gt; &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; -d &lt;span class="s1"&gt;&amp;#39;{
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;model&amp;#34;: &amp;#34;o4-mini&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;training_file&amp;#34;: &amp;#34;&amp;lt;your-training-file-id&amp;gt;&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;method&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;reinforcement&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reinforcement&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;grader&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;type&amp;#34;: &amp;#34;string_check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;name&amp;#34;: &amp;#34;answer-check&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;input&amp;#34;: &amp;#34;{{sample.output_text}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;reference&amp;#34;: &amp;#34;{{item.reference_answer}}&amp;#34;,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;operation&amp;#34;: &amp;#34;eq&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;hyperparameters&amp;#34;: {
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;n_epochs&amp;#34;: 2,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;compute_multiplier&amp;#34;: 1.0
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; },
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; &amp;#34;trainingType&amp;#34;: &amp;#34;globalstandard&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s1"&gt; }&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;trainingType: globalstandard&lt;/code&gt; 플래그가 핵심적인 차이점입니다.&lt;/p&gt;
&lt;h2 id="새로운-모델-그레이더-gpt-41-패밀리"&gt;새로운 모델 그레이더: GPT-4.1 패밀리&lt;/h2&gt;
&lt;p&gt;그레이더는 모델이 최적화하는 보상 신호를 정의합니다. 지금까지 모델 기반 그레이더는 소수의 모델로 제한되어 있었습니다. 이제 세 가지 새로운 옵션이 추가되었습니다: GPT-4.1, GPT-4.1-mini, GPT-4.1-nano.&lt;/p&gt;
&lt;p&gt;결정적 그레이더 대신 모델 그레이더를 사용해야 할 때는? 태스크 출력이 개방형일 때, 여러 차원에서 부분 점수가 필요할 때, 또는 도구 호출의 정확성이 의미적 맥락에 따라 달라지는 에이전트 워크플로를 구축할 때입니다.&lt;/p&gt;
&lt;p&gt;핵심은 티어링 전략이 실용적이라는 것입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-nano&lt;/strong&gt; 초기 반복용. 낮은 비용, 빠른 피드백 루프.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1-mini&lt;/strong&gt; 평가 기준이 안정되고 더 높은 정확도가 필요할 때.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GPT-4.1&lt;/strong&gt; 프로덕션 평가 또는 모든 점수 결정이 중요한 복잡한 기준용.&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;단일 RFT 작업에서 그레이더 유형을 혼합할 수도 있습니다. &amp;ldquo;정답&amp;rdquo; 차원에는 string-match를 사용하고 추론 품질 평가에는 모델 그레이더를 사용하세요. 솔직히 이 유연성이 실제 워크로드에서 유용한 이유입니다.&lt;/p&gt;
&lt;h2 id="rft-데이터-형식-주의사항"&gt;RFT 데이터 형식 주의사항&lt;/h2&gt;
&lt;p&gt;많은 사람들이 여기서 실수합니다. RFT 데이터 형식은 SFT와 다릅니다. 각 행의 마지막 메시지는 User 또는 Developer 역할이어야 합니다 — Assistant가 아닙니다. 예상 답변은 그레이더가 직접 참조하는 &lt;code&gt;reference_answer&lt;/code&gt;와 같은 최상위 키에 넣습니다.&lt;/p&gt;
&lt;p&gt;지금까지 지도 파인튜닝을 해왔고 RFT로 전환하고 싶다면, 트레이닝 데이터를 재구성해야 합니다. 이 단계를 건너뛰면 작업이 조용히 실패합니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-왜-중요한가"&gt;.NET 개발자에게 왜 중요한가&lt;/h2&gt;
&lt;p&gt;Azure OpenAI SDK를 통해 .NET 앱에서 파인튜닝된 모델을 호출하고 있다면, 더 저렴한 트레이닝은 더 공격적으로 반복할 수 있다는 뜻입니다. 모델 그레이더 옵션은 정확 일치 시나리오뿐만 아니라 미묘한 태스크에 대해서도 파인튜닝할 수 있다는 것을 의미합니다. 그리고 &lt;a href="https://github.com/microsoft-foundry/fine-tuning/blob/main/Demos/Agentic_RFT_PrivatePreview/RFT_Best_Practice.md"&gt;GitHub&lt;/a&gt;의 모범 사례 가이드는 실제 디버깅 시간을 절약해 줄 것입니다.&lt;/p&gt;
&lt;p&gt;작게 시작하세요. 10개에서 100개 샘플. 간단한 그레이더. 루프를 검증하세요. 그다음 확장하세요.&lt;/p&gt;</content:encoded></item><item><title>Global Azure Spain 2026</title><link>https://thedotnetblog.com/ko/events/global-azure-spain-2026/</link><pubDate>Sat, 18 Apr 2026 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/events/global-azure-spain-2026/</guid><description>스페인 최대의 Azure 커뮤니티 이벤트 — Azure, AI, 데이터, 보안, 클라우드 네이티브 개발에 관한 하루 종일 세션, 38명의 발표자, 3개 트랙.</description><content:encoded>&lt;p&gt;Global Azure Spain 2026은 &lt;strong&gt;2026년 4월 18일&lt;/strong&gt; 마드리드 Alcobendas의 &lt;strong&gt;Kinépolis Diversia&lt;/strong&gt;에서 개최됩니다. 스페인 최대의 커뮤니티 주도 Azure 이벤트로, AI 에이전트, Azure 네트워킹, Cosmos DB, Fabric, IoT, 보안 등을 다루는 3개 병렬 트랙에 38명의 발표자가 참여합니다.&lt;/p&gt;
&lt;p&gt;이벤트는 &lt;strong&gt;08:30부터 18:30&lt;/strong&gt;까지 진행되며, 키노트, 커피 브레이크, 점심, 클로징 Q&amp;amp;A 세션을 포함합니다.&lt;/p&gt;
&lt;h2 id="어젠다-하이라이트"&gt;어젠다 하이라이트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Domando Agentes de IA&lt;/strong&gt;: Azure AI Foundry와 Azure API Management를 활용한 거버넌스, 도구, API&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Construyendo agentes con LibreChat en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;How Can I Steal Your Data with Azure Private Endpoints&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Stop Building APIs. Forge Agents with Azure&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agentic DevOps Meets IoT: Real-Time Systems with Fabric and GitHub Copilot&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;El regreso de los tamagotchis!&lt;/strong&gt;: 멀티 에이전트 시스템 실전&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry Control Plane como plataforma de Agentes global&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Rompiendo el perímetro: Zero Trust aplicado en Azure&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="티켓"&gt;티켓&lt;/h2&gt;
&lt;p&gt;등록은 상징적인 기부입니다 — 티켓 전체 금액은 &lt;strong&gt;Plan International&lt;/strong&gt;에 직접 기부되어 전 세계 아동 권리와 평등을 지원합니다. 정원이 제한되어 있으니 서둘러 등록하세요.&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;a href="https://www.eventbrite.es/e/entradas-global-azure-spain-2026-en-madrid-1981594189564"&gt;Eventbrite에서 티켓 구매&lt;/a&gt;&lt;/li&gt;
&lt;li&gt;&lt;a href="https://globalazure.es/"&gt;이벤트 웹사이트&lt;/a&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="azure-tour-2026"&gt;Azure Tour 2026&lt;/h2&gt;
&lt;p&gt;마드리드 외에도 Global Azure Tour 2026은 &lt;strong&gt;사라고사&lt;/strong&gt;, &lt;strong&gt;테네리페&lt;/strong&gt;, &lt;strong&gt;세비야&lt;/strong&gt;에서도 개최됩니다.&lt;/p&gt;</content:encoded></item><item><title>Docker Sandbox로 Copilot 에이전트가 머신 위험 없이 코드를 리팩터링할 수 있게 되었다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/</guid><description>Docker Sandbox는 GitHub Copilot 에이전트에게 안전한 마이크로VM을 제공하여 권한 프롬프트 없이, 호스트 위험 없이 자유롭게 리팩터링할 수 있게 합니다. 대규모 .NET 현대화에 왜 이것이 모든 것을 바꾸는지 알아보세요.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/copilot-docker-sandbox-agentic-refactoring/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Copilot의 에이전트 모드를 작은 편집 이상의 용도로 써본 적이 있다면, 그 고통을 알 겁니다. 파일 쓰기마다, 터미널 명령마다 — 또 권한 프롬프트. 이제 이걸 50개 프로젝트에서 한다고 상상해 보세요. 전혀 재미없죠.&lt;/p&gt;
&lt;p&gt;Azure 팀이 &lt;a href="https://devblogs.microsoft.com/all-things-azure/best-of-both-worlds-for-agentic-refactoring-github-copilot-microvms-via-docker-sandbox/"&gt;GitHub Copilot 에이전트를 위한 Docker Sandbox&lt;/a&gt;에 관한 포스트를 공개했는데, 솔직히 제가 본 에이전틱 툴링 개선 중 가장 실용적인 것 중 하나입니다. 마이크로VM을 활용해 Copilot에게 완전히 격리된 환경을 제공하여 패키지 설치, 빌드 실행, 테스트 실행까지 — 호스트 시스템을 전혀 건드리지 않고 자유롭게 작업할 수 있게 합니다.&lt;/p&gt;
&lt;h2 id="docker-sandbox가-실제로-제공하는-것"&gt;Docker Sandbox가 실제로 제공하는 것&lt;/h2&gt;
&lt;p&gt;핵심 아이디어는 간단합니다: 완전한 Linux 환경을 갖춘 경량 마이크로VM을 띄우고, 워크스페이스를 그 안에 동기화한 다음, Copilot 에이전트가 내부에서 자유롭게 작업하게 하는 것입니다. 작업이 끝나면 변경 사항이 다시 동기화됩니다.&lt;/p&gt;
&lt;p&gt;단순히 &amp;ldquo;컨테이너 안에서 실행하는 것&amp;rdquo; 이상으로 만드는 요소들입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;양방향 워크스페이스 동기화&lt;/strong&gt;로 절대 경로가 보존됩니다. 프로젝트 구조가 샌드박스 안에서도 동일하게 보입니다. 경로 관련 빌드 실패가 없습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;프라이빗 Docker 데몬&lt;/strong&gt;이 마이크로VM 안에서 실행됩니다. 에이전트는 호스트의 Docker 소켓을 마운트하지 않고도 컨테이너를 빌드하고 실행할 수 있습니다. 보안 측면에서 큰 발전입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;HTTP/HTTPS 필터링 프록시&lt;/strong&gt;가 에이전트의 네트워크 접근을 제어합니다. 어떤 레지스트리와 엔드포인트를 허용할지는 여러분이 결정합니다. 샌드박스 내 악의적인 &lt;code&gt;npm install&lt;/code&gt;로 인한 공급망 공격? 차단됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;YOLO 모드&lt;/strong&gt; — 네, 정말로 그렇게 부릅니다. 에이전트가 호스트를 말 그대로 손상시킬 수 없기 때문에 권한 프롬프트 없이 실행됩니다. 모든 파괴적 행위가 격리됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="net-개발자가-주목해야-하는-이유"&gt;.NET 개발자가 주목해야 하는 이유&lt;/h2&gt;
&lt;p&gt;지금 수많은 팀이 직면하고 있는 현대화 작업을 생각해 보세요. 30개 프로젝트가 있는 .NET Framework 솔루션이 있고, .NET 9로 마이그레이션해야 합니다. 수백 개의 파일 변경이 필요합니다 — 프로젝트 파일, 네임스페이스 업데이트, API 교체, NuGet 마이그레이션.&lt;/p&gt;
&lt;p&gt;Docker Sandbox를 사용하면 Copilot 에이전트를 프로젝트에 지정하고, 마이크로VM 안에서 자유롭게 리팩터링하게 한 다음, &lt;code&gt;dotnet build&lt;/code&gt;와 &lt;code&gt;dotnet test&lt;/code&gt;로 검증하고, 실제로 작동하는 변경 사항만 받아들일 수 있습니다. 실험 과정에서 로컬 개발 환경을 실수로 망가뜨릴 위험이 없습니다.&lt;/p&gt;
&lt;p&gt;포스트에서는 &lt;strong&gt;병렬 에이전트 플릿&lt;/strong&gt; 운영도 설명합니다 — 각각 자체 샌드박스에서 서로 다른 프로젝트를 동시에 처리합니다. 대규모 .NET 솔루션이나 마이크로서비스 아키텍처에서는 엄청난 시간 절약입니다. 서비스당 에이전트 하나, 모두 격리 실행, 모두 독립 검증.&lt;/p&gt;
&lt;h2 id="보안-관점이-중요하다"&gt;보안 관점이 중요하다&lt;/h2&gt;
&lt;p&gt;대부분의 사람들이 놓치는 점이 있습니다: AI 에이전트에게 임의의 명령 실행을 허용하면, 여러분의 전체 머신을 맡기는 겁니다. Docker Sandbox는 이 모델을 뒤집습니다. 에이전트는 일회용 환경에서 완전한 자율성을 얻습니다. 네트워크 프록시가 승인된 소스에서만 다운로드할 수 있도록 보장합니다. 호스트 파일시스템, Docker 데몬, 자격 증명은 그대로 유지됩니다.&lt;/p&gt;
&lt;p&gt;컴플라이언스 요구사항이 있는 팀 — 대부분의 엔터프라이즈 .NET 기업이 해당합니다 — 에게 이것은 &amp;ldquo;에이전틱 AI를 사용할 수 없다&amp;quot;와 &amp;ldquo;안전하게 도입할 수 있다&amp;quot;의 차이입니다.&lt;/p&gt;
&lt;h2 id="정리"&gt;정리&lt;/h2&gt;
&lt;p&gt;Docker Sandbox는 에이전틱 코딩의 근본적인 긴장을 해결합니다: 에이전트가 유용하려면 자유가 필요하지만, 호스트 머신에서의 자유는 위험합니다. 마이크로VM은 둘 다 가능하게 합니다. 대규모 .NET 리팩터링이나 현대화를 계획하고 있다면, 지금 설정할 가치가 있습니다. Copilot의 코드 인텔리전스와 안전한 실행 환경의 조합은 프로덕션 팀이 기다려온 바로 그것입니다.&lt;/p&gt;</content:encoded></item><item><title>터미널 감시는 그만: Aspire의 분리 모드가 워크플로를 바꾼다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/</link><pubDate>Fri, 17 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/</guid><description>Aspire 13.2에서는 AppHost를 백그라운드에서 실행하고 터미널을 되찾을 수 있습니다. 새로운 CLI 명령과 에이전트 지원과 결합하면, 생각보다 훨씬 큰 변화입니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-detached-mode-free-your-terminal/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aspire AppHost를 실행할 때마다 터미널이 사라집니다. 잠겨버립니다. Ctrl+C를 누를 때까지 점유된 상태입니다. 빠르게 명령어를 실행해야 하나요? 다른 탭을 엽니다. 로그를 확인하고 싶나요? 또 다른 탭. 작은 불편함이지만 빠르게 쌓입니다.&lt;/p&gt;
&lt;p&gt;Aspire 13.2가 이 문제를 해결합니다. James Newton-King이 &lt;a href="https://devblogs.microsoft.com/aspire/aspire-detached-mode-and-process-management/"&gt;자세한 내용을 작성했는데&lt;/a&gt;, 솔직히 이건 사용하는 순간 바로 작업 방식이 바뀌는 기능 중 하나입니다.&lt;/p&gt;
&lt;h2 id="분리-모드-명령어-하나로-터미널-되찾기"&gt;분리 모드: 명령어 하나로 터미널 되찾기&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이것은 &lt;code&gt;aspire run --detach&lt;/code&gt;의 단축 명령입니다. AppHost가 백그라운드에서 시작되고 터미널이 즉시 돌아옵니다. 추가 탭 없이. 터미널 멀티플렉서 없이. 프롬프트만 준비된 상태로요.&lt;/p&gt;
&lt;h2 id="실행-중인-프로세스-관리하기"&gt;실행 중인 프로세스 관리하기&lt;/h2&gt;
&lt;p&gt;핵심은 이겁니다 — 백그라운드 실행은 실행 중인 것을 관리할 수 있어야만 의미가 있습니다. Aspire 13.2는 바로 이를 위한 완전한 CLI 명령 세트를 제공합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# List all running AppHosts&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire ps
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Inspect the state of a specific AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire describe
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Stream logs from a running AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire logs
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Stop a specific AppHost&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire stop
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이로써 Aspire CLI가 본격적인 프로세스 관리자가 됩니다. 여러 AppHost를 시작하고, 상태를 확인하고, 로그를 추적하고, 종료할 수 있습니다 — 모두 하나의 터미널 세션에서.&lt;/p&gt;
&lt;h2 id="격리-모드와-결합하기"&gt;격리 모드와 결합하기&lt;/h2&gt;
&lt;p&gt;분리 모드는 격리 모드와 자연스럽게 어울립니다. 포트 충돌 없이 같은 프로젝트의 인스턴스 두 개를 백그라운드에서 실행하고 싶다면?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start --isolated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire start --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;각각 랜덤 포트, 별도의 시크릿, 자체 라이프사이클을 갖습니다. &lt;code&gt;aspire ps&lt;/code&gt;로 둘 다 확인하고, &lt;code&gt;aspire stop&lt;/code&gt;으로 필요 없는 것을 중지하세요.&lt;/p&gt;
&lt;h2 id="코딩-에이전트에게-이것이-중요한-이유"&gt;코딩 에이전트에게 이것이 중요한 이유&lt;/h2&gt;
&lt;p&gt;여기서부터 정말 흥미로워집니다. 터미널에서 작업하는 코딩 에이전트가 이제 다음을 할 수 있습니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;aspire start&lt;/code&gt;로 앱 시작&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aspire describe&lt;/code&gt;로 상태 조회&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aspire logs&lt;/code&gt;로 로그를 확인하여 문제 진단&lt;/li&gt;
&lt;li&gt;완료 후 &lt;code&gt;aspire stop&lt;/code&gt;으로 중지&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;모두 터미널 세션을 잃지 않고 수행할 수 있습니다. 분리 모드 이전에는 AppHost를 실행한 에이전트가 자신의 터미널에 갇혀버렸습니다. 이제는 시작, 관찰, 반복, 정리가 가능합니다 — 자율 에이전트에게 기대하는 바로 그 동작입니다.&lt;/p&gt;
&lt;p&gt;Aspire 팀은 이 부분에 공을 들였습니다. &lt;code&gt;aspire agent init&lt;/code&gt;을 실행하면 에이전트에게 이러한 명령을 가르치는 Aspire 스킬 파일이 설정됩니다. 이를 통해 Copilot의 코딩 에이전트 같은 도구가 바로 Aspire 워크로드를 관리할 수 있습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;분리 모드는 단순한 플래그로 위장한 워크플로 업그레이드입니다. 터미널 간 컨텍스트 전환이 사라지고, 에이전트가 스스로를 차단하지 않으며, 새로운 CLI 명령으로 실행 중인 것을 실시간으로 파악할 수 있습니다. 실용적이고, 깔끔하며, 일상 개발 사이클이 눈에 띄게 매끄러워집니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/aspire/aspire-detached-mode-and-process-management/"&gt;전체 글&lt;/a&gt;에서 모든 세부 사항을 확인하고, &lt;code&gt;aspire update --self&lt;/code&gt;로 Aspire 13.2를 설치하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure MCP 도구가 Visual Studio 2022에 기본 탑재 — 확장 프로그램 설치 불필요</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/</guid><description>Azure MCP 도구가 Visual Studio 2022의 Azure 개발 워크로드의 일부로 제공됩니다. 230개 이상의 도구, 45개 Azure 서비스, 설치할 확장 프로그램 제로.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문을 보시려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-tools-built-into-visual-studio-2022/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio에서 별도 확장 프로그램을 통해 Azure MCP 도구를 사용해 왔다면, 그 과정을 잘 아실 겁니다 — VSIX 설치, 재시작, 문제가 안 생기길 바라기, 버전 불일치 관리. 그 번거로움이 사라졌습니다.&lt;/p&gt;
&lt;p&gt;Yun Jung Choi가 &lt;a href="https://devblogs.microsoft.com/visualstudio/azure-mcp-tools-now-ship-built-into-visual-studio-2022-no-extension-required/"&gt;발표&lt;/a&gt;한 바와 같이, Azure MCP 도구가 이제 Visual Studio 2022의 Azure 개발 워크로드의 일부로 직접 제공됩니다. 확장 프로그램 없음. VSIX 없음. 재시작 댄스 없음.&lt;/p&gt;
&lt;h2 id="이것이-실제로-의미하는-것"&gt;이것이 실제로 의미하는 것&lt;/h2&gt;
&lt;p&gt;Visual Studio 2022 버전 17.14.30부터 Azure MCP Server가 Azure 개발 워크로드에 번들로 포함됩니다. 이미 해당 워크로드가 설치되어 있다면, GitHub Copilot Chat에서 활성화하기만 하면 됩니다.&lt;/p&gt;
&lt;p&gt;45개 Azure 서비스에 걸친 230개 이상의 도구 — 채팅 창에서 직접 접근할 수 있습니다. 스토리지 계정 목록 조회, ASP.NET Core 앱 배포, App Service 문제 진단, Log Analytics 쿼리 — 브라우저 탭을 열 필요 없이 모두 가능합니다.&lt;/p&gt;
&lt;h2 id="왜-이것이-들리는-것보다-더-중요한가"&gt;왜 이것이 들리는 것보다 더 중요한가&lt;/h2&gt;
&lt;p&gt;개발자 도구에 대해 이런 말이 있습니다: 추가 단계 하나하나가 마찰이고, 마찰은 도입을 망칩니다. MCP가 별도 확장 프로그램이었을 때는 버전 불일치, 설치 실패, 그리고 업데이트해야 할 것이 하나 더 생긴다는 것을 의미했습니다. 워크로드에 내장된다는 것은:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;단일 업데이트 경로&lt;/strong&gt; — Visual Studio Installer를 통해&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;버전 차이 없음&lt;/strong&gt; — 확장 프로그램과 IDE 간에&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;항상 최신&lt;/strong&gt; — MCP Server가 정기 VS 릴리스와 함께 업데이트&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure를 표준으로 사용하는 팀에게 이것은 큰 의미가 있습니다. 워크로드를 한 번 설치하고, 도구를 활성화하면, 매 세션마다 사용할 수 있습니다.&lt;/p&gt;
&lt;h2 id="이것으로-무엇을-할-수-있는가"&gt;이것으로 무엇을 할 수 있는가&lt;/h2&gt;
&lt;p&gt;도구들은 Copilot Chat를 통해 전체 개발 라이프사이클을 지원합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;학습&lt;/strong&gt; — Azure 서비스, 모범 사례, 아키텍처 패턴에 대해 질문&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설계 및 개발&lt;/strong&gt; — 서비스 추천 받기, 앱 코드 구성&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;배포&lt;/strong&gt; — 리소스 프로비저닝 및 IDE에서 직접 배포&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;문제 해결&lt;/strong&gt; — 로그 쿼리, 리소스 상태 확인, 프로덕션 문제 진단&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;간단한 예시 — Copilot Chat에 다음을 입력해 보세요:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;List my storage accounts in my current subscription.
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;Copilot이 뒤에서 Azure MCP 도구를 호출하고, 구독을 조회하여, 이름, 위치, SKU가 포함된 정리된 목록을 반환합니다. 포털이 필요 없습니다.&lt;/p&gt;
&lt;h2 id="활성화-방법"&gt;활성화 방법&lt;/h2&gt;
&lt;ol&gt;
&lt;li&gt;Visual Studio 2022 &lt;strong&gt;17.14.30&lt;/strong&gt; 이상으로 업데이트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure development&lt;/strong&gt; 워크로드가 설치되어 있는지 확인&lt;/li&gt;
&lt;li&gt;GitHub Copilot Chat 열기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Select tools&lt;/strong&gt; 버튼(렌치 아이콘) 클릭&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure MCP Server&lt;/strong&gt; 활성화&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;끝입니다. 세션 간에 활성화 상태가 유지됩니다.&lt;/p&gt;
&lt;h2 id="한-가지-주의사항"&gt;한 가지 주의사항&lt;/h2&gt;
&lt;p&gt;도구는 기본적으로 비활성화되어 있습니다 — 직접 활성화해야 합니다. 그리고 VS 2026 전용 도구는 VS 2022에서 사용할 수 없습니다. 도구 사용 가능 여부는 Azure 구독 권한에 따라 달라지며, 포털과 동일합니다.&lt;/p&gt;
&lt;h2 id="더-큰-그림"&gt;더 큰 그림&lt;/h2&gt;
&lt;p&gt;이것은 분명한 트렌드의 일부입니다: MCP는 개발자 IDE에서 클라우드 도구를 제공하는 표준이 되어가고 있습니다. 이미 &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;Azure MCP Server 2.0 안정 버전 출시&lt;/a&gt;와 VS Code 및 기타 에디터에서의 MCP 통합을 봐왔습니다. Visual Studio의 워크로드 시스템에 내장하는 것은 자연스러운 발전입니다.&lt;/p&gt;
&lt;p&gt;Visual Studio에서 살다시피 하는 .NET 개발자에게, Azure 포털로 컨텍스트 전환해야 할 이유가 하나 더 사라진 셈입니다. 솔직히, 탭 전환은 적을수록 좋으니까요.&lt;/p&gt;</content:encoded></item><item><title>핀 클러스터링이 드디어 .NET MAUI Maps에 도착 — 프로퍼티 하나, 고통 제로</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</link><pubDate>Thu, 16 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/maui-maps-pin-clustering-finally/</guid><description>.NET MAUI 11 Preview 3에서 Map 컨트롤에 네이티브 핀 클러스터링이 추가되었습니다. 프로퍼티 하나, 독립적인 클러스터링 그룹, 탭 처리 — 모두 내장.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/maui-maps-pin-clustering-finally/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;지도에 핀 100개를 로드했더니 전체가 읽을 수 없는 덩어리가 되는 그 순간, 아시죠? 네, 지금까지 .NET MAUI Maps 경험이 딱 그랬습니다. 이제 끝입니다.&lt;/p&gt;
&lt;p&gt;David Ortinau가 &lt;a href="https://devblogs.microsoft.com/dotnet/pin-clustering-in-dotnet-maui-maps/"&gt;방금 발표했습니다&lt;/a&gt;. .NET MAUI 11 Preview 3에서 Android와 iOS/Mac Catalyst에 핀 클러스터링이 기본 탑재됩니다. 그리고 가장 좋은 점 — 활성화하는 게 말도 안 되게 간단합니다.&lt;/p&gt;
&lt;h2 id="모든-것을-지배하는-하나의-프로퍼티"&gt;모든 것을 지배하는 하나의 프로퍼티&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-xml" data-lang="xml"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nt"&gt;&amp;lt;maps:Map&lt;/span&gt; &lt;span class="na"&gt;IsClusteringEnabled=&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;True&amp;#34;&lt;/span&gt; &lt;span class="nt"&gt;/&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이게 전부입니다. 가까운 핀들이 카운트 배지가 달린 클러스터로 그룹화됩니다. 확대하면 펼쳐지고, 축소하면 접힙니다. 모던한 지도라면 당연히 기대하는 동작 — 이제 프로퍼티 하나로 얻을 수 있습니다.&lt;/p&gt;
&lt;h2 id="독립적인-클러스터링-그룹"&gt;독립적인 클러스터링 그룹&lt;/h2&gt;
&lt;p&gt;여기서부터 흥미로워집니다. 모든 핀이 함께 클러스터링되어야 하는 건 아닙니다. 커피숍과 공원은 다른 것이고, 지도도 그걸 알아야 합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ClusteringIdentifier&lt;/code&gt; 프로퍼티를 사용하면 핀을 독립적인 그룹으로 분리할 수 있습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Pike Place Coffee&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6097&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3331&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;coffee&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Add&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Pin&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Label&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Occidental Square&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Location&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Location&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;47.6064&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="m"&gt;122.3325&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ClusteringIdentifier&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;parks&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;같은 식별자를 가진 핀은 함께 클러스터링됩니다. 다른 식별자는 지리적으로 가까워도 독립적인 클러스터를 형성합니다. 식별자 없음? 기본 그룹. 깔끔하고 예측 가능합니다.&lt;/p&gt;
&lt;h2 id="클러스터-탭-처리"&gt;클러스터 탭 처리&lt;/h2&gt;
&lt;p&gt;사용자가 클러스터를 탭하면 필요한 모든 것이 담긴 &lt;code&gt;ClusterClicked&lt;/code&gt; 이벤트를 받습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;map&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClusterClicked&lt;/span&gt; &lt;span class="p"&gt;+=&lt;/span&gt; &lt;span class="kd"&gt;async&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;sender&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;names&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Join&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;\n&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;e&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Pins&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Select&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;p&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;p&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Label&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;DisplayAlert&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;$&amp;#34;Cluster ({e.Pins.Count} pins)&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;names&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;OK&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// Suppress default zoom-to-cluster behavior:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="c1"&gt;// e.Handled = true;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이벤트 인수로 &lt;code&gt;Pins&lt;/code&gt;(클러스터 내 핀), &lt;code&gt;Location&lt;/code&gt;(지리적 중심), &lt;code&gt;Handled&lt;/code&gt;(기본 줌 동작을 재정의하려면 &lt;code&gt;true&lt;/code&gt;로 설정)를 받습니다. 간단하고, 실용적이고, 정확히 기대한 대로입니다.&lt;/p&gt;
&lt;h2 id="알아두면-좋은-플랫폼-세부사항"&gt;알아두면 좋은 플랫폼 세부사항&lt;/h2&gt;
&lt;p&gt;Android에서는 클러스터링이 줌 변경 시 재계산하는 커스텀 그리드 기반 알고리즘을 사용합니다 — 외부 의존성 없음. iOS와 Mac Catalyst에서는 MapKit의 네이티브 &lt;code&gt;MKClusterAnnotation&lt;/code&gt; 지원을 활용하여 부드럽고 플랫폼 네이티브한 애니메이션을 제공합니다.&lt;/p&gt;
&lt;p&gt;MAUI 팀이 올바른 결정을 내린 사례입니다 — 의미 있는 곳에서 플랫폼에 의존하기.&lt;/p&gt;
&lt;h2 id="왜-이것이-중요한가"&gt;왜 이것이 중요한가&lt;/h2&gt;
&lt;p&gt;핀 클러스터링은 .NET MAUI에서 가장 많이 요청된 기능 중 하나였습니다(&lt;a href="https://github.com/dotnet/maui/issues/11811"&gt;issue #11811&lt;/a&gt;). 당연한 이유가 있습니다. 지도에 위치를 표시하는 모든 앱 — 배송 추적, 매장 찾기, 부동산 — 에 필요합니다. 이전에는 직접 구현하거나 서드파티 라이브러리를 사용해야 했습니다. 이제는 내장되어 있습니다.&lt;/p&gt;
&lt;p&gt;크로스플랫폼 모바일 앱을 만드는 .NET 개발자들에게, 이것은 MAUI를 지도 중심 시나리오에서 진정으로 실용적인 선택으로 만드는 삶의 질 개선입니다.&lt;/p&gt;
&lt;h2 id="시작하기"&gt;시작하기&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://dotnet.microsoft.com/download/dotnet/11.0"&gt;.NET 11 Preview 3&lt;/a&gt;를 설치하고 .NET MAUI 워크로드를 업데이트하세요. &lt;a href="https://github.com/dotnet/maui-samples/tree/main/10.0/UserInterface/Views/Map/MapDemo/WorkingWithMaps"&gt;Maps 샘플&lt;/a&gt;에 바로 사용해볼 수 있는 새로운 클러스터링 페이지가 포함되어 있습니다.&lt;/p&gt;
&lt;p&gt;뭔가 만들어 보세요 — 그리고 지도가 드디어 숨 쉴 수 있게 해주세요.&lt;/p&gt;</content:encoded></item><item><title>.NET 2026년 4월 서비싱 — 오늘 바로 적용해야 할 보안 패치</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/</guid><description>2026년 4월 서비싱 릴리스는 .NET 10, .NET 9, .NET 8, .NET Framework에 걸쳐 6개의 CVE를 패치합니다 — 원격 코드 실행 취약점 2건을 포함합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-april-2026-servicing-security-patches/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;.NET과 .NET Framework의 &lt;a href="https://devblogs.microsoft.com/dotnet/dotnet-and-dotnet-framework-april-2026-servicing-updates/"&gt;2026년 4월 서비싱 업데이트&lt;/a&gt;가 출시되었습니다. 이번에는 빨리 적용하고 싶은 보안 수정 사항이 포함되어 있습니다. 6개의 CVE가 패치되었으며, 그 중 2개는 원격 코드 실행(RCE) 취약점입니다.&lt;/p&gt;
&lt;h2 id="패치된-내용"&gt;패치된 내용&lt;/h2&gt;
&lt;p&gt;빠른 요약은 다음과 같습니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;CVE&lt;/th&gt;
&lt;th&gt;유형&lt;/th&gt;
&lt;th&gt;영향 범위&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-26171&lt;/td&gt;
&lt;td&gt;보안 기능 우회&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32178&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;원격 코드 실행&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-33116&lt;/td&gt;
&lt;td&gt;&lt;strong&gt;원격 코드 실행&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32203&lt;/td&gt;
&lt;td&gt;서비스 거부&lt;/td&gt;
&lt;td&gt;.NET 10, 9, 8 + .NET Framework&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-23666&lt;/td&gt;
&lt;td&gt;서비스 거부&lt;/td&gt;
&lt;td&gt;.NET Framework 3.0–4.8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;CVE-2026-32226&lt;/td&gt;
&lt;td&gt;서비스 거부&lt;/td&gt;
&lt;td&gt;.NET Framework 2.0–4.8.1&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;2개의 RCE CVE(CVE-2026-32178 및 CVE-2026-33116)는 가장 넓은 범위의 .NET 버전에 영향을 미치며 우선적으로 대응해야 합니다.&lt;/p&gt;
&lt;h2 id="업데이트된-버전"&gt;업데이트된 버전&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;.NET 10&lt;/strong&gt;: 10.0.6&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.NET 9&lt;/strong&gt;: 9.0.15&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;.NET 8&lt;/strong&gt;: 8.0.26&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모두 일반적인 채널을 통해 사용할 수 있습니다 — &lt;a href="https://dotnet.microsoft.com/download/dotnet/10.0"&gt;dotnet.microsoft.com&lt;/a&gt;, MCR의 컨테이너 이미지, Linux 패키지 관리자.&lt;/p&gt;
&lt;h2 id="해야-할-일"&gt;해야 할 일&lt;/h2&gt;
&lt;p&gt;프로젝트와 CI/CD 파이프라인을 최신 패치 버전으로 업데이트하세요. 컨테이너를 실행 중이라면 최신 이미지를 풀하세요. .NET Framework를 사용 중이라면 해당 패치에 대해 &lt;a href="https://learn.microsoft.com/dotnet/framework/release-notes/release-notes"&gt;.NET Framework 릴리스 노트&lt;/a&gt;를 확인하세요.&lt;/p&gt;
&lt;p&gt;.NET 10을 프로덕션에서 실행하고 있다면(현재 릴리스입니다), 10.0.6은 필수 업데이트입니다. LTS 트랙의 .NET 9.0.15와 .NET 8.0.26도 마찬가지입니다. 2개의 RCE 취약점은 미룰 수 있는 것이 아닙니다.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2에 MongoDB EF Core와 Azure Data Lake 추가 — 꼭 써봐야 할 두 가지 통합</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/</guid><description>Aspire 13.2에 제로 설정 헬스 체크와 서비스 디스커버리를 갖춘 MongoDB Entity Framework Core 및 Azure Data Lake Storage 통합이 추가되었습니다. 실제로 어떻게 사용하는지 살펴봅니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-mongodb-efcore-data-lake/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aspire 13.2가 &lt;a href="https://devblogs.microsoft.com/aspire/aspire-new-database-integrations/"&gt;두 가지 새로운 데이터베이스 통합&lt;/a&gt;과 함께 출시되었습니다. 주목할 만한 것은 MongoDB Entity Framework Core와 Azure Data Lake Storage입니다. Aspire 앱에서 MongoDB와 EF Core를 사용하고 싶었거나, 서비스 디스커버리가 포함된 Data Lake 워크로드를 연결해야 했다면, 이번 릴리스가 둘 다 제공합니다.&lt;/p&gt;
&lt;h2 id="aspire에서-mongodb가-ef-core를-만나다"&gt;Aspire에서 MongoDB가 EF Core를 만나다&lt;/h2&gt;
&lt;p&gt;이것이 제가 가장 기대하고 있는 통합입니다. Aspire는 한동안 MongoDB를 지원해 왔지만, 항상 원시 드라이버였습니다 — EF Core 없이, &lt;code&gt;DbContext&lt;/code&gt; 없이, 문서에 대한 LINQ 쿼리 없이. 이제 MongoDB에서 완전한 EF Core 경험을 얻을 수 있으며, Aspire의 자동 헬스 체크와 서비스 디스커버리도 함께 제공됩니다.&lt;/p&gt;
&lt;p&gt;설정은 전형적인 Aspire 패턴을 따릅니다. AppHost에서:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;mongodb&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddMongoDB&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;mongodb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithDataVolume&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithLifetime&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;ContainerLifetime&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Persistent&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;apiService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ApiService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;mongodb&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그런 다음 소비 프로젝트에서 EF Core 통합을 추가합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Aspire.MongoDB.EntityFrameworkCore
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그리고 &lt;code&gt;DbContext&lt;/code&gt;를 등록합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddMongoDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;MyDbContext&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;mongodb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;mydb&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이후로는 표준 EF Core입니다. 엔티티를 정의하고, 다른 프로바이더와 마찬가지로 &lt;code&gt;DbContext&lt;/code&gt;를 사용하면 됩니다. 커넥션 풀링, OpenTelemetry 트레이스, 헬스 체크는 통합이 백그라운드에서 처리합니다.&lt;/p&gt;
&lt;p&gt;원시 드라이버로 MongoDB를 사용하면서 커넥션 문자열을 수동으로 설정하던 .NET 개발자들에게 이것은 반가운 개선입니다. Aspire의 서비스 디스커버리를 잃지 않으면서 완전한 EF Core 추상화를 얻을 수 있습니다.&lt;/p&gt;
&lt;h2 id="azure-data-lake-storage-합류"&gt;Azure Data Lake Storage 합류&lt;/h2&gt;
&lt;p&gt;두 번째 큰 추가 사항은 &lt;a href="https://aspire.dev/integrations/cloud/azure/azure-storage-datalake/"&gt;Azure Data Lake Storage (ADLS) 통합&lt;/a&gt;입니다. 데이터 파이프라인, ETL 프로세스 또는 분석 플랫폼을 구축하고 있다면, 이제 다른 Aspire 의존성과 동일한 방식으로 Data Lake 리소스를 연결할 수 있습니다.&lt;/p&gt;
&lt;p&gt;AppHost에서:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddAzureStorage&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;azure-storage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;dataLake&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDataLake&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;fileSystem&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;storage&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddDataLakeFileSystem&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake-file-system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;analyticsService&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddProject&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;Projects&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AnalyticsService&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;analytics&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;dataLake&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;fileSystem&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;소비 프로젝트에서:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddAzureDataLakeServiceClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddAzureDataLakeFileSystemClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;data-lake-file-system&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;수동 커넥션 문자열 관리도, 크레덴셜 찾기도 필요 없습니다. Aspire가 리소스를 프로비저닝하고 주입합니다. 운영 데이터와 분석 워크로드를 모두 다루는 클라우드 네이티브 .NET 앱을 구축하는 우리에게, Data Lake가 Aspire 모델에서 일급 시민처럼 느껴지게 됩니다.&lt;/p&gt;
&lt;h2 id="사소하지만-중요한-수정-사항"&gt;사소하지만 중요한 수정 사항&lt;/h2&gt;
&lt;p&gt;주요 기능 외에도 몇 가지 주목할 만한 개선 사항이 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;MongoDB 커넥션 문자열 수정&lt;/strong&gt; — 데이터베이스 이름 앞의 슬래시가 이제 올바르게 처리됩니다. 우회 방법을 사용하고 있었다면 이제 제거할 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SQL Server 내보내기&lt;/strong&gt; — &lt;code&gt;Aspire.Hosting.SqlServer&lt;/code&gt;가 이제 더 세밀한 제어를 위한 추가 서버 구성 옵션을 내보냅니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;에뮬레이터 업데이트&lt;/strong&gt; — ServiceBus 에뮬레이터 2.0.0, App Configuration 에뮬레이터 1.0.2, CosmosDB 프리뷰 에뮬레이터에 레디니스 체크 추가&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Managed Redis&lt;/strong&gt; — 이제 기본적으로 &lt;code&gt;rediss://&lt;/code&gt;(Redis Secure)를 사용하여 연결이 기본 암호화됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;마지막 항목은 미묘하지만 중요합니다 — 기본 암호화 Redis는 프로덕션에서 설정해야 할 것이 하나 줄어든다는 의미입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Aspire 13.2는 점진적인 릴리스이지만, MongoDB EF Core와 Data Lake 통합은 실질적인 공백을 채웁니다. Aspire에서 MongoDB에 대한 적절한 EF Core 지원을 기다리고 있었거나, Data Lake를 일급 의존성으로 필요로 했다면, &lt;a href="https://get.aspire.dev"&gt;13.2로 업그레이드&lt;/a&gt;하고 사용해 보세요. &lt;code&gt;aspire add&lt;/code&gt; 명령이 필요한 모든 것을 스캐폴딩합니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aspire.dev/whats-new/aspire-13-2/#-integrations-updates"&gt;전체 릴리스 노트&lt;/a&gt;에서 자세한 내용을 확인하고, &lt;a href="https://aspire.dev/integrations/gallery/"&gt;통합 갤러리&lt;/a&gt;에서 전체 목록을 살펴보세요.&lt;/p&gt;</content:encoded></item><item><title>azd update — 모든 패키지 매니저를 지배하는 하나의 명령어</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/</guid><description>Azure Developer CLI에 설치 방법에 관계없이 작동하는 범용 업데이트 명령어가 추가되었습니다 — winget, Homebrew, Chocolatey, 설치 스크립트 모두 지원.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-update-universal-upgrade-command/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;몇 주마다 뜨는 &amp;ldquo;새로운 버전의 azd를 사용할 수 있습니다&amp;rdquo; 메시지 아시죠? &lt;code&gt;azd&lt;/code&gt;를 winget으로 설치했는지, Homebrew인지, 아니면 6개월 전에 실행한 curl 스크립트인지 기억이 안 나서 그냥 무시하게 되는 그 메시지요. 드디어 해결됐습니다.&lt;/p&gt;
&lt;p&gt;Microsoft가 &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-update/"&gt;&lt;code&gt;azd update&lt;/code&gt;&lt;/a&gt;를 출시했습니다 — 원래 어떤 방법으로 설치했든 상관없이 Azure Developer CLI를 최신 버전으로 업데이트하는 단 하나의 명령어입니다. Windows, macOS, Linux — 상관없습니다. 명령어 하나면 됩니다.&lt;/p&gt;
&lt;h2 id="작동-방식"&gt;작동 방식&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd update
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이게 전부입니다. 새로운 기능을 미리 체험하고 싶다면 일일 Insiders 빌드로 전환할 수 있습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd update --channel daily
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd update --channel stable
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 명령어는 현재 설치 방법을 감지하고 내부적으로 적절한 업데이트 메커니즘을 사용합니다. 더 이상 &amp;ldquo;잠깐, 이 컴퓨터에서 winget을 썼었나, choco였나?&amp;rdquo; 고민할 필요 없습니다.&lt;/p&gt;
&lt;h2 id="한-가지-참고사항"&gt;한 가지 참고사항&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd update&lt;/code&gt;는 버전 1.23.x부터 제공됩니다. 이전 버전을 사용 중이라면 원래 설치 방법으로 마지막 수동 업데이트를 한 번만 해주면 됩니다. 그 이후로는 &lt;code&gt;azd update&lt;/code&gt;가 모든 것을 처리합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;azd version&lt;/code&gt;으로 현재 버전을 확인하세요. 새로 설치가 필요하다면 &lt;a href="https://learn.microsoft.com/azure/developer/azure-developer-cli/install-azd"&gt;설치 문서&lt;/a&gt;를 참고하세요.&lt;/p&gt;
&lt;h2 id="왜-중요한가"&gt;왜 중요한가&lt;/h2&gt;
&lt;p&gt;작은 삶의 질 개선이지만, AI 에이전트와 Aspire 앱을 Azure에 배포하기 위해 매일 &lt;code&gt;azd&lt;/code&gt;를 사용하는 우리에게 최신 상태를 유지한다는 것은 &amp;ldquo;그 버그는 최신 버전에서 이미 수정됐습니다&amp;quot;라는 순간이 줄어든다는 의미입니다. 신경 쓸 일이 하나 줄어드는 거죠.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-update/"&gt;전체 발표&lt;/a&gt;와 Jon Gallant의 &lt;a href="https://blog.jongallant.com/2026/04/azd-update"&gt;상세 분석&lt;/a&gt;에서 자세한 내용을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps Server 2026년 4월 패치 — PR 완료 수정 및 보안 업데이트</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/</guid><description>Azure DevOps Server가 패치 3을 받았습니다. PR 완료 실패 수정, 로그아웃 유효성 검사 개선, GitHub Enterprise Server PAT 연결 복원이 포함됩니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-server-april-2026-patch/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;셀프 호스팅 Azure DevOps Server를 운영하는 팀들에게 빠른 안내입니다. Microsoft가 세 가지 수정 사항을 포함한 &lt;a href="https://devblogs.microsoft.com/devops/april-patches-for-azure-devops-server/"&gt;2026년 4월 패치 3&lt;/a&gt;을 릴리스했습니다.&lt;/p&gt;
&lt;h2 id="수정된-내용"&gt;수정된 내용&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Pull Request 완료 실패&lt;/strong&gt; — 작업 항목 자동 완료 중 null 참조 예외로 인해 PR 병합이 실패할 수 있었습니다. 무작위 PR 완료 오류를 겪었다면, 이것이 원인일 가능성이 높습니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;로그아웃 리디렉션 유효성 검사&lt;/strong&gt; — 잠재적인 악성 리디렉션을 방지하기 위해 로그아웃 시 유효성 검사가 개선되었습니다. 빠르게 적용할 가치가 있는 보안 수정입니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Enterprise Server PAT 연결&lt;/strong&gt; — GitHub Enterprise Server에 대한 Personal Access Token 연결 생성이 작동하지 않았는데, 이제 복원되었습니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="업데이트-방법"&gt;업데이트 방법&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://aka.ms/devopsserverpatch3"&gt;패치 3&lt;/a&gt;을 다운로드하고 설치 프로그램을 실행하세요. 패치가 적용되었는지 확인하려면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&amp;lt;patch-installer&amp;gt;.exe CheckInstall
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Azure DevOps Server를 온프레미스에서 운영하고 있다면, Microsoft는 보안과 안정성 모두를 위해 최신 패치를 유지할 것을 강력히 권장합니다. 전체 세부 사항은 &lt;a href="https://learn.microsoft.com/azure/devops/server/release-notes/azuredevopsserver?view=azure-devops#azure-devops-server-patch-3-release-date-april-14-2026"&gt;릴리스 노트&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure Smart Tier GA 출시 — 수명 주기 규칙 없이 Blob Storage 비용 자동 최적화</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/</guid><description>Azure Blob Storage smart tier가 정식 출시되었습니다. 실제 액세스 패턴을 기반으로 hot, cool, cold 티어 간에 객체를 자동으로 이동합니다 — 수명 주기 규칙이 필요 없습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-smart-tier-blob-storage-ga/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Azure Blob Storage 수명 주기 정책을 조정하는 데 시간을 쏟았다가 액세스 패턴이 바뀌면서 다 무너지는 걸 본 적이 있다면, 이 글이 딱 맞습니다. Microsoft가 Azure Blob 및 Data Lake Storage용 &lt;a href="https://azure.microsoft.com/en-us/blog/optimize-object-storage-costs-automatically-with-smart-tier-now-generally-available/"&gt;smart tier의 정식 출시&lt;/a&gt;를 발표했습니다 — 실제 사용량을 기반으로 hot, cool, cold 티어 간에 객체를 자동으로 이동하는 완전 관리형 티어링 기능입니다.&lt;/p&gt;
&lt;h2 id="smart-tier가-실제로-하는-일"&gt;Smart tier가 실제로 하는 일&lt;/h2&gt;
&lt;p&gt;개념은 간단합니다. smart tier는 스토리지 계정 내 각 객체의 마지막 액세스 시간을 지속적으로 평가합니다. 자주 액세스하는 데이터는 hot에 유지되고, 비활성 데이터는 30일 후 cool로, 그리고 60일 후 cold로 이동합니다. 데이터에 다시 액세스하면 즉시 hot으로 승격됩니다. 사이클이 다시 시작됩니다.&lt;/p&gt;
&lt;p&gt;구성할 수명 주기 규칙 없음. 액세스 패턴 예측 없음. 수동 튜닝 없음.&lt;/p&gt;
&lt;p&gt;프리뷰 기간 동안 Microsoft는 &lt;strong&gt;smart tier로 관리되는 용량의 50% 이상이 실제 액세스 패턴을 기반으로 자동으로 더 차가운 티어로 이동했다&lt;/strong&gt;고 보고했습니다. 대규모 스토리지 계정에 대해 의미 있는 비용 절감입니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-왜-중요한가"&gt;.NET 개발자에게 왜 중요한가&lt;/h2&gt;
&lt;p&gt;로그, 텔레메트리, 분석 데이터, 또는 어떤 종류든 계속 늘어나는 데이터 자산을 생성하는 애플리케이션을 구축하고 있다면 — 솔직히, 안 그런 사람이 있나요? — 스토리지 비용은 빠르게 쌓입니다. 기존 방식은 수명 주기 관리 정책을 작성하고, 테스트하고, 앱의 액세스 패턴이 변경되면 다시 조정하는 것이었습니다. Smart tier는 그 전체 워크플로를 제거합니다.&lt;/p&gt;
&lt;p&gt;도움이 되는 실용적인 시나리오들:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;애플리케이션 텔레메트리 및 로그&lt;/strong&gt; — 디버깅 중에는 hot, 몇 주 후에는 거의 액세스하지 않음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;데이터 파이프라인 및 ETL 출력&lt;/strong&gt; — 처리 중에는 집중적으로 액세스, 이후에는 대부분 cold&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;사용자 생성 콘텐츠&lt;/strong&gt; — 최근 업로드는 hot, 오래된 콘텐츠는 점차 냉각&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;백업 및 아카이브 데이터&lt;/strong&gt; — 컴플라이언스를 위해 가끔 액세스, 대부분 유휴 상태&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="설정-방법"&gt;설정 방법&lt;/h2&gt;
&lt;p&gt;Smart tier 활성화는 일회성 구성입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;새 계정&lt;/strong&gt;: 스토리지 계정 생성 시 smart tier를 기본 액세스 티어로 선택 (영역 중복 필요)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;기존 계정&lt;/strong&gt;: blob 액세스 티어를 현재 기본값에서 smart tier로 변경&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;128 KiB보다 작은 객체는 hot에 유지되며 모니터링 요금이 발생하지 않습니다. 그 외의 모든 객체는 티어 전환 요금 없이, 조기 삭제 수수료 없이, 데이터 검색 비용 없이 표준 hot/cool/cold 용량 요금을 지불합니다. 객체당 월별 모니터링 요금이 오케스트레이션을 커버합니다.&lt;/p&gt;
&lt;h2 id="알아야-할-트레이드오프"&gt;알아야 할 트레이드오프&lt;/h2&gt;
&lt;p&gt;Smart tier의 티어링 규칙은 고정입니다 (30일 → cool, 90일 → cold). 사용자 정의 임계값이 필요한 경우 — 예를 들어 특정 워크로드에 대해 7일 후 cool로 이동 — 수명 주기 규칙이 여전히 올바른 선택입니다. 그리고 둘 다 혼합하지 마세요: smart tier로 관리되는 객체에 수명 주기 규칙을 사용하면 충돌할 수 있으므로 피하세요.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;혁명적이진 않지만, 실제 운영상의 골칫거리를 해결합니다. 성장하는 blob storage 계정을 관리하고 있고 수명 주기 정책 유지 관리에 지쳤다면, &lt;a href="https://learn.microsoft.com/en-us/azure/storage/blobs/access-tiers-smart"&gt;smart tier를 활성화&lt;/a&gt;하고 Azure에 맡기세요. 현재 거의 모든 영역 퍼블릭 클라우드 리전에서 사용 가능합니다.&lt;/p&gt;</content:encoded></item><item><title>Azure에서 AI 에이전트를 어디에 호스팅해야 할까? 실용적인 의사결정 가이드</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</link><pubDate>Wed, 15 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/</guid><description>Azure는 원시 컨테이너부터 완전 관리형 Foundry Hosted Agents까지 AI 에이전트를 호스팅하는 6가지 방법을 제공합니다. .NET 워크로드에 적합한 것을 선택하는 방법을 알아보세요.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-ai-agent-hosting-options-guide/"&gt;여기&lt;/a&gt;를 참조하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;지금 .NET으로 AI 에이전트를 구축하고 있다면, 아마 눈치챘을 겁니다: Azure에서 호스팅하는 방법이 &lt;em&gt;정말 많다&lt;/em&gt;는 것을. Container Apps, AKS, Functions, App Service, Foundry Agents, Foundry Hosted Agents — 실제로 하나를 선택해야 할 때까지는 모두 합리적으로 들립니다. Microsoft가 방금 &lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;Azure AI 에이전트 호스팅에 대한 종합 가이드&lt;/a&gt;를 발표했고, .NET 개발자의 실용적인 관점에서 정리해 보겠습니다.&lt;/p&gt;
&lt;h2 id="6가지-옵션-한눈에-보기"&gt;6가지 옵션 한눈에 보기&lt;/h2&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;옵션&lt;/th&gt;
&lt;th&gt;최적 용도&lt;/th&gt;
&lt;th&gt;관리 대상&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Container Apps&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;K8s 복잡성 없이 전체 컨테이너 제어&lt;/td&gt;
&lt;td&gt;관측성, 상태, 라이프사이클&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;AKS&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;엔터프라이즈 컴플라이언스, 멀티 클러스터, 커스텀 네트워킹&lt;/td&gt;
&lt;td&gt;모든 것 (그것이 포인트)&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Azure Functions&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;이벤트 기반 단기 에이전트 작업&lt;/td&gt;
&lt;td&gt;거의 없음 — 진정한 서버리스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;App Service&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;단순 HTTP 에이전트, 예측 가능한 트래픽&lt;/td&gt;
&lt;td&gt;배포, 스케일링 설정&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;포털/SDK를 통한 코드 불필요 에이전트&lt;/td&gt;
&lt;td&gt;거의 없음&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Foundry Hosted Agents&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;관리형 인프라의 커스텀 프레임워크 에이전트&lt;/td&gt;
&lt;td&gt;에이전트 코드만&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;처음 4개는 범용 컴퓨팅입니다 — 에이전트를 실행&lt;em&gt;할 수는&lt;/em&gt; 있지만 그것을 위해 설계된 것은 아닙니다. 마지막 2개는 에이전트 네이티브로, 대화, 도구 호출, 에이전트 라이프사이클을 일급 개념으로 이해합니다.&lt;/p&gt;
&lt;h2 id="foundry-hosted-agents--net-에이전트-개발자를-위한-최적점"&gt;Foundry Hosted Agents — .NET 에이전트 개발자를 위한 최적점&lt;/h2&gt;
&lt;p&gt;제 주목을 끈 부분입니다. Foundry Hosted Agents는 정확히 중간에 위치합니다: 자신의 코드를 실행할 수 있는 유연성(Semantic Kernel, Agent Framework, LangGraph — 무엇이든)을 얻으면서 플랫폼이 인프라, 관측성, 대화 관리를 처리합니다.&lt;/p&gt;
&lt;p&gt;핵심은 &lt;strong&gt;Hosting Adapter&lt;/strong&gt;입니다 — 에이전트 프레임워크를 Foundry 플랫폼에 연결하는 얇은 추상화 레이어입니다. Microsoft Agent Framework의 경우:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.agentserver.agentframework&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;from_agent_framework&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;ChatAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;chat_client&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;AzureAIAgentClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="o"&gt;...&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;tools&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;get_local_time&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="vm"&gt;__name__&lt;/span&gt; &lt;span class="o"&gt;==&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;__main__&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;from_agent_framework&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;run&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이것이 호스팅의 전부입니다. 어댑터가 프로토콜 변환, server-sent events를 통한 스트리밍, 대화 이력, OpenTelemetry 트레이싱을 자동으로 처리합니다. 커스텀 미들웨어도, 수동 배관 작업도 필요 없습니다.&lt;/p&gt;
&lt;h2 id="배포가-진짜-간단합니다"&gt;배포가 진짜 간단합니다&lt;/h2&gt;
&lt;p&gt;이전에 Container Apps에 에이전트를 배포해 봤고 작동하지만, 상태 관리와 관측성을 위한 글루 코드를 많이 작성하게 됩니다. Hosted Agents와 &lt;code&gt;azd&lt;/code&gt;를 사용하면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# AI 에이전트 익스텐션 설치&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ext install azure.ai.agents
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 템플릿에서 초기화&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 빌드, 푸시, 배포 — 완료&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이 하나의 &lt;code&gt;azd up&lt;/code&gt;이 컨테이너를 빌드하고, ACR에 푸시하고, Foundry 프로젝트를 프로비저닝하고, 모델 엔드포인트를 배포하고, 에이전트를 시작합니다. 다섯 단계가 하나의 명령어로 압축됩니다.&lt;/p&gt;
&lt;h2 id="내장-대화-관리"&gt;내장 대화 관리&lt;/h2&gt;
&lt;p&gt;프로덕션에서 가장 많은 시간을 절약하는 부분입니다. 자체 대화 상태 저장소를 구축하는 대신 Hosted Agents가 네이티브로 처리합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 영구 대화 생성&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 첫 번째 턴&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response1&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Remember: my favorite number is 42.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# 두 번째 턴 — 컨텍스트 유지&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;response2&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;MyAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Multiply my favorite number by 10.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Redis 불필요. Cosmos DB 세션 스토어 불필요. 메시지 직렬화를 위한 커스텀 미들웨어 불필요. 플랫폼이 그냥 처리합니다.&lt;/p&gt;
&lt;h2 id="나의-결정-프레임워크"&gt;나의 결정 프레임워크&lt;/h2&gt;
&lt;p&gt;6가지 옵션을 모두 검토한 후의 빠른 멘탈 모델:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;인프라가 필요 없다면?&lt;/strong&gt; → Foundry Agents (포털/SDK, 컨테이너 없음)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;커스텀 에이전트 코드가 있지만 관리형 호스팅을 원한다면?&lt;/strong&gt; → Foundry Hosted Agents&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이벤트 기반 단기 에이전트 작업이 필요하다면?&lt;/strong&gt; → Azure Functions&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;K8s 없이 최대한의 컨테이너 제어가 필요하다면?&lt;/strong&gt; → Container Apps&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;엄격한 컴플라이언스와 멀티 클러스터가 필요하다면?&lt;/strong&gt; → AKS&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;예측 가능한 트래픽의 간단한 HTTP 에이전트라면?&lt;/strong&gt; → App Service&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;Semantic Kernel이나 Microsoft Agent Framework로 구축하는 대부분의 .NET 개발자에게 Hosted Agents가 적절한 출발점일 것입니다. Kubernetes를 관리하거나 자체 관측성 스택을 구축하지 않고도 scale-to-zero, 내장 OpenTelemetry, 대화 관리, 프레임워크 유연성을 얻을 수 있습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Azure의 에이전트 호스팅 환경은 빠르게 성숙하고 있습니다. 오늘 새 AI 에이전트 프로젝트를 시작한다면, 습관적으로 Container Apps나 AKS를 선택하기 전에 Foundry Hosted Agents를 진지하게 고려해 보세요. 관리형 인프라가 실질적인 시간을 절약하고, hosting adapter 패턴으로 프레임워크 선택을 유지할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/all-things-azure/hostedagent/"&gt;Microsoft의 전체 가이드&lt;/a&gt;와 &lt;a href="https://github.com/microsoft-foundry/foundry-samples/tree/main/samples/python/hosted-agents"&gt;Foundry Samples 저장소&lt;/a&gt;에서 작동하는 예제를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>.NET의 Agent Skills가 정말 유연해졌다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</link><pubDate>Tue, 14 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/</guid><description>Microsoft Agent Framework가 이제 스킬을 만드는 세 가지 방법을 지원합니다 — 파일, 클래스, 인라인 코드 — 모두 단일 provider를 통해 조합 가능합니다. 왜 중요한지, 각각 어떻게 사용하는지 설명합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-skills-dotnet-three-authoring-patterns/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Microsoft Agent Framework로 에이전트를 구축해왔다면 흐름은 알고 있을 겁니다: 스킬을 정의하고, provider에 연결하고, 에이전트가 어떤 것을 호출할지 결정하게 합니다. 새로운 것은 스킬을 &lt;em&gt;만드는 방법&lt;/em&gt;이고, 유연성의 향상이 상당합니다.&lt;/p&gt;
&lt;p&gt;최신 업데이트는 에이전트 스킬에 대한 세 가지 작성 패턴을 도입합니다: &lt;strong&gt;파일 기반&lt;/strong&gt;, &lt;strong&gt;클래스 기반&lt;/strong&gt;, &lt;strong&gt;인라인 코드 정의&lt;/strong&gt;. 세 가지 모두 단일 &lt;code&gt;AgentSkillsProviderBuilder&lt;/code&gt;에 연결되므로 라우팅 로직이나 특별한 접착 코드 없이 자유롭게 조합할 수 있습니다. 각 패턴과 언제 사용해야 하는지 설명하겠습니다.&lt;/p&gt;
&lt;h2 id="파일-기반-스킬-시작점"&gt;파일 기반 스킬: 시작점&lt;/h2&gt;
&lt;p&gt;파일 기반 스킬은 말 그대로입니다 — &lt;code&gt;SKILL.md&lt;/code&gt; 파일, 선택적 스크립트, 참조 문서가 있는 디스크의 디렉토리입니다. 에이전트에 새로운 기능을 부여하는 가장 직접적인 방법입니다:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;skills/
└── onboarding-guide/
├── SKILL.md
├── scripts/
│ └── check-provisioning.py
└── references/
└── onboarding-checklist.md
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;&lt;code&gt;SKILL.md&lt;/code&gt;의 프론트매터에서 스킬 이름과 설명을 선언하고, 지시 섹션에서 에이전트에게 스크립트와 참조를 어떻게 사용하는지 알려줍니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-markdown" data-lang="markdown"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;name: onboarding-guide
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;description: &amp;gt;-
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; Walk new hires through their first-week setup checklist.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;---
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="gu"&gt;## Instructions
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;1.&lt;/span&gt; Ask for the employee&amp;#39;s name and start date.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;2.&lt;/span&gt; Run &lt;span class="sb"&gt;`scripts/check-provisioning.py`&lt;/span&gt; to verify accounts.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;3.&lt;/span&gt; Walk through &lt;span class="sb"&gt;`references/onboarding-checklist.md`&lt;/span&gt;.
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;4.&lt;/span&gt; Follow up on incomplete items.
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그런 다음 &lt;code&gt;SubprocessScriptRunner.RunAsync&lt;/code&gt;로 스크립트 실행을 연결합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AgentSkillsProvider&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;SubprocessScriptRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AzureOpenAIClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;ChatClientAgentOptions&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HRAgent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ChatOptions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are a helpful HR assistant.&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AIContextProviders&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;skillsProvider&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;deploymentName&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;에이전트는 자동으로 스킬을 발견하고 계정 상태를 확인해야 할 때 프로비저닝 스크립트를 호출합니다. 깔끔하고 간단합니다.&lt;/p&gt;
&lt;h2 id="클래스-기반-스킬-nuget으로-배포"&gt;클래스 기반 스킬: NuGet으로 배포&lt;/h2&gt;
&lt;p&gt;여기서 팀에게 흥미로워집니다. 클래스 기반 스킬은 &lt;code&gt;AgentClassSkill&amp;lt;T&amp;gt;&lt;/code&gt;에서 파생하며 &lt;code&gt;[AgentSkillResource]&lt;/code&gt;와 &lt;code&gt;[AgentSkillScript]&lt;/code&gt; 같은 속성을 사용하여 프레임워크가 리플렉션을 통해 모든 것을 발견합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;BenefitsEnrollmentSkill&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;AgentClassSkill&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;BenefitsEnrollmentSkill&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="n"&gt;AgentSkillFrontmatter&lt;/span&gt; &lt;span class="n"&gt;Frontmatter&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;benefits-enrollment&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Enroll an employee in health, dental, or vision plans.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;protected&lt;/span&gt; &lt;span class="kd"&gt;override&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Instructions&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Read&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;available&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;plans&lt;/span&gt; &lt;span class="n"&gt;resource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Confirm&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;plan&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;wants&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;enroll&lt;/span&gt; &lt;span class="n"&gt;script&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="n"&gt;complete&lt;/span&gt; &lt;span class="n"&gt;enrollment&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [AgentSkillResource(&amp;#34;available-plans&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Description(&amp;#34;Plan options with monthly pricing.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;AvailablePlans&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="err"&gt;##&lt;/span&gt; &lt;span class="n"&gt;Available&lt;/span&gt; &lt;span class="n"&gt;Plans&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2026&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Health&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="n"&gt;HMO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;0&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Premium&lt;/span&gt; &lt;span class="n"&gt;PPO&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;45&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Dental&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Standard&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;12&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt; &lt;span class="n"&gt;Enhanced&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;25&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;Vision&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Basic&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="err"&gt;$&lt;/span&gt;&lt;span class="m"&gt;8&lt;/span&gt;&lt;span class="p"&gt;/&lt;/span&gt;&lt;span class="n"&gt;month&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [AgentSkillScript(&amp;#34;enroll&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [Description(&amp;#34;Enrolls employee in the specified benefit plan.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;private&lt;/span&gt; &lt;span class="kd"&gt;static&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Enroll&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;planCode&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;bool&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrClient&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;EnrollInPlan&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;success&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;planCode&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;멋진 점은 팀이 이것을 NuGet 패키지로 패키징할 수 있다는 것입니다. 프로젝트에 추가하고, 빌더에 넣으면 파일 기반 스킬과 함께 조율 없이 동작합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AgentSkillsProviderBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BenefitsEnrollmentSkill&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;두 스킬 모두 에이전트의 시스템 프롬프트에 나타납니다. 에이전트가 대화에 따라 어떤 것을 사용할지 결정합니다 — 라우팅 코드가 필요 없습니다.&lt;/p&gt;
&lt;h2 id="인라인-스킬-빠른-브릿지"&gt;인라인 스킬: 빠른 브릿지&lt;/h2&gt;
&lt;p&gt;다른 팀이 정확히 필요한 스킬을 만들고 있는데 다음 스프린트까지 완성되지 않는 그 순간 아시죠? &lt;code&gt;AgentInlineSkill&lt;/code&gt;이 당신의 브릿지입니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;timeOffSkill&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AgentInlineSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;time-off-balance&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Calculate remaining vacation and sick days.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;1.&lt;/span&gt; &lt;span class="n"&gt;Ask&lt;/span&gt; &lt;span class="k"&gt;for&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;employee&lt;/span&gt; &lt;span class="n"&gt;ID&lt;/span&gt; &lt;span class="k"&gt;if&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="n"&gt;provided&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;2.&lt;/span&gt; &lt;span class="n"&gt;Use&lt;/span&gt; &lt;span class="n"&gt;calculate&lt;/span&gt;&lt;span class="p"&gt;-&lt;/span&gt;&lt;span class="n"&gt;balance&lt;/span&gt; &lt;span class="n"&gt;to&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt; &lt;span class="n"&gt;the&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;balance&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="m"&gt;3.&lt;/span&gt; &lt;span class="n"&gt;Present&lt;/span&gt; &lt;span class="n"&gt;used&lt;/span&gt; &lt;span class="n"&gt;and&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="n"&gt;days&lt;/span&gt; &lt;span class="n"&gt;clearly&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;&amp;#34;&amp;#34;)
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AddScript&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;calculate-balance&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetAnnualAllowance&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HrDatabase&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetDaysUsed&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;int&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt; &lt;span class="p"&gt;-&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="n"&gt;JsonSerializer&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Serialize&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="n"&gt;employeeId&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;leaveType&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;totalDays&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;daysUsed&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;remaining&lt;/span&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;});&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;다른 것들처럼 빌더에 추가합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AgentSkillsProviderBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BenefitsEnrollmentSkill&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;NuGet 패키지가 최종 출시되면 인라인 스킬을 클래스 기반 버전으로 교체하면 됩니다. 에이전트는 차이를 모릅니다.&lt;/p&gt;
&lt;p&gt;하지만 인라인 스킬은 브릿지만을 위한 것이 아닙니다. 런타임에 동적으로 스킬을 생성해야 할 때 — 구성에서 로드되는 비즈니스 유닛별 스킬을 생각해보세요 — 또는 스크립트가 DI 컨테이너에 속하지 않는 로컬 상태를 캡처해야 할 때도 올바른 선택입니다.&lt;/p&gt;
&lt;h2 id="스크립트-승인-휴먼-인-더-루프"&gt;스크립트 승인: 휴먼 인 더 루프&lt;/h2&gt;
&lt;p&gt;프로덕션 에이전트를 구축하는 .NET 개발자로서 이 부분이 배포 논의를 정말로 열어줍니다. 일부 스크립트에는 실제 결과가 있습니다 — 누군가를 복리후생에 등록하거나 프로덕션 인프라를 조회하는 것. &lt;code&gt;UseScriptApproval&lt;/code&gt;을 활성화하면 에이전트가 스크립트 실행 전에 일시 중지합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;skillsProvider&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AgentSkillsProviderBuilder&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Path&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Combine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;AppContext&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;BaseDirectory&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;skills&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;BenefitsEnrollmentSkill&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseSkill&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;timeOffSkill&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseFileScriptRunner&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;SubprocessScriptRunner&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;UseScriptApproval&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Build&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;에이전트가 스크립트를 실행하려 할 때, 대신 승인 요청을 반환합니다. 앱이 결정을 수집하고 — 승인 또는 거부 — 에이전트가 그에 따라 계속합니다. 규제 환경에서는 &amp;ldquo;이것을 배포할 수 있다&amp;quot;와 &amp;ldquo;법무팀이 안 된다고 했다&amp;rdquo; 사이의 차이입니다.&lt;/p&gt;
&lt;h2 id="왜-이-조합이-중요한가"&gt;왜 이 조합이 중요한가&lt;/h2&gt;
&lt;p&gt;진정한 힘은 개별 패턴이 아니라 구성에 있습니다. 다음이 가능합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;파일 기반 스킬로 &lt;strong&gt;작게 시작&lt;/strong&gt;하고, 지시를 반복하고, C#을 작성하지 않고도 게시&lt;/li&gt;
&lt;li&gt;다른 팀이 한 줄로 추가할 수 있는 NuGet 패키지로 &lt;strong&gt;재사용 가능한 스킬을 배포&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;em&gt;지금&lt;/em&gt; 필요한 것이 있을 때 인라인 스킬로 &lt;strong&gt;격차를 메움&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;에이전트가 로드해야 할 것만 로드하도록 프레디케이트로 &lt;strong&gt;공유 디렉토리를 필터링&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;프로덕션 시스템을 건드리는 스크립트에 &lt;strong&gt;인간 감독을 추가&lt;/strong&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 모든 것이 &lt;code&gt;AgentSkillsProviderBuilder&lt;/code&gt;를 통해 구성됩니다. 특별한 라우팅 없이, 조건 로직 없이, 스킬 타입 체크 없이.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;.NET의 에이전트 스킬은 이제 진정으로 유연한 작성 모델을 갖추었습니다. 파일 기반 스킬로 프로토타이핑하는 솔로 개발자이든 NuGet을 통해 패키지된 기능을 배포하는 엔터프라이즈 팀이든 패턴이 맞습니다. 그리고 스크립트 승인 메커니즘이 인간 체크포인트가 필요한 환경에서 프로덕션 준비를 가능하게 합니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/agent-framework/agent-skills-in-net-three-ways-to-author-one-provider-to-run-them/"&gt;원본 발표&lt;/a&gt;, Microsoft Learn의 &lt;a href="https://learn.microsoft.com/en-us/agent-framework/agents/skills"&gt;Agent Skills 문서&lt;/a&gt;, GitHub의 &lt;a href="https://github.com/microsoft/agent-framework/tree/main/dotnet/samples/02-agents/AgentSkills"&gt;.NET 샘플&lt;/a&gt;을 확인하고 시작하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure MCP Server 2.0 출시 — 자체 호스팅 에이전트형 클라우드 자동화가 이제 시작됩니다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</link><pubDate>Sat, 11 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/</guid><description>Azure MCP Server 2.0이 자체 호스팅 원격 배포, 57개 Azure 서비스에 걸친 276개 도구, 엔터프라이즈급 보안과 함께 안정화되었습니다. .NET 개발자들이 에이전트형 워크플로우를 구축할 때 알아야 할 내용을 정리했습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-mcp-server-2-self-hosted-agentic-cloud/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;최근에 MCP와 Azure로 뭔가를 구축해본 분이라면 로컬 환경에서는 잘 작동한다는 걸 아실 겁니다. MCP 서버를 연결하고, AI 에이전트가 Azure 리소스와 대화하도록 하고, 끝. 하지만 그 설정을 팀 전체에서 공유해야 하는 순간? 그곳이 바로 복잡해지던 지점이었습니다.&lt;/p&gt;
&lt;p&gt;이제 더 이상 그럴 필요 없습니다. Azure MCP Server &lt;a href="https://devblogs.microsoft.com/azure-sdk/announcing-azure-mcp-server-2-0-stable-release/"&gt;방금 2.0 안정 버전에 도달했고&lt;/a&gt;, 이번 주요 기능은 정확히 엔터프라이즈 팀들이 요청해온 것입니다: &lt;strong&gt;자체 호스팅 원격 MCP 서버 지원&lt;/strong&gt;.&lt;/p&gt;
&lt;h2 id="azure-mcp-server란"&gt;Azure MCP Server란?&lt;/h2&gt;
&lt;p&gt;간단히 정리하겠습니다. Azure MCP Server는 &lt;a href="https://modelcontextprotocol.io/docs/getting-started/intro"&gt;Model Context Protocol&lt;/a&gt; 명세를 구현하고 Azure의 기능을 구조화되고 발견 가능한 도구로 노출하여 AI 에이전트가 호출할 수 있도록 합니다. 에이전트와 Azure 사이의 표준화된 브릿지라고 생각하면 됩니다. 프로비저닝, 배포, 모니터링, 진단, 모든 것이 하나의 일관된 인터페이스를 통해 이루어집니다.&lt;/p&gt;
&lt;p&gt;숫자만 봐도 충분합니다: &lt;strong&gt;57개 Azure 서비스에 걸친 276개의 MCP 도구&lt;/strong&gt;. 정말 강력한 커버리지입니다.&lt;/p&gt;
&lt;h2 id="핵심-자체-호스팅-원격-배포"&gt;핵심: 자체 호스팅 원격 배포&lt;/h2&gt;
&lt;p&gt;이게 중요한 이유는 뭘까요. 로컬 머신에서 MCP를 실행하는 건 개발과 실험에는 충분합니다. 하지만 실제 팀 환경에서는 다음이 필요합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;개발자와 내부 에이전트 시스템을 위한 공유 액세스&lt;/li&gt;
&lt;li&gt;중앙 집중식 구성(테넌트 컨텍스트, 구독 기본값, 텔레메트리)&lt;/li&gt;
&lt;li&gt;엔터프라이즈 네트워크 및 정책 경계&lt;/li&gt;
&lt;li&gt;CI/CD 파이프라인 통합&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure MCP Server 2.0은 이 모든 것을 다룹니다. HTTP 기반 전송, 적절한 인증, 일관된 거버넌스와 함께 중앙에서 관리되는 내부 서비스로 배포할 수 있습니다.&lt;/p&gt;
&lt;p&gt;인증에 대해서는 두 가지 견고한 옵션이 있습니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;Managed Identity&lt;/strong&gt; — &lt;a href="https://aka.ms/azmcp/self-host/foundry"&gt;Microsoft Foundry&lt;/a&gt;와 함께 실행할 때&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;On-Behalf-Of (OBO) flow&lt;/strong&gt; — 로그인한 사용자의 컨텍스트를 사용하여 Azure API를 호출하는 OpenID Connect 위임&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;이 OBO 흐름은 우리 .NET 개발자들에게 특히 흥미롭습니다. 이는 에이전트형 워크플로우가 과도한 권한을 가진 서비스 계정이 아닌 실제 사용자의 권한으로 작동할 수 있다는 의미입니다. 최소 권한 원칙이 처음부터 내장되어 있는 것입니다.&lt;/p&gt;
&lt;h2 id="보안-강화"&gt;보안 강화&lt;/h2&gt;
&lt;p&gt;단순한 기능 릴리스가 아닙니다. 보안 측면의 업그레이드이기도 합니다. 2.0 릴리스는 다음을 추가합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;더 강화된 엔드포인트 검증&lt;/li&gt;
&lt;li&gt;쿼리 지향 도구의 주입 패턴에 대한 보호&lt;/li&gt;
&lt;li&gt;개발 환경을 위한 더 엄격한 격리 제어&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;MCP를 공유 서비스로 노출할 거라면, 이러한 보안 조치들은 정말 중요합니다.&lt;/p&gt;
&lt;h2 id="어디서-사용할-수-있나요"&gt;어디서 사용할 수 있나요?&lt;/h2&gt;
&lt;p&gt;클라이언트 호환성 범위는 매우 넓습니다. Azure MCP Server 2.0은 다음과 함께 작동합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;IDE&lt;/strong&gt;: VS Code, Visual Studio, IntelliJ, Eclipse, Cursor&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;CLI 에이전트&lt;/strong&gt;: GitHub Copilot CLI, Claude Code&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;독립 실행형&lt;/strong&gt;: 간단한 설정을 위한 로컬 서버&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;자체 호스팅 원격&lt;/strong&gt;: 2.0의 새로운 주인공&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;또한 Azure US Government와 21Vianet에 의해 운영되는 Azure를 위한 소버린 클라우드 지원이 있으며, 이는 규제 대상 배포에 필수적입니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-왜-중요한가요"&gt;.NET 개발자에게 왜 중요한가요?&lt;/h2&gt;
&lt;p&gt;Semantic Kernel, Microsoft Agent Framework, 또는 자체 오케스트레이션이든 .NET으로 에이전트형 애플리케이션을 구축하고 있다면, Azure MCP Server 2.0은 에이전트가 Azure 인프라와 상호작용할 수 있는 프로덕션 준비 방식을 제공합니다. 커스텀 REST 래퍼 없음. 서비스별 통합 패턴 없음. 오직 MCP뿐입니다.&lt;/p&gt;
&lt;p&gt;며칠 전에 출시된 &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;MCP Apps용 유창한 API&lt;/a&gt;와 함께라면, .NET MCP 생태계는 빠르게 성숙해지고 있습니다.&lt;/p&gt;
&lt;h2 id="시작하기"&gt;시작하기&lt;/h2&gt;
&lt;p&gt;자신의 경로를 선택하세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp"&gt;GitHub Repo&lt;/a&gt;&lt;/strong&gt; — 소스 코드, 문서, 모든 것&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/docker"&gt;Docker Image&lt;/a&gt;&lt;/strong&gt; — 컨테이너화된 배포&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/download/vscode"&gt;VS Code Extension&lt;/a&gt;&lt;/strong&gt; — IDE 통합&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;&lt;a href="https://aka.ms/azmcp/self-host"&gt;Self-hosting guide&lt;/a&gt;&lt;/strong&gt; — 2.0의 주요 기능&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마치며"&gt;마치며&lt;/h2&gt;
&lt;p&gt;Azure MCP Server 2.0은 데모에서는 화려해 보이지 않지만 실제로는 모든 것을 바꾸는 인프라 업그레이드입니다. 적절한 인증, 보안 강화, 소버린 클라우드 지원과 함께하는 자체 호스팅 원격 MCP는 MCP가 Azure에서 실제 에이전트형 워크플로우를 구축하는 실제 팀을 위해 준비되었다는 의미입니다. &amp;ldquo;엔터프라이즈 준비 완료&amp;quot;라는 신호를 기다리고 있었다면, 이것이 바로 그 신호입니다.&lt;/p&gt;</content:encoded></item><item><title>.NET Aspire 13.2는 AI 에이전트의 가장 친한 친구가 되고 싶어한다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/</guid><description>Aspire 13.2가 에이전틱 개발에 올인합니다 — 구조화된 CLI 출력, 격리된 실행, 자동 복구 환경, 그리고 완전한 OpenTelemetry 데이터로 AI 에이전트가 실제로 앱을 빌드, 실행, 관찰할 수 있게 합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-agentic-development-build-run-observe/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;AI 코딩 에이전트가 꽤 괜찮은 코드를 작성해서 기대했는데, 그것을 실제로 &lt;em&gt;실행&lt;/em&gt;하려고 하면 전부 무너지는 그 순간 아시죠? 포트 충돌, 고스트 프로세스, 잘못된 환경 변수 — 갑자기 에이전트가 기능을 만드는 대신 시작 문제를 디버깅하느라 토큰을 소모합니다.&lt;/p&gt;
&lt;p&gt;Aspire 팀이 바로 이 문제에 대한 &lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;정말 사려 깊은 글&lt;/a&gt;을 발표했고, 그들의 답은 설득력이 있습니다: Aspire 13.2는 인간만을 위한 것이 아니라 AI 에이전트를 위해서도 설계되었습니다.&lt;/p&gt;
&lt;h2 id="문제는-현실입니다"&gt;문제는 현실입니다&lt;/h2&gt;
&lt;p&gt;AI 에이전트는 코드 작성에 놀라운 능력을 보여줍니다. 하지만 작동하는 풀스택 앱을 배포하려면 파일 생성 이상의 것이 필요합니다. 서비스를 올바른 순서로 시작하고, 포트를 관리하고, 환경 변수를 설정하고, 데이터베이스를 연결하고, 문제가 생겼을 때 피드백을 받아야 합니다. 현재 대부분의 에이전트는 이 모든 것을 시행착오로 처리합니다 — 명령 실행, 에러 출력 읽기, 재시도.&lt;/p&gt;
&lt;p&gt;Markdown 지침, 커스텀 스킬, 프롬프트를 쌓아올려 가이드하려 하지만, 이것들은 예측 불가능하고 컴파일할 수 없으며 파싱하는 것만으로도 토큰이 듭니다. Aspire 팀은 핵심 인사이트를 정확히 짚었습니다: 에이전트에게 필요한 것은 &lt;strong&gt;컴파일러와 구조화된 API&lt;/strong&gt;이지, 더 많은 Markdown이 아닙니다.&lt;/p&gt;
&lt;h2 id="에이전트-인프라로서의-aspire"&gt;에이전트 인프라로서의 Aspire&lt;/h2&gt;
&lt;p&gt;Aspire 13.2가 에이전틱 개발 테이블에 가져오는 것들:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;전체 스택을 타입이 있는 코드로.&lt;/strong&gt; AppHost가 앱의 전체 토폴로지 — API, 프론트엔드, 데이터베이스, 캐시 — 를 컴파일 가능한 TypeScript 또는 C#로 정의합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-typescript" data-lang="typescript"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;import&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt; &lt;span class="kr"&gt;from&lt;/span&gt; &lt;span class="s1"&gt;&amp;#39;./.modules/aspire.js&amp;#39;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;createBuilder&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;postgres&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addPostgres&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;pg&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;).&lt;/span&gt;&lt;span class="nx"&gt;addDatabase&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;catalog&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;cache&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addRedis&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;cache&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kr"&gt;const&lt;/span&gt; &lt;span class="nx"&gt;api&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addNodeApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./api&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;src/index.ts&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withHttpEndpoint&lt;/span&gt;&lt;span class="p"&gt;({&lt;/span&gt; &lt;span class="nx"&gt;env&lt;/span&gt;&lt;span class="o"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;PORT&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;postgres&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;cache&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;addViteApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;./frontend&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;withReference&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;waitFor&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="nx"&gt;api&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="nx"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="nx"&gt;build&lt;/span&gt;&lt;span class="p"&gt;().&lt;/span&gt;&lt;span class="nx"&gt;run&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;에이전트는 이것을 읽어 앱 토폴로지를 이해하고, 리소스를 추가하고, 연결을 설정하고, &lt;em&gt;검증을 위해 빌드&lt;/em&gt;할 수 있습니다. 컴파일러가 뭔가 잘못되면 즉시 알려줍니다. 추측 불필요, 설정 파일에 대한 시행착오 불필요.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;하나의 명령으로 모두 지배.&lt;/strong&gt; 에이전트가 &lt;code&gt;docker compose up&lt;/code&gt;, &lt;code&gt;npm run dev&lt;/code&gt;, 데이터베이스 시작 스크립트를 저글링하는 대신, 모든 것이 &lt;code&gt;aspire start&lt;/code&gt; 하나입니다. 모든 리소스가 올바른 순서로, 올바른 포트에, 올바른 설정으로 시작됩니다. 장시간 실행 프로세스도 에이전트를 멈추지 않습니다 — Aspire가 관리합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;병렬 에이전트를 위한 격리 모드.&lt;/strong&gt; &lt;code&gt;--isolated&lt;/code&gt;를 사용하면 각 Aspire 실행이 자체 랜덤 포트와 별도의 사용자 시크릿을 갖습니다. 여러 에이전트가 git worktree에서 작업 중인가요? 충돌하지 않습니다. 이것은 VS Code의 백그라운드 에이전트처럼 병렬 환경을 생성하는 도구에 매우 중요합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;텔레메트리를 통한 에이전트의 눈.&lt;/strong&gt; 여기서 정말 강력해집니다. Aspire CLI는 개발 중 완전한 OpenTelemetry 데이터를 노출합니다 — 트레이스, 메트릭, 구조화된 로그. 에이전트가 콘솔 출력을 읽고 최선을 바라는 것이 아닙니다. 서비스 간 실패한 요청을 추적하고, 느린 엔드포인트를 프로파일링하고, 정확히 어디서 문제가 발생하는지 파악할 수 있습니다. 개발 루프에 프로덕션급 관찰 가능성이 있는 것입니다.&lt;/p&gt;
&lt;h2 id="볼링-범퍼-비유"&gt;볼링 범퍼 비유&lt;/h2&gt;
&lt;p&gt;Aspire 팀은 훌륭한 비유를 사용합니다: Aspire를 AI 에이전트를 위한 볼링 레인 범퍼라고 생각하세요. 에이전트가 완벽하지 않다면 (그리고 완벽하지 않을 것입니다), 범퍼가 거터볼을 치지 않도록 막아줍니다. 스택 정의가 잘못된 구성을 방지하고, 컴파일러가 오류를 잡고, CLI가 프로세스 관리를 담당하고, 텔레메트리가 피드백 루프를 제공합니다.&lt;/p&gt;
&lt;p&gt;이것을 Playwright CLI 같은 것과 결합하면, 에이전트가 실제로 앱을 &lt;em&gt;사용&lt;/em&gt;할 수 있습니다 — 플로우를 클릭하고, DOM을 확인하고, 텔레메트리에서 깨진 것을 보고, 코드를 수정하고, 재시작하고, 다시 테스트합니다. 빌드, 실행, 관찰, 수정. 이것이 우리가 추구해온 자율 개발 루프입니다.&lt;/p&gt;
&lt;h2 id="시작하기"&gt;시작하기&lt;/h2&gt;
&lt;p&gt;Aspire가 처음이세요? &lt;a href="https://get.aspire.dev"&gt;get.aspire.dev&lt;/a&gt;에서 CLI를 설치하고 &lt;a href="https://aspire.dev/get-started/first-app"&gt;시작 가이드&lt;/a&gt;를 따르세요.&lt;/p&gt;
&lt;p&gt;이미 Aspire를 사용 중이세요? &lt;code&gt;aspire update --self&lt;/code&gt;를 실행하여 13.2를 받고, 좋아하는 코딩 에이전트를 레포에 연결하세요. Aspire의 가드레일이 있으면 에이전트가 얼마나 더 멀리까지 갈 수 있는지 놀라실 수 있습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Aspire 13.2는 더 이상 단순한 분산 앱 프레임워크가 아닙니다 — 필수적인 에이전트 인프라가 되고 있습니다. 구조화된 스택 정의, 원커맨드 시작, 격리된 병렬 실행, 실시간 텔레메트리가 AI 에이전트에게 코드 작성에서 앱 배포로 넘어가는 데 필요한 모든 것을 제공합니다.&lt;/p&gt;
&lt;p&gt;Aspire 팀의 &lt;a href="https://devblogs.microsoft.com/aspire/agentic-dev-aspirations/"&gt;전체 포스트&lt;/a&gt;에서 모든 세부사항과 데모 비디오를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Aspire의 격리 모드가 병렬 개발의 포트 충돌 악몽을 해결한다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/</guid><description>Aspire 13.2가 --isolated 모드를 도입합니다: 랜덤 포트, 분리된 시크릿, 동일한 AppHost의 여러 인스턴스를 실행할 때 충돌 제로. AI 에이전트, worktree, 병렬 워크플로우에 완벽합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-isolated-mode-parallel-instances/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;같은 프로젝트의 두 인스턴스를 동시에 실행하려고 해본 적이 있다면, 그 고통을 알 것입니다. 포트 8080이 이미 사용 중입니다. 포트 17370이 점유되어 있습니다. 뭔가를 kill하고, 재시작하고, 환경 변수를 저글링하는 — 생산성 킬러입니다.&lt;/p&gt;
&lt;p&gt;이 문제는 나아지는 게 아니라 악화되고 있습니다. AI 에이전트가 독립적으로 작업하기 위해 git worktree를 만듭니다. 백그라운드 에이전트가 별도의 환경을 생성합니다. 개발자가 피처 브랜치를 위해 같은 레포를 두 번 체크아웃합니다. 이 모든 시나리오가 같은 벽에 부딪힙니다: 같은 앱의 두 인스턴스가 같은 포트를 놓고 싸우는 것입니다.&lt;/p&gt;
&lt;p&gt;Aspire 13.2가 단 하나의 플래그로 이것을 해결합니다. Aspire 팀의 James Newton-King이 &lt;a href="https://devblogs.microsoft.com/aspire/aspire-isolated-mode-parallel-development/"&gt;전체 상세 내용을 작성했는데&lt;/a&gt;, &amp;ldquo;왜 진작 이게 없었지?&amp;ldquo;라는 기능 중 하나입니다.&lt;/p&gt;
&lt;h2 id="해결책---isolated"&gt;해결책: &lt;code&gt;--isolated&lt;/code&gt;&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;끝입니다. 각 실행이 다음을 얻습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;랜덤 포트&lt;/strong&gt; — 인스턴스 간 충돌 없음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;격리된 사용자 시크릿&lt;/strong&gt; — 연결 문자열과 API 키가 인스턴스별로 분리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;수동 포트 재할당이 필요 없습니다. 환경 변수 저글링도 필요 없습니다. 각 실행이 자동으로 깨끗하고 충돌 없는 환경을 얻습니다.&lt;/p&gt;
&lt;h2 id="이-기능이-빛나는-실제-시나리오"&gt;이 기능이 빛나는 실제 시나리오&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;다중 체크아웃.&lt;/strong&gt; 한 디렉토리에 피처 브랜치가 있고 다른 디렉토리에 버그픽스가 있는 경우:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/projects/my-app-feature
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;# Terminal 2&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; ~/projects/my-app-bugfix
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire run --isolated
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;둘 다 충돌 없이 실행됩니다. 대시보드에서 무엇이 어디서 실행 중인지 확인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;VS Code의 백그라운드 에이전트.&lt;/strong&gt; Copilot Chat의 백그라운드 에이전트가 코드에 독립적으로 작업하기 위해 git worktree를 만들면, Aspire AppHost를 실행해야 할 수 있습니다. &lt;code&gt;--isolated&lt;/code&gt; 없이는 기본 worktree와 포트 충돌이 발생합니다. 이것이 있으면 두 인스턴스 모두 문제없이 동작합니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;aspire agent init&lt;/code&gt;에 포함된 Aspire 스킬은 worktree에서 작업할 때 &lt;code&gt;--isolated&lt;/code&gt;를 사용하도록 에이전트에게 자동으로 지시합니다. 따라서 Copilot의 백그라운드 에이전트는 이것을 기본적으로 처리할 것입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;개발과 병행하는 통합 테스트.&lt;/strong&gt; 기능을 계속 만들면서 라이브 AppHost에 대해 테스트를 실행해야 하나요? 격리 모드는 각 컨텍스트에 자체 포트와 설정을 제공합니다.&lt;/p&gt;
&lt;h2 id="내부-작동-원리"&gt;내부 작동 원리&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;--isolated&lt;/code&gt;를 전달하면, CLI가 해당 실행을 위한 고유 인스턴스 ID를 생성합니다. 이것이 두 가지 동작을 구동합니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;포트 랜덤화&lt;/strong&gt; — AppHost 설정에 정의된 예측 가능한 포트에 바인딩하는 대신, 격리 모드는 모든 것에 대해 사용 가능한 랜덤 포트를 선택합니다 — 대시보드, 서비스 엔드포인트, 전부. 서비스 디스커버리가 자동으로 조정되어 어떤 포트에 할당되든 서비스들이 서로를 찾습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;시크릿 격리&lt;/strong&gt; — 각 격리된 실행은 인스턴스 ID로 키가 지정된 자체 사용자 시크릿 저장소를 갖습니다. 한 실행의 연결 문자열과 API 키가 다른 실행으로 누출되지 않습니다.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;코드 변경은 필요 없습니다. Aspire의 서비스 디스커버리가 런타임에 엔드포인트를 해석하므로, 포트 할당에 관계없이 모든 것이 올바르게 연결됩니다.&lt;/p&gt;
&lt;h2 id="언제-사용할-것인가"&gt;언제 사용할 것인가&lt;/h2&gt;
&lt;p&gt;같은 AppHost의 여러 인스턴스를 동시에 실행할 때 &lt;code&gt;--isolated&lt;/code&gt;를 사용하세요 — 병렬 개발, 자동화된 테스트, AI 에이전트, 또는 git worktree 어떤 경우든. 예측 가능한 포트를 선호하는 단일 인스턴스 개발에는 일반 &lt;code&gt;aspire run&lt;/code&gt;이 여전히 잘 작동합니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;격리 모드는 실제적이고 점점 더 흔해지는 문제를 해결하는 작은 기능입니다. AI 지원 개발이 더 많은 병렬 워크플로우 — 다중 에이전트, 다중 worktree, 다중 컨텍스트 — 로 우리를 밀어붙이는 만큼, 포트 경쟁 없이 또 다른 인스턴스를 간단히 띄울 수 있는 능력은 필수적입니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/aspire/aspire-isolated-mode-parallel-development/"&gt;전체 포스트&lt;/a&gt;에서 모든 기술적 세부사항을 확인하고, &lt;code&gt;aspire update --self&lt;/code&gt;로 13.2를 받아 시도해 보세요.&lt;/p&gt;</content:encoded></item><item><title>Azure Functions의 MCP 서버를 Foundry 에이전트에 연결하는 방법</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/</guid><description>MCP 서버를 한 번 구축하고 Azure Functions에 배포한 다음, 적절한 인증으로 Microsoft Foundry 에이전트에 연결하세요. 도구는 어디서나 작동합니다 — VS Code, Cursor, 그리고 이제 엔터프라이즈 AI 에이전트에서도.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-agents-mcp-servers-azure-functions/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MCP 생태계에서 제가 좋아하는 점이 있습니다: 서버를 한 번 구축하면 어디서나 작동한다는 것입니다. VS Code, Visual Studio, Cursor, ChatGPT — 모든 MCP 클라이언트가 여러분의 도구를 발견하고 사용할 수 있습니다. 이제 Microsoft가 그 목록에 또 다른 소비자를 추가하고 있습니다: Foundry 에이전트입니다.&lt;/p&gt;
&lt;p&gt;Azure SDK 팀의 Lily Ma가 Azure Functions에 배포된 MCP 서버를 Microsoft Foundry 에이전트에 연결하는 &lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;실용 가이드를 발표&lt;/a&gt;했습니다. 이미 MCP 서버가 있다면 순수한 부가가치입니다 — 재구축이 필요 없습니다.&lt;/p&gt;
&lt;h2 id="이-조합이-합리적인-이유"&gt;이 조합이 합리적인 이유&lt;/h2&gt;
&lt;p&gt;Azure Functions는 MCP 서버 호스팅을 위한 확장 가능한 인프라, 기본 제공 인증, 서버리스 과금을 제공합니다. Microsoft Foundry는 추론하고, 계획하고, 행동할 수 있는 AI 에이전트를 제공합니다. 둘을 연결하면 커스텀 도구 — 데이터베이스 쿼리, 비즈니스 API 호출, 검증 로직 실행 — 가 엔터프라이즈 AI 에이전트가 자율적으로 발견하고 사용할 수 있는 기능이 됩니다.&lt;/p&gt;
&lt;p&gt;핵심 포인트: MCP 서버는 그대로 유지됩니다. Foundry를 또 다른 소비자로 추가하는 것뿐입니다. VS Code 설정에서 작동하는 동일한 도구가 이제 팀이나 고객이 상호작용하는 AI 에이전트를 구동합니다.&lt;/p&gt;
&lt;h2 id="인증-옵션"&gt;인증 옵션&lt;/h2&gt;
&lt;p&gt;여기서 이 글이 진정한 가치를 제공합니다. 시나리오에 따른 네 가지 인증 방법:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;방법&lt;/th&gt;
&lt;th&gt;사용 사례&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;키 기반&lt;/strong&gt; (기본)&lt;/td&gt;
&lt;td&gt;개발 또는 Entra 인증 없는 서버&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;Microsoft Entra&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;관리 ID를 사용한 프로덕션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;OAuth 아이덴티티 패스스루&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;각 사용자가 개별 인증하는 프로덕션&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;strong&gt;인증 없음&lt;/strong&gt;&lt;/td&gt;
&lt;td&gt;개발/테스트 또는 공개 데이터만&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;프로덕션에서는 에이전트 ID를 사용한 Microsoft Entra가 권장 경로입니다. OAuth 아이덴티티 패스스루는 사용자 컨텍스트가 중요할 때 사용합니다 — 에이전트가 사용자에게 로그인을 요청하고, 각 요청이 사용자 자신의 토큰을 전달합니다.&lt;/p&gt;
&lt;h2 id="설정하기"&gt;설정하기&lt;/h2&gt;
&lt;p&gt;대략적인 흐름:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;MCP 서버를 Azure Functions에 배포&lt;/strong&gt; — &lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;.NET&lt;/a&gt;, Python, TypeScript, Java 샘플 제공&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;함수 앱에서 기본 제공 MCP 인증 활성화&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;엔드포인트 URL 가져오기&lt;/strong&gt; — &lt;code&gt;https://&amp;lt;FUNCTION_APP_NAME&amp;gt;.azurewebsites.net/runtime/webhooks/mcp&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry에 MCP 서버를 도구로 추가&lt;/strong&gt; — 포털에서 에이전트로 이동, 새 MCP 도구 추가, 엔드포인트와 자격 증명 제공&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;그런 다음 Agent Builder 플레이그라운드에서 도구 중 하나를 트리거할 프롬프트를 보내 테스트합니다.&lt;/p&gt;
&lt;h2 id="제-의견"&gt;제 의견&lt;/h2&gt;
&lt;p&gt;여기서의 조합성 이야기는 정말 강력해지고 있습니다. .NET(또는 Python, TypeScript, Java)으로 MCP 서버를 한 번 구축하고, Azure Functions에 배포하면, 모든 MCP 호환 클라이언트가 사용할 수 있습니다 — 코딩 도구, 채팅 앱, 그리고 이제 엔터프라이즈 AI 에이전트. 실제로 작동하는 &amp;ldquo;한 번 작성, 어디서나 사용&amp;rdquo; 패턴입니다.&lt;/p&gt;
&lt;p&gt;특히 .NET 개발자에게 &lt;a href="https://github.com/Azure-Samples/remote-mcp-functions-dotnet"&gt;Azure Functions MCP 확장&lt;/a&gt;이 이를 간단하게 만들어줍니다. 도구를 Azure Functions로 정의하고, 배포하면, Azure Functions가 제공하는 모든 보안과 확장성을 갖춘 프로덕션 등급의 MCP 서버를 갖게 됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Azure Functions에서 MCP 도구를 실행하고 있다면, Foundry 에이전트에 연결하는 것은 빠른 성과입니다 — 커스텀 도구가 적절한 인증을 갖춘 엔터프라이즈 AI 기능이 되며, 서버 자체의 코드 변경은 없습니다.&lt;/p&gt;
&lt;p&gt;각 인증 방법에 대한 단계별 안내는 &lt;a href="https://devblogs.microsoft.com/azure-sdk/give-your-foundry-agent-custom-tools-with-mcp-servers-on-azure-functions/"&gt;전체 가이드&lt;/a&gt;를, 프로덕션 설정에 대해서는 &lt;a href="https://learn.microsoft.com/azure/azure-functions/functions-mcp-foundry-tools?tabs=entra%2Cmcp-extension%2Cfoundry"&gt;상세 문서&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>GitHub Copilot의 모더나이제이션 평가는 아직 사용하지 않고 있는 최고의 마이그레이션 도구</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/</guid><description>GitHub Copilot의 모더나이제이션 확장은 단순히 코드 변경을 제안하는 것이 아니라, 실행 가능한 이슈, Azure 대상 비교, 협업 워크플로가 포함된 완전한 마이그레이션 평가를 생성합니다. 평가 문서가 모든 것의 핵심인 이유를 설명합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/dotnet-modernization-assessment-github-copilot/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;레거시 .NET Framework 앱을 최신 .NET으로 마이그레이션하는 것은 모두가 해야 한다는 것을 알지만 아무도 시작하고 싶어하지 않는 작업 중 하나입니다. 단순히 &amp;ldquo;대상 프레임워크 변경&amp;quot;으로 끝나지 않습니다. 사라진 API, 더 이상 존재하지 않는 패키지, 완전히 다르게 작동하는 호스팅 모델, 그리고 무엇을 컨테이너화하고, 무엇을 다시 작성하고, 무엇을 그대로 둘지에 대한 수백만 가지 작은 결정이 있습니다.&lt;/p&gt;
&lt;p&gt;Jeffrey Fritz가 &lt;a href="https://devblogs.microsoft.com/dotnet/your-migrations-source-of-truth-the-modernization-assessment/"&gt;GitHub Copilot의 모더나이제이션 평가에 대한 심층 분석&lt;/a&gt;을 발표했는데, 솔직히? .NET에서 본 최고의 마이그레이션 도구입니다. 코드 생성 때문이 아닙니다 — 그건 이제 기본입니다. 생성하는 평가 문서 때문입니다.&lt;/p&gt;
&lt;h2 id="단순한-코드-제안-엔진이-아닙니다"&gt;단순한 코드 제안 엔진이 아닙니다&lt;/h2&gt;
&lt;p&gt;VS Code 확장은 &lt;strong&gt;평가 → 계획 → 실행&lt;/strong&gt; 모델을 따릅니다. 평가 단계는 전체 코드베이스를 분석하고 모든 것을 캡처하는 구조화된 문서를 생성합니다: 무엇을 변경해야 하는지, 어떤 Azure 리소스를 프로비저닝해야 하는지, 어떤 배포 모델을 사용해야 하는지. 이후의 모든 것 — Infrastructure as Code, 컨테이너화, 배포 매니페스트 — 은 평가 결과에서 흘러나옵니다.&lt;/p&gt;
&lt;p&gt;평가는 프로젝트의 &lt;code&gt;.github/modernize/assessment/&lt;/code&gt;에 저장됩니다. 각 실행은 독립적인 보고서를 생성하므로 이력을 쌓아가며 이슈를 수정함에 따라 마이그레이션 태세가 어떻게 발전하는지 추적할 수 있습니다.&lt;/p&gt;
&lt;h2 id="두-가지-시작-방법"&gt;두 가지 시작 방법&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;권장 평가&lt;/strong&gt; — 빠른 경로. 큐레이션된 도메인(Java/.NET 업그레이드, 클라우드 준비, 보안)에서 선택하고 구성을 건드리지 않고도 의미 있는 결과를 얻습니다. 앱의 현재 상태를 처음 확인하기에 좋습니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;사용자 정의 평가&lt;/strong&gt; — 표적화된 경로. 분석할 내용을 정확히 구성: 대상 컴퓨팅(App Service, AKS, Container Apps), 대상 OS, 컨테이너화 분석. 여러 Azure 대상을 선택하여 마이그레이션 접근 방식을 나란히 비교합니다.&lt;/p&gt;
&lt;p&gt;그 비교 뷰는 정말 유용합니다. App Service에서 필수 이슈가 3개인 앱이 AKS에서는 7개일 수 있습니다. 둘 다 보는 것은 마이그레이션 경로를 결정하기 전에 호스팅 결정을 내리는 데 도움이 됩니다.&lt;/p&gt;
&lt;h2 id="이슈-분류는-실행-가능합니다"&gt;이슈 분류는 실행 가능합니다&lt;/h2&gt;
&lt;p&gt;각 이슈에는 심각도 수준이 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;필수&lt;/strong&gt; — 수정해야 하며, 그렇지 않으면 마이그레이션 실패&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;잠재적&lt;/strong&gt; — 마이그레이션에 영향을 줄 수 있으며, 인간의 판단이 필요&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;선택적&lt;/strong&gt; — 권장 개선 사항, 마이그레이션을 차단하지 않음&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;그리고 각 이슈는 영향받는 파일과 줄 번호에 링크되고, 무엇이 잘못되었고 왜 대상 플랫폼에 중요한지에 대한 상세한 설명을 제공하며, 구체적인 수정 단계를 제시하고(&amp;ldquo;이걸 고쳐&amp;quot;가 아닌), 공식 문서 링크를 포함합니다.&lt;/p&gt;
&lt;p&gt;개별 이슈를 개발자에게 전달할 수 있으며, 그들은 조치에 필요한 모든 것을 갖추고 있습니다. 이것이 &amp;ldquo;문제가 있다&amp;quot;고 알려주는 도구와 &amp;ldquo;해결 방법&amp;quot;을 알려주는 도구의 차이입니다.&lt;/p&gt;
&lt;h2 id="다루는-업그레이드-경로"&gt;다루는 업그레이드 경로&lt;/h2&gt;
&lt;p&gt;.NET 구체적으로:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;.NET Framework → .NET 10&lt;/li&gt;
&lt;li&gt;ASP.NET → ASP.NET Core&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;각 업그레이드 경로에는 어떤 API가 제거되었는지, 어떤 패턴에 직접적인 등가물이 없는지, 어떤 보안 이슈에 주의가 필요한지 아는 탐지 규칙이 있습니다.&lt;/p&gt;
&lt;p&gt;여러 앱을 관리하는 팀을 위해 다중 레포 배치 평가를 지원하는 CLI도 있습니다 — 모든 레포를 클론하고, 전부 평가하고, 앱별 보고서와 통합된 포트폴리오 뷰를 얻을 수 있습니다.&lt;/p&gt;
&lt;h2 id="제-의견"&gt;제 의견&lt;/h2&gt;
&lt;p&gt;레거시 .NET Framework 앱을 보유하고 있다면(솔직히, 대부분의 엔터프라이즈 팀이 그렇습니다), 이것이 시작해야 할 &lt;em&gt;바로 그&lt;/em&gt; 도구입니다. 평가 문서만으로도 시간 투자의 가치가 있습니다 — 모호한 &amp;ldquo;현대화해야 한다&amp;quot;를 명확한 전진 경로가 있는 구체적이고 우선순위가 매겨진 작업 항목 목록으로 변환합니다.&lt;/p&gt;
&lt;p&gt;협업 워크플로도 영리합니다: 평가를 내보내고, 팀과 공유하고, 재실행 없이 가져옵니다. 의사결정자가 도구를 실행하는 사람이 아닌 아키텍처 리뷰? 커버됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;GitHub Copilot의 모더나이제이션 평가는 .NET 마이그레이션을 무섭고 정의되지 않은 프로젝트에서 구조화되고 추적 가능한 프로세스로 변환합니다. 권장 평가로 시작하여 현재 위치를 확인한 다음, 사용자 정의 평가로 Azure 대상을 비교하고 마이그레이션 계획을 수립하세요.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/dotnet/your-migrations-source-of-truth-the-modernization-assessment/"&gt;전체 워크스루&lt;/a&gt;를 읽고 &lt;a href="https://aka.ms/ghcp-appmod/vscode-ext"&gt;VS Code 확장&lt;/a&gt;을 받아 자신의 코드베이스에서 사용해 보세요.&lt;/p&gt;</content:encoded></item><item><title>MCP Apps에 Fluent API 도입 — .NET에서 3단계로 풍부한 AI 도구 UI 구축</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/</guid><description>Azure Functions의 MCP Apps용 새로운 Fluent 구성 API를 사용하면 몇 줄의 코드만으로 모든 .NET MCP 도구를 뷰, 권한, CSP 정책이 포함된 완전한 앱으로 변환할 수 있습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/mcp-fluent-api-azure-functions-dotnet/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;MCP 도구는 AI 에이전트에게 기능을 부여하는 데 훌륭합니다. 하지만 도구가 사용자에게 무언가를 보여줘야 한다면요? 대시보드, 폼, 인터랙티브 시각화 같은 것들이요. 바로 여기서 MCP Apps가 등장하며, 이제 훨씬 더 쉽게 만들 수 있게 되었습니다.&lt;/p&gt;
&lt;p&gt;Azure SDK 팀의 Lilian Kasem이 .NET Azure Functions의 MCP Apps를 위한 &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;새로운 Fluent 구성 API를 발표&lt;/a&gt;했습니다. 왜 처음부터 이렇게 간단하지 않았을까 싶은 그런 개발자 경험 개선입니다.&lt;/p&gt;
&lt;h2 id="mcp-apps란"&gt;MCP Apps란?&lt;/h2&gt;
&lt;p&gt;MCP Apps는 Model Context Protocol을 확장하여 도구가 자체 UI 뷰, 정적 에셋, 보안 제어를 가질 수 있게 합니다. 단순히 텍스트를 반환하는 대신 MCP 도구가 완전한 HTML 경험을 렌더링할 수 있습니다 — 인터랙티브 대시보드, 데이터 시각화, 구성 폼 — 모두 AI 에이전트가 호출 가능하고 MCP 클라이언트를 통해 사용자에게 표시됩니다.&lt;/p&gt;
&lt;p&gt;문제는 이 모든 것을 수동으로 연결하려면 MCP 스펙을 깊이 이해해야 했다는 것입니다: &lt;code&gt;ui://&lt;/code&gt; URI, 특수 MIME 타입, 도구와 리소스 간의 메타데이터 조정. 어렵지는 않지만 번거로웠습니다.&lt;/p&gt;
&lt;h2 id="fluent-api-3단계"&gt;Fluent API 3단계&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;1단계: 함수를 정의합니다.&lt;/strong&gt; 표준 Azure Functions MCP 도구:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt;[Function(nameof(HelloApp))]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;HelloApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [McpToolTrigger(&amp;#34;HelloApp&amp;#34;, &amp;#34;A simple MCP App that says hello.&amp;#34;)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;ToolInvocationContext&lt;/span&gt; &lt;span class="n"&gt;context&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;return&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;Hello from app&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;2단계: MCP App으로 승격시킵니다.&lt;/strong&gt; 프로그램 시작 시:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConfigureMcpTool&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;HelloApp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsMcpApp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;app&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/hello-app.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithTitle&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Hello App&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithPermissions&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardWrite&lt;/span&gt; &lt;span class="p"&gt;|&lt;/span&gt; &lt;span class="n"&gt;McpAppPermissions&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ClipboardRead&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowBaseUri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://www.microsoft.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;3단계: HTML 뷰를 추가합니다.&lt;/strong&gt; 필요한 UI로 &lt;code&gt;assets/hello-app.html&lt;/code&gt;을 생성합니다.&lt;/p&gt;
&lt;p&gt;끝입니다. Fluent API가 MCP 프로토콜의 모든 배관 작업을 처리합니다 — 합성 리소스 함수 생성, 올바른 MIME 타입 설정, 도구와 뷰를 연결하는 메타데이터 주입.&lt;/p&gt;
&lt;h2 id="api-설계가-훌륭합니다"&gt;API 설계가 훌륭합니다&lt;/h2&gt;
&lt;p&gt;특히 마음에 드는 점 몇 가지:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;뷰 소스가 유연합니다.&lt;/strong&gt; 디스크의 파일에서 HTML을 제공하거나, 독립 배포를 위해 리소스를 어셈블리에 직접 포함할 수 있습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromFile&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;assets/my-view.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithView&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpViewSource&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromEmbeddedResource&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;MyApp.Resources.view.html&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;CSP가 조합 가능합니다.&lt;/strong&gt; 최소 권한 원칙에 따라 앱에 필요한 출처를 명시적으로 허용합니다. &lt;code&gt;WithCsp&lt;/code&gt;를 여러 번 호출하면 출처가 누적됩니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithCsp&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;csp&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;csp&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ConnectTo&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://api.example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;LoadResourcesFrom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://cdn.example.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AllowFrame&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://youtube.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;})&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;가시성 제어.&lt;/strong&gt; 도구를 LLM에만 표시, 호스트 UI에만 표시, 또는 둘 다에 표시할 수 있습니다. UI만 렌더링하고 모델에서 호출되지 않아야 하는 도구를 원하시나요? 간단합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WithVisibility&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;McpVisibility&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;App&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="c1"&gt;// UI-only, hidden from the model&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="시작하기"&gt;시작하기&lt;/h2&gt;
&lt;p&gt;프리뷰 패키지를 추가합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dotnet add package Microsoft.Azure.Functions.Worker.Extensions.Mcp --version 1.5.0-preview.1
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이미 Azure Functions로 MCP 도구를 만들고 있다면 패키지 업데이트만 하면 됩니다. 개념이 처음이라면 &lt;a href="https://learn.microsoft.com/azure/azure-functions/scenario-mcp-apps?tabs=bash%2Clinux&amp;amp;pivots=programming-language-csharp"&gt;MCP Apps 빠른 시작&lt;/a&gt;이 가장 좋은 출발점입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;MCP Apps는 AI 도구 분야에서 가장 흥미로운 발전 중 하나입니다 — 단순히 &lt;em&gt;무언가를 하는&lt;/em&gt; 것이 아니라 사용자에게 &lt;em&gt;무언가를 보여줄 수 있는&lt;/em&gt; 도구. Fluent API는 프로토콜 복잡성을 제거하고 중요한 것에 집중하게 해줍니다: 도구의 로직과 UI.&lt;/p&gt;
&lt;p&gt;완전한 API 리퍼런스와 예제는 &lt;a href="https://devblogs.microsoft.com/azure-sdk/mcp-as-easy-as-1-2-3-introducing-the-fluent-api-for-mcp-apps/"&gt;전체 게시물&lt;/a&gt;을 읽어보세요.&lt;/p&gt;</content:encoded></item><item><title>Microsoft Foundry 2026년 3월 — GPT-5.4, Agent Service GA, 그리고 모든 것을 바꾸는 SDK 리프레시</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/</guid><description>Microsoft Foundry의 2026년 3월 업데이트는 대규모입니다: Agent Service가 GA에 도달, GPT-5.4가 안정적인 추론을 제공, azure-ai-projects SDK가 모든 언어에서 안정화, Fireworks AI가 오픈 모델을 Azure에 제공합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/microsoft-foundry-march-2026-whats-new/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;월간 &amp;ldquo;Microsoft Foundry 새 소식&amp;rdquo; 포스트는 보통 점진적 개선과 가끔의 헤드라인 기능이 섞여 있습니다. &lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;2026년 3월판&lt;/a&gt;은요? 기본적으로 전부 헤드라인 기능입니다. Foundry Agent Service가 GA에 도달하고, GPT-5.4가 프로덕션용으로 출시되고, SDK가 대규모 안정 릴리스를 받고, Fireworks AI가 오픈 모델 추론을 Azure에 가져옵니다. .NET 개발자에게 중요한 것이 무엇인지 살펴보겠습니다.&lt;/p&gt;
&lt;h2 id="foundry-agent-service가-프로덕션-준비-완료"&gt;Foundry Agent Service가 프로덕션 준비 완료&lt;/h2&gt;
&lt;p&gt;이것이 가장 큰 뉴스입니다. 차세대 에이전트 런타임이 정식 출시되었습니다 — OpenAI Responses API 위에 구축되었으며, OpenAI 에이전트와 와이어 호환되고, 여러 제공업체의 모델에 개방되어 있습니다. 오늘 Responses API로 구축하고 있다면, Foundry로 마이그레이션하면 기존 에이전트 로직 위에 엔터프라이즈 보안, 프라이빗 네트워킹, Entra RBAC, 전체 트레이싱, 그리고 평가가 추가됩니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;project_client&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;주요 추가 사항: 엔드투엔드 프라이빗 네트워킹, MCP 인증 확장(OAuth 패스스루 포함), 음성 대 음성 에이전트를 위한 Voice Live 프리뷰, 6개 신규 리전에서의 호스팅 에이전트.&lt;/p&gt;
&lt;h2 id="gpt-54--순수한-지능보다-신뢰성"&gt;GPT-5.4 — 순수한 지능보다 신뢰성&lt;/h2&gt;
&lt;p&gt;GPT-5.4는 더 똑똑해지는 것이 아닙니다. 더 신뢰할 수 있게 되는 것입니다. 긴 상호작용에서의 강력한 추론, 더 나은 지시 준수, 워크플로 중간 실패 감소, 통합된 컴퓨터 사용 기능. 프로덕션 에이전트에게는 이러한 신뢰성이 벤치마크 점수보다 훨씬 중요합니다.&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;모델&lt;/th&gt;
&lt;th&gt;가격 (백만 토큰당)&lt;/th&gt;
&lt;th&gt;최적 용도&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 (≤272K)&lt;/td&gt;
&lt;td&gt;$2.50 / $15 출력&lt;/td&gt;
&lt;td&gt;프로덕션 에이전트, 코딩, 문서 워크플로&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Pro&lt;/td&gt;
&lt;td&gt;$30 / $180 출력&lt;/td&gt;
&lt;td&gt;심층 분석, 과학적 추론&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;GPT-5.4 Mini&lt;/td&gt;
&lt;td&gt;비용 효율적&lt;/td&gt;
&lt;td&gt;분류, 추출, 경량 도구 호출&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;스마트한 전략은 라우팅입니다: GPT-5.4 Mini가 대용량·저지연 작업을 처리하고 GPT-5.4가 추론이 무거운 요청을 담당합니다.&lt;/p&gt;
&lt;h2 id="sdk가-드디어-안정화"&gt;SDK가 드디어 안정화&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azure-ai-projects&lt;/code&gt; SDK가 모든 언어에서 안정 릴리스를 발표했습니다 — Python 2.0.0, JS/TS 2.0.0, Java 2.0.0, 그리고 .NET 2.0.0 (4월 1일). &lt;code&gt;azure-ai-agents&lt;/code&gt; 의존성은 사라졌습니다 — 모든 것이 &lt;code&gt;AIProjectClient&lt;/code&gt; 아래에 있습니다. &lt;code&gt;pip install azure-ai-projects&lt;/code&gt;로 설치하면 패키지가 &lt;code&gt;openai&lt;/code&gt;과 &lt;code&gt;azure-identity&lt;/code&gt;를 직접 의존성으로 번들합니다.&lt;/p&gt;
&lt;p&gt;.NET 개발자에게 이는 Foundry 전체 기능에 대한 단일 NuGet 패키지를 의미합니다. 더 이상 별도의 에이전트 SDK를 겹쳐 사용할 필요가 없습니다.&lt;/p&gt;
&lt;h2 id="fireworks-ai가-오픈-모델을-azure에-제공"&gt;Fireworks AI가 오픈 모델을 Azure에 제공&lt;/h2&gt;
&lt;p&gt;아마도 아키텍처적으로 가장 흥미로운 추가: Fireworks AI가 매일 13조 이상의 토큰을 ~180K 요청/초로 처리하며, 이제 Foundry를 통해 사용 가능합니다. DeepSeek V3.2, gpt-oss-120b, Kimi K2.5, MiniMax M2.5가 출시 시 제공됩니다.&lt;/p&gt;
&lt;p&gt;진짜 이야기는 &lt;strong&gt;bring-your-own-weights&lt;/strong&gt; — 서빙 스택을 변경하지 않고 어디에서나 양자화되거나 파인튜닝된 가중치를 업로드할 수 있습니다. 서버리스 토큰당 과금 또는 프로비저닝된 처리량으로 배포하세요.&lt;/p&gt;
&lt;h2 id="기타-하이라이트"&gt;기타 하이라이트&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Phi-4 Reasoning Vision 15B&lt;/strong&gt; — 차트, 다이어그램, 문서 레이아웃을 위한 멀티모달 추론&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Evaluations GA&lt;/strong&gt; — Azure Monitor에 연결된 지속적 프로덕션 모니터링과 함께 즉시 사용 가능한 평가기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Priority Processing&lt;/strong&gt; (프리뷰) — 지연 민감 워크로드를 위한 전용 컴퓨트 레인&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Voice Live&lt;/strong&gt; — Foundry 에이전트에 직접 연결되는 음성 대 음성 런타임&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tracing GA&lt;/strong&gt; — 정렬 및 필터링이 가능한 엔드투엔드 에이전트 트레이스 검사&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;PromptFlow 지원 종료&lt;/strong&gt; — 2027년 1월까지 Microsoft Framework Workflows로 마이그레이션&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;2026년 3월은 Foundry의 전환점입니다. Agent Service GA, 모든 언어의 안정 SDK, 신뢰할 수 있는 프로덕션 에이전트를 위한 GPT-5.4, Fireworks AI를 통한 오픈 모델 추론 — 플랫폼이 본격적인 워크로드를 위해 준비되었습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/foundry/whats-new-in-microsoft-foundry-mar-2026/"&gt;전체 요약&lt;/a&gt;을 읽고 &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;첫 번째 에이전트를 구축&lt;/a&gt;하여 시작하세요.&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server — AI 에이전트에게 데이터베이스 접근을 제공하는 올바른 방법</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/</guid><description>Data API builder의 SQL MCP Server는 스키마를 노출하거나 NL2SQL에 의존하지 않고 AI 에이전트에게 안전하고 결정론적인 데이터베이스 접근을 제공합니다. RBAC, 캐싱, 다중 데이터베이스 지원 — 모두 기본 제공.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/sql-mcp-server-data-api-builder/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;솔직히 말합시다: 오늘날 사용 가능한 대부분의 데이터베이스 MCP 서버는 무섭습니다. 자연어 쿼리를 받아서 즉석에서 SQL을 생성하고 프로덕션 데이터에 대해 실행합니다. 뭐가 잘못될 수 있을까요? (전부요. 전부 잘못될 수 있습니다.)&lt;/p&gt;
&lt;p&gt;Azure SQL 팀이 방금 &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;SQL MCP Server를 발표&lt;/a&gt;했는데, 근본적으로 다른 접근 방식을 취합니다. Data API builder(DAB) 2.0의 기능으로 구축되어, AI 에이전트에게 구조화되고 결정론적인 데이터베이스 작업 접근을 제공합니다 — NL2SQL 없이, 스키마 노출 없이, 매 단계마다 완전한 RBAC와 함께.&lt;/p&gt;
&lt;h2 id="왜-nl2sql이-아닌가"&gt;왜 NL2SQL이 아닌가?&lt;/h2&gt;
&lt;p&gt;이것이 가장 흥미로운 설계 결정입니다. 모델은 결정론적이지 않으며, 복잡한 쿼리가 미묘한 오류를 생성할 가능성이 가장 높습니다. 사용자가 AI가 생성해주길 바라는 바로 그 쿼리가 비결정론적으로 생성될 때 가장 많은 검토가 필요한 쿼리이기도 합니다.&lt;/p&gt;
&lt;p&gt;대신, SQL MCP Server는 &lt;strong&gt;NL2DAB&lt;/strong&gt; 접근 방식을 사용합니다. 에이전트는 Data API builder의 엔티티 추상화 레이어와 내장 쿼리 빌더로 작업하여 정확하고 잘 형성된 T-SQL을 결정론적으로 생성합니다. 사용자에게는 같은 결과이지만, 환각된 JOIN이나 우발적인 데이터 노출 위험이 없습니다.&lt;/p&gt;
&lt;h2 id="7개의-도구-700개가-아닌"&gt;7개의 도구, 700개가 아닌&lt;/h2&gt;
&lt;p&gt;SQL MCP Server는 데이터베이스 크기에 관계없이 정확히 7개의 DML 도구를 노출합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;describe_entities&lt;/code&gt; — 사용 가능한 엔티티 및 작업 발견&lt;/li&gt;
&lt;li&gt;&lt;code&gt;create_record&lt;/code&gt; — 행 삽입&lt;/li&gt;
&lt;li&gt;&lt;code&gt;read_records&lt;/code&gt; — 테이블 및 뷰 쿼리&lt;/li&gt;
&lt;li&gt;&lt;code&gt;update_record&lt;/code&gt; — 행 수정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;delete_record&lt;/code&gt; — 행 삭제&lt;/li&gt;
&lt;li&gt;&lt;code&gt;execute_entity&lt;/code&gt; — 저장 프로시저 실행&lt;/li&gt;
&lt;li&gt;&lt;code&gt;aggregate_records&lt;/code&gt; — 집계 쿼리&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이것은 현명합니다. 컨텍스트 윈도우는 에이전트의 사고 공간이기 때문입니다. 수백 개의 도구 정의로 채우면 추론을 위한 공간이 줄어듭니다. 7개의 고정 도구는 에이전트를 &lt;em&gt;탐색&lt;/em&gt;이 아닌 &lt;em&gt;사고&lt;/em&gt;에 집중하게 합니다.&lt;/p&gt;
&lt;p&gt;각 도구는 개별적으로 활성화하거나 비활성화할 수 있습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="s2"&gt;&amp;#34;runtime&amp;#34;&lt;/span&gt;&lt;span class="err"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;path&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;/mcp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;dml-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;describe-entities&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;create-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;read-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;update-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;delete-record&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;execute-entity&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;aggregate-records&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="세-가지-명령으로-시작"&gt;세 가지 명령으로 시작&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab init &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --database-type mssql &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --connection-string &lt;span class="s2"&gt;&amp;#34;@env(&amp;#39;sql_connection_string&amp;#39;)&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab add Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --source dbo.Customers &lt;span class="se"&gt;\
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; --permissions &lt;span class="s2"&gt;&amp;#34;anonymous:*&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;dab start
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이것으로 Customers 테이블을 노출하는 SQL MCP Server가 실행됩니다. 엔티티 추상화 레이어는 이름과 열에 별칭을 지정하고, 역할별로 필드를 제한하며, 에이전트가 보는 것을 정확히 제어할 수 있게 합니다 — 내부 스키마 세부 정보를 노출하지 않으면서.&lt;/p&gt;
&lt;h2 id="보안-이야기는-탄탄합니다"&gt;보안 이야기는 탄탄합니다&lt;/h2&gt;
&lt;p&gt;여기서 Data API builder의 성숙도가 빛을 발합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;모든 계층에서 RBAC&lt;/strong&gt; — 각 엔티티가 어떤 역할이 읽기, 생성, 업데이트, 삭제할 수 있는지, 어떤 필드가 표시되는지 정의&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Azure Key Vault 통합&lt;/strong&gt; — 연결 문자열과 비밀을 안전하게 관리&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Microsoft Entra + 커스텀 OAuth&lt;/strong&gt; — 프로덕션 등급 인증&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Content Security Policy&lt;/strong&gt; — 에이전트는 원시 SQL이 아닌 통제된 계약을 통해 상호작용&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;스키마 추상화는 특히 중요합니다. 내부 테이블 및 열 이름은 에이전트에게 절대 노출되지 않습니다. AI 상호작용에 의미 있는 엔티티, 별칭, 설명을 정의합니다 — 데이터베이스 ERD 다이어그램이 아니라.&lt;/p&gt;
&lt;h2 id="멀티-데이터베이스-및-멀티-프로토콜"&gt;멀티 데이터베이스 및 멀티 프로토콜&lt;/h2&gt;
&lt;p&gt;SQL MCP Server는 Microsoft SQL, PostgreSQL, Azure Cosmos DB, MySQL을 지원합니다. DAB의 기능이므로 동일한 구성에서 REST, GraphQL, MCP 엔드포인트를 동시에 얻을 수 있습니다. 동일한 엔티티 정의, 동일한 RBAC 규칙, 동일한 보안 — 세 가지 프로토콜 모두에서.&lt;/p&gt;
&lt;p&gt;DAB 2.0의 자동 구성은 빠른 프로토타이핑을 위해 추상화를 줄이고 싶다면 데이터베이스를 검사하고 구성을 동적으로 빌드할 수도 있습니다.&lt;/p&gt;
&lt;h2 id="제-의견"&gt;제 의견&lt;/h2&gt;
&lt;p&gt;이것이 AI 에이전트를 위한 엔터프라이즈 데이터베이스 접근이 작동해야 하는 방식입니다. &amp;ldquo;LLM아, SQL 좀 써줘, 프로덕션에 YOLO 할게&amp;quot;가 아닙니다. 대신: 잘 정의된 엔티티 레이어, 결정론적 쿼리 생성, 매 단계의 RBAC, 캐싱, 모니터링, 텔레메트리. 최고의 의미로 지루합니다.&lt;/p&gt;
&lt;p&gt;.NET 개발자에게 통합 이야기는 깔끔합니다 — DAB는 .NET 도구이고, MCP Server는 컨테이너로 실행되며, 대부분이 이미 사용하고 있는 Azure SQL과 함께 작동합니다. 데이터 접근이 필요한 AI 에이전트를 구축한다면 여기서 시작하세요.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;SQL MCP Server는 무료, 오픈소스이며 어디서나 실행됩니다. AI 에이전트에게 안전한 데이터베이스 접근을 제공하기 위한 Microsoft의 규범적 접근 방식입니다. 시작하려면 &lt;a href="https://devblogs.microsoft.com/azure-sql/introducing-sql-mcp-server/"&gt;전체 게시물&lt;/a&gt;과 &lt;a href="https://aka.ms/sql/mcp"&gt;문서&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.116 — Agents 앱에 키보드 내비게이션과 파일 컨텍스트 자동완성 추가</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/</guid><description>VS Code 1.116은 Agents 앱 개선에 집중합니다 — 전용 키바인딩, 접근성 개선, 파일 컨텍스트 자동완성, CSS @import 링크 해석.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-116-agents-app-updates/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VS Code 1.116은 2026년 4월 릴리스입니다. 최근 몇몇 업데이트보다 가벼운 편이지만, 변경 사항은 집중적이고 의미 있습니다 — 특히 Agents 앱을 매일 사용하고 있다면요.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;공식 릴리스 노트&lt;/a&gt;를 바탕으로 무엇이 추가되었는지 살펴보겠습니다.&lt;/p&gt;
&lt;h2 id="agents-앱-개선-사항"&gt;Agents 앱 개선 사항&lt;/h2&gt;
&lt;p&gt;Agents 앱은 일상 워크플로에 진정한 차이를 만드는 사용성 개선으로 계속 성숙해지고 있습니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;전용 키바인딩&lt;/strong&gt; — 이제 변경 사항 뷰, 변경 사항 내의 파일 트리, 그리고 채팅 커스터마이제이션 뷰에 전용 명령과 키보드 단축키로 포커스를 맞출 수 있습니다. Agents 앱에서 여기저기 클릭하며 탐색하고 있었다면, 이제 완전한 키보드 기반 워크플로가 가능합니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;접근성 도움말 대화상자&lt;/strong&gt; — 채팅 입력 상자에서 &lt;code&gt;Alt+F1&lt;/code&gt;을 누르면 사용 가능한 명령과 키바인딩을 보여주는 접근성 도움말 대화상자가 열립니다. 스크린 리더 사용자는 안내 방송의 상세도도 제어할 수 있습니다. 좋은 접근성은 모든 사람에게 도움이 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;파일 컨텍스트 자동완성&lt;/strong&gt; — Agents 앱 채팅에서 &lt;code&gt;#&lt;/code&gt;을 입력하면 현재 워크스페이스 범위의 파일 컨텍스트 자동완성이 트리거됩니다. 모든 상호작용을 빠르게 해주는 작은 편의성 개선 중 하나입니다 — 코드를 참조할 때 전체 파일 경로를 입력할 필요가 없어집니다.&lt;/p&gt;
&lt;h2 id="css-import-링크-해석"&gt;CSS &lt;code&gt;@import&lt;/code&gt; 링크 해석&lt;/h2&gt;
&lt;p&gt;프론트엔드 개발자에게 좋은 소식: VS Code가 이제 node_modules 경로를 사용하는 CSS &lt;code&gt;@import&lt;/code&gt; 참조를 해석합니다. 번들러를 사용할 때 &lt;code&gt;@import &amp;quot;some-module/style.css&amp;quot;&lt;/code&gt; 같은 임포트를 &lt;code&gt;Ctrl+클릭&lt;/code&gt;으로 따라갈 수 있습니다. 작지만 CSS 워크플로의 마찰점을 제거합니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;VS Code 1.116은 세련됨에 관한 것입니다 — Agents 앱을 더 탐색하기 쉽고, 더 접근 가능하며, 더 키보드 친화적으로 만드는 것. Agents 앱에서 상당한 시간을 보내고 있다면 (그리고 많은 분들이 그럴 것으로 생각합니다), 이러한 변경 사항들은 쌓여갑니다.&lt;/p&gt;
&lt;p&gt;전체 목록은 &lt;a href="https://code.visualstudio.com/updates/v1_116"&gt;전체 릴리스 노트&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>몰랐던 Visual Studio 플로팅 윈도우 설정 (하지만 알아야 할)</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/</guid><description>Visual Studio의 숨겨진 설정으로 플로팅 윈도우를 완벽하게 제어하세요 — 독립적인 작업 표시줄 항목, 적절한 멀티 모니터 동작, 그리고 완벽한 FancyZones 통합. 드롭다운 하나로 모든 것이 바뀝니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-floating-windows-powertoys/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio에서 여러 모니터를 사용한다면 (솔직히 요즘 누가 안 쓰겠어요?), 아마 이런 불편함을 경험했을 겁니다: 플로팅 도구 창이 메인 IDE를 최소화하면 사라지고, 항상 다른 모든 것 위에 표시되며, 작업 표시줄에 별도의 버튼으로 나타나지 않습니다. 일부 워크플로에서는 괜찮지만 멀티 모니터 설정에서는 정말 답답합니다.&lt;/p&gt;
&lt;p&gt;Visual Studio 팀의 Mads Kristensen이 플로팅 윈도우의 동작을 완전히 바꾸는 &lt;a href="https://devblogs.microsoft.com/visualstudio/take-full-control-of-your-floating-windows-in-visual-studio/"&gt;잘 알려지지 않은 설정을 공유했습니다&lt;/a&gt;. 드롭다운 하나. 그게 전부입니다.&lt;/p&gt;
&lt;h2 id="설정"&gt;설정&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;Tools &amp;gt; Options &amp;gt; Environment &amp;gt; Windows &amp;gt; Floating Windows&lt;/strong&gt;&lt;/p&gt;
&lt;p&gt;드롭다운 &amp;ldquo;These floating windows are owned by the main window&amp;quot;에는 세 가지 옵션이 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;None&lt;/strong&gt; — 완전한 독립. 모든 플로팅 윈도우가 자체 작업 표시줄 항목을 가지며 일반 Windows 창처럼 동작합니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Tool Windows&lt;/strong&gt; (기본값) — 문서는 자유롭게 플로팅, 도구 창은 IDE에 연결됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Documents and Tool Windows&lt;/strong&gt; — 클래식 Visual Studio 동작, 모든 것이 메인 창에 연결됩니다.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="멀티-모니터-설정에서-none이-최적인-이유"&gt;멀티 모니터 설정에서 &amp;ldquo;None&amp;quot;이 최적인 이유&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;None&lt;/strong&gt;으로 설정하면 갑자기 모든 플로팅 도구 창과 문서가 진짜 Windows 애플리케이션처럼 동작합니다. 작업 표시줄에 나타나고, Visual Studio 메인 창을 최소화해도 보이며, 더 이상 모든 것 앞으로 강제되지 않습니다.&lt;/p&gt;
&lt;p&gt;이것을 &lt;strong&gt;PowerToys FancyZones&lt;/strong&gt;와 결합하면 완전히 달라집니다. 모니터 전체에 커스텀 레이아웃을 만들고, 솔루션 탐색기를 한 존에, 디버거를 다른 존에, 코드 파일을 원하는 곳에 배치하세요. 모든 것이 제자리에 있고, 모든 것이 독립적으로 접근 가능하며, 작업 공간이 혼란스럽지 않고 정돈된 느낌입니다.&lt;/p&gt;
&lt;h2 id="빠른-추천"&gt;빠른 추천&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;멀티 모니터 파워 유저&lt;/strong&gt;: &lt;strong&gt;None&lt;/strong&gt;으로 설정하고 FancyZones와 함께 사용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;가끔 플로팅하는 분&lt;/strong&gt;: &lt;strong&gt;Tool Windows&lt;/strong&gt; (기본값)가 좋은 중간 지점&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;전통적인 워크플로&lt;/strong&gt;: &lt;strong&gt;Documents and Tool Windows&lt;/strong&gt;가 클래식한 방식 유지&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;프로 팁: 아무 도구 창의 제목 표시줄에서 &lt;strong&gt;Ctrl + 더블 클릭&lt;/strong&gt;으로 즉시 플로팅 또는 도킹할 수 있습니다. 설정 변경 후 재시작이 필요 없습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;전형적인 &amp;ldquo;이걸 왜 몰랐지&amp;rdquo; 설정입니다. Visual Studio의 플로팅 윈도우가 한 번이라도 불편했다면, 지금 바로 바꾸러 가세요.&lt;/p&gt;
&lt;p&gt;자세한 내용과 스크린샷은 &lt;a href="https://devblogs.microsoft.com/visualstudio/take-full-control-of-your-floating-windows-in-visual-studio/"&gt;전체 포스트&lt;/a&gt;에서 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>블랙박스처럼 느껴지지 않는 실시간 멀티 에이전트 UI 구축하기</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/</guid><description>AG-UI와 Microsoft Agent Framework가 멀티 에이전트 워크플로우에 진정한 프론트엔드를 제공합니다 — 실시간 스트리밍, 인간 승인, 에이전트 동작의 완전한 가시성을 갖추고 있습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/ag-ui-real-time-multi-agent-ui-maf/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;멀티 에이전트 시스템의 문제는 이렇습니다: 데모에서는 놀라울 정도로 멋져 보입니다. 세 개의 에이전트가 작업을 주고받고, 문제를 해결하고, 의사결정을 내립니다. 그런데 실제 사용자 앞에 놓으면&amp;hellip; 침묵. 돌아가는 로딩 인디케이터. 어떤 에이전트가 뭘 하고 있는지, 왜 시스템이 멈췄는지 전혀 알 수 없습니다. 이건 제품이 아닙니다 — 신뢰 문제입니다.&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework 팀이 MAF 워크플로우를 &lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;AG-UI&lt;/a&gt;와 결합하는 &lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;훌륭한 워크스루&lt;/a&gt;를 발표했습니다. AG-UI는 Server-Sent Events를 통해 에이전트 실행 이벤트를 프론트엔드로 스트리밍하는 오픈 프로토콜입니다. 솔직히? 이건 우리에게 빠져있던 바로 그 다리입니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-중요한-이유"&gt;.NET 개발자에게 중요한 이유&lt;/h2&gt;
&lt;p&gt;AI 기반 앱을 만들고 있다면, 아마 이 벽에 부딪혀 봤을 겁니다. 백엔드 오케스트레이션은 완벽하게 동작합니다 — 에이전트들이 서로 작업을 넘기고, 도구가 실행되고, 결정이 내려집니다. 하지만 프론트엔드는 뒤에서 무슨 일이 벌어지고 있는지 전혀 모릅니다. AG-UI는 에이전트 이벤트(&lt;code&gt;RUN_STARTED&lt;/code&gt;, &lt;code&gt;STEP_STARTED&lt;/code&gt;, &lt;code&gt;TOOL_CALL_*&lt;/code&gt;, &lt;code&gt;TEXT_MESSAGE_*&lt;/code&gt; 등)를 SSE를 통해 UI 레이어로 직접 스트리밍하는 표준 프로토콜을 정의하여 이 문제를 해결합니다.&lt;/p&gt;
&lt;p&gt;데모는 세 개의 에이전트로 구성된 고객 지원 워크플로우입니다: 요청을 라우팅하는 트리아지 에이전트, 환불을 처리하는 환불 에이전트, 교체를 관리하는 주문 에이전트. 각 에이전트는 자체 도구를 가지고 있으며, 핸드오프 토폴로지가 명시적으로 정의되어 있습니다 — &amp;ldquo;프롬프트에서 알아내라&amp;quot;는 식이 아닙니다.&lt;/p&gt;
&lt;h2 id="핸드오프-토폴로지가-진짜-주인공"&gt;핸드오프 토폴로지가 진짜 주인공&lt;/h2&gt;
&lt;p&gt;제 눈을 사로잡은 것은 &lt;code&gt;HandoffBuilder&lt;/code&gt;로 에이전트 간 방향성 라우팅 그래프를 선언할 수 있다는 점입니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;builder&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;HandoffBuilder&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ag_ui_handoff_workflow_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;participants&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;termination_condition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;termination_condition&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;builder&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Refunds, damaged-item claims...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement, exchange...&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;refund&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Replacement logistics needed after refund.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;add_handoff&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;order&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;triage&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt; &lt;span class="n"&gt;description&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;After replacement/shipping tasks complete.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;각 &lt;code&gt;add_handoff&lt;/code&gt;는 자연어 설명이 포함된 방향성 엣지를 생성합니다. 프레임워크는 이 토폴로지를 기반으로 각 에이전트의 핸드오프 도구를 생성합니다. 따라서 라우팅 결정은 오케스트레이션 구조에 기반하며, LLM이 마음대로 결정하는 것이 아닙니다. 이것은 프로덕션 안정성에 있어 엄청난 차이입니다.&lt;/p&gt;
&lt;h2 id="실제로-작동하는-human-in-the-loop"&gt;실제로 작동하는 Human-in-the-loop&lt;/h2&gt;
&lt;p&gt;데모는 실제 에이전트 앱에 필요한 두 가지 인터럽트 패턴을 보여줍니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;도구 승인 인터럽트&lt;/strong&gt; — 에이전트가 &lt;code&gt;approval_mode=&amp;quot;always_require&amp;quot;&lt;/code&gt;로 표시된 도구를 호출하면, 워크플로우가 일시 중지되고 이벤트를 발생시킵니다. 프론트엔드는 도구 이름과 인수가 포함된 승인 모달을 렌더링합니다. 토큰을 소모하는 재시도 루프 없이, 깔끔한 일시중지-승인-재개 흐름입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;정보 요청 인터럽트&lt;/strong&gt; — 에이전트가 사용자로부터 더 많은 컨텍스트(예: 주문 ID)가 필요할 때, 일시 중지하고 질문합니다. 프론트엔드가 질문을 표시하고, 사용자가 응답하면, 실행이 멈춘 바로 그 지점에서 재개됩니다.&lt;/p&gt;
&lt;p&gt;두 패턴 모두 표준 AG-UI 이벤트로 스트리밍되므로, 프론트엔드에 에이전트별 커스텀 로직이 필요 없습니다 — SSE 연결을 통해 들어오는 이벤트를 그대로 렌더링하면 됩니다.&lt;/p&gt;
&lt;h2 id="연결이-놀라울-정도로-간단합니다"&gt;연결이 놀라울 정도로 간단합니다&lt;/h2&gt;
&lt;p&gt;MAF와 AG-UI의 통합은 단 하나의 함수 호출입니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;agent_framework.ag_ui&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AgentFrameworkWorkflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;add_agent_framework_fastapi_endpoint&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;app&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;FastAPI&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;demo_workflow&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;AgentFrameworkWorkflow&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;workflow_factory&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="k"&gt;lambda&lt;/span&gt; &lt;span class="n"&gt;_thread_id&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;create_handoff_workflow&lt;/span&gt;&lt;span class="p"&gt;(),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;ag_ui_handoff_workflow_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;add_agent_framework_fastapi_endpoint&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;app&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;demo_workflow&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;path&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;/handoff_demo&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;code&gt;workflow_factory&lt;/code&gt;는 스레드마다 새로운 워크플로우를 생성하여, 각 대화가 격리된 상태를 가집니다. 엔드포인트는 모든 SSE 배관을 자동으로 처리합니다. 이미 FastAPI를 사용하고 있다면(또는 경량 레이어로 추가할 수 있다면), 거의 마찰 없이 사용할 수 있습니다.&lt;/p&gt;
&lt;h2 id="제-생각"&gt;제 생각&lt;/h2&gt;
&lt;p&gt;우리 .NET 개발자들에게 즉각적인 질문은 &amp;ldquo;C#으로 할 수 있나?&amp;ldquo;입니다. Agent Framework는 .NET과 Python 모두에서 사용 가능하고, AG-UI 프로토콜은 언어에 구애받지 않습니다(그냥 SSE입니다). 따라서 이 특정 데모가 Python과 FastAPI를 사용하지만, 패턴은 직접 적용할 수 있습니다. 동일한 AG-UI 이벤트 스키마를 따르는 SSE 엔드포인트가 있는 ASP.NET Core 최소 API를 구성할 수 있습니다.&lt;/p&gt;
&lt;p&gt;더 큰 시사점은 멀티 에이전트 UI가 사후 고려사항이 아닌 일급 관심사가 되고 있다는 것입니다. 에이전트가 인간과 상호작용하는 무엇이든 구축하고 있다면 — 고객 지원, 승인 워크플로우, 문서 처리 — MAF 오케스트레이션과 AG-UI 투명성의 조합이 따라야 할 패턴입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;AG-UI + Microsoft Agent Framework는 두 세계의 장점을 모두 제공합니다: 백엔드의 강력한 멀티 에이전트 오케스트레이션과 프론트엔드의 실시간 가시성. 더 이상 블랙박스 에이전트 인터랙션은 없습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/agent-framework/ag-ui-multi-agent-workflow-demo/"&gt;전체 워크스루&lt;/a&gt;와 &lt;a href="https://github.com/ag-ui-protocol/ag-ui"&gt;AG-UI 프로토콜 저장소&lt;/a&gt;를 확인하여 더 깊이 알아보세요.&lt;/p&gt;</content:encoded></item><item><title>에이전틱 플랫폼 엔지니어링이 현실이 되고 있다 — Git-APE가 방법을 보여준다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</link><pubDate>Fri, 10 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/</guid><description>Microsoft의 Git-APE 프로젝트가 에이전틱 플랫폼 엔지니어링을 실전에 적용합니다 — GitHub Copilot 에이전트와 Azure MCP를 사용하여 자연어 요청을 검증된 클라우드 인프라로 전환합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agentic-platform-engineering-git-ape/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;플랫폼 엔지니어링은 컨퍼런스에서는 멋지게 들리지만 보통 &amp;ldquo;내부 포털과 Terraform 래퍼를 만들었습니다&amp;quot;를 의미하는 용어 중 하나였습니다. 진정한 약속 — 실제로 안전하고, 거버넌스가 적용되고, 빠른 셀프 서비스 인프라 — 는 항상 몇 발짝 떨어져 있었습니다.&lt;/p&gt;
&lt;p&gt;Azure 팀이 &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;에이전틱 플랫폼 엔지니어링 시리즈의 파트 2&lt;/a&gt;를 발표했는데, 이번에는 실전 구현에 대한 내용입니다. &lt;strong&gt;Git-APE&lt;/strong&gt;라고 부릅니다 (네, 약어는 의도적입니다). 이것은 GitHub Copilot 에이전트와 Azure MCP 서버를 사용하여 자연어 요청을 검증되고 배포된 인프라로 전환하는 오픈소스 프로젝트입니다.&lt;/p&gt;
&lt;h2 id="git-ape가-실제로-하는-것"&gt;Git-APE가 실제로 하는 것&lt;/h2&gt;
&lt;p&gt;핵심 아이디어: 개발자가 Terraform 모듈을 배우거나, 포털 UI를 탐색하거나, 플랫폼 팀에 티켓을 올리는 대신, Copilot 에이전트와 대화합니다. 에이전트가 의도를 해석하고, Infrastructure-as-Code를 생성하고, 정책에 대해 검증하고, 배포합니다 — 모두 VS Code 안에서.&lt;/p&gt;
&lt;p&gt;설정은 이렇습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;git clone https://github.com/Azure/git-ape
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="nb"&gt;cd&lt;/span&gt; git-ape
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;VS Code에서 워크스페이스를 열면 에이전트 설정 파일이 GitHub Copilot에 의해 자동 검색됩니다. 에이전트와 직접 상호작용합니다:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape deploy a function app with storage in West Europe
&lt;/code&gt;&lt;/pre&gt;&lt;p&gt;에이전트는 내부적으로 Azure MCP Server를 사용하여 Azure 서비스와 상호작용합니다. VS Code 설정의 MCP 구성이 특정 기능을 활성화합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.serverMode&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;namespace&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.enabledServices&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deploy&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;bestpractices&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;group&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;subscription&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;functionapp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;storage&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;sql&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;monitor&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;azureMcp.readOnly&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;false&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="왜-이게-중요한가"&gt;왜 이게 중요한가&lt;/h2&gt;
&lt;p&gt;Azure에서 개발하는 우리에게 이것은 플랫폼 엔지니어링 대화를 &amp;ldquo;포털을 어떻게 만들까&amp;quot;에서 &amp;ldquo;가드레일을 API로 어떻게 기술할까&amp;quot;로 전환시킵니다. 플랫폼의 인터페이스가 AI 에이전트가 되면, 제약 조건과 정책의 품질이 곧 제품이 됩니다.&lt;/p&gt;
&lt;p&gt;파트 1 블로그는 이론을 제시했습니다: 잘 기술된 API, 제어 스키마, 그리고 명시적인 가드레일이 플랫폼을 에이전트 대응(agent-ready)으로 만듭니다. 파트 2는 실제 도구를 제공하여 이것이 작동한다는 것을 증명합니다. 에이전트는 리소스를 무작정 생성하지 않습니다 — 모범 사례에 대해 검증하고, 명명 규칙을 존중하며, 조직의 정책을 적용합니다.&lt;/p&gt;
&lt;p&gt;정리도 마찬가지로 간단합니다:&lt;/p&gt;
&lt;pre tabindex="0"&gt;&lt;code&gt;@git-ape destroy my-resource-group
&lt;/code&gt;&lt;/pre&gt;&lt;h2 id="내-생각"&gt;내 생각&lt;/h2&gt;
&lt;p&gt;솔직히 — 이건 특정 도구보다는 패턴에 대한 이야기입니다. Git-APE 자체는 데모/참조 아키텍처입니다. 하지만 근본적인 아이디어 — 플랫폼의 인터페이스로서의 에이전트, 프로토콜로서의 MCP, 호스트로서의 GitHub Copilot — 이것이 엔터프라이즈 개발자 경험이 향하는 방향입니다.&lt;/p&gt;
&lt;p&gt;내부 도구를 에이전트 친화적으로 만드는 방법을 찾는 플랫폼 팀이라면, 이보다 나은 출발점은 없습니다. 그리고 .NET 개발자로서 이것이 자신의 세계와 어떻게 연결되는지 궁금하다면: Azure MCP Server와 GitHub Copilot 에이전트는 모든 Azure 워크로드에서 작동합니다. ASP.NET Core API, .NET Aspire 스택, 컨테이너화된 마이크로서비스 — 모두가 에이전틱 배포 플로우의 대상이 될 수 있습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Git-APE는 에이전틱 플랫폼 엔지니어링 실전의 초기이지만 구체적인 모습입니다. &lt;a href="https://github.com/Azure/git-ape"&gt;저장소&lt;/a&gt;를 클론하고, 데모를 시도하고, 에이전트가 안전하게 사용할 수 있도록 플랫폼의 API와 정책이 어떤 모습이어야 하는지 생각해 보세요.&lt;/p&gt;
&lt;p&gt;자세한 워크스루와 데모 비디오는 &lt;a href="https://devblogs.microsoft.com/all-things-azure/putting-agentic-platform-engineering-to-the-test/"&gt;전체 포스트&lt;/a&gt;를 읽어보세요.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.115 — 백그라운드 터미널 알림, SSH 에이전트 모드 등</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/</link><pubDate>Mon, 06 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/</guid><description>VS Code 1.115에서는 에이전트를 위한 백그라운드 터미널 알림, SSH 원격 에이전트 호스팅, 터미널 파일 붙여넣기, 세션 인식 편집 추적이 도입되었습니다. .NET 개발자에게 중요한 내용을 정리했습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-115-agent-improvements/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;VS Code 1.115가 &lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;출시&lt;/a&gt;되었습니다. 주요 기능 면에서는 가벼운 릴리스이지만, AI 코딩 어시스턴트를 매일 사용하고 있다면 에이전트 관련 개선사항들이 정말 유용합니다.&lt;/p&gt;
&lt;p&gt;실제로 알아둘 가치가 있는 것들을 짚어보겠습니다.&lt;/p&gt;
&lt;h2 id="백그라운드-터미널이-에이전트에게-알림을-보냅니다"&gt;백그라운드 터미널이 에이전트에게 알림을 보냅니다&lt;/h2&gt;
&lt;p&gt;이번 릴리스의 핵심 기능입니다. 백그라운드 터미널이 이제 명령이 완료되면 종료 코드와 터미널 출력을 포함하여 에이전트에게 자동으로 알림을 보냅니다. 백그라운드 터미널의 입력 프롬프트도 감지되어 사용자에게 표시됩니다.&lt;/p&gt;
&lt;p&gt;왜 중요할까요? Copilot의 에이전트 모드로 빌드 명령이나 테스트 스위트를 백그라운드에서 실행해 본 적이 있다면, &amp;ldquo;그거 끝났나?&amp;ldquo;라는 고통을 알 것입니다. 백그라운드 터미널은 기본적으로 실행 후 잊어버리는 방식이었습니다. 이제 에이전트가 &lt;code&gt;dotnet build&lt;/code&gt;나 &lt;code&gt;dotnet test&lt;/code&gt;가 완료되면 알림을 받고, 출력을 확인하고, 그에 따라 대응할 수 있습니다. 작은 변화지만 에이전트 기반 워크플로우의 신뢰성을 크게 향상시킵니다.&lt;/p&gt;
&lt;p&gt;또한 새로운 &lt;code&gt;send_to_terminal&lt;/code&gt; 도구가 추가되어 에이전트가 사용자 확인을 거쳐 백그라운드 터미널에 명령을 보낼 수 있게 되었습니다. 이로써 &lt;code&gt;run_in_terminal&lt;/code&gt;에 타임아웃을 설정하면 터미널이 백그라운드로 이동하고 읽기 전용이 되는 문제가 해결되었습니다.&lt;/p&gt;
&lt;h2 id="ssh-원격-에이전트-호스팅"&gt;SSH 원격 에이전트 호스팅&lt;/h2&gt;
&lt;p&gt;VS Code가 이제 SSH를 통해 원격 머신에 연결하고, CLI를 자동으로 설치하여 에이전트 호스트 모드로 시작할 수 있습니다. 이는 AI 에이전트 세션이 원격 환경을 직접 타겟팅할 수 있다는 의미입니다. Linux 서버나 클라우드 VM에서 빌드하고 테스트하는 .NET 개발자에게 유용합니다.&lt;/p&gt;
&lt;h2 id="에이전트-세션의-편집-추적"&gt;에이전트 세션의 편집 추적&lt;/h2&gt;
&lt;p&gt;에이전트 세션 중에 수행된 파일 편집이 이제 diff, 실행 취소/다시 실행, 상태 복원과 함께 추적되고 복원됩니다. 에이전트가 코드를 변경했는데 문제가 생기면, 정확히 무엇이 변경되었는지 확인하고 롤백할 수 있습니다. 에이전트가 코드베이스를 수정하도록 맡길 때 마음의 평화를 줍니다.&lt;/p&gt;
&lt;h2 id="브라우저-탭-인식-및-기타-개선사항"&gt;브라우저 탭 인식 및 기타 개선사항&lt;/h2&gt;
&lt;p&gt;몇 가지 추가적인 생활의 질 개선사항:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;브라우저 탭 추적&lt;/strong&gt; — 채팅이 세션 중 열린 브라우저 탭을 추적하고 링크할 수 있어 에이전트가 보고 있는 웹 페이지를 참조할 수 있습니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;터미널 파일 붙여넣기&lt;/strong&gt; — Ctrl+V, 드래그 앤 드롭 또는 우클릭으로 터미널에 파일(이미지 포함)을 붙여넣기&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;미니맵의 테스트 커버리지&lt;/strong&gt; — 테스트 커버리지 표시가 이제 미니맵에 나타나 빠른 시각적 개요를 제공합니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Mac에서 핀치 투 줌&lt;/strong&gt; — 통합 브라우저가 핀치 투 줌 제스처를 지원합니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;세션의 Copilot 사용 권한&lt;/strong&gt; — 상태 표시줄이 세션 보기에서 사용량 정보를 표시합니다&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;파일로 이동의 파비콘&lt;/strong&gt; — 열린 웹 페이지가 빠른 선택 목록에 파비콘을 표시합니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;VS Code 1.115는 점진적인 릴리스이지만, 에이전트 개선 — 백그라운드 터미널 알림, SSH 에이전트 호스팅, 편집 추적 — 이 합쳐져 AI 지원 개발에서 눈에 띄게 부드러운 경험을 제공합니다. .NET 프로젝트에서 Copilot의 에이전트 모드를 사용하고 있다면, 이런 것들이 매일의 마찰을 줄여주는 생활의 질 개선입니다.&lt;/p&gt;
&lt;p&gt;모든 세부사항은 &lt;a href="https://code.visualstudio.com/updates/v1_115"&gt;전체 릴리스 노트&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>C# 15에 유니온 타입 도입 — 우리가 원하던 바로 그것</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</link><pubDate>Sun, 05 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/</guid><description>C# 15가 union 키워드를 도입합니다 — 컴파일러가 강제하는 판별 공용체와 완전한 패턴 매칭. 어떤 모습인지, 왜 중요한지, 그리고 오늘 바로 시도하는 방법을 알아봅니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문을 보시려면 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/csharp-15-union-types-exhaustive-matching/"&gt;여기를 클릭하세요&lt;/a&gt;.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;바로 이것을 기다려왔습니다. C# 15가 &lt;code&gt;union&lt;/code&gt; 키워드를 도입했습니다 — 컴파일러가 강제하는 완전한 패턴 매칭을 갖춘 진정한 판별 공용체입니다. F#의 판별 공용체나 Rust의 enum을 부러워한 적이 있다면, 이것이 왜 중요한지 정확히 알 것입니다.&lt;/p&gt;
&lt;p&gt;Bill Wagner가 .NET 블로그에 &lt;a href="https://devblogs.microsoft.com/dotnet/csharp-15-union-types/"&gt;심층 분석을 게시했는데&lt;/a&gt;, 솔직히? 디자인이 깔끔하고, 실용적이며, 매우 C#답습니다. 실제로 무엇이 있는지, 그리고 왜 첫눈에 보이는 것보다 더 큰 의미가 있는지 보여드리겠습니다.&lt;/p&gt;
&lt;h2 id="유니온이-해결하는-문제"&gt;유니온이 해결하는 문제&lt;/h2&gt;
&lt;p&gt;C# 15 이전에는 메서드에서 &amp;ldquo;여러 가능한 타입 중 하나&amp;quot;를 반환하는 것이 항상 타협이었습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;&lt;code&gt;object&lt;/code&gt;&lt;/strong&gt; — 제약 없음, 컴파일러 도움 없음, 어디서나 방어적 캐스팅&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;마커 인터페이스&lt;/strong&gt; — 더 낫지만, 누구나 구현 가능. 컴파일러는 집합이 완전하다고 판단할 수 없음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;추상 기본 클래스&lt;/strong&gt; — 같은 문제, 게다가 타입들이 공통 조상이 필요함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 중 어느 것도 실제로 원하는 것을 제공하지 못합니다: 컴파일러가 모든 케이스를 처리했음을 보장하는 닫힌 타입 집합. 유니온 타입이 바로 그것을 합니다.&lt;/p&gt;
&lt;h2 id="구문은-아름다울-정도로-간결합니다"&gt;구문은 아름다울 정도로 간결합니다&lt;/h2&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;record&lt;/span&gt; &lt;span class="nc"&gt;class&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;Pet&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;Cat&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;Bird&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;한 줄. &lt;code&gt;Pet&lt;/code&gt;은 &lt;code&gt;Cat&lt;/code&gt;, &lt;code&gt;Dog&lt;/code&gt;, 또는 &lt;code&gt;Bird&lt;/code&gt;를 담을 수 있습니다. 암시적 변환이 자동으로 생성됩니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Pet&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Dog&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Rex&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;pet&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Value&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt; &lt;span class="c1"&gt;// Dog { Name = Rex }&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그리고 여기가 마법입니다 — 컴파일러가 완전한 매칭을 강제합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;string&lt;/span&gt; &lt;span class="n"&gt;name&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;pet&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Dog&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;d&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Cat&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;c&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Bird&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;b&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;디스카드 &lt;code&gt;_&lt;/code&gt;가 필요 없습니다. 컴파일러는 이 switch가 모든 가능한 케이스를 커버한다는 것을 알고 있습니다. 나중에 유니온에 네 번째 타입을 추가하면, 그것을 처리하지 않는 모든 switch 식이 경고를 생성합니다. 누락된 케이스가 런타임이 아니라 빌드 시점에 잡힙니다.&lt;/p&gt;
&lt;h2 id="실용적으로-빛나는-곳"&gt;실용적으로 빛나는 곳&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;Pet&lt;/code&gt; 예제는 귀엽지만, 여기서부터가 유니온이 실제 코드에서 진짜로 빛나는 부분입니다.&lt;/p&gt;
&lt;h3 id="다양한-형태를-반환하는-api-응답"&gt;다양한 형태를 반환하는 API 응답&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;ApiResult&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ApiError&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;ValidationFailure&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이제 모든 소비자가 성공, 오류, 유효성 검증 실패를 처리하도록 강제됩니다. &amp;ldquo;에러 케이스 체크를 깜빡했다&amp;rdquo; 버그는 더 이상 없습니다.&lt;/p&gt;
&lt;h3 id="단일-값-또는-컬렉션"&gt;단일 값 또는 컬렉션&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;OneOrMore&amp;lt;T&amp;gt;&lt;/code&gt; 패턴은 유니온이 헬퍼 메서드를 가진 본문을 가질 수 있음을 보여줍니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;union&lt;/span&gt; &lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;(&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="k"&gt;switch&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;T&lt;/span&gt; &lt;span class="n"&gt;single&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="n"&gt;single&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;IEnumerable&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="n"&gt;T&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;multiple&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kc"&gt;null&lt;/span&gt; &lt;span class="p"&gt;=&amp;gt;&lt;/span&gt; &lt;span class="p"&gt;[]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;호출자는 편리한 형태를 전달합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;dotnet&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;OneOrMore&lt;/span&gt;&lt;span class="p"&gt;&amp;lt;&lt;/span&gt;&lt;span class="kt"&gt;string&lt;/span&gt;&lt;span class="p"&gt;&amp;gt;&lt;/span&gt; &lt;span class="n"&gt;moreTags&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;[]&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;csharp&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;unions&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;preview&amp;#34;&lt;/span&gt; &lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;tag&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;tags&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsEnumerable&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;$&amp;#34;[{tag}] &amp;#34;&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// [dotnet]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h3 id="관련-없는-타입들의-합성"&gt;관련 없는 타입들의 합성&lt;/h3&gt;
&lt;p&gt;이것이 전통적 계층 구조에 대한 킬러 기능입니다. 공통점이 전혀 없는 타입들을 유니온할 수 있습니다 — &lt;code&gt;string&lt;/code&gt;과 &lt;code&gt;Exception&lt;/code&gt;, &lt;code&gt;int&lt;/code&gt;와 &lt;code&gt;IEnumerable&amp;lt;T&amp;gt;&lt;/code&gt;. 공통 조상이 필요 없습니다.&lt;/p&gt;
&lt;h2 id="기존-라이브러리를-위한-커스텀-유니온"&gt;기존 라이브러리를 위한 커스텀 유니온&lt;/h2&gt;
&lt;p&gt;똑똑한 디자인 선택이 있습니다: 기본 패턴(케이스 타입에 대한 public 생성자와 &lt;code&gt;Value&lt;/code&gt; 프로퍼티)을 따르기만 하면, &lt;code&gt;[Union]&lt;/code&gt; 어트리뷰트가 있는 모든 클래스나 구조체가 유니온 타입으로 인식됩니다. 이미 유니온과 유사한 타입을 제공하는 OneOf 같은 라이브러리들이 내부를 재작성하지 않고도 컴파일러 지원에 옵트인할 수 있습니다.&lt;/p&gt;
&lt;p&gt;값 타입을 사용하는 성능에 민감한 시나리오에서는 라이브러리가 &lt;code&gt;HasValue&lt;/code&gt;와 &lt;code&gt;TryGetValue&lt;/code&gt; 메서드로 박싱 없는 접근 패턴을 구현할 수 있습니다.&lt;/p&gt;
&lt;h2 id="더-큰-그림"&gt;더 큰 그림&lt;/h2&gt;
&lt;p&gt;유니온 타입은 C#에 오고 있는 더 넓은 완전성 이야기의 일부입니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;유니온 타입&lt;/strong&gt; — 닫힌 타입 집합에 대한 완전한 매칭 (지금 프리뷰에서 사용 가능)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;닫힌 계층 구조&lt;/strong&gt; — &lt;code&gt;closed&lt;/code&gt; 수정자가 정의 어셈블리 외부의 파생 클래스를 방지 (제안됨)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;닫힌 enum&lt;/strong&gt; — 선언된 멤버 이외의 값 생성을 방지 (제안됨)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이 세 가지 기능이 합쳐지면, C#은 모든 주류 언어 중 가장 포괄적인 타입 안전 패턴 매칭 시스템 중 하나를 갖게 될 것입니다.&lt;/p&gt;
&lt;h2 id="오늘-바로-시도해보세요"&gt;오늘 바로 시도해보세요&lt;/h2&gt;
&lt;p&gt;유니온 타입은 .NET 11 Preview 2에서 사용 가능합니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;a href="https://dotnet.microsoft.com/download/dotnet"&gt;.NET 11 Preview SDK&lt;/a&gt;를 설치&lt;/li&gt;
&lt;li&gt;프로젝트에서 &lt;code&gt;net11.0&lt;/code&gt;을 타깃으로 설정&lt;/li&gt;
&lt;li&gt;&lt;code&gt;&amp;lt;LangVersion&amp;gt;preview&amp;lt;/LangVersion&amp;gt;&lt;/code&gt;을 설정&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;한 가지 주의사항: Preview 2에서는 런타임에 아직 포함되어 있지 않으므로 프로젝트에서 &lt;code&gt;UnionAttribute&lt;/code&gt;와 &lt;code&gt;IUnion&lt;/code&gt;을 선언해야 합니다. docs 레포에서 &lt;a href="https://github.com/dotnet/docs/blob/e68b5dd1e557b53c45ca43e61b013bc919619fb9/docs/csharp/language-reference/builtin-types/snippets/unions/RuntimePolyfill.cs"&gt;RuntimePolyfill.cs&lt;/a&gt;를 가져오거나, 다음을 추가하세요:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;namespace&lt;/span&gt; &lt;span class="nn"&gt;System.Runtime.CompilerServices&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; [AttributeUsage(AttributeTargets.Class | AttributeTargets.Struct,
&lt;/span&gt;&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="na"&gt; AllowMultiple = false)]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="kd"&gt;sealed&lt;/span&gt; &lt;span class="k"&gt;class&lt;/span&gt; &lt;span class="nc"&gt;UnionAttribute&lt;/span&gt; &lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;Attribute&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kd"&gt;public&lt;/span&gt; &lt;span class="k"&gt;interface&lt;/span&gt; &lt;span class="nc"&gt;IUnion&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="kt"&gt;object?&lt;/span&gt; &lt;span class="n"&gt;Value&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt; &lt;span class="k"&gt;get&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;유니온 타입은 그것 없이 어떻게 지냈는지 의아하게 만드는 기능 중 하나입니다. 컴파일러가 강제하는 완전한 매칭, 깔끔한 구문, 제네릭 지원, 기존 패턴 매칭과의 통합 — 우리가 요청해온 모든 것이 C#의 방식으로 구현되었습니다.&lt;/p&gt;
&lt;p&gt;.NET 11 Preview 2에서 시도하고, 이것저것 부숴보고, &lt;a href="https://github.com/dotnet/csharplang/discussions/9663"&gt;GitHub에서 피드백을 공유하세요&lt;/a&gt;. 이것은 프리뷰이며, C# 팀은 적극적으로 듣고 있습니다. 여러분의 엣지 케이스와 디자인 피드백이 최종 릴리스를 형성할 것입니다.&lt;/p&gt;
&lt;p&gt;전체 언어 참조는 &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/builtin-types/union"&gt;유니온 타입 문서&lt;/a&gt;와 &lt;a href="https://learn.microsoft.com/dotnet/csharp/language-reference/proposals/unions"&gt;기능 사양&lt;/a&gt;을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2에 문서 CLI가 탑재 — AI 에이전트도 사용할 수 있습니다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</link><pubDate>Sat, 04 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-docs-cli-ai-skills/</guid><description>.NET Aspire 13.2에 aspire docs가 추가되었습니다. 터미널을 떠나지 않고 공식 문서를 검색, 탐색, 읽을 수 있는 CLI입니다. AI 에이전트의 도구로도 작동합니다. 이것이 왜 중요한지 알려드립니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-docs-cli-ai-skills/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Aspire AppHost 깊숙이 들어가서 통합을 연결하는 중에, Redis 통합이 정확히 어떤 파라미터를 기대하는지 확인해야 하는 그 순간을 아시죠? Alt-Tab으로 브라우저로 전환하고, aspire.dev를 뒤지고, API 문서를 눈을 가늘게 뜨고 보다가, 다시 에디터로 돌아옵니다. 컨텍스트를 잃었고, 플로우가 끊겼습니다.&lt;/p&gt;
&lt;p&gt;Aspire 13.2가 바로 &lt;a href="https://devblogs.microsoft.com/aspire/aspire-docs-in-your-terminal/"&gt;그 해결책을 출시했습니다&lt;/a&gt;. &lt;code&gt;aspire docs&lt;/code&gt; CLI를 사용하면 터미널에서 직접 Aspire 공식 문서를 검색하고, 탐색하고, 읽을 수 있습니다. 그리고 재사용 가능한 서비스에 기반하고 있어서, AI 에이전트와 스킬이 같은 명령어를 사용해 문서를 조회할 수 있습니다. 존재하지 않는 API를 환각하는 대신에요.&lt;/p&gt;
&lt;h2 id="이것이-실제로-해결하는-문제"&gt;이것이 실제로 해결하는 문제&lt;/h2&gt;
&lt;p&gt;David Pine이 원문에서 정확히 짚었습니다: AI 에이전트는 개발자가 Aspire 앱을 구축하는 것을 돕는 데 &lt;em&gt;끔찍했습니다&lt;/em&gt;. &lt;code&gt;aspire run&lt;/code&gt; 대신 &lt;code&gt;dotnet run&lt;/code&gt;을 추천하고, aspire.dev에 있는 문서에 대해 learn.microsoft.com을 참조하고, 오래된 NuGet 패키지를 제안하고, 그리고 — 개인적으로 가장 좋아하는 — 존재하지 않는 API를 환각했습니다.&lt;/p&gt;
&lt;p&gt;왜 그럴까요? Aspire가 폴리글랏이 된 것보다 .NET 전용이었던 기간이 훨씬 길었고, LLM은 최신 기능보다 앞선 학습 데이터로 작동하기 때문입니다. AI 에이전트에게 현재 문서를 실제로 조회할 수 있는 능력을 주면, 추측을 멈추고 유용해지기 시작합니다.&lt;/p&gt;
&lt;h2 id="세-가지-명령어-브라우저-탭은-제로"&gt;세 가지 명령어, 브라우저 탭은 제로&lt;/h2&gt;
&lt;p&gt;CLI는 상쾌할 정도로 간단합니다:&lt;/p&gt;
&lt;h3 id="모든-문서-나열"&gt;모든 문서 나열&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs list
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;aspire.dev에서 사용 가능한 모든 문서 페이지를 반환합니다. 기계가 읽을 수 있는 출력이 필요하세요? &lt;code&gt;--format Json&lt;/code&gt;을 추가하세요.&lt;/p&gt;
&lt;h3 id="주제-검색"&gt;주제 검색&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;가중 관련성 점수로 제목과 콘텐츠 모두를 검색합니다. 내부적으로 문서 도구를 구동하는 것과 같은 검색 엔진입니다. 제목, 슬러그, 관련성 점수가 포함된 순위별 결과를 얻을 수 있습니다.&lt;/p&gt;
&lt;h3 id="전체-페이지-읽기-또는-한-섹션만"&gt;전체 페이지 읽기 (또는 한 섹션만)&lt;/h3&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;전체 페이지를 마크다운으로 터미널에 스트리밍합니다. 한 섹션만 필요하세요?&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Add Redis resource&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;외과적 정밀도. 500줄을 스크롤할 필요 없습니다. 필요한 부분만.&lt;/p&gt;
&lt;h2 id="ai-에이전트-관점"&gt;AI 에이전트 관점&lt;/h2&gt;
&lt;p&gt;AI 도구로 개발하는 우리 개발자들에게 흥미로워지는 부분입니다. 같은 &lt;code&gt;aspire docs&lt;/code&gt; 명령어가 스킬, MCP 서버, 또는 간단한 CLI 래퍼를 통해 AI 에이전트의 도구로 작동합니다.&lt;/p&gt;
&lt;p&gt;AI 어시스턴트가 오래된 학습 데이터를 기반으로 Aspire API를 지어내는 대신, &lt;code&gt;aspire docs search &amp;quot;postgres&amp;quot;&lt;/code&gt;를 호출하고, 공식 통합 문서를 찾고, 올바른 페이지를 읽고, 문서화된 접근 방식을 제공할 수 있습니다. 실시간이고 최신인 문서 — 모델이 6개월 전에 기억한 것이 아닙니다.&lt;/p&gt;
&lt;p&gt;이 뒤의 아키텍처는 의도적입니다. Aspire 팀은 일회성 통합 대신 재사용 가능한 서비스(&lt;code&gt;IDocsIndexService&lt;/code&gt;, &lt;code&gt;IDocsSearchService&lt;/code&gt;, &lt;code&gt;IDocsFetcher&lt;/code&gt;, &lt;code&gt;IDocsCache&lt;/code&gt;)를 구축했습니다. 이는 같은 검색 엔진이 터미널의 사람, 에디터의 AI 에이전트, CI 파이프라인의 자동화를 위해 작동한다는 의미입니다.&lt;/p&gt;
&lt;h2 id="실제-시나리오"&gt;실제 시나리오&lt;/h2&gt;
&lt;p&gt;&lt;strong&gt;터미널에서 빠른 조회:&lt;/strong&gt; 파일 세 개 깊이에 있고 Redis 설정 파라미터가 필요합니다. 두 개의 명령어, 90초, 다시 작업으로:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;redis&amp;#34;&lt;/span&gt; --limit &lt;span class="m"&gt;1&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs get redis-integration --section &lt;span class="s2"&gt;&amp;#34;Configuration&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;&lt;strong&gt;AI 지원 개발:&lt;/strong&gt; VS Code 스킬이 CLI 명령어를 래핑합니다. &amp;ldquo;내 AppHost에 PostgreSQL 데이터베이스를 추가해&amp;quot;라고 물으면 에이전트가 답변하기 전에 실제 문서를 조회합니다. 환각 없음.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;CI/CD 검증:&lt;/strong&gt; 파이프라인이 공식 문서에 대해 AppHost 설정을 프로그래밍 방식으로 검증합니다. &lt;code&gt;--format Json&lt;/code&gt; 출력은 &lt;code&gt;jq&lt;/code&gt; 및 다른 도구와 깔끔하게 연결됩니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;커스텀 지식 베이스:&lt;/strong&gt; 자체 AI 도구를 구축하고 있나요? 구조화된 JSON 출력을 지식 베이스에 직접 파이프:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;aspire docs search &lt;span class="s2"&gt;&amp;#34;monitoring&amp;#34;&lt;/span&gt; --format Json &lt;span class="p"&gt;|&lt;/span&gt; jq &lt;span class="s1"&gt;&amp;#39;[.[] | {slug, title, summary}]&amp;#39;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;웹 스크래핑 없음. API 키 없음. 문서 도구가 내부적으로 사용하는 것과 같은 구조화된 데이터.&lt;/p&gt;
&lt;h2 id="문서는-항상-최신-상태"&gt;문서는 항상 최신 상태&lt;/h2&gt;
&lt;p&gt;이것이 제가 가장 높이 평가하는 부분입니다. CLI는 스냅샷을 다운로드하지 않습니다 — ETag 기반 캐싱으로 aspire.dev를 조회합니다. 문서가 업데이트되는 순간, CLI와 그 위에 구축된 모든 스킬이 이를 반영합니다. 오래된 복사본도 없고, &amp;ldquo;하지만 위키에는&amp;hellip;&amp;ldquo;하는 순간도 없습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;aspire docs&lt;/code&gt;는 실제 문제를 깔끔하게 해결하는 작은 기능 중 하나입니다. 사람은 터미널 네이티브 문서 접근을 얻습니다. AI 에이전트는 추측을 멈추고 실제 문서를 참조할 수 있는 방법을 얻습니다. 그리고 모든 것이 같은 진실의 원천에 의해 뒷받침됩니다.&lt;/p&gt;
&lt;p&gt;.NET Aspire로 개발하고 있고 아직 CLI를 시도해보지 않았다면, &lt;code&gt;aspire docs search &amp;quot;여러분의-주제&amp;quot;&lt;/code&gt; 를 실행하고 어떤 느낌인지 확인해 보세요. 그런 다음 사용 중인 AI 스킬이나 자동화 설정에 이 명령어들을 래핑하는 것을 고려해 보세요 — 여러분의 에이전트가 감사할 것입니다.&lt;/p&gt;
&lt;p&gt;문서 도구가 어떻게 만들어졌는지에 대한 &lt;a href="https://davidpine.dev/posts/aspire-docs-mcp-tools/"&gt;David Pine의 심층 분석&lt;/a&gt;과 모든 세부 사항이 담긴 &lt;a href="https://aspire.dev/reference/cli/commands/aspire-docs/"&gt;공식 CLI 레퍼런스&lt;/a&gt;를 확인해 보세요.&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework 1.0 출시 — .NET 개발자에게 정말 중요한 것들</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-framework-1-0-production-ready/</link><pubDate>Fri, 03 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-framework-1-0-production-ready/</guid><description>Microsoft Agent Framework 1.0이 안정적인 API, 멀티 에이전트 오케스트레이션, 모든 주요 AI 제공업체용 커넥터를 갖추고 프로덕션 준비가 완료되었습니다. .NET 개발자로서 알아야 할 내용을 정리했습니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원문은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agent-framework-1-0-production-ready/"&gt;여기를 클릭&lt;/a&gt;하여 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Semantic Kernel과 AutoGen 초기부터 Agent Framework의 여정을 지켜봐 왔다면, 이번 소식은 의미가 큽니다. Microsoft Agent Framework가 &lt;a href="https://devblogs.microsoft.com/agent-framework/microsoft-agent-framework-version-1-0/"&gt;버전 1.0에 도달&lt;/a&gt;했습니다 — 프로덕션 준비 완료, 안정적인 API, 장기 지원 약속. .NET과 Python 모두에서 사용할 수 있으며, 실제 워크로드를 처리할 준비가 되어 있습니다.&lt;/p&gt;
&lt;p&gt;발표의 소음을 걷어내고 .NET으로 AI 기반 앱을 구축하는 분들에게 중요한 내용에 집중하겠습니다.&lt;/p&gt;
&lt;h2 id="짧은-요약"&gt;짧은 요약&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0은 기존의 Semantic Kernel과 AutoGen을 하나의 오픈소스 SDK로 통합합니다. 하나의 에이전트 추상화. 하나의 오케스트레이션 엔진. 다수의 AI 제공업체. 엔터프라이즈 패턴을 위한 Semantic Kernel과 연구용 멀티 에이전트 워크플로를 위한 AutoGen 사이를 오갔다면, 이제 그만해도 됩니다. 이것이 유일한 SDK입니다.&lt;/p&gt;
&lt;h2 id="시작하기가-거의-불공평할-정도로-쉽습니다"&gt;시작하기가 거의 불공평할 정도로 쉽습니다&lt;/h2&gt;
&lt;p&gt;.NET에서 작동하는 에이전트 코드입니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// dotnet add package Microsoft.Agents.AI.OpenAI --prerelease&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Microsoft.Agents.AI.Foundry&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;using&lt;/span&gt; &lt;span class="nn"&gt;Azure.Identity&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;https://your-project.services.ai.azure.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;gpt-5.3&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;HaikuBot&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s"&gt;&amp;#34;You are an upbeat assistant that writes beautifully.&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;Write a haiku about shipping 1.0.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이게 전부입니다. 몇 줄의 코드로 Azure Foundry에서 실행되는 AI 에이전트가 완성됩니다. Python 버전도 마찬가지로 간결합니다. 함수 도구, 멀티턴 대화, 스트리밍은 필요할 때 추가하면 됩니다 — API 표면이 이상해지지 않으면서 확장됩니다.&lt;/p&gt;
&lt;h2 id="멀티-에이전트-오케스트레이션--이것이-진짜입니다"&gt;멀티 에이전트 오케스트레이션 — 이것이 진짜입니다&lt;/h2&gt;
&lt;p&gt;단일 에이전트는 데모에는 괜찮지만, 프로덕션 시나리오는 보통 조율이 필요합니다. Agent Framework 1.0은 Microsoft Research와 AutoGen에서 직접 가져온 실전 검증된 오케스트레이션 패턴을 탑재하고 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;순차적&lt;/strong&gt; — 에이전트가 순서대로 처리 (작성자 → 검토자 → 편집자)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;동시적&lt;/strong&gt; — 여러 에이전트에게 병렬로 분배하고, 결과를 수렴&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;핸드오프&lt;/strong&gt; — 하나의 에이전트가 의도에 따라 다른 에이전트에게 위임&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;그룹 채팅&lt;/strong&gt; — 여러 에이전트가 논의하고 해결책으로 수렴&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Magentic-One&lt;/strong&gt; — MSR의 연구용 멀티 에이전트 패턴&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모두 스트리밍, 체크포인팅, 인간 참여 승인, 일시 중지/재개를 지원합니다. 체크포인팅 부분이 중요합니다 — 장시간 실행되는 워크플로가 프로세스 재시작을 견뎌냅니다. Azure Functions로 지속성 있는 워크플로를 구축해 본 .NET 개발자에게는 익숙한 느낌일 겁니다.&lt;/p&gt;
&lt;h2 id="가장-중요한-기능들"&gt;가장 중요한 기능들&lt;/h2&gt;
&lt;p&gt;알아둘 가치가 있는 항목 목록입니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;미들웨어 훅.&lt;/strong&gt; ASP.NET Core에 미들웨어 파이프라인이 있는 거 아시죠? 같은 개념인데, 에이전트 실행용입니다. 모든 단계를 가로채서 — 콘텐츠 안전, 로깅, 컴플라이언스 정책을 추가 — 에이전트 프롬프트를 건드리지 않고 할 수 있습니다. 이것이 에이전트를 엔터프라이즈 수준으로 만드는 방법입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;플러거블 메모리.&lt;/strong&gt; 대화 이력, 영속적 키-값 상태, 벡터 기반 검색. 백엔드를 선택하세요: Foundry Agent Service, Mem0, Redis, Neo4j, 또는 직접 구현. 메모리는 상태 없는 LLM 호출을 실제로 컨텍스트를 기억하는 에이전트로 바꿔주는 핵심입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;선언적 YAML 에이전트.&lt;/strong&gt; 에이전트의 지시사항, 도구, 메모리, 오케스트레이션 토폴로지를 버전 관리되는 YAML 파일에 정의합니다. 단일 API 호출로 로드하고 실행합니다. 이것은 코드를 재배포하지 않고 에이전트 동작을 반복하고 싶은 팀에게 게임 체인저입니다.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;A2A 및 MCP 지원.&lt;/strong&gt; MCP(Model Context Protocol)는 에이전트가 외부 도구를 동적으로 발견하고 호출할 수 있게 합니다. A2A(Agent-to-Agent 프로토콜)는 크로스 런타임 협업을 가능하게 합니다 — .NET 에이전트가 다른 프레임워크에서 실행되는 에이전트와 조율할 수 있습니다. A2A 1.0 지원은 곧 출시 예정입니다.&lt;/p&gt;
&lt;h2 id="주목할-만한-프리뷰-기능"&gt;주목할 만한 프리뷰 기능&lt;/h2&gt;
&lt;p&gt;1.0에서 프리뷰로 출시된 기능들이 있습니다 — 작동하지만 API가 변경될 수 있습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;DevUI&lt;/strong&gt; — 에이전트 실행, 메시지 흐름, 도구 호출을 실시간으로 시각화하는 브라우저 기반 로컬 디버거. Application Insights의 에이전트 추론 버전이라고 생각하면 됩니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;GitHub Copilot SDK 및 Claude Code SDK&lt;/strong&gt; — 오케스트레이션 코드에서 직접 Copilot이나 Claude를 에이전트 하네스로 사용합니다. 같은 워크플로에서 코딩 가능한 에이전트를 다른 에이전트와 함께 구성할 수 있습니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Agent Harness&lt;/strong&gt; — 에이전트에게 셸, 파일 시스템, 메시징 루프에 대한 접근을 제공하는 커스터마이즈 가능한 로컬 런타임. 코딩 에이전트와 자동화 패턴을 떠올려 보세요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Skills&lt;/strong&gt; — 에이전트에게 즉시 사용 가능한 구조화된 기능을 제공하는 재사용 가능한 도메인 능력 패키지.&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="semantic-kernel-또는-autogen에서-마이그레이션"&gt;Semantic Kernel 또는 AutoGen에서 마이그레이션&lt;/h2&gt;
&lt;p&gt;기존 Semantic Kernel 또는 AutoGen 코드가 있다면, 코드를 분석하고 단계별 마이그레이션 계획을 생성하는 전용 마이그레이션 어시스턴트가 있습니다. &lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-semantic-kernel"&gt;Semantic Kernel 마이그레이션 가이드&lt;/a&gt;와 &lt;a href="https://learn.microsoft.com/en-us/agent-framework/migration-guide/from-autogen"&gt;AutoGen 마이그레이션 가이드&lt;/a&gt;가 모든 과정을 안내해 줍니다.&lt;/p&gt;
&lt;p&gt;RC 패키지를 사용하고 계셨다면, 1.0으로의 업그레이드는 버전 번호만 바꾸면 됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Agent Framework 1.0은 엔터프라이즈 팀이 기다려온 프로덕션 마일스톤입니다. 안정적인 API, 멀티 제공업체 지원, 실제로 대규모에서 작동하는 오케스트레이션 패턴, 그리고 Semantic Kernel과 AutoGen 모두에서의 마이그레이션 경로.&lt;/p&gt;
&lt;p&gt;프레임워크는 &lt;a href="https://github.com/microsoft/agent-framework"&gt;GitHub에서 완전한 오픈소스&lt;/a&gt;이며, &lt;code&gt;dotnet add package Microsoft.Agents.AI&lt;/code&gt;로 오늘 바로 시작할 수 있습니다. &lt;a href="https://learn.microsoft.com/en-us/agent-framework/get-started/"&gt;빠른 시작 가이드&lt;/a&gt;와 &lt;a href="https://github.com/microsoft/agent-framework"&gt;샘플&lt;/a&gt;을 확인해서 직접 경험해 보세요.&lt;/p&gt;
&lt;p&gt;&amp;ldquo;프로덕션에서 안전하게 사용할 수 있다&amp;quot;는 신호를 기다리고 있었다면 — 바로 이것입니다.&lt;/p&gt;</content:encoded></item><item><title>Aspire 13.2 대시보드에 텔레메트리 API가 추가됐다 — 그리고 모든 것이 바뀐다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/</guid><description>.NET Aspire 13.2가 스마트한 텔레메트리 내보내기, 트레이스와 로그를 위한 프로그래밍 가능한 API, GenAI 시각화 개선을 제공합니다. 디버깅 워크플로에 왜 중요한지 알아보세요.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/aspire-132-dashboard-export-telemetry/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;.NET Aspire로 분산 앱을 구축해왔다면, 대시보드가 전체 경험에서 가장 훌륭한 부분이라는 걸 이미 알고 있을 겁니다. 모든 트레이스, 로그, 메트릭이 한 곳에 — 외부 Jaeger도 필요 없고, Seq 설정도 필요 없고, &amp;ldquo;다른 터미널 확인해 볼게&amp;rdquo; 같은 순간도 없습니다.&lt;/p&gt;
&lt;p&gt;Aspire 13.2가 이를 크게 개선했습니다. James Newton-King이 &lt;a href="https://devblogs.microsoft.com/aspire/aspire-dashboard-improvements-export-and-telemetry/"&gt;업데이트를 발표&lt;/a&gt;했는데, 솔직히? 텔레메트리 내보내기와 API 기능만으로도 업그레이드할 가치가 있습니다.&lt;/p&gt;
&lt;h2 id="텔레메트리를-제대로-내보내기"&gt;텔레메트리를 제대로 내보내기&lt;/h2&gt;
&lt;p&gt;우리 모두 겪어본 시나리오입니다: 분산 문제를 디버깅하면서 20분간의 설정 끝에 마침내 재현했는데, 이제 팀에게 무슨 일이 있었는지 공유해야 합니다. 이전에는? 스크린샷. 트레이스 ID 복사 붙여넣기. 항상 그러는 것처럼.&lt;/p&gt;
&lt;p&gt;Aspire 13.2는 &lt;strong&gt;로그 및 텔레메트리 관리&lt;/strong&gt; 대화상자를 추가했습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;모든 텔레메트리 삭제 (재현 시도 전에 유용)&lt;/li&gt;
&lt;li&gt;선택한 텔레메트리를 표준 OTLP/JSON 형식의 ZIP 파일로 내보내기&lt;/li&gt;
&lt;li&gt;나중에 해당 ZIP을 아무 Aspire 대시보드에 다시 가져오기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;마지막 부분이 핵심 기능입니다. 버그를 재현하고, 텔레메트리를 내보내고, 작업 항목에 첨부하면, 팀원이 자신의 대시보드에 가져와서 당신이 본 것과 정확히 같은 것을 볼 수 있습니다. &amp;ldquo;네 컴퓨터에서 재현해볼 수 있어?&amp;ldquo;는 이제 그만.&lt;/p&gt;
&lt;p&gt;개별 트레이스, 스팬, 로그에도 컨텍스트 메뉴에 &amp;ldquo;Export JSON&amp;rdquo; 옵션이 있습니다. 특정 트레이스를 공유해야 할 때? 우클릭, JSON 복사, PR 설명에 붙여넣기. 끝.&lt;/p&gt;
&lt;h2 id="텔레메트리-api가-진짜-게임-체인저"&gt;텔레메트리 API가 진짜 게임 체인저&lt;/h2&gt;
&lt;p&gt;가장 기대되는 부분입니다. 대시보드가 이제 &lt;code&gt;/api/telemetry&lt;/code&gt; 하위에 HTTP API를 제공하여 텔레메트리 데이터를 프로그래밍 방식으로 조회할 수 있습니다. 사용 가능한 엔드포인트:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/resources&lt;/code&gt; — 텔레메트리가 있는 리소스 목록&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/spans&lt;/code&gt; — 필터를 사용한 스팬 조회&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/logs&lt;/code&gt; — 필터를 사용한 로그 조회&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces&lt;/code&gt; — 트레이스 목록&lt;/li&gt;
&lt;li&gt;&lt;code&gt;GET /api/telemetry/traces/{traceId}&lt;/code&gt; — 특정 트레이스의 모든 스팬 가져오기&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;모든 것이 OTLP JSON 형식으로 반환됩니다. 이것은 새로운 CLI 명령 &lt;code&gt;aspire agent mcp&lt;/code&gt;와 &lt;code&gt;aspire otel&lt;/code&gt;을 구동하지만, 진정한 의미는 더 큽니다: 이제 앱의 텔레메트리를 직접 조회하는 도구, 스크립트, AI 에이전트 통합을 구축할 수 있습니다.&lt;/p&gt;
&lt;p&gt;디버깅 중에 실제 분산 트레이스를 볼 수 있는 AI 코딩 에이전트를 상상해보세요. 더 이상 가설이 아닙니다 — 이 API가 가능하게 하는 것입니다.&lt;/p&gt;
&lt;h2 id="genai-텔레메트리가-실용적으로"&gt;GenAI 텔레메트리가 실용적으로&lt;/h2&gt;
&lt;p&gt;Semantic Kernel이나 Microsoft.Extensions.AI로 AI 기반 앱을 구축하고 있다면, 개선된 GenAI 텔레메트리 시각화 도구를 좋아할 겁니다. Aspire 13.2 추가 기능:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AI 도구 설명을 Markdown으로 렌더링&lt;/li&gt;
&lt;li&gt;트레이스 페이지에 전용 GenAI 버튼으로 빠른 접근&lt;/li&gt;
&lt;li&gt;잘린 또는 비표준 GenAI JSON에 대한 더 나은 에러 처리&lt;/li&gt;
&lt;li&gt;도구 정의 간 클릭-하이라이트 내비게이션&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;블로그 포스트에서 VS Code Copilot chat, Copilot CLI, OpenCode 모두 &lt;code&gt;OTEL_EXPORTER_OTLP_ENDPOINT&lt;/code&gt; 설정을 지원한다고 언급합니다. Aspire 대시보드를 가리키면 텔레메트리를 통해 AI 에이전트가 실시간으로 생각하는 모습을 말 그대로 볼 수 있습니다. 다른 곳에서는 찾을 수 없는 디버깅 경험입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Aspire 13.2는 대시보드를 &amp;ldquo;괜찮은 디버깅 UI&amp;quot;에서 &amp;ldquo;프로그래밍 가능한 관찰성 플랫폼&amp;quot;으로 변화시킵니다. 내보내기/가져오기 워크플로만으로도 분산 디버깅에서 실질적인 시간을 절약하고, 텔레메트리 API는 AI 지원 진단의 문을 엽니다.&lt;/p&gt;
&lt;p&gt;이미 Aspire를 사용 중이라면 업그레이드하세요. 아직이라면 — &lt;a href="https://aspire.dev"&gt;aspire.dev&lt;/a&gt;를 확인해볼 좋은 이유입니다.&lt;/p&gt;</content:encoded></item><item><title>azd로 AI 에이전트를 로컬에서 실행하고 디버깅할 수 있게 됐다 — 2026년 3월 변경사항 정리</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/</guid><description>Azure Developer CLI가 2026년 3월에 7개 릴리스를 발행했습니다. 하이라이트: AI 에이전트의 로컬 실행 및 디버그 루프, GitHub Copilot 프로젝트 설정 통합, Container App Jobs 지원.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azd-march-2026-local-ai-agent-debugging/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;한 달에 7개 릴리스. Azure Developer CLI (&lt;code&gt;azd&lt;/code&gt;) 팀이 2026년 3월에 발행한 것이며, 메인 기능은 제가 기다리던 것입니다: &lt;strong&gt;AI 에이전트를 위한 로컬 실행 및 디버그 루프&lt;/strong&gt;.&lt;/p&gt;
&lt;p&gt;PC Chan이 &lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;전체 요약을 게시&lt;/a&gt;했는데, 내용이 많지만 AI 기반 앱을 구축하는 .NET 개발자에게 실제로 중요한 것만 걸러보겠습니다.&lt;/p&gt;
&lt;h2 id="배포-없이-ai-에이전트-실행-및-디버깅"&gt;배포 없이 AI 에이전트 실행 및 디버깅&lt;/h2&gt;
&lt;p&gt;이것이 핵심입니다. 새로운 &lt;code&gt;azure.ai.agents&lt;/code&gt; 확장이 AI 에이전트를 위한 적절한 이너 루프 경험을 제공하는 명령을 추가합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;code&gt;azd ai agent run&lt;/code&gt; — 에이전트를 로컬에서 시작&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt; — 메시지 전송 (로컬 또는 배포된 에이전트)&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent show&lt;/code&gt; — 컨테이너 상태 및 건강 표시&lt;/li&gt;
&lt;li&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt; — 컨테이너 로그를 실시간 스트리밍&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;이전에는 AI 에이전트 테스트가 변경할 때마다 Microsoft Foundry로 배포하는 것을 의미했습니다. 이제 로컬에서 반복하고, 에이전트 동작을 테스트하고, 준비가 되면 배포할 수 있습니다.&lt;/p&gt;
&lt;h2 id="github-copilot이-azd-프로젝트를-설정"&gt;GitHub Copilot이 azd 프로젝트를 설정&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd init&lt;/code&gt;에 &amp;ldquo;Set up with GitHub Copilot (Preview)&amp;rdquo; 옵션이 추가됐습니다. 프로젝트 구조에 대한 프롬프트에 수동으로 답하는 대신, Copilot 에이전트가 구성을 생성합니다. 명령이 실패하면 &lt;code&gt;azd&lt;/code&gt;가 AI 지원 문제 해결을 제공합니다.&lt;/p&gt;
&lt;h2 id="container-app-jobs-및-배포-개선"&gt;Container App Jobs 및 배포 개선&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Container App Jobs&lt;/strong&gt;: &lt;code&gt;azd&lt;/code&gt;가 기존 &lt;code&gt;host: containerapp&lt;/code&gt; 설정으로 &lt;code&gt;Microsoft.App/jobs&lt;/code&gt; 배포&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;설정 가능한 배포 타임아웃&lt;/strong&gt;: &lt;code&gt;azd deploy&lt;/code&gt;의 새 &lt;code&gt;--timeout&lt;/code&gt; 플래그와 &lt;code&gt;azure.yaml&lt;/code&gt;의 &lt;code&gt;deployTimeout&lt;/code&gt; 필드&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;원격 빌드 폴백&lt;/strong&gt;: ACR 빌드 실패 시 로컬 Docker/Podman 빌드로 자동 폴백&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;로컬 프리플라이트 검증&lt;/strong&gt;: 배포 전 Bicep 매개변수를 로컬에서 검증&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="dx-개선"&gt;DX 개선&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;자동 pnpm/yarn 감지&lt;/strong&gt; — JS/TS 프로젝트용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;pyproject.toml 지원&lt;/strong&gt; — Python 패키징용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;로컬 템플릿 디렉토리&lt;/strong&gt; — &lt;code&gt;azd init --template&lt;/code&gt;이 파일시스템 경로 허용&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;개선된 오류 메시지&lt;/strong&gt; — &lt;code&gt;--no-prompt&lt;/code&gt; 모드&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;빌드 환경 변수&lt;/strong&gt; — 모든 프레임워크 빌드 서브프로세스에 주입 (.NET, Node.js, Java, Python)&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;로컬 AI 에이전트 디버그 루프가 이번 릴리스의 스타이지만, 배포 개선과 DX 폴리시의 축적으로 &lt;code&gt;azd&lt;/code&gt;가 그 어느 때보다 성숙해졌습니다. Azure에 .NET 앱을 배포하고 있다면 — 특히 AI 에이전트라면 — 이번 업데이트는 가치가 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/azure-sdk/azure-developer-cli-azd-march-2026/"&gt;전체 릴리스 노트&lt;/a&gt;에서 모든 세부사항을 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps가 드디어 모두가 불평하던 Markdown 편집기를 고쳤다</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/</guid><description>Azure DevOps 작업 항목의 Markdown 편집기가 미리보기와 편집 모드의 명확한 구분을 얻었습니다. 작은 변경이지만 정말 성가신 워크플로 문제를 해결합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-markdown-editor-work-items/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Azure Boards를 사용한다면 아마 이런 경험이 있을 겁니다: 작업 항목 설명을 읽고 있는데, 인수 기준을 확인하는 중에 실수로 더블클릭을 합니다. 쾅 — 편집 모드에 들어갔습니다. 아무것도 편집하고 싶지 않았는데. 그냥 읽고 있었을 뿐인데.&lt;/p&gt;
&lt;p&gt;Dan Hellem이 &lt;a href="https://devblogs.microsoft.com/devops/improving-the-markdown-editor-for-work-items/"&gt;수정을 발표&lt;/a&gt;했는데, 작아 보이지만 일상 워크플로에서 진짜 마찰을 제거하는 변경입니다.&lt;/p&gt;
&lt;h2 id="무엇이-바뀌었나"&gt;무엇이 바뀌었나&lt;/h2&gt;
&lt;p&gt;작업 항목 텍스트 필드의 Markdown 편집기가 이제 &lt;strong&gt;기본적으로 미리보기 모드&lt;/strong&gt;로 열립니다. 콘텐츠를 읽고 상호작용할 수 있습니다 — 링크 따라가기, 포맷 확인 — 실수로 편집 모드에 들어갈 걱정 없이.&lt;/p&gt;
&lt;p&gt;실제로 편집하고 싶을 때 필드 상단의 편집 아이콘을 클릭합니다. 완료하면 명시적으로 미리보기 모드로 돌아갑니다. 단순하고, 의도적이고, 예측 가능합니다.&lt;/p&gt;
&lt;h2 id="보이는-것보다-더-중요한-이유"&gt;보이는 것보다 더 중요한 이유&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://developercommunity.visualstudio.com/t/Markdown-editor-for-work-item-multi-line/10935496"&gt;커뮤니티 피드백 스레드&lt;/a&gt;가 길었습니다. 더블클릭으로 편집하는 동작은 2025년 7월 Markdown 편집기와 함께 도입되었고, 불만은 거의 즉시 시작되었습니다.&lt;/p&gt;
&lt;p&gt;Azure Boards로 스프린트 계획, 백로그 개선, 코드 리뷰를 하는 팀에게 이런 미세한 마찰은 누적됩니다.&lt;/p&gt;
&lt;h2 id="배포-상태"&gt;배포 상태&lt;/h2&gt;
&lt;p&gt;이미 일부 고객에게 배포되고 있으며 앞으로 2~3주에 걸쳐 전체로 확대됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;모든 개선이 헤드라인 기능이 될 필요는 없습니다. 때로 최고의 업데이트는 단순히 성가신 것을 제거하는 것입니다. 이것이 바로 그런 것 — 작업 항목을 평화롭게 읽고 싶은 사람들을 위해 Azure Boards를 덜 적대적으로 만드는 작은 UX 수정입니다.&lt;/p&gt;</content:encoded></item><item><title>Bookmark Studio가 Visual Studio 북마크에 슬롯 기반 내비게이션과 공유 기능을 추가</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/</guid><description>Mads Kristensen의 새로운 Bookmark Studio 확장이 키보드 기반 슬롯 내비게이션, 북마크 관리자, 색상, 라벨 및 내보내기 기능을 Visual Studio 북마크에 추가합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/bookmark-studio-visual-studio-extension/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio의 북마크는 항상&amp;hellip;그럭저럭이었습니다. 하나 설정하고, 다음으로 이동하고, 어떤 게 어떤 건지 잊어버립니다. 작동하지만 강력하다고 부를 수 있는 기능은 아니었습니다.&lt;/p&gt;
&lt;p&gt;Mads Kristensen이 &lt;a href="https://devblogs.microsoft.com/visualstudio/bookmark-studio-evolving-bookmarks-in-visual-studio/"&gt;Bookmark Studio를 출시&lt;/a&gt;했습니다. 정기적으로 북마크를 사용한다면 느꼈을 빈틈을 정확히 채우는 실험적 확장입니다.&lt;/p&gt;
&lt;h2 id="슬롯-기반-내비게이션"&gt;슬롯 기반 내비게이션&lt;/h2&gt;
&lt;p&gt;북마크를 1-9번 슬롯에 할당하고 &lt;code&gt;Alt+Shift+1&lt;/code&gt;부터 &lt;code&gt;Alt+Shift+9&lt;/code&gt;로 직접 이동할 수 있습니다. 새 북마크는 자동으로 다음 사용 가능한 슬롯을 받습니다.&lt;/p&gt;
&lt;h2 id="북마크-관리자"&gt;북마크 관리자&lt;/h2&gt;
&lt;p&gt;새 도구 창에서 모든 북마크를 표시하고 이름, 파일, 위치, 색상, 슬롯으로 필터링할 수 있습니다.&lt;/p&gt;
&lt;h2 id="라벨-색상-폴더로-정리"&gt;라벨, 색상, 폴더로 정리&lt;/h2&gt;
&lt;p&gt;북마크에 라벨, 색상을 추가하고 폴더로 그룹화할 수 있습니다. 메타데이터는 솔루션별로 저장됩니다.&lt;/p&gt;
&lt;h2 id="내보내기-및-공유"&gt;내보내기 및 공유&lt;/h2&gt;
&lt;p&gt;Bookmark Studio는 북마크를 일반 텍스트, Markdown 또는 CSV로 내보낼 수 있습니다.&lt;/p&gt;
&lt;h2 id="코드-이동을-따라가는-북마크"&gt;코드 이동을 따라가는 북마크&lt;/h2&gt;
&lt;p&gt;Bookmark Studio는 고정된 텍스트에 상대적으로 북마크를 추적하므로 편집 중 잘못된 줄로 떠내려가지 않습니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Bookmark Studio는 아무것도 재발명하지 않습니다. 수년간 &amp;ldquo;충분했던&amp;rdquo; 기능을 진정으로 유용하게 만듭니다. &lt;a href="https://marketplace.visualstudio.com/items?itemName=MadsKristensen.BookmarkStudio"&gt;Visual Studio Marketplace&lt;/a&gt;에서 다운로드하세요.&lt;/p&gt;</content:encoded></item><item><title>Visual Studio 3월 업데이트로 커스텀 Copilot 에이전트 제작 가능 — find_symbol이 큰 변화</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</link><pubDate>Thu, 02 Apr 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/</guid><description>Visual Studio 2026년 3월 업데이트가 커스텀 Copilot 에이전트, 재사용 가능한 스킬, 언어 인식 find_symbol 도구, Test Explorer에서의 Copilot 프로파일링을 제공합니다.</description><content:encoded>&lt;blockquote&gt;
&lt;p&gt;&lt;em&gt;이 글은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/visual-studio-march-2026-custom-copilot-agents/"&gt;여기&lt;/a&gt;에서 확인하세요.&lt;/em&gt;&lt;/p&gt;
&lt;/blockquote&gt;
&lt;p&gt;Visual Studio가 가장 중요한 Copilot 업데이트를 받았습니다. Mark Downie가 &lt;a href="https://devblogs.microsoft.com/visualstudio/visual-studio-march-update-build-your-own-custom-agents/"&gt;3월 릴리스를 발표&lt;/a&gt;했는데, 헤드라인은 커스텀 에이전트이지만 솔직히 &lt;code&gt;find_symbol&lt;/code&gt; 도구가 워크플로를 가장 많이 바꿀 기능일 수 있습니다.&lt;/p&gt;
&lt;h2 id="리포에-커스텀-copilot-에이전트"&gt;리포에 커스텀 Copilot 에이전트&lt;/h2&gt;
&lt;p&gt;Copilot이 팀의 코딩 표준을 따르게 하고 싶으세요? 커스텀 에이전트는 리포의 &lt;code&gt;.github/agents/&lt;/code&gt;에 &lt;code&gt;.agent.md&lt;/code&gt; 파일로 정의됩니다. 각 에이전트는 워크스페이스 인식, 코드 이해, 도구, 선호 모델, MCP 연결에 대한 전체 접근 권한을 가집니다.&lt;/p&gt;
&lt;h2 id="에이전트-스킬-재사용-가능한-인스트럭션-팩"&gt;에이전트 스킬: 재사용 가능한 인스트럭션 팩&lt;/h2&gt;
&lt;p&gt;스킬은 리포의 &lt;code&gt;.github/skills/&lt;/code&gt;나 프로필의 &lt;code&gt;~/.copilot/skills/&lt;/code&gt;에서 자동 로드됩니다.&lt;/p&gt;
&lt;h2 id="find_symbol-언어-인식-내비게이션"&gt;find_symbol: 언어 인식 내비게이션&lt;/h2&gt;
&lt;p&gt;새로운 &lt;code&gt;find_symbol&lt;/code&gt; 도구는 Copilot의 에이전트 모드에 언어 서비스 기반 심볼 내비게이션을 제공합니다. 텍스트 검색 대신 심볼의 모든 참조를 찾고 타입 정보와 스코프에 접근할 수 있습니다.&lt;/p&gt;
&lt;p&gt;.NET 개발자에게 이것은 엄청난 개선입니다 — 깊은 타입 계층 구조를 가진 C# 코드베이스가 크게 혜택을 받습니다.&lt;/p&gt;
&lt;h2 id="copilot으로-테스트-프로파일링"&gt;Copilot으로 테스트 프로파일링&lt;/h2&gt;
&lt;p&gt;Test Explorer 컨텍스트 메뉴에 &lt;strong&gt;Profile with Copilot&lt;/strong&gt;이 추가됐습니다. Profiling Agent가 테스트를 실행하고 자동으로 성능을 분석합니다.&lt;/p&gt;
&lt;h2 id="라이브-디버깅-중-perf-tips"&gt;라이브 디버깅 중 Perf Tips&lt;/h2&gt;
&lt;p&gt;성능 최적화가 이제 디버깅 중에 이루어집니다. Visual Studio가 인라인으로 실행 시간을 표시합니다. 느린 라인을 발견하면 Perf Tip을 클릭하고 Copilot에게 최적화 제안을 요청하세요.&lt;/p&gt;
&lt;h2 id="solution-explorer에서-nuget-취약점-수정"&gt;Solution Explorer에서 NuGet 취약점 수정&lt;/h2&gt;
&lt;p&gt;NuGet 패키지 취약점이 감지되면 Solution Explorer에 직접 &lt;strong&gt;Fix with GitHub Copilot&lt;/strong&gt; 링크가 표시됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;커스텀 에이전트와 스킬이 헤드라인이지만, &lt;code&gt;find_symbol&lt;/code&gt;이 숨겨진 보석입니다 — .NET 코드 리팩토링 시 Copilot의 정확도를 근본적으로 바꿉니다. &lt;a href="https://visualstudio.microsoft.com/downloads/"&gt;Visual Studio 2026 Insiders&lt;/a&gt;를 다운로드해서 모든 기능을 체험해보세요.&lt;/p&gt;</content:encoded></item><item><title>KubeCon Europe 2026: .NET 개발자가 실제로 알아야 할 것</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</link><pubDate>Sun, 29 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/</guid><description>Microsoft가 KubeCon Europe 2026에서 대량의 Kubernetes 발표를 쏟아냈습니다. .NET 앱을 배포하고 있다면 실제로 중요한 AKS와 클라우드 네이티브 업데이트만 필터링해서 정리했습니다.</description><content:encoded>&lt;p&gt;&lt;em&gt;이 게시물은 자동 번역되었습니다. 원본은 &lt;a href="https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/kubecon-2026-aks-updates-dotnet-developers/"&gt;여기를 클릭&lt;/a&gt;하세요.&lt;/em&gt;&lt;/p&gt;
&lt;p&gt;거대한 발표 글이 올라오고 스크롤하면서 &amp;ldquo;멋지긴 한데, 이게 실제로 나한테 뭘 바꿔주는 거지?&amp;ldquo;라고 생각하는 그 느낌 아시죠? 매 KubeCon 시즌마다 저한테 벌어지는 일입니다.&lt;/p&gt;
&lt;p&gt;Microsoft가 방금 &lt;a href="https://opensource.microsoft.com/blog/2026/03/24/whats-new-with-microsoft-in-open-source-and-kubernetes-at-kubecon-cloudnativecon-europe-2026/"&gt;KubeCon Europe 2026 전체 요약&lt;/a&gt;을 발표했는데요 — Brendan Burns 본인이 직접 작성했습니다 — 솔직히? 진짜 내용이 있습니다. 기능 체크리스트가 아니라, 프로덕션에서 운영하는 방식을 바꿔주는 운영 개선 사항들입니다.&lt;/p&gt;
&lt;p&gt;.NET 개발자로서 진짜 중요한 것만 정리해 보겠습니다.&lt;/p&gt;
&lt;h2 id="서비스-메시-세금-없는-mtls"&gt;서비스 메시 세금 없는 mTLS&lt;/h2&gt;
&lt;p&gt;서비스 메시의 문제점: 모두가 보안 보장을 원하지만, 운영 오버헤드는 아무도 원하지 않습니다. AKS가 드디어 이 격차를 메우고 있습니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/application-network"&gt;Azure Kubernetes Application Network&lt;/a&gt;은 상호 TLS, 애플리케이션 인식 인가, 트래픽 텔레메트리를 제공합니다 — 사이드카가 무거운 풀 메시를 배포할 필요 없이요. &lt;a href="https://aka.ms/acns/cilium-mtls"&gt;Advanced Container Networking Services의 Cilium mTLS&lt;/a&gt;와 결합하면, X.509 인증서와 SPIRE 신원 관리를 사용한 암호화된 pod 간 통신을 얻을 수 있습니다.&lt;/p&gt;
&lt;p&gt;실제로 의미하는 것: ASP.NET Core API가 백그라운드 워커와 통신하고, gRPC 서비스가 서로 호출하는 것 — 모두 네트워크 수준에서 암호화되고 신원 검증되며, 애플리케이션 코드 변경은 제로. 이건 큽니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;ingress-nginx&lt;/code&gt;에서 마이그레이션하는 팀을 위해, &lt;a href="https://aka.ms/aks/app-routing/gateway-api"&gt;Meshless Istio를 사용한 Application Routing&lt;/a&gt;도 있으며 Kubernetes Gateway API를 완전히 지원합니다. 사이드카 없음. 표준 기반. 점진적 마이그레이션을 위한 &lt;code&gt;ingress2gateway&lt;/code&gt; 도구도 함께 출시되었습니다.&lt;/p&gt;
&lt;h2 id="뒤늦은-생각이-아닌-gpu-관측성"&gt;뒤늦은 생각이 아닌 GPU 관측성&lt;/h2&gt;
&lt;p&gt;.NET 서비스와 함께 AI 추론을 실행하고 있다면(솔직히, 누가 시작하지 않고 있겠어요?), GPU 모니터링 사각지대를 경험했을 겁니다. CPU/메모리 대시보드는 훌륭했는데, GPU는&amp;hellip; 수동 익스포터 설정 없이는 아무것도 없었죠.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://aka.ms/aks/managed-gpu-metrics"&gt;AKS가 이제 GPU 메트릭을 네이티브로 노출&lt;/a&gt;합니다 — 관리형 Prometheus와 Grafana에서. 같은 스택, 같은 대시보드, 같은 알림 파이프라인. 커스텀 익스포터도 서드파티 에이전트도 불필요.&lt;/p&gt;
&lt;p&gt;네트워크 측에서는, HTTP, gRPC, Kafka 트래픽에 대한 플로우별 가시성이 &lt;a href="https://learn.microsoft.com/en-us/azure/aks/container-network-observability-logs"&gt;원클릭 Azure Monitor 경험&lt;/a&gt;과 함께 추가되었습니다. IP, 포트, 워크로드, 플로우 방향, 정책 결정 — 모두 내장 대시보드에서.&lt;/p&gt;
&lt;p&gt;그리고 두 번 쳐다보게 만든 것: &lt;a href="https://learn.microsoft.com/en-us/azure/aks/advanced-container-networking-services-overview"&gt;agentic container networking&lt;/a&gt;이 자연어로 클러스터의 네트워크 상태에 대해 질문할 수 있는 웹 UI를 추가합니다. &amp;ldquo;Pod X가 서비스 Y에 도달하지 못하는 이유는?&amp;rdquo; → 라이브 텔레메트리에서 읽기 전용 진단. 새벽 2시에 진짜 유용합니다.&lt;/p&gt;
&lt;h2 id="박사-학위-필요-없는-크로스-클러스터-네트워킹"&gt;박사 학위 필요 없는 크로스 클러스터 네트워킹&lt;/h2&gt;
&lt;p&gt;멀티 클러스터 Kubernetes는 역사적으로 &amp;ldquo;자체 네트워크 접착제를 가져오세요&amp;rdquo; 경험이었습니다. Azure Kubernetes Fleet Manager가 이제 관리형 Cilium 클러스터 메시를 통한 &lt;a href="https://aka.ms/kubernetes-fleet/networking/cross-cluster"&gt;크로스 클러스터 네트워킹&lt;/a&gt;을 제공합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;AKS 클러스터 간 통합 연결&lt;/li&gt;
&lt;li&gt;크로스 클러스터 디스커버리를 위한 글로벌 서비스 레지스트리&lt;/li&gt;
&lt;li&gt;클러스터마다 반복하지 않고 중앙에서 관리되는 설정&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;복원력이나 컴플라이언스를 위해 여러 리전에서 .NET 마이크로서비스를 실행하고 있다면, 많은 취약한 커스텀 접착제를 대체합니다. West Europe의 서비스 A가 메시를 통해 East US의 서비스 B를 발견하고 호출할 수 있으며, 일관된 라우팅과 보안 정책이 적용됩니다.&lt;/p&gt;
&lt;h2 id="용기가-필요-없는-업그레이드"&gt;용기가 필요 없는 업그레이드&lt;/h2&gt;
&lt;p&gt;솔직히 — 프로덕션에서의 Kubernetes 업그레이드는 스트레스입니다. &amp;ldquo;업그레이드하고 기도하기&amp;quot;가 너무 많은 팀의 사실상 전략이었고, 클러스터가 버전에서 뒤처지는 주된 이유입니다.&lt;/p&gt;
&lt;p&gt;두 가지 새로운 기능이 이것을 바꿉니다:&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;Blue-green 에이전트 풀 업그레이드&lt;/strong&gt;는 새 설정으로 병렬 노드 풀을 생성합니다. 동작을 검증하고, 트래픽을 점진적으로 이동하고, 깨끗한 롤백 경로를 유지하세요. 프로덕션 노드에서의 인플레이스 변경은 이제 끝.&lt;/p&gt;
&lt;p&gt;&lt;strong&gt;에이전트 풀 롤백&lt;/strong&gt;은 업그레이드가 잘못된 후 클러스터를 재구축하지 않고 노드 풀을 이전 Kubernetes 버전과 노드 이미지로 되돌릴 수 있게 합니다.&lt;/p&gt;
&lt;p&gt;함께 사용하면, 운영자에게 업그레이드 생명주기에 대한 진정한 통제력을 제공합니다. .NET 팀에게 중요한 이유는 플랫폼 속도가 새로운 런タ임, 보안 패치, 네트워크 기능을 얼마나 빨리 채택하는지를 직접 제어하기 때문입니다.&lt;/p&gt;
&lt;h2 id="ai-워크로드가-kubernetes의-일급-시민이-되다"&gt;AI 워크로드가 Kubernetes의 일급 시민이 되다&lt;/h2&gt;
&lt;p&gt;업스트림 오픈소스 작업도 마찬가지로 중요합니다. Dynamic Resource Allocation (DRA)이 Kubernetes 1.36에서 GA가 되어, GPU 스케줄링이 우회 방법이 아닌 진정한 일급 기능이 되었습니다.&lt;/p&gt;
&lt;p&gt;주목할 프로젝트들:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;프로젝트&lt;/th&gt;
&lt;th&gt;하는 일&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/kaito-project/kubeairunway"&gt;AI Runway&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;추론을 위한 공통 Kubernetes API — K8s를 몰라도 모델 배포 가능, HuggingFace 검색과 비용 추정 포함&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://www.cncf.io/blog/2026/01/07/holmesgpt-agentic-troubleshooting-built-for-the-cloud-native-era/"&gt;HolmesGPT&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;클라우드 네이티브를 위한 에이전트 문제 해결 — CNCF Sandbox 프로젝트로 합류&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;a href="https://github.com/project-dalec/dalec"&gt;Dalec&lt;/a&gt;&lt;/td&gt;
&lt;td&gt;SBOM 생성을 포함한 선언적 컨테이너 이미지 빌드 — 빌드 단계에서 CVE 감소&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;방향은 명확합니다: 여러분의 .NET API, Semantic Kernel 오케스트레이션 레이어, 추론 워크로드 모두 하나의 일관된 플랫폼 모델에서 실행되어야 합니다. 거기에 도달하고 있습니다.&lt;/p&gt;
&lt;h2 id="이번-주부터-시작한다면"&gt;이번 주부터 시작한다면&lt;/h2&gt;
&lt;p&gt;팀에서 이러한 변경 사항을 평가하고 있다면, 제 솔직한 우선순위 목록:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;관측성 먼저&lt;/strong&gt; — 비프로덕션 클러스터에서 GPU 메트릭과 네트워크 플로우 로그를 활성화하세요. 놓치고 있던 것을 확인하세요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Blue-green 업그레이드 테스트&lt;/strong&gt; — 다음 프로덕션 클러스터 업그레이드 전에 롤백 워크플로우를 테스트하세요. 프로세스에 대한 신뢰를 구축하세요.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;신원 인식 네트워킹 파일럿&lt;/strong&gt; — 내부 서비스 경로 하나를 선택해서 Cilium으로 mTLS를 활성화하세요. 오버헤드를 측정하세요 (스포일러: 최소).&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Fleet Manager 평가&lt;/strong&gt; — 두 개 이상의 클러스터를 운영한다면, 크로스 클러스터 네트워킹은 커스텀 접착제 감소만으로도 투자 대비 이득.&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;작은 실험, 빠른 피드백. 항상 정답인 방법입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;KubeCon 발표는 압도적일 수 있지만, 이번 배치는 AKS의 .NET 팀에게 진정으로 바늘을 움직입니다. 메시 오버헤드 없는 더 나은 네트워크 보안, 진짜 GPU 관측성, 더 안전한 업그레이드, 그리고 더 강력한 AI 인프라 기반.&lt;/p&gt;
&lt;p&gt;이미 AKS를 사용하고 있다면, 운영 기준선을 강화할 좋은 시점입니다. .NET 워크로드를 Kubernetes로 이동할 계획이라면 — 플랫폼이 훨씬 더 프로덕션에 준비되었습니다.&lt;/p&gt;</content:encoded></item><item><title>SQL MCP Server, SSMS의 Copilot, AI 에이전트가 포함된 Database Hub: SQLCon 2026에서 실제로 중요한 것</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</link><pubDate>Sat, 28 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/agentic-ai-microsoft-databases-what-matters/</guid><description>Microsoft가 SQLCon 2026에서 데이터베이스 관련 발표를 쏟아냈습니다. Azure SQL에서 AI 기반 앱을 구축하고 있다면 실제로 중요한 내용을 정리했습니다.</description><content:encoded>&lt;p&gt;Microsoft가 &lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;애틀랜타에서 FabCon과 함께 SQLCon 2026&lt;/a&gt;을 시작했는데, 풀어봐야 할 내용이 정말 많습니다. 원래 발표는 비용 절감 플랜부터 엔터프라이즈 컴플라이언스 기능까지 전부 다룹니다. 저는 엔터프라이즈 가격 슬라이드는 건너뛰고 Azure SQL과 AI로 무언가를 만들고 있는 개발자에게 중요한 부분에 집중하겠습니다.&lt;/p&gt;
&lt;h2 id="sql-mcp-server-퍼블릭-프리뷰-출시"&gt;SQL MCP Server 퍼블릭 프리뷰 출시&lt;/h2&gt;
&lt;p&gt;이게 저에게는 헤드라인입니다. Azure SQL Database Hyperscale에 &lt;strong&gt;SQL MCP Server&lt;/strong&gt; 퍼블릭 프리뷰가 추가되어 &lt;a href="https://modelcontextprotocol.io/"&gt;Model Context Protocol&lt;/a&gt;을 사용해 SQL 데이터를 AI 에이전트와 Copilot에 안전하게 연결할 수 있게 되었습니다.&lt;/p&gt;
&lt;p&gt;MCP 물결을 따라오고 계셨다면 — 솔직히 지금은 안 보이는 게 더 어려운데 — 이건 큰 뉴스입니다. 데이터베이스에서 AI 에이전트에 컨텍스트를 제공하기 위해 커스텀 데이터 파이프라인을 구축하는 대신, SQL 데이터를 직접 노출하는 표준화된 프로토콜을 얻게 됩니다. 에이전트가 라이브 데이터베이스 정보를 쿼리하고, 추론하고, 행동할 수 있습니다.&lt;/p&gt;
&lt;p&gt;Semantic Kernel이나 Microsoft Agent Framework로 AI 에이전트를 구축하는 우리에게 이건 깔끔한 통합 경로를 열어줍니다. 에이전트가 재고를 확인해야 하나요? 고객 레코드를 조회해야 하나요? 주문을 검증해야 하나요? MCP가 시나리오마다 맞춤형 데이터 가져오기 코드를 작성하지 않아도 되는 구조화된 방법을 제공합니다.&lt;/p&gt;
&lt;h2 id="ssms-22의-github-copilot-ga-출시"&gt;SSMS 22의 GitHub Copilot GA 출시&lt;/h2&gt;
&lt;p&gt;SQL Server Management Studio에서 시간을 보내신다면 — 솔직히 대부분이 아직 그렇죠 — GitHub Copilot이 SSMS 22에서 정식 출시되었습니다. VS Code와 Visual Studio에서 이미 사용하고 있는 것과 동일한 Copilot 경험을 T-SQL에서 사용할 수 있습니다.&lt;/p&gt;
&lt;p&gt;실용적 가치는 명확합니다: 쿼리 작성, 저장 프로시저 리팩터링, 성능 문제 트러블슈팅, 관리 작업을 위한 채팅 기반 지원. 개념적으로 혁명적이진 않지만, SSMS 안에 바로 있다는 것은 데이터베이스 작업에서 AI 도움을 받기 위해 다른 에디터로 컨텍스트 스위치할 필요가 없다는 뜻입니다.&lt;/p&gt;
&lt;h2 id="벡터-인덱스가-대폭-업그레이드"&gt;벡터 인덱스가 대폭 업그레이드&lt;/h2&gt;
&lt;p&gt;Azure SQL Database에 insert, update, delete를 완전히 지원하는 더 빠르고 강력한 벡터 인덱스가 추가되었습니다. 벡터 데이터가 실시간으로 최신 상태를 유지합니다 — 배치 재인덱싱이 필요 없습니다.&lt;/p&gt;
&lt;p&gt;새로운 기능은 다음과 같습니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;양자화&lt;/strong&gt;로 정확도를 크게 잃지 않으면서 인덱스 크기 축소&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;반복 필터링&lt;/strong&gt;으로 더 정밀한 결과&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;쿼리 옵티마이저와의 긴밀한 통합&lt;/strong&gt;으로 예측 가능한 성능&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Azure SQL을 벡터 스토어로 사용해서 Retrieval-Augmented Generation (RAG)을 하고 있다면, 이 개선 사항들은 직접적으로 유용합니다. 관계형 데이터와 동일한 데이터베이스에 벡터를 유지할 수 있어서, 별도의 벡터 데이터베이스를 운영하는 것에 비해 아키텍처가 크게 단순화됩니다.&lt;/p&gt;
&lt;p&gt;동일한 벡터 개선 사항은 Fabric의 SQL Database에서도 사용할 수 있습니다. 둘 다 같은 SQL 엔진 위에서 동작하기 때문입니다.&lt;/p&gt;
&lt;h2 id="fabric의-database-hub-에이전트-기반-관리"&gt;Fabric의 Database Hub: 에이전트 기반 관리&lt;/h2&gt;
&lt;p&gt;이건 좀 더 미래지향적이지만 흥미롭습니다. Microsoft가 &lt;strong&gt;Microsoft Fabric의 Database Hub&lt;/strong&gt;(얼리 액세스)를 발표했는데, Azure SQL, Cosmos DB, PostgreSQL, MySQL, SQL Server via Arc를 하나의 통합 뷰로 제공합니다.&lt;/p&gt;
&lt;p&gt;흥미로운 점은 단순히 통합 뷰가 아니라 에이전트 기반 관리 접근 방식입니다. AI 에이전트가 데이터베이스 환경을 지속적으로 모니터링하고, 무엇이 변경되었는지 알려주고, 왜 중요한지 설명하고, 다음에 무엇을 해야 할지 제안합니다. 에이전트가 사전 작업을 하고 여러분이 결정을 내리는 human-in-the-loop 모델입니다.&lt;/p&gt;
&lt;p&gt;여러 데이터베이스를 관리하는 팀에게 이건 운영 노이즈를 실질적으로 줄여줄 수 있습니다. 포털 사이를 오가며 수동으로 메트릭을 확인하는 대신, 에이전트가 신호를 가져다줍니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-의미하는-것"&gt;.NET 개발자에게 의미하는 것&lt;/h2&gt;
&lt;p&gt;이 모든 발표를 관통하는 흐름은 명확합니다: Microsoft는 데이터베이스 스택의 모든 레이어에 AI 에이전트를 내장하고 있습니다. 기믹이 아니라 실용적인 도구 레이어로서요.&lt;/p&gt;
&lt;p&gt;Azure SQL 기반 .NET 앱을 구축하고 있다면, 제가 실제로 할 일은 이렇습니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;strong&gt;SQL MCP Server를 사용해 보세요&lt;/strong&gt; — AI 에이전트를 구축하고 있다면. 커스텀 배관 없이 에이전트에 데이터베이스 접근을 제공하는 가장 깔끔한 방법입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;SSMS에서 Copilot을 활성화하세요&lt;/strong&gt; — 아직 안 했다면. 일상적인 SQL 작업에 무료 생산성 향상입니다.&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;벡터 인덱스를 살펴보세요&lt;/strong&gt; — RAG을 하고 있고 현재 별도의 벡터 스토어를 운영 중이라면. Azure SQL로 통합하면 관리할 서비스가 하나 줄어듭니다.&lt;/li&gt;
&lt;/ol&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;전체 발표에는 더 많은 내용이 있습니다 — 비용 절감 플랜, 마이그레이션 어시스턴트, 컴플라이언스 기능 — 하지만 개발자를 위한 스토리는 MCP Server, 벡터 개선, 에이전트 기반 관리 레이어에 있습니다. 이것들이 예산이 아니라 구축 방식을 바꾸는 부분입니다.&lt;/p&gt;
&lt;p&gt;전체 그림은 &lt;a href="https://www.microsoft.com/en-us/sql-server/blog/2026/03/18/advancing-agentic-ai-with-microsoft-databases-across-a-unified-data-estate/"&gt;Shireesh Thota의 전체 발표&lt;/a&gt;를 확인하시고, 새로운 관리 경험을 시도하고 싶다면 &lt;a href="https://aka.ms/database-hub"&gt;Database Hub 얼리 액세스에 등록&lt;/a&gt;하세요.&lt;/p&gt;</content:encoded></item><item><title>Azure DevOps MCP Server가 Microsoft Foundry에 등장: AI 에이전트에 어떤 의미인가</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/azure-devops-mcp-server-microsoft-foundry/</guid><description>Azure DevOps MCP Server가 이제 Microsoft Foundry에서 사용 가능합니다. 몇 번의 클릭으로 AI 에이전트를 DevOps 워크플로 — 작업 항목, 저장소, 파이프라인 — 에 직접 연결하세요.</description><content:encoded>&lt;p&gt;MCP(Model Context Protocol)가 주목받고 있습니다. AI 에이전트 생태계를 따라가고 있다면, MCP 서버가 곳곳에서 등장하고 있다는 것을 알아차렸을 것입니다 — 표준화된 프로토콜을 통해 에이전트가 외부 도구 및 서비스와 상호 작용할 수 있게 해줍니다.&lt;/p&gt;
&lt;p&gt;이제 &lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;Azure DevOps MCP Server가 Microsoft Foundry에서 사용 가능&lt;/a&gt;하며, 이것은 실용적인 가능성에 대해 생각하게 만드는 통합 중 하나입니다.&lt;/p&gt;
&lt;h2 id="실제로-무슨-일이-일어나고-있는가"&gt;실제로 무슨 일이 일어나고 있는가&lt;/h2&gt;
&lt;p&gt;Microsoft는 이미 Azure DevOps MCP Server를 &lt;a href="https://devblogs.microsoft.com/devops/azure-devops-remote-mcp-server-public-preview"&gt;퍼블릭 프리뷰&lt;/a&gt;로 출시했습니다 — 그것이 MCP 서버 자체입니다. 새로운 것은 Foundry 통합입니다. 이제 도구 카탈로그에서 직접 Azure DevOps MCP Server를 Foundry 에이전트에 추가할 수 있습니다.&lt;/p&gt;
&lt;p&gt;아직 Foundry를 모르는 분들을 위해: 대규모로 AI 기반 애플리케이션과 에이전트를 구축하고 관리하기 위한 Microsoft의 통합 플랫폼입니다. 모델 접근, 오케스트레이션, 평가, 배포 — 모두 한 곳에서.&lt;/p&gt;
&lt;h2 id="설정하기"&gt;설정하기&lt;/h2&gt;
&lt;p&gt;설정은 놀라울 정도로 간단합니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;Foundry 에이전트에서 &lt;strong&gt;Add Tools&lt;/strong&gt; &amp;gt; &lt;strong&gt;Catalog&lt;/strong&gt;으로 이동&lt;/li&gt;
&lt;li&gt;&amp;ldquo;Azure DevOps&amp;rdquo; 검색&lt;/li&gt;
&lt;li&gt;Azure DevOps MCP Server(preview)를 선택하고 &lt;strong&gt;Create&lt;/strong&gt; 클릭&lt;/li&gt;
&lt;li&gt;조직 이름을 입력하고 연결&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;그게 전부입니다. 이제 에이전트가 Azure DevOps 도구에 접근할 수 있습니다.&lt;/p&gt;
&lt;h2 id="에이전트가-접근할-수-있는-것-제어하기"&gt;에이전트가 접근할 수 있는 것 제어하기&lt;/h2&gt;
&lt;p&gt;제가 높이 평가하는 부분입니다: 전부 아니면 전무 방식에 갇히지 않습니다. 에이전트에 사용 가능한 도구를 지정할 수 있습니다. 작업 항목만 읽고 파이프라인은 건드리지 않도록 하려면 그렇게 설정할 수 있습니다. 최소 권한 원칙을 AI 에이전트에 적용하는 것이죠.&lt;/p&gt;
&lt;p&gt;이것은 누군가가 &amp;ldquo;릴리스를 도와줘&amp;quot;라고 요청했다고 해서 에이전트가 실수로 배포 파이프라인을 트리거하는 것을 원하지 않는 엔터프라이즈 시나리오에서 중요합니다.&lt;/p&gt;
&lt;h2 id="net-팀에게-왜-흥미로운가"&gt;.NET 팀에게 왜 흥미로운가&lt;/h2&gt;
&lt;p&gt;실제로 이것이 무엇을 가능하게 하는지 생각해 보세요:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;스프린트 계획 어시스턴트&lt;/strong&gt; — 작업 항목을 가져오고, 속도 데이터를 분석하고, 스프린트 용량을 제안할 수 있는 에이전트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;코드 리뷰 봇&lt;/strong&gt; — 실제로 저장소와 연결된 작업 항목을 읽을 수 있기 때문에 PR 컨텍스트를 이해하는 에이전트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;인시던트 대응&lt;/strong&gt; — 작업 항목을 생성하고, 최근 배포를 조회하고, 버그와 최근 변경 사항을 상관시킬 수 있는 에이전트&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;개발자 온보딩&lt;/strong&gt; — &amp;ldquo;무엇을 해야 하나요?&amp;ldquo;가 실제 프로젝트 데이터에 기반한 진짜 답변을 받게 됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;CI/CD 파이프라인과 프로젝트 관리에 이미 Azure DevOps를 사용하는 .NET 팀에게, 이러한 시스템과 직접 상호 작용할 수 있는 AI 에이전트는 유용한 자동화를 향한 의미 있는 한 걸음입니다.&lt;/p&gt;
&lt;h2 id="더-큰-mcp-그림"&gt;더 큰 MCP 그림&lt;/h2&gt;
&lt;p&gt;이것은 더 넓은 트렌드의 일부입니다: MCP 서버는 AI 에이전트가 외부 세계와 상호 작용하는 표준 방식이 되어가고 있습니다. GitHub, Azure DevOps, 데이터베이스, SaaS API에서 볼 수 있으며 — Foundry는 이 모든 연결이 모이는 허브가 되고 있습니다.&lt;/p&gt;
&lt;p&gt;.NET 생태계에서 에이전트를 구축하고 있다면, MCP에 주목할 가치가 있습니다. 프로토콜은 표준화되고, 도구는 성숙해지고 있으며, Foundry 통합은 수동으로 서버 연결을 설정할 필요 없이 접근 가능하게 해줍니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Foundry의 Azure DevOps MCP Server는 프리뷰 상태이므로 발전을 기대하세요. 하지만 핵심 워크플로는 견고합니다: 연결하고, 도구 접근을 설정하고, 에이전트가 DevOps 데이터로 작업하게 하세요. 이미 Foundry 생태계에 있다면 몇 번의 클릭이면 됩니다. 시도해보고 어떤 워크플로를 구축할 수 있는지 확인해 보세요.&lt;/p&gt;
&lt;p&gt;단계별 설정과 자세한 내용은 &lt;a href="https://devblogs.microsoft.com/devops/remote-mcp-server-preview-in-microsoft-foundry/"&gt;전체 공지&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Foundry Agent Service GA: .NET 에이전트 개발자에게 정말 중요한 것</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/foundry-agent-service-ga-what-matters/</guid><description>Microsoft의 Foundry Agent Service가 프라이빗 네트워킹, Voice Live, 프로덕션 평가, 오픈 멀티모델 런타임으로 GA에 도달했습니다. 알아야 할 것들을 정리합니다.</description><content:encoded>&lt;p&gt;솔직히 말하면 — AI 에이전트 프로토타입을 만드는 건 쉬운 부분입니다. 어려운 건 그 이후의 모든 것: 적절한 네트워크 격리로 프로덕션에 올리기, 실제로 의미 있는 평가를 실행하기, 컴플라이언스 요구사항 처리하기, 새벽 2시에 아무것도 안 깨뜨리기.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;Foundry Agent Service가 GA에 도달했습니다&lt;/a&gt;. 이 릴리스는 &amp;ldquo;그 이후의 모든 것&amp;rdquo; 간극에 레이저처럼 집중하고 있습니다.&lt;/p&gt;
&lt;h2 id="responses-api-위에-구축"&gt;Responses API 위에 구축&lt;/h2&gt;
&lt;p&gt;헤드라인: 차세대 Foundry Agent Service는 OpenAI Responses API 위에 구축되었습니다. 이미 그 와이어 프로토콜로 개발하고 있다면 Foundry로의 마이그레이션은 최소한의 코드 변경으로 가능합니다. 얻는 것: 엔터프라이즈 보안, 프라이빗 네트워킹, Entra RBAC, 완전한 트레이싱, 평가 — 기존 에이전트 로직 위에.&lt;/p&gt;
&lt;p&gt;아키텍처는 의도적으로 열려 있습니다. 하나의 모델 제공자나 하나의 오케스트레이션 프레임워크에 종속되지 않습니다. 계획에 DeepSeek, 생성에 OpenAI, 오케스트레이션에 LangGraph — 런타임이 일관성 레이어를 처리합니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="kn"&gt;from&lt;/span&gt; &lt;span class="nn"&gt;azure.ai.projects.models&lt;/span&gt; &lt;span class="kn"&gt;import&lt;/span&gt; &lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;with&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AIProjectClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;endpoint&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_PROJECT_ENDPOINT&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;credential&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;get_openai_client&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt; &lt;span class="k"&gt;as&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;):&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;project_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;agents&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create_version&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;agent_name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;my-enterprise-agent&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;definition&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;PromptAgentDefinition&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;model&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;instructions&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;You are a helpful assistant.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;conversations&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;responses&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;conversation&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;id&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;input&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;What are best practices for building AI agents?&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;extra_body&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;agent_reference&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;print&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;output_text&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;blockquote&gt;
&lt;p&gt;&lt;code&gt;azure-ai-agents&lt;/code&gt; 패키지에서 오는 경우, 에이전트는 이제 &lt;code&gt;azure-ai-projects&lt;/code&gt;의 &lt;code&gt;AIProjectClient&lt;/code&gt;에서 퍼스트 클래스 작업입니다. 독립 의존성을 제거하고 &lt;code&gt;get_openai_client()&lt;/code&gt;를 사용하여 응답을 구동하세요.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="프라이빗-네트워킹-엔터프라이즈-블로커-제거"&gt;프라이빗 네트워킹: 엔터프라이즈 블로커 제거&lt;/h2&gt;
&lt;p&gt;이것이 엔터프라이즈 채택의 잠금을 해제하는 기능입니다. Foundry는 이제 BYO VNet으로 완전한 엔드투엔드 프라이빗 네트워킹을 지원합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;퍼블릭 이그레스 없음&lt;/strong&gt; — 에이전트 트래픽이 공개 인터넷에 접촉하지 않음&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;컨테이너/서브넷 인젝션&lt;/strong&gt;으로 로컬 통신을 위해 네트워크에 주입&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;도구 연결성 포함&lt;/strong&gt; — MCP 서버, Azure AI Search, Fabric 데이터 에이전트 모두 프라이빗 경로로 작동&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;마지막 포인트가 중요합니다. 프라이빗으로 유지되는 건 추론 호출만이 아닙니다 — 모든 도구 호출과 검색 콜도 네트워크 경계 내에 머무릅니다. 외부 라우팅을 금지하는 데이터 분류 정책 하에서 운영하는 팀에게 이것이 빠져있던 것입니다.&lt;/p&gt;
&lt;h2 id="mcp-인증-제대로-하기"&gt;MCP 인증 제대로 하기&lt;/h2&gt;
&lt;p&gt;MCP 서버 연결은 이제 인증 패턴의 전체 스펙트럼을 지원합니다:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;인증 방식&lt;/th&gt;
&lt;th&gt;사용 시점&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;키 기반&lt;/td&gt;
&lt;td&gt;조직 전체 내부 도구의 간단한 공유 액세스&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Agent Identity&lt;/td&gt;
&lt;td&gt;서비스 간; 에이전트가 자기 자신으로 인증&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;Entra Managed Identity&lt;/td&gt;
&lt;td&gt;프로젝트별 격리; 자격증명 관리 불필요&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;OAuth Identity Passthrough&lt;/td&gt;
&lt;td&gt;사용자 위임 액세스; 에이전트가 사용자를 대신하여 행동&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;p&gt;OAuth Identity Passthrough가 흥미로운 것입니다. 사용자가 에이전트에 개인 데이터 — OneDrive, Salesforce 조직, 사용자별 스코프 SaaS API — 에 대한 액세스를 부여해야 할 때, 에이전트는 표준 OAuth 플로우로 사용자를 대신하여 행동합니다. 모든 사람인 척하는 공유 시스템 ID는 없습니다.&lt;/p&gt;
&lt;h2 id="voice-live-배관-없는-음성-대-음성"&gt;Voice Live: 배관 없는 음성 대 음성&lt;/h2&gt;
&lt;p&gt;에이전트에 음성을 추가하는 것은 STT, LLM, TTS를 연결하는 것을 의미했습니다 — 세 개의 서비스, 세 번의 지연 홉, 세 개의 과금 표면, 모두 수동 동기화. &lt;strong&gt;Voice Live&lt;/strong&gt;는 이것을 단일 관리 API로 압축합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;시맨틱 음성 활동 및 턴 종료 감지 (침묵이 아닌 의미를 이해)&lt;/li&gt;
&lt;li&gt;서버 측 노이즈 억제 및 에코 캔슬레이션&lt;/li&gt;
&lt;li&gt;끼어들기 지원 (사용자가 응답 중간에 끼어들 수 있음)&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;음성 상호작용은 텍스트와 같은 에이전트 런타임을 통과합니다. 같은 평가자, 같은 트레이스, 같은 비용 가시성. 고객 지원, 현장 서비스, 접근성 시나리오에서 이전에 커스텀 오디오 파이프라인이 필요했던 것을 대체합니다.&lt;/p&gt;
&lt;h2 id="평가-체크박스에서-지속적-모니터링으로"&gt;평가: 체크박스에서 지속적 모니터링으로&lt;/h2&gt;
&lt;p&gt;여기서 Foundry는 프로덕션 품질에 대해 진지해집니다. 평가 시스템에는 이제 세 개의 레이어가 있습니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;기본 제공 평가자&lt;/strong&gt; — 일관성, 관련성, 근거성, 검색 품질, 안전성. 데이터셋이나 라이브 트래픽에 연결하여 점수를 받으세요.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;커스텀 평가자&lt;/strong&gt; — 자체 비즈니스 로직, 톤 표준, 도메인별 컴플라이언스 규칙을 인코딩하세요.&lt;/p&gt;
&lt;/li&gt;
&lt;li&gt;
&lt;p&gt;&lt;strong&gt;지속적 평가&lt;/strong&gt; — Foundry가 라이브 프로덕션 트래픽을 샘플링하고, 평가자 스위트를 실행하고, 대시보드에 결과를 표시합니다. 근거성이 떨어지거나 안전 임계값이 초과되면 Azure Monitor 알림을 설정하세요.&lt;/p&gt;
&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;모든 것이 Azure Monitor Application Insights에 게시됩니다. 에이전트 품질, 인프라 상태, 비용, 앱 텔레메트리 — 모두 한 곳에.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-python" data-lang="python"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;eval_object&lt;/span&gt; &lt;span class="o"&gt;=&lt;/span&gt; &lt;span class="n"&gt;openai_client&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;evals&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;create&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;name&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;Agent Quality Evaluation&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;data_source_config&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="n"&gt;DataSourceConfigCustom&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nb"&gt;type&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;custom&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;item_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;object&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;properties&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;string&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;}},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;required&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;include_sample_schema&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="kc"&gt;True&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;testing_criteria&lt;/span&gt;&lt;span class="o"&gt;=&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;azure_ai_evaluator&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;evaluator_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;builtin.fluency&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;initialization_parameters&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;deployment_name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="n"&gt;os&lt;/span&gt;&lt;span class="o"&gt;.&lt;/span&gt;&lt;span class="n"&gt;environ&lt;/span&gt;&lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;AZURE_AI_MODEL_DEPLOYMENT_NAME&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;]&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;data_mapping&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;query&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{item.query}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s2"&gt;&amp;#34;response&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;{{sample.output_text}}&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;},&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;h2 id="호스티드-에이전트를-위한-6개-새-지역"&gt;호스티드 에이전트를 위한 6개 새 지역&lt;/h2&gt;
&lt;p&gt;호스티드 에이전트가 East US, North Central US, Sweden Central, Southeast Asia, Japan East 등에서 사용 가능합니다. 데이터 거주 요구사항과 에이전트가 데이터 소스 가까이에서 실행될 때 지연 시간을 압축하는 데 중요합니다.&lt;/p&gt;
&lt;h2 id="net-개발자에게-왜-중요한가"&gt;.NET 개발자에게 왜 중요한가&lt;/h2&gt;
&lt;p&gt;GA 공지의 코드 샘플은 Python 우선이지만, 기반 인프라는 언어에 구애받지 않습니다 — 그리고 &lt;code&gt;azure-ai-projects&lt;/code&gt;의 .NET SDK도 같은 패턴을 따릅니다. Responses API, 평가 프레임워크, 프라이빗 네트워킹, MCP 인증 — 이 모든 것이 .NET에서 사용 가능합니다.&lt;/p&gt;
&lt;p&gt;AI 에이전트가 &amp;ldquo;멋진 데모&amp;quot;에서 &amp;ldquo;실제로 직장에서 출하할 수 있는 것&amp;quot;으로 바뀌기를 기다리고 있었다면, 이 GA 릴리스가 그 신호입니다. 프라이빗 네트워킹, 적절한 인증, 지속적 평가, 프로덕션 모니터링이 빠져있던 퍼즐 조각입니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;Foundry Agent Service는 지금 사용할 수 있습니다. SDK를 설치하고, &lt;a href="https://ai.azure.com"&gt;포털&lt;/a&gt;을 열고, 빌드를 시작하세요. &lt;a href="https://learn.microsoft.com/azure/foundry/quickstarts/get-started-code"&gt;빠른 시작 가이드&lt;/a&gt;가 몇 분 만에 제로에서 동작하는 에이전트까지 안내합니다.&lt;/p&gt;
&lt;p&gt;모든 코드 샘플이 포함된 전체 기술 딥다이브는 &lt;a href="https://devblogs.microsoft.com/foundry/foundry-agent-service-ga/"&gt;GA 공지&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Microsoft Agent Framework의 백그라운드 응답: 더 이상 타임아웃 걱정 없이</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/background-responses-agent-framework-long-running-tasks/</guid><description>Microsoft Agent Framework가 이제 연속 토큰으로 장시간 실행 AI 작업을 오프로드할 수 있습니다. 백그라운드 응답의 작동 방식과 .NET 에이전트에 중요한 이유를 알아보세요.</description><content:encoded>&lt;p&gt;o3나 GPT-5.2 같은 추론 모델로 무언가를 만들어 본 적이 있다면, 그 고통을 알 것입니다. 에이전트가 복잡한 작업을 생각하기 시작하고, 클라이언트는 기다리고, &amp;ldquo;괜찮아&amp;quot;와 &amp;ldquo;크래시한 건가?&amp;rdquo; 사이 어딘가에서 연결이 타임아웃됩니다. 그 모든 작업은? 사라집니다.&lt;/p&gt;
&lt;p&gt;Microsoft Agent Framework가 &lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;백그라운드 응답&lt;/a&gt;을 출시했습니다 — 솔직히, 이건 처음부터 있었어야 할 기능 중 하나입니다.&lt;/p&gt;
&lt;h2 id="블로킹-호출의-문제"&gt;블로킹 호출의 문제&lt;/h2&gt;
&lt;p&gt;전통적인 요청-응답 패턴에서는 에이전트가 끝날 때까지 클라이언트가 블로킹됩니다. 빠른 작업에는 잘 작동합니다. 하지만 추론 모델에 깊은 연구, 다단계 분석, 20페이지 보고서 생성을 요청하면? 실제 시간으로 몇 분이 걸립니다. 그 시간 동안:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;HTTP 연결이 타임아웃될 수 있음&lt;/li&gt;
&lt;li&gt;네트워크 끊김이 전체 작업을 죽임&lt;/li&gt;
&lt;li&gt;사용자는 스피너를 보며 무슨 일이 일어나고 있는지 궁금해 함&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;백그라운드 응답은 이것을 뒤집습니다.&lt;/p&gt;
&lt;h2 id="연속-토큰의-작동-방식"&gt;연속 토큰의 작동 방식&lt;/h2&gt;
&lt;p&gt;블로킹 대신, 에이전트 작업을 시작하고 &lt;strong&gt;연속 토큰&lt;/strong&gt;을 받습니다. 수리점의 픽업 티켓처럼 생각하세요 — 카운터에서 서서 기다릴 필요 없이, 준비되면 돌아오면 됩니다.&lt;/p&gt;
&lt;p&gt;흐름은 간단합니다:&lt;/p&gt;
&lt;ol&gt;
&lt;li&gt;&lt;code&gt;AllowBackgroundResponses = true&lt;/code&gt;로 요청 전송&lt;/li&gt;
&lt;li&gt;에이전트가 백그라운드 처리를 지원하면 연속 토큰을 받음&lt;/li&gt;
&lt;li&gt;토큰이 &lt;code&gt;null&lt;/code&gt;을 반환할 때까지 폴링 — 결과가 준비되었다는 의미&lt;/li&gt;
&lt;/ol&gt;
&lt;p&gt;.NET 버전은 다음과 같습니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AIAgent&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;AzureOpenAIClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;Uri&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;https://&amp;lt;myresource&amp;gt;.openai.azure.com&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;),&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;new&lt;/span&gt; &lt;span class="n"&gt;DefaultAzureCredential&lt;/span&gt;&lt;span class="p"&gt;())&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;GetResponsesClient&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="s"&gt;&amp;#34;&amp;lt;deployment-name&amp;gt;&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;AsAIAgent&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentResponse&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Write a detailed market analysis for the Q4 product launch.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 완료까지 폴링&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;while&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="k"&gt;is&lt;/span&gt; &lt;span class="n"&gt;not&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;)&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;Task&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Delay&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;TimeSpan&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;FromSeconds&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="m"&gt;2&lt;/span&gt;&lt;span class="p"&gt;));&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;response&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;WriteLine&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;response&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;에이전트가 즉시 완료하면(간단한 작업, 백그라운드 처리가 필요 없는 모델), 연속 토큰이 반환되지 않습니다. 코드는 그냥 작동합니다 — 특별한 처리가 필요 없습니다.&lt;/p&gt;
&lt;h2 id="재개가-가능한-스트리밍-진짜-마법"&gt;재개가 가능한 스트리밍: 진짜 마법&lt;/h2&gt;
&lt;p&gt;폴링은 fire-and-forget 시나리오에 괜찮지만, 실시간 진행 상황을 원한다면? 백그라운드 응답은 내장 재개 기능이 있는 스트리밍도 지원합니다.&lt;/p&gt;
&lt;p&gt;각 스트리밍 업데이트는 자체 연속 토큰을 가집니다. 스트리밍 중에 연결이 끊기면, 중단된 정확한 지점에서 재개합니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-csharp" data-lang="csharp"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentRunOptions&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;new&lt;/span&gt;&lt;span class="p"&gt;()&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;AllowBackgroundResponses&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;};&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentSession&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;CreateSessionAsync&lt;/span&gt;&lt;span class="p"&gt;();&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;AgentResponseUpdate&lt;/span&gt;&lt;span class="p"&gt;?&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="kc"&gt;null&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="s"&gt;&amp;#34;Write a detailed market analysis for the Q4 product launch.&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="k"&gt;break&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt; &lt;span class="c1"&gt;// 네트워크 중단 시뮬레이션&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="c1"&gt;// 중단된 정확한 지점에서 재개&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt; &lt;span class="p"&gt;=&lt;/span&gt; &lt;span class="n"&gt;latestUpdate&lt;/span&gt;&lt;span class="p"&gt;?.&lt;/span&gt;&lt;span class="n"&gt;ContinuationToken&lt;/span&gt;&lt;span class="p"&gt;;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="k"&gt;await&lt;/span&gt; &lt;span class="k"&gt;foreach&lt;/span&gt; &lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="kt"&gt;var&lt;/span&gt; &lt;span class="n"&gt;update&lt;/span&gt; &lt;span class="k"&gt;in&lt;/span&gt; &lt;span class="n"&gt;agent&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;RunStreamingAsync&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;session&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt; &lt;span class="n"&gt;options&lt;/span&gt;&lt;span class="p"&gt;))&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="n"&gt;Console&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Write&lt;/span&gt;&lt;span class="p"&gt;(&lt;/span&gt;&lt;span class="n"&gt;update&lt;/span&gt;&lt;span class="p"&gt;.&lt;/span&gt;&lt;span class="n"&gt;Text&lt;/span&gt;&lt;span class="p"&gt;);&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;클라이언트에 무슨 일이 일어나든 에이전트는 서버 측에서 계속 처리합니다. 재시도 로직이나 서킷 브레이커를 작성하지 않고도 내장된 장애 허용입니다.&lt;/p&gt;
&lt;h2 id="언제-실제로-사용해야-하나"&gt;언제 실제로 사용해야 하나&lt;/h2&gt;
&lt;p&gt;모든 에이전트 호출에 백그라운드 응답이 필요한 것은 아닙니다. 빠른 완료에는 이유 없이 복잡성을 추가하는 것입니다. 하지만 다음에서 빛을 발합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;복잡한 추론 작업&lt;/strong&gt; — 다단계 분석, 깊은 연구, 추론 모델을 진지하게 생각하게 만드는 모든 것&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;긴 콘텐츠 생성&lt;/strong&gt; — 상세 보고서, 다중 파트 문서, 광범위한 분석&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;불안정한 네트워크&lt;/strong&gt; — 모바일 클라이언트, 엣지 배포, 불안정한 기업 VPN&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;비동기 UX 패턴&lt;/strong&gt; — 작업을 제출하고, 다른 일을 하고, 결과를 가지러 돌아옴&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;엔터프라이즈 앱을 구축하는 .NET 개발자에게 마지막 포인트가 특히 흥미롭습니다. 사용자가 복잡한 보고서를 요청하는 Blazor 앱을 생각해 보세요 — 에이전트 작업을 시작하고, 프로그레스 인디케이터를 보여주고, 계속 작업하게 합니다. WebSocket 곡예 없이, 커스텀 큐 인프라 없이, 토큰과 폴링 루프만 있으면 됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;백그라운드 응답은 Microsoft Agent Framework를 통해 .NET과 Python 모두에서 지금 사용할 수 있습니다. 단순한 Q&amp;amp;A 이상을 하는 에이전트를 구축하고 있다면, 툴킷에 추가할 가치가 있습니다. 연속 토큰 패턴은 매우 현실적인 프로덕션 문제를 해결하면서 것을 심플하게 유지합니다.&lt;/p&gt;
&lt;p&gt;전체 API 참조와 더 많은 예제는 &lt;a href="https://devblogs.microsoft.com/agent-framework/handling-long-running-operations-with-background-responses/"&gt;전체 문서&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>VS Code 1.112: .NET 개발자가 정말 주목해야 할 것들</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/vscode-1-112-dotnet-developers/</guid><description>VS Code 1.112가 에이전트 업그레이드, 통합 브라우저 디버거, MCP 샌드박싱, 모노레포 지원으로 출시되었습니다. .NET으로 개발한다면 정말 중요한 것들을 정리합니다.</description><content:encoded>&lt;p&gt;VS Code 1.112가 도착했고, 솔직히? .NET 세계에서 매일을 보내고 있다면 이번 릴리스는 다르게 다가옵니다. &lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;공식 릴리스 노트&lt;/a&gt;에 많은 내용이 있지만, 스크롤을 좀 줄여드리고 우리에게 정말 중요한 것에 집중하겠습니다.&lt;/p&gt;
&lt;h2 id="copilot-cli가-훨씬-유용해졌다"&gt;Copilot CLI가 훨씬 유용해졌다&lt;/h2&gt;
&lt;p&gt;이번 릴리스의 큰 테마는 &lt;strong&gt;에이전트 자율성&lt;/strong&gt; — Copilot에게 더 많은 자유를 주어 당신이 매 단계를 감시하지 않아도 되게 하는 것입니다.&lt;/p&gt;
&lt;h3 id="메시지-스티어링과-큐잉"&gt;메시지 스티어링과 큐잉&lt;/h3&gt;
&lt;p&gt;Copilot CLI가 작업 중간에 있는데 뭔가 말하는 걸 깜빡했다는 걸 깨닫는 그 순간 알죠? 전에는 기다려야 했습니다. 이제 요청이 아직 실행 중일 때도 메시지를 보낼 수 있습니다 — 현재 응답을 방향 전환하거나 후속 지시를 큐에 넣거나.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;dotnet&lt;/code&gt; 스캐폴딩의 긴 작업을 보면서 &amp;ldquo;아 잠깐, MassTransit도 필요한데&amp;quot;라고 생각하는 경우에 이것은 대단합니다.&lt;/p&gt;
&lt;h3 id="권한-레벨"&gt;권한 레벨&lt;/h3&gt;
&lt;p&gt;이것이 가장 흥분되는 것입니다. Copilot CLI 세션이 이제 세 가지 권한 레벨을 지원합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;기본 권한&lt;/strong&gt; — 도구가 실행 전에 확인을 요청하는 일반적인 흐름&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;승인 우회&lt;/strong&gt; — 모든 것을 자동 승인하고 오류 시 재시도&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;오토파일럿&lt;/strong&gt; — 완전 자율: 도구를 승인하고, 자체 질문에 답하고, 작업이 완료될 때까지 계속&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;Entity Framework, 마이그레이션, Docker 설정으로 새 ASP.NET Core API를 만드는 것 같은 작업을 한다면 — 오토파일럿 모드는 원하는 것을 설명하고 커피를 가지러 가면 됩니다. 알아서 할 겁니다.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;chat.autopilot.enabled&lt;/code&gt; 설정으로 오토파일럿을 활성화할 수 있습니다.&lt;/p&gt;
&lt;h3 id="위임-전-변경사항-미리보기"&gt;위임 전 변경사항 미리보기&lt;/h3&gt;
&lt;p&gt;Copilot CLI에 작업을 위임하면 워크트리가 생성됩니다. 전에는 커밋하지 않은 변경사항이 있으면 소스 컨트롤을 확인해서 뭐가 영향받는지 봐야 했습니다. 이제 채팅 뷰에서 복사, 이동, 무시를 결정하기 전에 보류 중인 변경사항을 바로 보여줍니다.&lt;/p&gt;
&lt;p&gt;작은 것이지만 &amp;ldquo;잠깐, 스테이징에 뭐가 있었지?&amp;rdquo; 하는 순간을 없애줍니다.&lt;/p&gt;
&lt;h2 id="vs-code를-떠나지-않고-웹-앱-디버그"&gt;VS Code를 떠나지 않고 웹 앱 디버그&lt;/h2&gt;
&lt;p&gt;통합 브라우저가 이제 &lt;strong&gt;완전한 디버깅&lt;/strong&gt;을 지원합니다. 브레이크포인트를 설정하고, 코드를 스텝스루하고, 변수를 검사할 수 있습니다 — 모두 VS Code 안에서. Edge DevTools로 전환할 필요 없습니다.&lt;/p&gt;
&lt;p&gt;새로운 &lt;code&gt;editor-browser&lt;/code&gt; 디버그 타입이 있고, 이미 &lt;code&gt;msedge&lt;/code&gt;나 &lt;code&gt;chrome&lt;/code&gt; 실행 구성이 있다면 &lt;code&gt;launch.json&lt;/code&gt;의 &lt;code&gt;type&lt;/code&gt; 필드만 바꾸면 됩니다:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;type&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;editor-browser&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;request&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;launch&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;name&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;Debug Blazor App&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;url&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;https://localhost:5001&amp;#34;&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;Blazor 개발자에게 이것은 게임 체인저입니다. 이미 터미널에서 &lt;code&gt;dotnet watch&lt;/code&gt;를 실행하고 있으니 — 이제 디버깅도 같은 창에 머무릅니다.&lt;/p&gt;
&lt;p&gt;브라우저에 독립적인 줌 레벨(드디어), 적절한 우클릭 컨텍스트 메뉴, 웹사이트별 줌 기억 기능도 추가되었습니다.&lt;/p&gt;
&lt;h2 id="mcp-서버-샌드박싱"&gt;MCP 서버 샌드박싱&lt;/h2&gt;
&lt;p&gt;이것은 생각보다 중요합니다. MCP 서버를 사용하고 있다면 — Azure 리소스나 데이터베이스 쿼리를 위한 커스텀 서버를 설정했을 수 있습니다 — VS Code 프로세스와 같은 권한으로 실행되고 있었습니다. 파일 시스템, 네트워크, 모든 것에 대한 전체 액세스를 의미합니다.&lt;/p&gt;
&lt;p&gt;이제 샌드박스처리할 수 있습니다. &lt;code&gt;mcp.json&lt;/code&gt;에서:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;servers&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;my-azure-tools&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;command&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="s2"&gt;&amp;#34;node&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;args&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="p"&gt;[&lt;/span&gt;&lt;span class="s2"&gt;&amp;#34;./mcp-server.js&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;],&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;sandboxEnabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;샌드박스된 서버가 가지고 있지 않은 것에 대한 액세스가 필요하면 VS Code가 권한 부여를 요청합니다. &amp;ldquo;아무도 이상한 걸 안 하길 바라자&amp;rdquo; 접근방식보다 훨씬 낫습니다.&lt;/p&gt;
&lt;blockquote&gt;
&lt;p&gt;&lt;strong&gt;참고:&lt;/strong&gt; 샌드박싱은 현재 macOS와 Linux에서 사용 가능합니다. Windows 지원이 준비 중입니다 — WSL 같은 원격 시나리오는 작동합니다.&lt;/p&gt;
&lt;/blockquote&gt;
&lt;h2 id="모노레포-커스터마이제이션-발견"&gt;모노레포 커스터마이제이션 발견&lt;/h2&gt;
&lt;p&gt;모노레포에서 작업하고 있다면 (솔직히 많은 엔터프라이즈 .NET 솔루션이 모노레포가 됩니다), 이것은 진짜 페인 포인트를 해결합니다.&lt;/p&gt;
&lt;p&gt;이전에는 레포의 하위 폴더를 열면 레포지토리 루트에 있는 &lt;code&gt;copilot-instructions.md&lt;/code&gt;, &lt;code&gt;AGENTS.md&lt;/code&gt;, 커스텀 스킬을 VS Code가 찾지 못했습니다. 이제 &lt;code&gt;chat.useCustomizationsInParentRepositories&lt;/code&gt; 설정으로 &lt;code&gt;.git&lt;/code&gt; 루트까지 올라가서 모든 것을 발견합니다.&lt;/p&gt;
&lt;p&gt;팀이 모노레포의 모든 프로젝트에 걸쳐 에이전트 지시, 프롬프트 파일, 커스텀 도구를 공유할 수 있게 됩니다. 모두가 루트 폴더를 열 필요 없이.&lt;/p&gt;
&lt;h2 id="에이전트-디버깅을-위한-troubleshoot"&gt;에이전트 디버깅을 위한 /troubleshoot&lt;/h2&gt;
&lt;p&gt;커스텀 지시나 스킬을 설정한 후 왜 감지되지 않는지 궁금했던 적 있나요? 새로운 &lt;code&gt;/troubleshoot&lt;/code&gt; 스킬이 에이전트 디버그 로그를 읽고 무슨 일이 있었는지 알려줍니다 — 어떤 도구가 사용되거나 건너뛰어졌는지, 왜 지시가 로드되지 않았는지, 무엇이 느린 응답을 유발하는지.&lt;/p&gt;
&lt;p&gt;다음 설정으로 활성화하세요:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-json" data-lang="json"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;{&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;&lt;span class="p"&gt;,&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt; &lt;span class="nt"&gt;&amp;#34;github.copilot.chat.agentDebugLog.fileLogging.enabled&amp;#34;&lt;/span&gt;&lt;span class="p"&gt;:&lt;/span&gt; &lt;span class="kc"&gt;true&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;&lt;span class="p"&gt;}&lt;/span&gt;
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;그런 다음 채팅에서 &lt;code&gt;/troubleshoot why is my custom skill not loading?&lt;/code&gt;을 입력하면 됩니다.&lt;/p&gt;
&lt;p&gt;이 디버그 로그를 내보내기와 가져오기도 할 수 있어서, 뭔가 예상대로 작동하지 않을 때 팀과 공유하기 좋습니다.&lt;/p&gt;
&lt;h2 id="이미지와-바이너리-파일-지원"&gt;이미지와 바이너리 파일 지원&lt;/h2&gt;
&lt;p&gt;에이전트가 이제 디스크에서 이미지 파일과 바이너리 파일을 네이티브로 읽을 수 있습니다. 바이너리 파일은 hexdump 형식으로 표시되고, 이미지 출력(통합 브라우저의 스크린샷 등)은 캐러셀 뷰로 나타납니다.&lt;/p&gt;
&lt;p&gt;.NET 개발자의 경우: UI 버그의 스크린샷을 채팅에 붙여넣고 에이전트가 무엇이 잘못되었는지 이해하게 하거나, Blazor 컴포넌트 렌더링 출력을 분석하게 할 수 있습니다.&lt;/p&gt;
&lt;h2 id="자동-심볼-참조"&gt;자동 심볼 참조&lt;/h2&gt;
&lt;p&gt;작은 삶의 질 개선: 심볼 이름(클래스, 메서드 등)을 복사해서 채팅에 붙여넣으면, VS Code가 자동으로 &lt;code&gt;#sym:Name&lt;/code&gt; 참조로 변환합니다. 수동으로 추가하지 않아도 에이전트에 해당 심볼의 전체 컨텍스트를 제공합니다.&lt;/p&gt;
&lt;p&gt;일반 텍스트를 원하면 &lt;code&gt;Ctrl+Shift+V&lt;/code&gt;를 사용하세요.&lt;/p&gt;
&lt;h2 id="플러그인-활성화비활성화-가능"&gt;플러그인 활성화/비활성화 가능&lt;/h2&gt;
&lt;p&gt;이전에는 MCP 서버나 플러그인을 비활성화하려면 제거해야 했습니다. 이제 켜고 끌 수 있습니다 — 전역적으로도 워크스페이스별로도. 확장 뷰나 커스터마이제이션 뷰에서 우클릭하면 됩니다.&lt;/p&gt;
&lt;p&gt;npm과 pypi의 플러그인도 자동 업데이트가 가능하지만, 업데이트가 기기에서 새 코드를 실행하는 것을 의미하므로 먼저 승인을 요청합니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;VS Code 1.112는 확실히 에이전트 경험을 강하게 밀어붙이고 있습니다 — 더 많은 자율성, 더 나은 디버깅, 더 단단한 보안. .NET 개발자에게 통합 브라우저 디버깅과 Copilot CLI 개선이 두드러진 기능입니다.&lt;/p&gt;
&lt;p&gt;.NET 프로젝트를 위해 오토파일럿 모드에서 전체 Copilot CLI 세션을 아직 시도해보지 않았다면, 이번 릴리스가 시작하기 좋은 때입니다. 권한을 설정하고 맡기면 됩니다.&lt;/p&gt;
&lt;p&gt;&lt;a href="https://code.visualstudio.com/updates/v1_112"&gt;VS Code 1.112 다운로드&lt;/a&gt; 또는 VS Code 내에서 &lt;strong&gt;도움말 &amp;gt; 업데이트 확인&lt;/strong&gt;으로 업데이트하세요.&lt;/p&gt;</content:encoded></item><item><title>노트북에서 프로덕션까지: 두 개의 명령으로 AI 에이전트를 Microsoft Foundry에 배포</title><link>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</link><pubDate>Thu, 26 Mar 2026 00:00:00 +0000</pubDate><author>Emiliano Montesdeoca</author><guid>https://thedotnetblog.com/ko/posts/emiliano-montesdeoca/deploy-ai-agents-foundry-azd-two-commands/</guid><description>Azure Developer CLI에 'azd ai agent' 명령이 추가되어 AI 에이전트를 로컬 개발에서 몇 분 만에 Foundry 프로덕션 엔드포인트로 가져갑니다. 전체 워크플로를 소개합니다.</description><content:encoded>&lt;p&gt;&amp;ldquo;내 컴퓨터에서는 되는데&amp;quot;와 &amp;ldquo;배포되어 트래픽을 처리 중&amp;rdquo;—이 사이의 간극을 아시나요? AI 에이전트의 경우 이 간극은 고통스럽게 넓었습니다. 리소스 프로비저닝, 모델 배포, ID 설정, 모니터링 구축 — 이 모든 것이 누군가가 실제로 에이전트를 호출할 수 있기 전에 필요한 작업입니다.&lt;/p&gt;
&lt;p&gt;Azure Developer CLI가 이것을 &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;두 개의 명령으로 해결&lt;/a&gt;했습니다.&lt;/p&gt;
&lt;h2 id="새로운-azd-ai-agent-워크플로"&gt;새로운 &lt;code&gt;azd ai agent&lt;/code&gt; 워크플로&lt;/h2&gt;
&lt;p&gt;실제로 어떤 모습인지 보여드리겠습니다. AI 에이전트 프로젝트가 있다고 합시다 — 호텔 컨시어지 에이전트라고 하죠. 로컬에서 동작합니다. Microsoft Foundry에서 실행하고 싶습니다.&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent init
&lt;/span&gt;&lt;/span&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd up
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;끝입니다. 두 개의 명령. &lt;code&gt;azd ai agent init&lt;/code&gt;이 저장소에 Infrastructure as Code를 생성하고, &lt;code&gt;azd up&lt;/code&gt;이 Azure에서 모든 것을 프로비저닝하고 에이전트를 퍼블리시합니다. Foundry 포털에서 에이전트로의 직접 링크를 받게 됩니다.&lt;/p&gt;
&lt;h2 id="내부에서-일어나는-일"&gt;내부에서 일어나는 일&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;init&lt;/code&gt; 명령은 저장소에 실제 검사 가능한 Bicep 템플릿을 생성합니다:&lt;/p&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;Foundry Resource&lt;/strong&gt; (최상위 컨테이너)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;Foundry Project&lt;/strong&gt; (에이전트가 존재하는 곳)&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;모델 배포&lt;/strong&gt; 설정 (GPT-4o 등)&lt;/li&gt;
&lt;li&gt;적절한 RBAC 역할 할당이 있는 &lt;strong&gt;관리 ID&lt;/strong&gt;&lt;/li&gt;
&lt;li&gt;서비스 맵용 &lt;code&gt;azure.yaml&lt;/code&gt;&lt;/li&gt;
&lt;li&gt;에이전트 메타데이터와 환경 변수가 있는 &lt;code&gt;agent.yaml&lt;/code&gt;&lt;/li&gt;
&lt;/ul&gt;
&lt;p&gt;핵심 포인트: 이 모든 것은 여러분 것입니다. 저장소에 버전 관리되는 Bicep입니다. 검사하고, 커스터마이즈하고, 에이전트 코드와 함께 커밋할 수 있습니다. 마법의 블랙박스는 없습니다.&lt;/p&gt;
&lt;h2 id="개발-내부-루프"&gt;개발 내부 루프&lt;/h2&gt;
&lt;p&gt;정말 마음에 드는 것은 로컬 개발 경험입니다. 에이전트 로직을 반복할 때, 프롬프트를 바꿀 때마다 재배포하고 싶지 않죠:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent run
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;이것으로 에이전트를 로컬에서 시작합니다. &lt;code&gt;azd ai agent invoke&lt;/code&gt;와 결합하여 테스트 프롬프트를 보내면 빠른 피드백 루프를 얻습니다. 코드 편집, 재시작, 호출, 반복.&lt;/p&gt;
&lt;p&gt;&lt;code&gt;invoke&lt;/code&gt; 명령은 라우팅도 똑똑합니다 — 로컬 에이전트가 실행 중이면 자동으로 그쪽을 타겟합니다. 실행 중이 아니면 원격 엔드포인트로 갑니다.&lt;/p&gt;
&lt;h2 id="실시간-모니터링"&gt;실시간 모니터링&lt;/h2&gt;
&lt;p&gt;이것이 저를 설득한 기능입니다. 에이전트가 배포되면:&lt;/p&gt;
&lt;div class="highlight"&gt;&lt;pre tabindex="0" class="chroma"&gt;&lt;code class="language-bash" data-lang="bash"&gt;&lt;span class="line"&gt;&lt;span class="cl"&gt;azd ai agent monitor --follow
&lt;/span&gt;&lt;/span&gt;&lt;/code&gt;&lt;/pre&gt;&lt;/div&gt;&lt;p&gt;에이전트를 통과하는 모든 요청과 응답이 실시간으로 터미널에 스트리밍됩니다. 프로덕션 문제를 디버깅하는 데 이것은 값으로 매길 수 없습니다. Log Analytics를 뒤질 필요 없이, 메트릭이 집계되길 기다릴 필요 없이 — 지금 무슨 일이 일어나고 있는지 볼 수 있습니다.&lt;/p&gt;
&lt;h2 id="전체-명령-세트"&gt;전체 명령 세트&lt;/h2&gt;
&lt;p&gt;빠른 참조:&lt;/p&gt;
&lt;table&gt;
&lt;thead&gt;
&lt;tr&gt;
&lt;th&gt;명령&lt;/th&gt;
&lt;th&gt;기능&lt;/th&gt;
&lt;/tr&gt;
&lt;/thead&gt;
&lt;tbody&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent init&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;IaC로 Foundry 에이전트 프로젝트 스캐폴드&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd up&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;Azure 리소스 프로비저닝 및 에이전트 배포&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent invoke&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;원격 또는 로컬 에이전트에 프롬프트 전송&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent run&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;개발용으로 에이전트를 로컬에서 실행&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent monitor&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;퍼블리시된 에이전트의 실시간 로그 스트리밍&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd ai agent show&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;에이전트 상태 및 건강 확인&lt;/td&gt;
&lt;/tr&gt;
&lt;tr&gt;
&lt;td&gt;&lt;code&gt;azd down&lt;/code&gt;&lt;/td&gt;
&lt;td&gt;모든 Azure 리소스 정리&lt;/td&gt;
&lt;/tr&gt;
&lt;/tbody&gt;
&lt;/table&gt;
&lt;h2 id="net-개발자에게-왜-중요한가"&gt;.NET 개발자에게 왜 중요한가&lt;/h2&gt;
&lt;p&gt;공지의 예제는 Python 기반이지만, 인프라 이야기는 언어에 구애받지 않습니다. .NET 에이전트도 동일한 Bicep 스캐폴딩, 동일한 관리 ID 설정, 동일한 모니터링 파이프라인을 받습니다. 그리고 이미 .NET Aspire 앱이나 Azure 배포에 &lt;code&gt;azd&lt;/code&gt;를 사용하고 있다면, 기존 워크플로에 바로 통합됩니다.&lt;/p&gt;
&lt;p&gt;AI 에이전트의 배포 간극은 생태계에서 가장 큰 마찰 포인트 중 하나였습니다. 작동하는 프로토타입에서 적절한 ID, 네트워킹, 모니터링을 갖춘 프로덕션 엔드포인트로 전환하는 데 일주일의 DevOps 작업이 필요해서는 안 됩니다. 이제 두 개의 명령과 몇 분이면 됩니다.&lt;/p&gt;
&lt;h2 id="마무리"&gt;마무리&lt;/h2&gt;
&lt;p&gt;&lt;code&gt;azd ai agent&lt;/code&gt;는 지금 사용할 수 있습니다. 인프라 설정이 너무 많은 작업처럼 보여서 AI 에이전트 배포를 미루고 있었다면 시도해 보세요. 프론트엔드 채팅 앱 통합을 포함한 완전한 단계별 가이드는 &lt;a href="https://devblogs.microsoft.com/azure-sdk/azd-ai-agent-end-to-end/"&gt;전체 워크스루&lt;/a&gt;를 확인하세요.&lt;/p&gt;</content:encoded></item><item><title>Emiliano Montesdeoca</title><link>https://thedotnetblog.com/ko/authors/emiliano-montesdeoca/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/authors/emiliano-montesdeoca/</guid><description/><content:encoded/></item><item><title>The .NET Blog에 기고하기</title><link>https://thedotnetblog.com/ko/contribute/</link><pubDate>Mon, 01 Jan 0001 00:00:00 +0000</pubDate><guid>https://thedotnetblog.com/ko/contribute/</guid><description>.NET 커뮤니티와 당신의 지식을 나눠보세요. 저자로 참여하고 첫 번째 글을 제출하는 방법을 알아보세요.</description><content:encoded>&lt;p&gt;The .NET Blog는 개발자들이 .NET, Azure, AI, 클라우드 네이티브 개발에 대한 인사이트, 튜토리얼, 이야기를 공유하는 커뮤니티 기반 출판물입니다. &lt;strong&gt;모든 수준의 개발자의 기고를 환영합니다&lt;/strong&gt; — 첫 번째 기술 글을 쓰는 분이든, 경험 많은 연사든 모두 환영합니다.&lt;/p&gt;
&lt;h2 id="참여-방법"&gt;참여 방법&lt;/h2&gt;
&lt;p&gt;모든 것은 GitHub에 있으며 풀 리퀘스트 워크플로우를 따릅니다.&lt;/p&gt;
&lt;h3 id="1-저장소-포크하기"&gt;1. 저장소 포크하기&lt;/h3&gt;
&lt;p&gt;&lt;a href="https://github.com/thedotnetblog/blog"&gt;github.com/thedotnetblog/blog&lt;/a&gt;로 이동하여 GitHub 계정으로 포크하세요.&lt;/p&gt;
&lt;h3 id="2-저자-프로필-만들기"&gt;2. 저자 프로필 만들기&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;content/authors/your-username/&lt;/code&gt; 폴더를 만들고 &lt;code&gt;index.md&lt;/code&gt; 파일을 추가하세요. 이름, 직책, 소개를 포함하고 아바타 이미지(정사각형, 최소 200×200px)를 &lt;code&gt;static/img/authors/&lt;/code&gt;에 추가하세요.&lt;/p&gt;
&lt;h3 id="3-글-작성하기"&gt;3. 글 작성하기&lt;/h3&gt;
&lt;p&gt;&lt;code&gt;content/posts/your-username/your-post-slug/&lt;/code&gt;에 새 폴더를 만들고 &lt;code&gt;index.md&lt;/code&gt; 파일을 추가하세요. 제목, 날짜, 저자, 설명, 태그를 포함하세요.&lt;/p&gt;
&lt;h3 id="4-풀-리퀘스트-열기"&gt;4. 풀 리퀘스트 열기&lt;/h3&gt;
&lt;p&gt;변경 사항을 포크에 푸시하고 &lt;code&gt;main&lt;/code&gt; 브랜치에 풀 리퀘스트를 여세요. 팀이 며칠 내에 검토하고 피드백을 드립니다.&lt;/p&gt;
&lt;h2 id="찾고-있는-콘텐츠"&gt;찾고 있는 콘텐츠&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;&lt;strong&gt;튜토리얼&lt;/strong&gt; — .NET, Azure, AI, Blazor, Aspire 등에 대한 단계별 가이드&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;심층 분석&lt;/strong&gt; — 기술, 패턴 또는 아키텍처에 대한 상세한 탐구&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;커뮤니티 이야기&lt;/strong&gt; — 프로덕션에서 .NET을 사용한 경험&lt;/li&gt;
&lt;li&gt;&lt;strong&gt;이벤트 요약&lt;/strong&gt; — 컨퍼런스, 밋업 또는 웨비나 요약&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="가이드라인"&gt;가이드라인&lt;/h2&gt;
&lt;ul&gt;
&lt;li&gt;콘텐츠는 .NET 생태계와 관련된 기술적인 내용이어야 합니다&lt;/li&gt;
&lt;li&gt;코드 예제는 실제 프로젝트에서 정확하고 테스트된 것이어야 합니다&lt;/li&gt;
&lt;li&gt;의미 있는 설명과 관련 태그를 최소 하나 이상 포함하세요&lt;/li&gt;
&lt;li&gt;글은 지원되는 모든 언어로 자동 번역됩니다&lt;/li&gt;
&lt;/ul&gt;
&lt;h2 id="문의하기"&gt;문의하기&lt;/h2&gt;
&lt;p&gt;&lt;a href="https://github.com/thedotnetblog/blog/issues"&gt;GitHub&lt;/a&gt;에서 이슈를 열거나 &lt;a href="https://x.com/thedotnetblog"&gt;X / Twitter&lt;/a&gt;에서 연락주세요. 커뮤니티에 여러분을 환영합니다!&lt;/p&gt;</content:encoded></item></channel></rss>