1. 서론: 대한민국 행정 현장의 4대 오피스 파편화와 AI 통합 컨트롤러의 필연성
글로벌 시장의 대다수 오피스 자동화 솔루션은 마이크로소프트의 Office 365 생태계(Word, Excel, PowerPoint)에 국한되어 개발됩니다. 하지만 대한민국 초·중·고교의 교육행정정보시스템(NEIS), 공공기관 전자결재망, 그리고 국방부 행정 전산망의 핵심 중추는 여전히 독자적인 규격을 가진 한글(HWP 2024 / 아래아한글)이 확고하게 장악하고 있습니다.
실무자들은 하루에도 수십 번씩 "한글 공문서의 학생 명단을 엑셀 통계표로 추출하고, 이를 기반으로 워드 기안문을 작성한 뒤 파워포인트 교안으로 변환"하는 복잡다단한 크로스-오피스(Cross-Office) 워크플로우를 수작업으로 수행합니다.
ZeliOffice는 이 파편화된 생산성 도구들을 단 하나의 통일된 대화형 인터페이스 아래 통합하기 위해,
70여 종에 달하는 Win32 OLE/COM 자동화 API를 정밀하게 분기·제어하는 통합 AI 커맨드 라우터(Command Router)와
자가 치유형 상태 머신(Resilient State Machine)을 구축했습니다. 본 백서에서는 ZeliOfficeWindow.xaml.cs에
구현된 핵심 아키텍처를 심층 분석합니다.
2. 다형적 오피스 엔트리: OfficeAppEntry 추상화와 단일 활성 타깃(_activeApp) 디스패치
각기 다른 프로세스 생명주기와 COM 인터페이스(`HwpObject.HwpObject`, `Excel.Application`, `Word.Application`, `PowerPoint.Application`)를 가진
독립 소프트웨어들을 다형적으로 관리하기 위해, ZeliOffice는 OfficeAppEntry 데이터 계약을 정의했습니다.
public class OfficeAppEntry : INotifyPropertyChanged
{
public string Id { get; set; } // "hwp", "excel", "word", "powerpoint", "outlook"
public string DisplayName { get; set; } // "한글 2024", "Excel", "Word", ...
public string ProgId { get; set; } // "HWPFrame.HwpObject", "Excel.Application", ...
public bool IsInstalled { get; set; }
private bool _isConnected;
public bool IsConnected { get => _isConnected; set { _isConnected = value; OnChanged(); } }
// Win32 COM 인터롭 객체에 대한 런타임 동적 바인딩 포인트
public dynamic ComInstance { get; set; }
// UI 카드 상태 반응형 브러시 및 이벤트...
}
메인 윈도우는 ObservableCollection<OfficeAppEntry> _apps 컬렉션을 유지하며,
사용자가 선택하거나 백그라운드 윈도우 포커스 추적기(`_focusTimer`)가 감지한 전경 윈도우의 HWND를 기반으로
_activeApp 포인터를 0.001초 만에 원자적으로 전환합니다.
이를 통해 모든 후속 AI 명령어는 단 하나의 활성 오피스 컨텍스트로 안전하게 캡슐화되어 전달됩니다.
3. 지능형 4대 분류 상태 머신: _docChangingActions, _readActions, _writeActions 거버넌스
LLM(AWS Bedrock Claude)이 생성한 JSON 배치 명령 목록은 무작위 순서로 실행되지 않습니다. 명령어가 애플리케이션의 메모리 상태, 문서 생명주기, 그리고 후속 생성 추론에 미치는 영향도에 따라 4대 전용 해시셋(HashSet) 기반 상태 머신 엔진이 실행 파이프라인을 중재합니다.
| 분류 범주 (Category) | 대표 액션 목록 (Action Sets) | 상태 머신 제어 거버넌스 (Governance Rule) |
|---|---|---|
| 문서 라이프사이클 변이 (_docChangingActions) |
excel_new_workbook, word_new_document, hwp_new_document, ppt_new_presentation, *_open_file, *_close, excel_add_sheet |
실행 후 _needsDocListRefresh = true 플래그를 세팅하여, 배치 완료 즉시 탭 목록 및 활성 문서 버퍼 캐시를 원자적으로 일괄 갱신. |
| 문맥 인지 읽기 (_readActions) |
excel_read_range, excel_read_chunk, word_read_text, hwp_read_text, *_get_page_count |
COM 버퍼에서 읽어들인 텍스트를 SafeReadContent로 살균한 뒤, _conversationHistory에 시스템 컨텍스트 메시지로 자동 역주입하여 연속 멀티턴 추론 접지(Grounding) 달성. |
| 데이터 및 서식 변이 (_writeActions) |
excel_write_range, excel_set_formula, word_write_text, hwp_write_text, hwp_table_merge_cell |
인젝션 방어기(Sanitizer) 통과 강제 및 DDE 수식 탈출 검증. 2차원 벌크 메모리 주입을 통한 RPC 트래픽 50배 감축. |
| 시트 및 구조 생성 (_sheetCreationActions) |
excel_add_sheet, excel_copy_sheet |
워크북 내부 컬렉션 구조 변동을 감지하고 인덱스 바운더리 검사를 강제하여 널 참조(NullReference) 예외 차단. |
private static readonly HashSet _readActions = new(StringComparer.OrdinalIgnoreCase)
{
"excel_read_range", "excel_read_chunk", "excel_inspect_cells",
"excel_find_text", "excel_get_used_range", "excel_list_sheets",
"word_read_text", "hwp_read_text",
"word_get_page_count", "word_get_document_name", "hwp_get_page_count"
};
private static readonly HashSet _docChangingActions = new(StringComparer.OrdinalIgnoreCase)
{
"excel_new_workbook", "word_new_document", "word_open_file", "word_close",
"hwp_new_document", "hwp_open_file", "ppt_new_presentation", "ppt_open_file",
"ppt_close", "excel_add_sheet", "excel_rename_sheet"
};
4. COM 크래시와 프리징의 저승사자: RPC_E_CALL_REJECTED와 지수적 백오프(Exponential Backoff) 복구 머신
윈도우 데스크톱 개발에서 가장 악명 높은 난제는 COM 서버와 클라이언트 간의 메시지 큐 충돌입니다. 엑셀이나 한글이 내부 연산(자동 저장, 화면 렌더링, 서식 재계산)을 수행하는 찰나에 C# 애플리케이션이 COM 프로퍼티에 접근하면 운영체제는 가차 없이 치명적인 HRESULT 에러 코드를 던집니다:
0x8001010A (RPC_E_SERVERCALL_RETRYLATER): 서버가 바쁜 상태이므로 나중에 다시 호출해야 함.0x80010001 (RPC_E_CALL_REJECTED): 대상 애플리케이션이 메시지 큐를 일시적으로 거부함.
대다수의 상용 매크로 프로그램은 이 시점에서 크래시를 일으키며 뻗어버립니다.
ZeliOffice는 ExecuteAiCommand에 3단계 지수적 백오프(Exponential Backoff) 자가 치유 루프를 구축하여,
단 한 번의 요청 실패도 없이 우아하게 살아납니다.
private async Task ExecuteAiCommand(JsonElement cmd)
{
if (_activeApp == null || !_activeApp.IsConnected) return;
var action = cmd.GetProperty("action").GetString();
var app = _activeApp;
const int maxRetries = 3;
const int retryDelayMs = 300;
for (int attempt = 1; attempt <= maxRetries; attempt++)
{
try
{
await Task.Run(() =>
{
// Excel 전용: 셀 편집 모드 감지 및 자동 가드
if (app.Id == "excel" && !ExcelEnsureReady(app))
{
throw new InvalidOperationException("Excel이 셀 편집 모드입니다.");
}
ExecuteAiCommandCore(cmd, app, action);
});
if (IsDocListChangingAction(action))
_needsDocListRefresh = true;
return; // ✅ 성공 시 루프 즉시 탈출
}
catch (COMException cex) when (
(uint)cex.ErrorCode == 0x8001010A || // RPC_E_SERVERCALL_RETRYLATER
(uint)cex.ErrorCode == 0x80010001) // RPC_E_CALL_REJECTED
{
if (attempt < maxRetries)
{
// 300ms, 600ms 점진적 대기를 통해 대상 프로세스의 메시지 큐 비우기 대기
AppendLog($"[COM] 재시도 {attempt}/{maxRetries}: {action} (Excel/HWP 처리 중 지연 복구)");
await Task.Delay(retryDelayMs * attempt);
}
else
{
AddChatBubble($"[!] '{action}' 명령 실패: 대상 오피스가 응답하지 않습니다. 다시 시도해주세요.",
isUser: false, isSystem: true);
}
}
catch (InvalidOperationException ioe) when (ioe.Message.Contains("편집 모드"))
{
AddChatBubble("[!] Excel이 셀 편집 모드입니다. Enter를 눌러 편집을 완료한 후 다시 시도해주세요.",
isUser: false, isSystem: true);
return;
}
// RuntimeBinderException 및 범용 예외 안전 격리...
}
}
5. 인간과의 상호작용 충돌 방어: ExcelEnsureReady 셀 편집 모드 실시간 감지 및 경고
AI 에이전트와 인간 사용자가 공존하는 데스크톱 환경에서 자주 일어나는 상황이 있습니다. 사용자가 엑셀 시트에서 특정 셀을 더블 클릭하거나 수식 입력줄(Formula Bar)에 커서를 둔 상태(이른바 Cell Edit Mode)에서는 마이크로소프트 엑셀 프로세스 자체가 모달 락(Modal Lock) 상태로 들어가 외부 COM 요청을 전면 차단합니다.
이때 무리하게 데이터를 주입하면 엑셀 프로세스가 좀비 상태가 되어 강제 종료해야만 합니다.
ZeliOffice는 명령 실행 직전 ExcelEnsureReady(app)를 선제적으로 프로빙하여,
프로세스 락 상태를 0ms 만에 감지하고 사용자에게 "Enter 키를 눌러 입력을 확정해 달라"는 안내 가이드를 표시함으로써
프로세스 파괴를 원천 방어합니다.
소프트웨어 자동화에서 가장 위험한 것은 사용자 액션과 AI 백그라운드 액션 간의 레이스 컨디션(Race Condition)입니다. ZeliOffice는 인간의 포커스를 존중하면서도 시스템 예외가 발생하기 전에 선제적으로 사용자 협력을 유도하는 Graceful Guard 정책을 표준화했습니다.
6. 스레드 데드락 0초 차단: SemaphoreSlim(1,1) 직렬화 게이트와 워치독 프로브 간 무간섭 공존
ZeliOffice의 백그라운드에는 오피스 프로세스가 살아있는지 감시하는 상시 워치독 타이머(`_watchdogTimer`)와 어떤 오피스 창이 활성화되었는지 추적하는 포커스 타이머(`_focusTimer`)가 500ms 간격으로 실행되고 있습니다.
만약 AI가 100행짜리 대규모 엑셀 표를 작성(`excel_write_range`)하고 있는 도중에,
백그라운드 타이머가 프로세스 생존 여부를 확인하기 위해 xl.Workbooks.Count 같은 COM 프로퍼티를 호출한다면
단일 스레드 아파트먼트(STA) 내부에서 치명적인 교착 상태(Deadlock)나 호출 거부 에러가 폭발합니다.
ZeliOffice는 이를 해결하기 위해 _comGate = new SemaphoreSlim(1, 1) 비동기 직렬화 게이트웨이를 도입했습니다:
// ── ZeliOfficeWindow.xaml.cs ──
private readonly System.Threading.SemaphoreSlim _comGate = new(1, 1);
// [1] AI 명령어 배치 실행 또는 수동 버튼 액션 시: 완전한 소유권 획득
await _comGate.WaitAsync();
try
{
foreach (var cmd in commandBatch)
{
await ExecuteAiCommand(cmd);
}
}
finally
{
_comGate.Release();
}
// [2] 백그라운드 워치독 및 포커스 감지 타이머 시: 대기 없이 논블로킹 패스
if (!_comGate.Wait(0))
{
// 현재 대용량 COM 작업이 실행 중이므로 이번 프로브는 안전하게 스킵한다!
return;
}
try
{
ProbeOfficeProcessesStatus();
}
finally
{
_comGate.Release();
}
_comGate.Wait(0) 패턴을 통해, 백그라운드 감시 루틴은
AI가 문서를 조작하는 동안 0.0001초의 블로킹이나 경합 유발 없이 조용히 패스하며,
명령어 실행이 완료된 후 다음 주기에서 자연스럽게 상태를 확인합니다.
7. Grounding 피드백 루프: SafeReadContent와 Bedrock 대화 히스토리 원자적 동기화
사용자가 "현재 엑셀 3행부터 10행까지의 학생 점수를 읽어서, 평균 80점 미만인 학생만 한글 표로 정리해 줘"라고 지시했을 때, AI는 먼저 읽기 명령(`excel_read_range`)을 수행하고 그 결과를 알아야만 후속 한글 작성 명령(`hwp_insert_table`)을 구성할 수 있습니다.
ZeliOffice의 라우터는 _readActions에 속하는 명령이 완료되는 즉시,
추출된 본문을 SafeReadContent 함수로 살균한 뒤
클로드 대화 히스토리(`_conversationHistory`)에 role: user 형식의 시스템 피드백 메시지로 직접 주입합니다.
case "excel_read_range":
var exRange = cmd.GetProperty("range").GetString();
var exContent = ExcelReadRange(app, exRange);
AddChatBubble($"[OK] {exRange} 범위를 읽었습니다.", isUser: false, isSystem: true);
// AI 모델에게 읽은 실제 데이터를 Grounding Context로 제공
_conversationHistory.Add(new BedrockMessage
{
Role = "user",
Content = SafeReadContent($"[시스템: Excel {exRange} 내용]", exContent)
});
break;
이 피드백 루프 덕분에 AI 에이전트는 환각(Hallucination) 없이 실제 사용자의 시트와 문서에 적힌 최신 데이터를 두 눈으로 확인하듯 인지하며 다음 단계의 오피스 조작을 빈틈없이 이어나갈 수 있습니다.
8. 결론: 단 하나의 오피스 튕김도 없는 무결점 교무·국방 AI 오토메이션의 미래
AI 기술이 연구실의 데모를 넘어 실제 업무 현장의 신뢰를 얻기 위해 가장 필요한 것은 화려한 수식어가 아니라 "단 한 번도 죽지 않고 끝까지 돌아가는 안정성"입니다.
특히 수십 년간 윈도우 OS의 레거시와 함께해 온 Win32 COM 아키텍처 위에서 최첨단 생성형 AI 모델을 접목하는 작업은 보이지 않는 타이밍 이슈와 프로세스 충돌과의 치열한 전쟁이었습니다.
ZeliOffice의 다형적 커맨드 라우터, 상태 머신 기반 생명주기 관리, 지수적 백오프 복구 머신, 그리고 SemaphoreSlim 동시성 거버넌스는 대한민국 50만 초·중·고 교원들과 국방부 실무자들이 매일 마주하는 오피스 문서 작업의 피로를 안전하고 완벽하게 덜어주는 기술적 초석입니다.