
Azure Functions Skills를 사용하여 Azure Functions 위에서 동작하는 에이전트를 AI 주도 개발하기!
요약
Microsoft Build 2026에서 공개된 Azure Functions Skills와 Serverless Agent Runtime을 활용하여 AI 에이전트를 개발하는 방법을 소개합니다. 코딩 에이전트에게 Azure Functions의 전문 지식을 학습시키고, 서버리스 환경에서 에이전트를 효율적으로 배포하고 운영하는 과정을 다룹니다.
핵심 포인트
- Azure Functions Skills를 통해 코딩 에이전트에 Azure Functions 전문 지식 주입 가능
- Serverless Agent Runtime을 사용하면 .agent.md 정의만으로 에이전트 배포 가능
- 이벤트 기반의 서버리스 구조로 비용 효율적인 에이전트 워크로드 구현
- GitHub Copilot, Claude Code 등 다양한 CLI 에이전트와 호환
서론
Microsoft Build 2026, 올해도 업데이트가 정말 많네요. 그중에서도 Azure Functions Skills와 Serverless Agent Runtime에 대해 다뤄보겠습니다.
먼저 Azure Functions Skills(@azure/functions-skills)입니다. Build 2026에서 공개된 npm 기반의 플러그인으로, GitHub Copilot CLI / Claude Code / Codex CLI와 같은 코딩 에이전트에게 Azure Functions 고유의 판단 지식(어떤 트리거를 사용할지, 어떤 설정이 권장되지 않는지, 배포 전에 무엇을 확인해야 하는지 등...)을 가르쳐 줍니다.
다른 하나는 Azure Functions의 Serverless Agent Runtime입니다. .agent.md로 에이전트를 정의하면, 나머지는 일반적인 Functions 앱으로 배포하기만 하면 되는 구조입니다(실행은 Microsoft Agent Framework가 담당합니다).
이 기사에서는 이 두 가지를 사용하여 AI 에이전트를 실제로 만들어 보겠습니다. 하나의 유스케이스에 집중하여, Copilot CLI + Skills를 이용한 AI 주도 개발(AI-driven development)로 제작부터 운영까지 전체 과정을 진행해 보겠습니다.
제작 주제
주제는 가상의 자동차 관련 사업입니다. "고객 프로필이 업데이트되었다"라는 시스템적인 이벤트를 계기로, 해당 고객에게 어울릴 만한 차종을 선제적으로 제안해 주는 에이전트를 만들어 보겠습니다.
- 기동:
event_grid_trigger(프로필 업데이트 / 계약 갱신 임박 이벤트. 페이로드에customer_id포함) - 처리: 보유 차량 이력 및 가족 구성으로부터 니즈 추론 → 카탈로그 조회 도구(tool)로 사실 확인 → 여러 가지 추천안을 이유와 함께 생성
- 출력: 최종 응답만 출력 (알림/전송은 하지 않음 = 부작용(side effect) 없음)
전체적인 모습은 다음과 같은 구성입니다. 이벤트를 기점으로 에이전트가 도구(tool)로 사실 확인을 하며 추천을 반환하기까지의 과정을 한눈에 볼 수 있습니다.

왜 Azure Functions인가?
Functions의 특징을 고려할 때, 다음과 같은 워크로드에 적합합니다.
불정기적으로 발생하는 이벤트에 즉각 대응하고, 대기 중에는 스케일링이 0으로 내려가는 구조
고객 이벤트는 언제 발생할지 알 수 없으며, 발생하면 즉시 처리하고 싶습니다. 특히 기존 시스템으로부터의 이벤트를 처리하고 싶을 때 적합합니다.
채팅 형태의 에이전트라면 Microsoft Foundry의 Agent Service를 사용하세요.
Azure Functions Skills 개요
install (또는 plugin install)을 하면, 플러그인 실체가 ~/.copilot/installed-plugins/azure-functions-skills/... (GitHub에서는 templates/skills/ 하위)에 전개됩니다. 내부를 살펴보니 Functions의 생성부터 운영까지를 두루 커버하는 스킬 그룹이 들어 있었습니다. 우선 "무엇이 준비되어 있고 어떤 구조인지" 파악해 두겠습니다.
준비된 스킬
실측(0.0.4-preview) 결과 11개의 스킬이 들어 있었습니다 (대응 에이전트는 GitHubCopilot / claudeCode / codex입니다).
| 스킬 | 역할 |
|---|---|
azure-functions-setup | 전제 조건(Azure CLI / Core Tools / 언어 런타임 (Language Runtime)) 확인 및 도입 안내 |
azure-functions-create | 신규 Functions 프로젝트의 스캐폴딩 (Scaffolding) |
azure-functions-agents | Functions 위에서 동작하는 AI 에이전트 (서버리스 에이전트 (Serverless Agent)) 구축 및 배포 |
azure-functions-deploy | 배포 (Azure Skills의 prepare → validate → deploy로 위임하는 프록시 (Proxy)) |
azure-functions-best-practices | 프로덕션 준비 상태 리뷰 (승인 게이트 (Approval Gate)가 포함된 시정 제안) |
azure-functions-diagnostics | 배포 / 런타임 / 트리거 / 로그 장애 조사 |
azure-functions-health-status | 가동 상태 / 메트릭 (Metrics) / 텔레메트리 (Telemetry) 취득 |
azure-functions-inventory | 구성 인벤토리 (SKU / 런타임 / 설정 / 함수 및 트리거 목록) 수집 |
azure-functions-doctor | 배포 전 로컬 검사 (결정론적 체크 (Deterministic Check) + 의미 분석 (Semantic Analysis)) |
azure-functions-feedback | 발견 사항을 Issue/PR 초안으로 작성 |
azure-functions-common | 언어 및 바인딩 (Binding) 공유 레퍼런스 (다른 스킬이 내부적으로 참조) |
마지막 azure-functions-common은 단독으로 호출하기보다는 다른 스킬이 가져다 쓰는 "공유 지식"입니다. 그리고 install을 사용하면, 이들을 의도에 따라 배분하는 라우팅 에이전트 (Routing Agent) functions-copilot 도 .github/agents/에 배치됩니다 (이번에는 플러그인 (plugin)만 사용하므로 배치하지 않았습니다).
스킬 1개의 구조
스킬은 모두 하나의 디렉토리로 구성되며, 대략 다음과 같은 구조를 가집니다.
skills/<skill-name>/
├─ SKILL.md # YAML 프런트매터 (YAML Frontmatter: name / description / argument-hint) + 본문
├─ references/*.md # 지식을 분할한 md (필요한 만큼만 읽음 = 점진적 공개 (Progressive Disclosure)의 실체)
...
SKILL.md 자체는 YAML 프런트매터 (name / description / argument-hint) + 본문으로 구성되며, 본문에는 "하고 싶은 일 (Need) → 읽어야 할 references"의 대응 관계가 적혀 있습니다. 이 description (언제 호출되는가)과 필요한 참조만 여는 메커니즘이 핵심입니다. 어떻게 호출되고 어떻게 지식을 조금씩 내놓는지(Progressive Disclosure)에 대해서는 다음 장에서 조금 더 정리하겠습니다.
Azure에서의 AI 에이전트에 대하여
여기서부터는 주제를 조금 바꾸어, Azure 위에서 동작하는 AI 에이전트에 대해 설명하겠습니다. 이번에 개발할 대상 에이전트이기도 합니다.
Microsoft Build 2026에서 에이전트와 관련된 여러 업데이트가 발표되어 혼란을 줄 수 있으므로 정리해 두겠습니다.
- 본 기사에서 만드는 것 = Azure Functions의 "Serverless Agent Runtime".
.agent.md(markdown)로 에이전트를 정의하고, 일반적인 Functions 앱으로 배포합니다. 실행은 Microsoft Agent Framework가 담당합니다. - Foundry의 "Hosted Agents"는 별개의 것입니다. Foundry Agent Service 위에서 동작하는 컨테이너형 에이전트입니다.
Serverless Agent Runtime에 대하여
이번에는 첫 번째 방식인 "Serverless Agent Runtime"을 사용합니다.
Functions 에이전트는 .agent.md로 정의된 에이전트를 Microsoft Agent Framework가 Functions 위에서 구동하는 방식입니다. Functions Skills는 이 에이전트의 생성부터 운영까지를 지원하는 스킬 집합입니다.
런타임 앱은 일반적인 Python Functions 프로젝트에 "에이전트용 파일"을 추가한 형태입니다.

필수: function_app.py (엔트리 포인트 (Entry Point))
*.agent.md (에이전트 정의 (Agent Definition))
host.json (Functions 호스트 구성 (Functions Host Configuration))
requirements.txt (런타임 + 의존성 (Runtime + Dependencies))
선택/조건부: agents.config.yaml (앱 전체의 기본값 = 모델이나 타임아웃 등)
mcp.json (MCP · 커넥터 정의 (MCP · Connector Definition))
tools/ (커스텀 Python 도구 (Custom Python Tools))
skills/ (재사용할 SKILL.md)
infra/ (azd 등의 IaC)
동작 레이어
대략 다음과 같은 계층으로 동작합니다.

이벤트/트리거 (Event/Trigger): HTTP, 타이머, 큐, Blob, Event Grid, Service Bus, 커넥터 등 Functions의 풍부한 트리거를 통해 에이전트를 실행할 수 있습니다.
런타임 (Runtime): .agent.md 등을 읽어 트리거 등록과 에이전트 구축을 수행합니다.
에이전트 실행 (Agent Execution): Microsoft Agent Framework가 **지시 사항 (.agent.md)**과 **모델 (Azure OpenAI / Foundry)**을 사용하여 에이전트를 구동합니다.
도구/기능 (Tools/Capabilities): 원격 MCP, 커넥터, 스킬, 샌드박스 실행, 커스텀 Python 도구를 필요에 따라 호출합니다.
서버리스 기반 (Serverless Infrastructure): Flex Consumption (종량제) 위에서 관리형 ID (Managed Identity), Application Insights, VNet 통합, 세션 히스토리 (Blob), 0→N 스케일링이 기본적으로 제공됩니다.
셋업!
@azure/functions-skills 도입에는 두 가지 방식이 있습니다.
install … 플러그인 등록과 워크스페이스 활성화 파일을 일괄적으로 배치합니다. 구체적으로는 .github/copilot-instructions.md (라우팅), .github/agents/functions-copilot.agent.md, .github/copilot/settings.json, .vscode/mcp.json (Azure MCP), .github/hooks/welcome-setup.json 등이 포함됩니다.
plugin install … 플러그인 등록만 수행합니다.
이번에는 plugin만 사용자 스코프(User Scope)로 설치하겠습니다.
npx @azure/functions-skills plugin install --agent ghcp --scope user --no-workspace
copilot을 실행하여 /plugin list에 나타나면 성공입니다.
● Installed Plugins:
• microsoft-365-agents-toolkit@work-iq v1.1.1
• workiq@copilot-plugins v1.0.0
...
Azure Functions Skills를 사용하여 개발하자🚀
그럼 바로 시작해 봅시다.
azure-functions-setup
- 전제 조건 확인하기
> Azure Functions 개발을 위한 전제 조건(Azure CLI / Core Tools / 언어 런타임)이 갖춰져 있는지 확인해 줘.
요청 내용에 맞는 스킬인 azure-functions-setup이 description을 단서로 호출되어, 부족한 요소를 찾아 설치까지 안내해 줍니다.
스킬이 로드되면 Azure CLI, Azure Developer CLI, Azure Functions Core Tools, Python 등의 전제 조건이 갖춰져 있는지 체크가 실행됩니다.

제 경우에는 일부 도구의 버전이 오래되었다는 지적을 받았습니다.

azure-functions-agents
- 설계를 상담하고 만들어 달라고 하기 (먼저 플랜 모드(Plan Mode)로, Azure Functions 위에서 동작하는 에이전트를 만드는 계획을 세워 달라고 요청해 봅시다.)
어떤 에이전트를 만들고 싶은지는 사전에 hosted-agent-design.md에 설계해 두었으므로, 해당 파일을 전달하여 설계를 요청합니다.
@docs/hosted-agent-design.md의 설계 사상에 따라, 고객 프로필 업데이트 이벤트 (Event Grid)로 기동하여,
보유 차량 이력과 가족 구성으로부터 추천 차종을 여러 개 제안하는 Azure Functions 에이전트를 Python으로 만들어줘.
제안은 카탈로그 조회 도구(Catalog Inquiry Tool)로 검증하고, 알림은 보내지 말고 최종 응답으로만 반환해줘.

azure-functions-skills를 로드하고, 그 안의 references를 읽으면서 Azure Functions에서 어떻게 구현하는 것이 좋을지 고민합니다.

스킬은 azure-functions-agents를 로드한 후, 태스크에 필요한 참조 파일만 읽습니다. 이번에 읽는 파일은 다음과 같습니다.
agent-files.md(.agent.md형식)triggers.md(event_grid_trigger스키마)tools-and-skills.md(커스텀 도구 및 스킬)project-files.md(필요 파일)
여기에 부속된 quickstart 샘플도 확인합니다. 거대한 지식 베이스(Knowledge Base)를 보유하면서도, 읽는 것은 이번에 필요한 만큼만 한다는 것이죠.
이 점이 Skill의 장점이라고 생각합니다.
이러한 계획이 도출되었습니다.
내용을 확인하고, 필요하다면 수정하고, 문제가 없다면 승인합시다~
나머지는 Autopilot에게 맡깁니다.

완성된 결과물의 개요
무엇이 만들어졌냐면,

도구가 참조하는 카탈로그와 고객 프로필은 검증용이므로 리포지토리 안에 배치한 스텁(Stub) JSON입니다 (data/catalog.json, data/profiles.json).
.agent.md의 프론트매터(Frontmatter)는 다음과 같습니다 (런타임 설정은 YAML로, 동작은 Markdown으로 작성합니다).
---
name: Vehicle Recommendation
description: 프로필 업데이트 이벤트로 기동하여, 카탈로그에 근거한 차종을 제안한다.
...
여기서 핵심이 되는 것이 "프롬프트가 아니라 도구로 접지(Grounding)한다"는 개념입니다. 존재하지 않는 차종이나 가격을 멋대로 만들어내지 않도록, 반드시 카탈로그 조회 도구의 결과에 기반하게 합니다. 이 부분이 AI 에이전트 품질의 핵심입니다. 나중에 나올 doctor와도 깔끔하게 맞물리게 됩니다.
이 블로그를 쓰는 동안 구현이 끝난 것 같네요~

생성된 결과물 (실물)
Autopilot이 20개의 파일을 생성했습니다 (발췌).
.
├─ azure.yaml / .gitignore
├─ infra/
...
event_grid_trigger / 카탈로그 접지 (catalog.json) / 스킬 분리 / 알림 없음 / 세션 풀(Session Pool) 및 커넥터 없음. 설계 사상대로 의도했던 구성이 그대로 나왔습니다.
그대로 func start를 실행하여 트리거 등록을 확인해 보겠습니다.
Functions:
recommend_vehicle: eventGridTrigger
에러 없이 eventGridTrigger로서 제대로 등록되었습니다.
azure-functions-doctor
- 배포 전에 사고를 방지하기 (
doctor에는 두 가지 진입점이 있습니다).
- CLI (
npx @azure/functions-skills doctor) … 결정론적 체크 (Tier 1) + 공급망 검사 (Supply Chain Inspection).--deep옵션으로 LLM 의미 분석 (Tier 2)도 실행되지만, 이 버전 (0.0.4-preview)에는--deep이 없습니다. - Copilot CLI의 스킬 (
azure-functions-doctor) … 코딩 에이전트 스스로가 의미 분석까지 수행합니다. CLI의--deep이 없더라도 이쪽에서 심층 분석이 가능합니다.
먼저 CLI의 결정론적 체크부터 시작합니다. 이 방식은 빠릅니다.
npx @azure/functions-skills doctor --dir ./src
host.json이 없는 상태라면, 무엇이 문제이고 어떻게 수정해야 하는지까지 알려줍니다.
Azure Functions Doctor
Built-in checks:
❌ project-exists host.json is missing
...
Tier 1은 고속 체크 및 공급망 검사(Supply Chain Inspection)입니다(고정되지 않은 프로덕션 의존성, lockfile 누락, 추적된 .env, install-script 의존성 등).
--deep (Tier 2)은 에러 핸들링 누락, 블로킹 I/O (Blocking I/O), 비밀 정보 하드코딩과 같은 의미론적(Semantic) 문제를 찾아냅니다.
스킬로 의미 분석하기
Copilot CLI 내에서 azure-functions-doctor를 호출하면, 스킬은 점진적 공개 (Progressive Disclosure) 방식으로 필요한 체크리스트만 읽어옵니다. routing.md
→ ai-semantic-checks.md
→ language-checks.md (Python)
→ supply-chain-checks.md (requirements.txt 있음)
→ iac-azure-resource-checks.md (Bicep 있음) 순서로 진행됩니다. 그 후 프로젝트를 분석하여 doctor-report.json을 생성합니다.
❯ /azure-functions-skills:azure-functions-doctor
실행하면 심각도별로 정리된 분석 요약이 출력됩니다 (아래 표).
몇 가지 지적 사항이 나왔습니다. 이것들도 수정하도록 시켜봅시다!
| 심각도 | ID | 위치 | 지적 사항 |
|---|---|---|---|
| 🔴 High | SC-005 | .gitignore | local.settings.json이 gitignore 되어 있지 않으며 AccountKey=를 포함함. 엔드포인트를 채우면 실제 시크릿을 commit 할 위험이 있음 |
| 🔴 High | iac-shared-key-access | infra/main.bicep | 스토리지가 Managed Identity로 운영됨에도 allowSharedKeyAccess: true로 설정됨. 최소 권한 원칙을 위해 비활성화 필요 |
| 🟡 Med | CQ-007 | src/tools/get_profile.py | 고객을 찾지 못했을 때 예외(Exception)가 아닌 {"error": ...}를 반환 → LLM이 정상 데이터로 오인하여 할루시네이션 (Hallucination)을 일으킬 수 있음 |
| 🟡 Med | CF-local-endpoint-empty | src/local.settings.json | FOUNDRY_PROJECT_ENDPOINT가 비어 있음 → 로컬 첫 실행 시 실패 |
| 🟡 Med | SC-008 | infra/app/api.bicep | Function App에 minTlsVersion이 설정되지 않음 (스토리지의 경우 TLS 1.2로 고정되어 있음) |
| 🔵 Low | CQ-005 | recommend_vehicle.agent.md | Event Grid의 At-least-once 전달에 대한 멱등성 (Idempotency) 가드 없음 (현재는 Read-only라 무해하지만, 쓰기 작업이 추가되면 위험함) |
| 🔵 Low | PY-003 | src/requirements.txt | azure-functions를 직접 선언하지 않았으며 버전 고정도 없음 (전이적 의존성) |
실제로 "수정해줘"라고 지시하면, IaC 패치나 코드 수정으로서 고쳐줍니다 (수정 후의 상태는 다음의 best-practices 단계에서 검증합니다).
--deep (CLI)의 보안 모델
CLI의 --deep은 --accept-deep-risk가 필수이며 (에이전트가 승격된 권한으로 동작하는 것에 대한 승인), 신뢰할 수 있는 워크스페이스 (Workspace)에서만 동작합니다. PR 워크스페이스에서는 실행이 거부됩니다 (프롬프트 인젝션 (Prompt Injection) 방지). CI에서 사용하려면 push: main + GitHub Environment를 사용하는 것이 정석입니다 (후술).
azure-functions-best-practices
- 운영 환경에 배포해도 괜찮은가 (```
이 앱을 운영 환경에 배포해도 괜찮을지, Azure Functions 베스트 프랙티스 (best practices)를 바탕으로 리뷰해줘.
스킬은 `review-checklist.md`와 `remediation-patterns.md`를 읽고, Azure 베스트 프랙티스 MCP (Model Context Protocol)의 가이던스도 반영하여, 소스 코드와 IaC (Infrastructure as Code)를 운영 준비성 (production readiness) 관점에서 철저히 정밀 조사합니다 (아직 배포 전이므로 대상은 로컬의 Bicep 및 코드입니다).
우선 기뻤던 점은, 앞 단계의 `doctor`가 지적한 7가지 사항이 현재 파일에서 모두 해결되어 있었다는 것입니다 (`gitignore`, `allowSharedKeyAccess`, `get_profile`의 `None` 반환, `minTlsVersion`, 멱등성 (idempotency) 주석, azure-functions, 엔드포인트 설정). `doctor`로 발견하고 → 수정하고 → `best-practices`로 재확인하는 흐름이군요.
그다음, 더 상위 단계인 "운영 환경에 배포해도 되는가"를 판정합니다. 결론은 "이대로는 불가. Critical 2건"이었습니다.

| 심각도 | 문제 | 위치 | 영향 |
|---|---|---|---|
| 🔴 Critical | 스텁 (stub) 데이터를 실제 고객에게 반환 | `src/data/*.json` | 실제 고객 DB 및 카탈로그 API로 교체 필수 |
| 🔴 Critical | Event Grid 구독이 IaC에 없음 | `infra/main.bicep` | 배포는 성공하지만 이벤트가 전달되지 않아 에이전트가 전혀 작동하지 않음 |
| 🔴 High | 모델 자동 업그레이드 (`versionUpgradeOption`) | `infra/app/foundry.bicep` | 출력 포맷 및 동작이 통보 없이 변경됨 → `NoAutoUpgrade`로 설정 필요 |
| 🔴 High | `ftpsState` 미설정 | `infra/app/api.bicep` | `Disabled`를 명시해야 함 |
| 🟡 Med | `maximumInstanceCount: 100` × 30분 AI | `infra/app/api.bicep` | 비용 폭발 위험. 초기에는 5~10으로 설정 |
| 🟡 Med | 로그 보존 30일 / 장애 알림 없음 / 리전 US 한정 / Preview API | `main.bicep` ・ `foundry.bicep` | 운영, 모니터링, 이식성 측면의 허점 |
| 🟢 Low | 콜드 스타트 (cold start) ・ 불필요한 CORS ・ 슬롯 (slot) 미검토 | infra | PoC 단계에서는 허용, 본격적인 운영 시 대응 |
AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기