FaroIQ: Azure AI Foundry를 사용하여 비영리 단체를 위한 9개 에이전트 파이프라인을 구축한 방법
요약
Azure AI Foundry를 활용하여 비영리 단체의 니즈 분석부터 실행 계획 수립, Microsoft 365 연동까지 수행하는 9단계 에이전트 파이프라인 'FaroIQ' 구축 사례를 소개합니다. 병렬 방식 대신 컨텍스트 체이닝을 통한 순차적 파이프라인 구조를 채택하여 결과물의 일관성을 확보했습니다.
핵심 포인트
- Azure AI Foundry와 Microsoft 365를 결합한 에이전트 아키텍처 설계
- 일관된 실행 계획을 위해 순차적(Sequential) 파이프라인 및 컨텍스트 체이닝 적용
- JSON 스키마를 활용한 에이전트 간 구조화된 데이터 전달
- Tavily 검색 및 WebSocket을 이용한 실시간 상태 스트리밍 구현
저는 아르헨티나 카타마르카 국립대학교(National University of Catamarca)에서 소프트웨어 디자인을 공부하고 있는 Carlos입니다. 이 포스트는 Microsoft Agents League 2026 기간 동안 제가 FaroIQ를 어떻게 구축했는지, 즉 제가 어떤 결정을 내렸고, 왜 그런 결정을 내렸으며, 그 과정에서 어떤 문제에 직면했는지를 다룹니다.
아이디어의 기원
아르헨티나 산후안(San Juan)에서 자라면서, 저는 Caritas와 같은 조직들이 학교와 대학교를 통해 기부금을 모으고 아주 적은 자원으로 할 수 있는 일을 해내는 모습을 지켜보았습니다. 문제는 의지의 부족이 아니었습니다. 그 조직들은 자신들의 공동체에 무엇이 필요한지 정확히 알고 있습니다. 그들에게 부족한 것은 그 지식을 구체적인 것, 즉 데이터, 단계, 예산이 포함된 계획으로 전환하는 방법입니다.
해커톤이 시작되었을 때, 저는 그 문제를 해결할 수 있는 무언가를 만들고 싶었습니다. 단순한 기술 데모가 아니라, 누군가 실제로 사용한다면 그들에게 유용할 수 있는 무언가를 말입니다.
아이디어: 사용자가 평이한 언어로 자신의 조직을 설명하면, 시스템이 90초 이내에 니즈 분석(needs analysis), 단계별 실행 계획, 영향력 예측, 제출 가능한 보조금 신청서(grant proposal)를 생성하고, 이 모든 것을 Microsoft 365(Calendar, To Do, OneDrive, Email)에서 자동으로 실행합니다.
FaroIQ란 무엇인가
FaroIQ는 세 가지 Microsoft IQ 레이어 위에 구축된 커뮤니티 인텔리전스 플랫폼입니다:
- Foundry IQ: 에이전트 추론(agent reasoning)을 위한
gpt-oss-120b모델을 사용하는 Azure AI Foundry - Fabric IQ: 세션 지속성(session persistence) 및 집계 분석(aggregated analytics)을 위한 Azure Blob Storage
- Work IQ: 실행을 위한 Azure Logic Apps를 통한 Microsoft 365
이 이름은 스페인어로 등대(lighthouse)를 뜻하는 단어에서 유래되었습니다. 더 이상의 설명은 필요 없을 것 같습니다.
아키텍처
병렬 에이전트 대신 순차적 파이프라인을 선택한 이유
첫 번째 결정 중 하나는 9개의 에이전트를 어떻게 구조화할 것인가였습니다. 두 가지 명확한 옵션이 있었습니다: 총 시간을 줄이기 위해 병렬(parallel)로 실행하거나, 각 에이전트가 이전 모든 에이전트의 출력을 컨텍스트(context)로 받는 순차적(sequence) 방식으로 실행하는 것이었습니다.
저는 순차적(sequence) 방식을 선택했습니다. 일관된 실행 계획(action plan)을 위해서는 각 단계가 이전 단계의 결과물을 바탕으로 구축되어야 하기 때문입니다. 만약 Planning 에이전트가 Analysis 에이전트가 식별한 요구사항이나 Classification 에이전트가 추정한 리소스 용량(resource capacity)을 알지 못한다면, 결국 일반적이고 모호한 결과물을 생성하게 됩니다. 컨텍스트 체이닝(context chaining)을 통해 각 에이전트는 이전 모든 에이전트의 구조화된 출력(structured output)과 함께, 자신의 시스템 프롬프트(system prompt) 및 반환해야 할 형식을 정확히 정의하는 JSON 스키마(JSON schema)를 전달받습니다.
| 에이전트 | 역할 |
|---|---|
| Research | 실제 통계 및 비교 가능한 NGO 프로그램을 위한 실시간 Tavily 웹 검색 |
| ... |
모든 에이전트는 Azure AI Foundry 엔드포인트(endpoint)를 대상으로 AsyncAzureOpenAI를 사용합니다. 각 이벤트(시작, 진행, 완료)는 WebSocket을 통해 프론트엔드로 실시간 스트리밍되므로, 사용자는 로딩 화면을 바라보는 대신 파이프라인이 실행되는 과정을 지켜볼 수 있습니다.
자율적 수정 루프 (The autonomous revision loop)
이 부분은 제대로 구상하는 데 가장 오랜 시간이 걸린 부분이었습니다. Evaluator가 작업을 마치면, Critique 에이전트가 전체 파이프라인 출력값에 대해 0.0에서 1.0 사이의 점수를 매깁니다. 만약 점수가 0.70 미만으로 떨어지면, 시스템은 사용자에게 어떻게 할지 묻지 않습니다. 대신 Critique의 피드백을 추가적인 컨텍스트(context)로 주입하고, 해당 관찰 사항들을 포함하여 Planner와 Evaluator를 다시 실행합니다. 이 과정은 최대 2회 사이클까지 반복됩니다.
제한을 2회로 설정한 것은 실용적인 결정이었습니다. 세 번째 사이클은 결과물을 유의미하게 개선하는 경우가 드물었고, 전체 소요 시간이 이미 90초에 근접했기 때문입니다. 2회를 초과하는 수정은 사용자가 예측할 수 없는 무한 루프처럼 느껴지기 시작했습니다.
UI에서 사용자는 품질 점수, 완료된 사이클 횟수, 식별된 핵심 결함(critical gaps), 그리고 구체적인 권장 사항을 확인할 수 있습니다. 또한 Critique가 무엇을 감지했는지, 그리고 왜 수정을 결정했는지를 정확히 보여주는 확장 가능한 패널이 있습니다. 시스템은 단순히 조용히 스스로를 개선하는 것이 아니라, 자신의 작업 과정을 투명하게 보여줍니다.
Fabric IQ: 왜 모든 것을 유지해야 하는가
처음부터 저는 분석 결과가 브라우저 세션 이후에도 유지되기를 원했습니다. 비영리 단체가 탭을 닫거나 iOS에서 연결이 끊겼다는 이유로(이에 대해서는 나중에 더 자세히 다루겠습니다) 분석 내용을 잃어버리는 것은 말이 되지 않기 때문입니다.
완료된 각 분석은 faroiq-lakehouse 컨테이너 아래 Azure Blob Storage에 구조화된 JSON 형식으로 저장됩니다. 각 세션은 UUID에서 파생된 8자리 코드를 가지며, 이를 통해 인증 없이도 누구나 세션을 불러올 수 있습니다. reports라고 불리는 두 번째 컨테이너에는 렌더링된 HTML 버전의 보고서가 영구적인 공개 URL 형태로 저장됩니다.
Intelligence Dashboard는 저장된 모든 세션의 데이터를 집계합니다: 섹터 분포, 평균 타당성 점수, 긴급도 트렌드, 누적 수혜자 예측 등입니다. 데이터셋이 커짐에 따라 개별 분석의 유용성은 시간이 갈수록 높아집니다.
Work IQ: Microsoft 365에서의 실행
네 개의 Azure Logic Apps가 시스템을 Microsoft 365에 연결합니다:
- Calendar (캘린더): 각 실행 단계에 대한 Outlook 이벤트를 생성합니다.
- To Do (할 일): 조직 이름을 접두사로 사용하는 구조화된 작업 목록을 생성합니다. 예:
[Caritas San Juan] Phase 1: Diagnosis - OneDrive (원드라이브): 전체 HTML 보고서를
/FaroIQ Reports에 저장합니다. - Email (이메일): Outlook을 통해 전체 분석 내용을 전달합니다.
모든 Logic Apps 호출은 API 응답을 차단하지 않도록 백엔드에서 비동기(async) 백그라운드 작업으로 실행됩니다. 하나가 실패하더라도 로그에 기록될 뿐 사용자에게 에러로 나타나지는 않는데, 이는 M365 통합 기능이 분석 자체보다는 부차적인 기능이기 때문입니다.
또한, 엔터프라이즈 환경의 Microsoft 365 Copilot에 배포할 수 있도록 /teams-plugin/appPackage/에 선언적 에이전트(Declarative Agent) 매니페스트가 포함되어 있으며, 여기에는 9단계 추론 지침 세트와 영어 및 스페인어로 된 6개의 대화 시작 문구(conversation starters)가 포함되어 있습니다.
어려운 부분들
설계가 예상보다 오래 걸렸습니다
인터페이스를 구축하는 데 얼마나 많은 시간이 걸릴지 과소평가했습니다. 보여줘야 할 정보가 매우 많았습니다: 각 에이전트의 상태를 보여주는 파이프라인 시각화 도구(pipeline visualizer), 자율 수정 패널(autonomous revision panel), 탭이 포함된 전체 보고서, 비평 패널(critique panel), 채팅, 그리고 M365 통합 기능까지 말이죠. 사용자를 압도하지 않으면서 이 모든 것이 의미 있게 전달되도록 적절한 시각적 계층 구조(visual hierarchy)를 찾는 데 꽤 많은 반복 작업이 필요했습니다.
Three.js 라이트하우스(lighthouse) 배경은 그 자체로 하나의 도전 과제였습니다. 낮 모드와 밤 모드는 완전히 다른 장면을 렌더링합니다. 낮에는 햇빛이 비치는 크림색 타워를, 밤에는 별자리와 볼륨메트릭 빔(volumetric beam)이 있는 어두운 네이비 색상을 보여줍니다. 처음에는 테마 변경 시 장면을 변형(mutate)하려고 시도했지만, Three.js는 해당 상태를 깔끔하게 정리하지 못했습니다. 결국 테마가 변경될 때마다 React의 key prop을 통해 전체 리마운트(remount)를 강제하는 방식을 택했습니다. 이것이 가장 직접적인 해결책이며 부작용(side effects) 없이 작동합니다.
에이전트가 데이터를 지어내지 않도록 방지하기
처음부터 스스로 설정한 한 가지 요구 사항은 시스템이 지어낸 통계(invented statistics)를 반환해서는 안 된다는 것이었습니다. 만약 비영리 단체가 이 분석을 바탕으로 의사결정을 내린다면, 데이터는 검증 가능한 곳에서 가져와야 합니다.
그렇기 때문에 첫 번째 에이전트는 나머지 파이프라인이 시작되기 전에 Tavily를 사용하여 실시간 웹 검색을 수행합니다. 이후 에이전트들의 토큰 예산(token budget)을 초과하는 것을 방지하기 위해 결과는 3,000자로 잘리지만, 이를 통해 관련 정보는 보존됩니다. 분석가(Analyzer)와 기획자(Planner)는 첫 번째 단계의 실제 데이터에 접근할 수 있습니다.
WebSocket과 iOS
WebSocket 연결을 60~90초 동안 열어두는 것은 특히 iOS에서 문제가 발생합니다. iPhone의 Safari와 Chrome은 모두 WebKit을 사용하는데, 이는 데스크톱이나 Android보다 더 엄격한 연결 제한을 가지고 있습니다. 파이프라인이 완료되기도 전에 연결이 끊어져 버립니다.
저는 이를 단계별로 해결했습니다. 첫째, 연결을 유지하기 위해 8초마다 keepalive 핑 (keepalive ping)을 보냅니다. 둘째, 백엔드(backend)가 파이프라인이 시작되기 전에 프론트엔드(frontend)로 session_id를 전송하여, 사용자가 첫 순간부터 세션 코드를 가질 수 있도록 했습니다. 연결이 끊어지더라도 파이프라인은 서버에서 계속 실행되며, 사용자는 세션 조회(Session Lookup) 페이지에서 해당 코드를 입력하여 전체 분석 내용을 복구할 수 있습니다. 셋째, ErrorBoundary 컴포넌트가 어떤 에러 상태에서도 세션 코드를 표시하므로 코드를 절대 잃어버리지 않습니다.
모든 스트리밍(streaming) 방식을 서버 전송 이벤트 (Server-Sent Events, SSE)나 폴링 (polling) 방식으로 리팩터링하지 않는 한, iOS를 위한 완벽한 해결책은 없습니다. 이를 위해서는 백엔드의 상당 부분을 다시 작성해야 했을 것입니다. 현재의 솔루션은 다른 부분을 망가뜨리지 않으면서 해당 사용 사례를 충족합니다.
처음 실행했을 때 놀랐던 점
저는 파이프라인이 유용한 결과물을 만들어낼 것이라고 예상했습니다. 하지만 에이전트(agents)들이 작업할 수 있는 좋은 입력값(input)을 가졌을 때, 출력이 얼마나 상세하고 구체적일지는 예상하지 못했습니다.
실제 비영리 단체를 대상으로 전체 분석을 처음 실행했을 때, 출력물에는 단계별 구체적인 활동, 측정 가능한 마일스톤 (milestones), 완화 전략이 포함된 리스크 요인 (risk factors), 변화 이론 (theory of change)과 지속 가능성 계획이 포함된 자금 조달 제안서, 그리고 신뢰 구간 (confidence intervals)이 포함된 영향력 예측 등이 포함되어 있었습니다. 이 중 어느 것도 하드코딩된 것이 아니었습니다. 이는 9개의 에이전트에 걸친 컨텍스트 체이닝 (context chaining)을 통해 도출된 결과였습니다.
그때 저는 순차적 접근 방식 (sequential approach)의 추가된 복잡성이 왜 그만한 가치가 있는지 이해했습니다.
풀스택 (Full stack)
백엔드 (Backend): Python 3.12 · FastAPI · uvicorn · AsyncAzureOpenAI · azure-storage-blob · Tavily
프론트엔드 (Frontend): React 18 · TypeScript · Vite · Three.js · WebSocket
인프라스트럭처 (Infrastructure): Railway (백엔드, Hobby 플랜) · Vercel (프론트엔드) · Azure Blob Storage · Azure Logic Apps · Azure AI Foundry
통합 (Integrations): Microsoft 365 (Calendar, To Do, OneDrive, Email) · Microsoft 365 Copilot (Declarative Agent)
마치며
저는 227개의 커밋, 프로덕션 배포(production deploy), 실제 조직들의 실제 세션, 모든 기능의 스크린샷이 포함된 README, 데모 영상, 그리고 제출 완료와 함께 해커톤을 마쳤습니다.
파이프라인 시각화 도구(pipeline visualizer)가 실시간으로 작동하는 모습, Critique 에이전트의 추론 과정이 담긴 확장 가능한 수정 패널(expandable revision panel), 몇 초 만에 생성된 자금 조달 제안서(funding proposal), 그리고 Microsoft To Do에 자동으로 나타나는 작업들을 보았을 때, 저는 엔드 투 엔드(end to end)로 작동하는 무언가를 구축했다는 느낌을 받았습니다.
저는 Microsoft Agents League 2026의 Reasoning Agents 트랙에 참여했습니다. 우승은 하지 못했습니다. 하지만 FaroIQ는 배포되었고, 무료이며, 이를 발견하는 어떤 비영리 단체든 오늘 바로 사용할 수 있습니다. 그것만으로도 이것을 구축할 이유는 충분합니다.
링크
- 라이브 데모: faroiq.vercel.app
- GitHub: github.com/carlosjcastro/faroiq
Microsoft Agents League 2026 · Reasoning Agents Track · Hack for Good
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기