<?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>Python | The .NET Blog</title><link>https://thedotnetblog.com/ko/tags/python/</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>Sat, 25 Apr 2026 00:00:00 +0000</lastBuildDate><atom:link href="https://thedotnetblog.com/ko/tags/python/index.xml" rel="self" type="application/rss+xml"/><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>당신의 에이전트는 어디서 기억하나요? 채팅 기록 저장소 실용 가이드</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>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></channel></rss>