
결재 문서 작성 및 승인의 완전 자동화 AI Agent (AI-DLC로 개발) 【Microsoft Agent Hackathon 2026】
요약
Microsoft Agent Hackathon 2026에 출품된 결재 문서 작성 및 승인 자동화 AI Agent 프로젝트를 소개합니다. AI, 워크플로, 룰 베이스를 결합한 3층 구조 설계를 통해 단순 문서 작성을 넘어 승인 프로세스 전체를 자동화했습니다.
핵심 포인트
- AI, 워크플로, 룰 엔진을 결합한 3층 구조 설계
- 룰 기반 검증을 통해 AI의 확률적 판단 오류 보완
- 감사 로그 추적이 가능한 투명한 자동화 프로세스 구축
- 신청자, 승인자, 관리자별 맞춤형 인터페이스 제공
서론
평소에는 AWS 서버리스 아키텍처 (Serverless Architecture) 설계/개발, AI 구동 개발 (AI-Driven Development) 적용 검토, n8n이나 워크플로 (Workflow) 툴을 활용한 고도화된 AI 활용 제안/설계/개발 등을 하고 있습니다.
이번에 업무상 Azure를 사용하는 프로젝트에 참여하게 될 것 같은 타이밍에 Microsoft Agent Hackathon 2026이 개최되고 있어서, "Azure도 좀 만져볼까" 하는 느낌으로 도전해 보았습니다.
"AI만" 혹은 "AI Agent만" 사용하는 것이 아니라, AI × 워크플로 (Workflow) × 룰 베이스 (Rule-based)의 3층 구조로 설계하여, 기술적 선진성뿐만 아니라 "어떻게 실무를 움직일 수 있는가"를 중시했습니다.
사내 신청 자동 심사 시스템 (결재)
만든 것: 입니다
일본 기업의 결재 문서 승인은 건당 평균 1~2시간의 작성 및 확인 공수가 소요되며, 승인 플로 (Flow)가 개인의 역량에 의존하거나 다단계로 이루어져 정체되기 쉽습니다.
미야자키 은행이 Azure OpenAI를 사용하여 결재 문서 자동 생성을 구현해 작성 시간을 95% 절감(2시간 → 몇 분)한 사례가 있을 정도로, 이 분야에는 큰 개선 여지가 있습니다.
하지만 결재 문서의 자동 작성이나 AI에 의한 심사 지원만으로는 "전체 승인에 걸리는 시간"은 크게 변하지 않습니다.
결국 승인자와의 인간적인 상호작용이나 승인 대기 시간이 병목 (Bottleneck)으로 남기 때문입니다.
이번에 만든 것은 이를 포함한 "심사·승인 플로 (Flow) 전체"의 자동화입니다.
룰 (Rule)로 걸러낼 수 있는 것은 즉시 반려하고, 저위험 항목은 자동 승인하며, 그 외의 것만 인간에게 넘깁니다.
이 분기를 워크플로 (Workflow)로 구축함으로써 승인 대기가 발생하는 건수 자체를 줄이고 있습니다.
해커톤용 데모 영상
플로 (Flow)
신청자가 채팅으로 대화 → AI가 결재 문서를 자동 생성
→ 룰 엔진 (Rule Engine)으로 형식·내용·정책 체크
→ AI가 내용의 타당성을 심사
...
👀 신청부터 승인 완료까지, 승인자의 판단 이외에는 전부 자동입니다.
역할별로 가능한 일
신청자
- 채팅으로 대화하는 것만으로 결재 문서가 자동 생성됨
- 생성된 초안 (Draft)을 폼 (Form)에서 확인 및 수정 가능
- 신청 후에는 상태 화면에서 실시간으로 진행 상황을 확인 가능
- 반려·승인·거절은 메일로 통지됨
승인자
- 메일로 전달된 URL을 통해 승인 화면에 직접 접속 가능
- 신청 내용·룰 판정 결과·AI 심사 이유·우려 사항을 일람할 수 있음
- 승인/거절과 코멘트를 입력하는 것만으로 플로 (Flow)가 완료됨
관리자
- 모든 신청의 상태를 일람으로 확인 가능
- 각 신청의 감사 로그 (Audit Log) (누가 언제 어떤 판단을 했는지)를 시계열로 추적 가능
왜 AI만으로는 안 됐는가
이것이 이번 설계의 핵심입니다.
처음에는 "전부 AI에게 시키면 되잖아"라고 생각했습니다.
하지만 실제로 설계를 구체화하다 보니 세 가지 문제가 보였습니다.
문제 1: AI의 판단 정밀도가 너무 "확률적"임
"필수 항목이 미입력되었는지" 혹은 "금액이 10만 엔 이하인지" 등을 AI에게 판단하게 하면 가끔 틀립니다. 룰 (Rule)이 명확한 것은 코드로 작성하는 것이 100% 정확합니다.
문제 2: AI Agent만으로는 판단 추적이 어려움
"왜 이 신청이 반려되었는지", "어느 단계에서 언제 누가 판단했는지"를 나중에 조사하기 어려워집니다. 할루시네이션 (Hallucination) 리스크도 있으며, 감사 증적 (Audit Trail)으로 사용할 수 있는 수준이 되지 않습니다.
문제 3: 자동화 수준과 컨트롤 (Control) 사이의 트레이드오프 (Trade-off)
AI에게만 맡기면 "전부 AI가 결정한다" 또는 "전부 인간에게 넘긴다"라는 이지선다로 흐르기 쉽습니다. 실제로는 "명백히 OK인 것은 자동 승인, 그레이 존 (Gray Zone)은 인간이 판단"하는 분리를 하고 싶습니다.
해결책: AI × WF × 룰 베이스 (Rule-based)의 3층 설계
[신청자]
↓
[룰 엔진 (Rule Engine)] ← 형식·내용·정책·리스크를 기계적으로 판정 (0 또는 1)
...
룰 (Rule)이 명확한 것 → 룰 엔진 (Rule Engine) (Python) -
정성적인 판단이 필요한 것 → AI (Azure OpenAI) -
상태 관리·통지·라우팅 (Routing) → 워크플로 (Workflow) (Azure Logic Apps)
이 3층 구조로 함으로써
✅ 룰 베이스 (Rule-based) 부분은 100% 정확
✅ AI의 판단은 "보조"로 사용하고, 인간이 최종 판단
✅ Logic Apps의 실행 로그 + 감사 테이블 (Audit Table)로 모든 단계를 추적 가능
구체적으로 어떤 신청이 어떤 경로를 통과하는지 정리해 두겠습니다.
해커톤용으로 간단한 룰 (Rule)과 신청 플로 (Flow)를 설정했습니다.
루트 맵 (Route Map)
| 조건 | 룰 엔진 (Rule Engine) 결과 | AI 심사 결과 | 최종 판단 |
|---|---|---|---|
| 필수 항목 미입력 | REJECTED | (호출되지 않음) | 즉시 반려 |
| ... | 자동 승인 (과장급 상당) | ||
| 금액 10만~100만·리스크 없음 | PENDING_REVIEW | 승인 권장 | |
| 부장에게 통지 → 인간 판단 | |||
| 금액 100만 초과 | PENDING_REVIEW | 확인 필요 | |
| 임원에게 통지 → 인간 판단 | |||
| 신규 거래처 등록 (금액 불문) | PENDING_REVIEW | 확인 필요 | |
| 임원에게 통지 → 인간 판단 | |||
| 긴급 신청 (7일 이내)·고액·센시티브 키워드 | PENDING_REVIEW | 확인 필요 | 담당 승인자에게 통지 (주의 플래그 포함) |
| 목적·기대 효과 기술 부족 | APPROVED or PENDING_REVIEW | 반려 권장 | AI 판단으로 반려 |
리스크 플래그 (Risk Flag) 종류
룰 엔진 (Rule Engine)이 감지하는 리스크 플래그는 6종류가 있습니다.
플래그가 1건이라도 있으면 자동 승인은 되지 않으며, 승인자 통지 루트로 들어갑니다.
| 플래그명 | 조건 |
|---|---|
HIGH_AMOUNT | 금액 100만 엔 초과 |
NEW_VENDOR | 신청 구분이 신규 거래처 등록 |
VENDOR_REASON_MISSING | 거래처 선정 이유 없음 & 금액 50만 엔 초과 |
URGENT_REQUEST | 실시 예정 시기가 신청일로부터 7일 이내 |
NO_ATTACHMENT | 첨부 자료 없음 & 금액 30만 엔 초과 |
SENSITIVE_KEYWORD | 제목·목적에 「대납(立替)」「사비(私費)」「개인(個人)」「교제비(交際費)」를 포함 |
승인자 라우팅 (Routing)
금액 베이스로 승인자가 자동 결정됩니다.
~10만 엔 → 과장 (자동 승인 후보)
~100만 엔 → 부장
100만 엔 초과 → 임원
...
아키텍처 도표

사용 기술 스택 (Tech Stack)
| 레이어 | 기술 |
|---|---|
| 프론트엔드/백엔드 | Python Flask |
| ... |
동작 예시 스크린샷
채팅 화면 (신청 정보 수집)


AI 자동 반려 시 (메일 통지)

승인자 화면 (AI 심사 결과·판단 이유 표시)

관리자 화면 (감사 로그)

Logic Apps 워크플로 실행 로그

구현의 노하우
노하우 1: 룰 엔진을 MECE하게 설계
품의서 체크를 4개의 독립된 카테고리로 분할했습니다.
RuleEvaluator
├─ FormChecker 형식 체크 (필수 항목·글자 수·날짜 형식)
├─ ContentChecker 내용 체크 (신청 구분별 논리적 정합성)
...
각 체커(Checker)는 **순수 함수 (Pure Function)**로 구현하여 테스트하기 쉽게 만들었습니다.
# 좋은 설계: 인수에만 의존, 부작용(Side Effect) 없음
def check_form(doc: RingiDocument) -> CheckResult:
messages = []
...
룰 임계값은 rules_config.py에 집약하여, 코드를 건드리지 않고도 비즈니스 룰을 변경할 수 있도록 했습니다.
# rules_config.py
AUTO_APPROVAL_MAX_AMOUNT = 100_000 # 10만 엔 이하는 자동 승인 후보
CATEGORY_AMOUNT_LIMITS = {
...
}
노하우 2: Structured Outputs로 품의서 생성을 결정론적으로
AI가 생성하는 품의서의 JSON 형식이 매번 다르면 곤란하므로, Azure OpenAI의 Structured Outputs를 사용했습니다.
response = client.chat.completions.create(
model=deployment_name,
messages=[...],
...
)
이로써 "AI가 반환하는 JSON 구조가 매번 다르다"는 문제를 제로(0)로 만들었습니다.
노하우 3: AI의 완료 감지를 JSON 플래그로 구현
채팅에서 "필요한 정보가 모두 수집되었는가"를 어떻게 판정할 것인가, 이것이 은근히 어렵습니다.
시스템 프롬프트에 다음과 같이 설정했습니다.
필요 정보가 모두 수집되었다고 판단하면, 반드시 다음 JSON만을 반환할 것:
{"is_complete": true, "summary": "수집 내용 요약 (일본어)"}
그 외의 일반적인 응답은 일반 텍스트 (Plain Text)로 반환할 것.
서버 측에서 JSON 파싱 (Parsing)을 시도하여, is_complete == true라면 수집 완료로 판단합니다.
심플하지만 상당히 안정적으로 동작했습니다.
고안 4: AI의 판단 이유를 승인자 화면에 표시
"AI가 이렇게 말했으니까 승인했다"는 방식은 감사 (Audit) 용도로 사용할 수 없습니다.
승인자 화면에는 AI의 심사 결과 (recommendation), 판단 이유 (reasoning), 그리고 우려 사항 (concerns)을 모두 표시하고 있습니다.
{
"recommendation": "확인 필요",
"reasoning": "금액이 50만 엔을 초과하였으며, 거래처 선정 이유가 기재되어 있지 않습니다. HIGH_AMOUNT, VENDOR_REASON_MISSING 플래그가 감지되었습니다.",
...
}
승인자는 "AI가 왜 그렇게 판단했는가"를 보면서 최종 판단을 내릴 수 있습니다.
이것이 바로 "AI의 설명 가능성 (Explainability)" 구현입니다.
고안 5: Idempotency Guard로 중복 실행 방지
Logic Apps의 재시도 (Retry) 과정에서 동일한 품의서 ID가 규칙 엔진 (Rule Engine)으로 여러 번 전달되는 경우가 있습니다.
ringi_id를 키 (Key)로 Table Storage에 캐싱하여, 동일한 요청이 오면 평가를 스킵하고 동일한 결과를 반환합니다.
def get_cached_result(ringi_id: str) -> dict | None:
entity = table.get_entity("rule_evaluation", ringi_id)
return json.loads(entity["result_json"]) if entity else None
고안 6: Prompt Loading on Demand
프롬프트 (Prompt)를 파일에서 매번 읽어오는 설계로 만들었습니다.
def _load_prompt(filename: str) -> str:
prompt_path = os.path.join(os.path.dirname(__file__), "prompts", filename)
with open(prompt_path, encoding="utf-8") as f:
...
배포 (Deployment) 없이도 프롬프트를 개선할 수 있습니다.
로컬 파일 읽기는 1ms 미만이므로 성능 (Performance)에 미치는 영향도 없습니다.
고안 7: Managed Identity + Key Vault Reference로 시크릿을 코드에 작성하지 않기
모든 시크릿 (Secret, API Key, 연결 문자열 등)은 Azure Key Vault에 집약하고, App Settings에서 KV Reference를 통해 참조합니다.
// IaC로 KV Reference 설정
{
name: 'AZURE_OPENAI_API_KEY'
...
}
코드에 시크릿을 작성할 필요가 전혀 없어집니다.
빠지기 쉬운 함정 (ハマりポイント)
AI Foundry의 RBAC
Azure Functions의 Managed Identity에 Azure AI Developer 역할을 부여해도 Agents API를 호출할 수 없었습니다.
정확하게는 AI Foundry Project 스코프 (Scope)에서 Foundry User 역할 (53ca6127-db72-4b80-b1b0-d745d6d5456d)이 필요했습니다.
resource aiFuncFoundryUserRole 'Microsoft.Authorization/roleAssignments@2022-04-01' = {
name = guid(aiProjectId, aiFuncId, 'FoundryUser')
scope = aiProject
...
}
문서에는 적혀 있지 않아서 꽤 많은 시간이 걸렸습니다.
Logic Apps의 Webhook 패턴
WaitForApproval을 위해 WebApp에 /approvals/register-callback 엔드포인트 (Endpoint)를 준비하고, 받은 callback_url을 Table Storage에 저장하는 설계로 했습니다.
이번에 타협한 점 (해커톤 범위)
해커톤이라는 제약 조건 속에서 의도적으로 절충한 부분도 있습니다.
실제 서비스 수준(Production-grade)으로 만든다면 개선하고 싶은 부분들입니다.
인증 및 보안 (Authentication & Security)
- 사용자 인증은
config.py에 하드코딩된 5명의 사용자로 대응 (본래는 Azure AD / Entra ID 연동 필요) - 에러 응답에 스택 트레이스(Stack Trace)를 그대로 반환 (디버깅 효율 우선. 실제 서비스에서는 삭제 필요)
AI 및 워크플로우 (AI & Workflow)
- AI API 재시도(Retry) 로직 없음 (타임아웃 시 즉시 에러 반환)
- Logic Apps의 메일 커넥터 인증이 OAuth2 방식 (개인 Google 계정에 의존. 실제 서비스에서는 SendGrid나 공유 계정 사용 권장)
테스트 (Testing)
- E2E 워크플로우 테스트(pytest)를 위한 절차서는 작성 완료했으나, Azure 환경 접속 설정 후 실시 예정
- 실제 환경에 가까운 프로퍼티 기반 테스트(Property-based testing)는 이번 범위에서 제외
운영 (Operations)
- 승인자 메일 매핑은 Logic Apps의 파라미터에 정적으로 정의 (실제 서비스에서는 DB나 설정 화면을 통해 동적으로 변경 가능하도록 구현 희망)
- 모니터링 알림 없음 (Application Insights를 통해 수시로 확인하는 방식)
향후 발전 구상
정확도 향상
- 과거 신청 데이터를 RAG (Retrieval-Augmented Generation)에 포함시켜 "유사한 안건은 보통 이런 식으로 판단한다"라는 내용을 AI가 참조하도록 함
- AI 심사 프롬프트(Prompt)를 커스텀할 수 있는 설정 화면 추가
- AI 판단의 신뢰 점수(Confidence Score)가 낮을 경우, 인간의 검토를 필수적으로 거치도록 하는 분기 추가
신청 경험 개선
- 채팅 전 "사전 상담" 모드를 통해 "이대로 신청해도 될까?"를 미리 확인할 수 있도록 구현
- 과거 본인의 신청 이력에서 유사한 내용을 가져와 초안(Draft)을 완성해 주는 기능
타 업무로의 수평 전개
- 품의서 외에도 "경비 정산 예외 신청", "채용 승인", "IT 시스템 변경 신청" 등에 동일한 3계층 구조를 적용할 수 있을 것으로 기대함
요약
이번 프로젝트의 가장 큰 배움은 "AI로 모든 것을 해결하려 하지 않는 설계"의 중요성입니다.
- 규칙이 명확한 것 $\rightarrow$ 룰 엔진 (Rule Engine) (100% 정확하며 추적 용이)
- 정성적인 판단 $\rightarrow$ AI (유연하지만 확률적임, 판단 이유를 반드시 가시화해야 함)
- 상태 관리 및 오케스트레이션 (Orchestration) $\rightarrow$ 워크플로우 (Logic Apps)
이 3계층 구조를 갖춤으로써, 자동화 수준을 높게 유지하면서도 인간이 언제든지 "왜 이런 판단을 내렸는가"를 추적할 수 있는 시스템이 되었습니다.
그리고 이번에 만든 3계층의 골격은 그대로 유지한 채, 각 기업 고유의 규칙이나 판단 기준을 끼워 넣는 것만으로도 다양한 업무에 응용할 수 있다고 생각합니다.
금융이라면 신용 심사 규칙, 제조라면 조달 정책, IT 서비스라면 변경 관리 프로세스 등
rules_config.py의 임계값(Threshold)과 AI 프롬프트를 수정하는 것만으로 플로우의 구조를 재사용할 수 있기 때문에, 범용성은 상당히 높을 것이라고 느낍니다.
Discussion

AI 자동 생성 콘텐츠
본 콘텐츠는 Zenn AI의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기