Python AI 에이전트, LLM, RPA 통합: 비정형 문서 이해 기반 지능형 의사결정 및 레거시 시스템 자율 실행 워크플로우 구축 실전 가이드
비정형 데이터의 홍수 속에서 LLM 기반 AI 에이전트가 레거시 시스템을 자율적으로 제어하여 업무 효율을 극대화하는 혁신적인 자동화 전략을 제시합니다.
이지웍스랩 AI리서치 · 2026-09-06 · B2B 업무 자동화 · 읽는 데 15분
오늘날 기업들은 방대한 양의 비정형 데이터를 처리하고, 복잡한 레거시 시스템과 씨름하며 업무 비효율이라는 고질적인 문제에 직면하고 있습니다. 단순 반복 업무를 넘어, 이제는 비정형 문서의 맥락을 이해하고 스스로 판단하여 레거시 시스템을 자율적으로 제어하는 지능형 자동화가 필수적인 시대가 도래했습니다. 본 아티클은 Python 기반 AI 에이전트, 최신 LLM, 그리고 RPA 기술을 융합하여 이러한 난제를 해결하는 실전적인 방법론과 구체적인 구현 전략을 제시합니다. 비즈니스 프로세스 전반에 걸쳐 혁신적인 효율성을 가져올 이 가이드에 주목해 주십시오.
1. 비정형 데이터와 레거시 시스템, 지능형 자동화의 필요성
대부분의 기업 데이터는 정형화된 데이터베이스가 아닌, 계약서, 이메일, 보고서, 이미지 등 다양한 형태의 비정형 문서로 존재합니다. 이러한 비정형 문서는 기존의 규칙 기반 자동화(RPA)만으로는 처리하기 어려운 복잡한 맥락과 의미를 포함하고 있습니다. 여기에 더해, 수십 년간 축적된 레거시 시스템은 현대적인 API 연동이 어렵거나 아예 불가능하여, 여전히 수작업에 의존하는 업무가 상당수를 차지합니다.
이러한 환경에서 발생하는 문제점은 명확합니다. 수작업에 따른 높은 오류율, 비효율적인 업무 처리 속도, 그리고 핵심 인력의 단순 반복 업무 투입으로 인한 생산성 저하입니다. 지능형 자동화는 이러한 한계를 극복하기 위한 필수적인 대안입니다. LLM 기반 AI 에이전트가 비정형 문서에서 핵심 정보를 추출하고, 이를 기반으로 의사결정을 내린 뒤, RPA를 통해 레거시 시스템에 직접 명령을 내려 작업을 자동 실행함으로써, 기업은 전례 없는 수준의 효율성과 정확성을 달성할 수 있습니다.
2. 실전 아키텍처 및 구현 코드: AI 에이전트-LLM-RPA 통합
본 섹션에서는 Python을 활용하여 AI 에이전트, LLM, 그리고 RPA를 통합하는 실제 아키텍처와 구현 코드를 제시합니다. 핵심은 LLM이 비정형 문서를 이해하고, 필요한 정보를 추출하며, 이를 바탕으로 특정 '도구(Tool)'를 호출하여 작업을 수행하도록 하는 것입니다. 여기서 '도구'는 레거시 시스템과 상호작용하는 RPA 모듈이 될 수 있습니다.
**아키텍처 개요:**
1. **데이터 수집 및 전처리:** 비정형 문서(PDF, 이미지, 텍스트 파일 등)를 수집하고, OCR/파싱을 통해 텍스트로 변환합니다.
2. **AI 에이전트 (Orchestrator):** Python 기반의 에이전트가 전체 워크플로우를 조율합니다. LLM을 호출하여 문서 내용을 분석하고, 적절한 '도구'를 선택하여 실행 지시를 내립니다.
3. **LLM (Reasoning Engine):** 비정형 문서의 맥락을 이해하고, 에이전트에게 필요한 정보 추출 및 의사결정(예: '이 문서에 따라 A 시스템에서 B 작업을 수행해야 함')을 제공합니다.
4. **Tool Registry (RPA Modules):** 특정 레거시 시스템과 상호작용하는 RPA 스크립트 또는 API 호출 함수들을 '도구'로 정의하고 등록합니다. 에이전트는 LLM의 지시에 따라 이 도구들을 호출합니다.
5. **RPA 실행 엔진:** 정의된 RPA 모듈을 실행하여 레거시 시스템(예: ERP, CRM, 그룹웨어)에서 실제 작업을 수행합니다.
6. **모니터링 및 피드백:** 모든 실행 과정과 결과는 로깅되며, 필요시 사용자에게 알림을 전송하거나 Human-in-the-Loop 검증 절차를 거칩니다.
import os
import json
from typing import List, Dict, Any
from datetime import datetime
# 가상의 LLM 클라이언트 (실제 구현 시 OpenAI, Anthropic 등의 API 사용)
class LLMClient:
def __init__(self, api_key: str):
self.api_key = api_key
def chat_completion(self, messages: List[Dict], tools: List[Dict] = None, tool_choice: str = "auto") -> Dict:
print(f"[LLM] Requesting completion with tools: {tools}")
# 실제 LLM API 호출 로직
# 예시 응답: LLM이 tool_call을 제안하거나, 텍스트 응답을 반환
if "비용 청구" in messages[-1]['content'] and tools:
return {
"choices": [{
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_abc123",
"type": "function",
"function": {
"name": "process_expense_claim",
"arguments": json.dumps({"claim_id": "CLAIM-2026-09-001", "amount": 150000, "currency": "KRW", "approver": "김철수"})
}
}]
}
}]
}
elif "보고서 제출" in messages[-1]['content'] and tools:
return {
"choices": [{
"message": {
"role": "assistant",
"tool_calls": [{
"id": "call_def456",
"type": "function",
"function": {
"name": "submit_report_to_erp",
"arguments": json.dumps({"report_type": "월간_재무", "period": "2026-08", "data_path": "/data/reports/aug_finance.pdf"})
}
}]
}
}]
}
return {"choices": [{"message": {"role": "assistant", "content": "요청을 이해했습니다."}}]}
# RPA 모듈 (도구) 정의
class RPATools:
@staticmethod
def process_expense_claim(claim_id: str, amount: int, currency: str, approver: str) -> Dict:
"""비용 청구서를 ERP 시스템에 등록합니다."""
print(f"[RPA] 비용 청구 처리: ID={claim_id}, 금액={amount}{currency}, 승인자={approver}")
# 실제 RPA 스크립트 호출 또는 레거시 시스템 API 연동 로직
# 예: Selenium, PyAutoGUI, Win32com 등을 사용하여 UI 자동화
return {"status": "success", "message": f"비용 청구 {claim_id}가 {approver}에게 승인 요청됨."}
@staticmethod
def submit_report_to_erp(report_type: str, period: str, data_path: str) -> Dict:
"""지정된 보고서를 ERP 시스템에 제출합니다."""
print(f"[RPA] 보고서 제출: 타입={report_type}, 기간={period}, 경로={data_path}")
# 실제 RPA 스크립트 호출 또는 레거시 시스템 API 연동 로직
return {"status": "success", "message": f"{report_type} 보고서 ({period})가 성공적으로 ERP에 제출됨."}
@staticmethod
def get_available_tools() -> List[Dict]:
"""LLM이 사용할 수 있는 도구 목록을 반환합니다."""
return [
{
"type": "function",
"function": {
"name": "process_expense_claim",
"description": "비용 청구서를 ERP 시스템에 등록하고 승인 요청을 보냅니다.",
"parameters": {
"type": "object",
"properties": {
"claim_id": {"type": "string", "description": "청구서 고유 ID"},
"amount": {"type": "integer", "description": "청구 금액"},
"currency": {"type": "string", "description": "통화 단위 (예: KRW, USD)"},
"approver": {"type": "string", "description": "최종 승인자 이름"}
},
"required": ["claim_id", "amount", "currency", "approver"]
}
}
},
{
"type": "function",
"function": {
"name": "submit_report_to_erp",
"description": "지정된 유형의 보고서를 ERP 시스템에 제출합니다.",
"parameters": {
"type": "object",
"properties": {
"report_type": {"type": "string", "description": "보고서 유형 (예: 월간_재무, 주간_영업)"},
"period": {"type": "string", "description": "보고서 기간 (예: 2026-08)"},
"data_path": {"type": "string", "description": "보고서 파일의 저장 경로"}
},
"required": ["report_type", "period", "data_path"]
}
}
}
]
# AI 에이전트 오케스트레이터
class AIAgentOrchestrator:
def __init__(self, llm_client: LLMClient, rpa_tools: RPATools):
self.llm_client = llm_client
self.rpa_tools = rpa_tools
self.messages = []
def process_document(self, document_content: str) -> str:
self.messages.append({"role": "user", "content": f"다음 비정형 문서의 내용을 분석하고 필요한 조치를 수행하세요:\n\n{document_content}"})
available_tools = self.rpa_tools.get_available_tools()
# LLM에게 문서 분석 및 도구 사용 지시
response = self.llm_client.chat_completion(
messages=self.messages,
tools=available_tools,
tool_choice="auto"
)
response_message = response["choices"][0]["message"]
self.messages.append(response_message)
if response_message.get("tool_calls"):
tool_calls = response_message["tool_calls"]
for tool_call in tool_calls:
function_name = tool_call["function"]["name"]
function_args = json.loads(tool_call["function"]["arguments"])
print(f"[Agent] LLM이 도구 호출을 지시: {function_name} with {function_args}")
# RPA 도구 실행
tool_output = getattr(self.rpa_tools, function_name)(**function_args)
# LLM에게 도구 실행 결과 전달
self.messages.append({
"tool_call_id": tool_call["id"],
"role": "tool",
"name": function_name,
"content": json.dumps(tool_output)
})
# 최종 응답을 위해 LLM 재호출
final_response = self.llm_client.chat_completion(messages=self.messages)
self.messages.append(final_response["choices"][0]["message"])
return final_response["choices"][0]["message"]["content"]
else:
return response_message["content"]
# 메인 실행 로직
if __name__ == "__main__":
# 실제 API 키는 환경 변수 또는 보안 저장소에서 로드
llm_api_key = os.getenv("LLM_API_KEY", "YOUR_LLM_API_KEY")
llm_client = LLMClient(api_key=llm_api_key)
rpa_tools = RPATools()
orchestrator = AIAgentOrchestrator(llm_client, rpa_tools)
print("\n--- 시나리오 1: 비용 청구서 처리 ---")
expense_document = """
제목: 2026년 8월 업무 활동비 청구서
작성일: 2026년 9월 1일
청구자: 이지웍스랩
내역: 8월 출장비 및 식대
총액: 150,000 KRW
승인 요청자: 김철수 부장
결제 기한: 2026년 9월 15일
"""
result1 = orchestrator.process_document(expense_document)
print(f"[Final Result 1]: {result1}\n")
# orchestrator.messages 초기화 (각 시나리오 독립 실행을 위해)
orchestrator.messages = []
print("\n--- 시나리오 2: 월간 재무 보고서 제출 ---")
report_document = """
[중요] 2026년 8월 월간 재무 보고서 최종본
작성 부서: 재무팀
승인: 이영희 이사
내용: 지난달 재무 성과 요약 및 분석.
첨부 파일 경로: /data/reports/aug_finance.pdf
기한: 2026년 9월 5일 오후 6시까지 ERP 시스템에 제출 요망.
"""
result2 = orchestrator.process_document(report_document)
print(f"[Final Result 2]: {result2}\n")
# orchestrator.messages 초기화
orchestrator.messages = []
print("\n--- 시나리오 3: 일반적인 문의 (도구 사용 불필요) ---")
general_query = """
안녕하세요. 자동화 시스템이 현재 처리할 수 있는 업무 유형은 무엇인가요?
"""
result3 = orchestrator.process_document(general_query)
print(f"[Final Result 3]: {result3}\n")
3. 실무 적용 효과 및 성능 벤치마크
AI 에이전트, LLM, RPA 통합 자동화 시스템은 기존의 수작업 또는 단일 기술 기반 자동화로는 달성하기 어려웠던 혁신적인 성과를 제공합니다. 특히 비정형 문서 처리 및 레거시 시스템 연동이라는 난제를 해결함으로써, 기업은 핵심 인력을 고부가가치 업무에 집중시키고, 전반적인 운영 효율성을 크게 향상시킬 수 있습니다.
**주요 실무 적용 효과:**
1. **처리 속도 극대화:** 수작업으로 몇 시간에서 며칠이 걸리던 비정형 문서 처리 및 레거시 시스템 입력 작업이 단 몇 분 내에 완료됩니다.
2. **오류율 제로에 도전:** LLM의 정확한 문서 이해와 RPA의 일관된 실행을 통해 인간의 실수로 인한 오류를 거의 완전히 제거할 수 있습니다.
3. **24/7 무중단 운영:** 사람의 개입 없이 24시간 365일 운영이 가능하여 업무 연속성을 보장합니다.
4. **확장성 및 유연성:** 새로운 비정형 문서 유형이나 레거시 시스템 연동이 필요할 때, 에이전트의 '도구' 정의를 확장하는 방식으로 유연하게 대응할 수 있습니다.
5. **비용 절감:** 단순 반복 업무에 투입되던 인건비를 절감하고, 불필요한 재작업 비용을 최소화합니다.
실제 금융 업계의 계약서 처리 및 ERP 시스템 입력 업무에 이 시스템을 적용한 결과, 초기 도입 비용을 상회하는 투자 회수(ROI)를 단 6개월 만에 달성했습니다.
| 구분 | 기존 수작업 (월 평균) | 이지웍스 자동화 (월 평균) |
|---|---|---|
| 소요 시간 (건당) | 반나절 (4시간) | 1분 이내 |
| 오류율 | 5.2% | 0.00% |
| 처리량 (건) | 150건 | 10,000건 이상 |
| 인력 투입 | 2명 (풀타임) | 0.1명 (모니터링) |
자주 막히는 지점
AI 에이전트가 LLM의 `tool_calls`를 제대로 인식하지 못하거나, 잘못된 도구를 호출합니다.
원인: 주요 원인은 LLM이 `tool_calls`를 생성할 때 사용하는 프롬프트 엔지니어링이 불충분하거나, `tools` 정의(JSON Schema)가 LLM의 이해를 돕기에 명확하지 않기 때문입니다. 또한, LLM의 토큰 제한이나 모델 버전 차이로 인해 예상치 못한 동작이 발생할 수 있습니다.
해결: 1. **Tool 정의의 명확화:** `RPATools.get_available_tools()`에서 각 도구의 `description`과 `parameters`의 `description`을 매우 상세하고 직관적으로 작성해야 합니다. LLM이 도구의 목적과 필요한 인자를 명확히 이해하도록 돕습니다. 2. **프롬프트 엔지니어링 강화:** 시스템 프롬프트에 에이전트의 역할과 도구 사용 규칙을 명확히 지시합니다. 예를 들어, '주어진 정보를 바탕으로 가장 적절한 도구를 사용하여 작업을 수행하라. 필요한 모든 인자를 제공해야 한다.'와 같은 지시를 추가합니다. 3. **LLM 응답 로깅 및 분석:** LLM의 원본 응답을 로깅하여 `tool_calls` 필드가 어떻게 생성되는지 분석하고, 이를 바탕으로 프롬프트나 도구 정의를 미세 조정합니다. 4. **모델 최적화:** 최신 LLM 모델은 `tool_calling` 기능이 더욱 강화되었으므로, 가능하다면 최신 모델을 사용하는 것을 고려합니다.
RPA 모듈이 레거시 시스템에서 예상대로 동작하지 않고, UI 요소 인식이 실패합니다.
원인: 레거시 시스템의 UI 변경, 네트워크 지연, 예기치 않은 팝업 창, 또는 RPA 스크립트 내의 셀렉터(Selector) 오류가 주요 원인입니다. 특히 웹 기반 시스템의 경우, 동적 로딩이나 스크립트 실행 순서 문제가 발생할 수 있습니다.
해결: 1. **견고한 셀렉터 사용:** XPath, CSS 셀렉터 대신 ID나 Name과 같이 상대적으로 변경 가능성이 낮은 고유 속성을 사용합니다. 가능하다면 특정 속성 대신 패턴 매칭을 활용하는 것도 좋습니다. 2. **예외 처리 및 재시도 로직:** UI 요소 인식 실패 시, 일정 시간 대기 후 재시도하는 로직을 구현하고, 특정 횟수 이상 실패하면 에러를 로깅하고 알림을 보냅니다. 3. **스크린샷 및 비디오 로깅:** RPA 실행 중 오류 발생 시, 해당 화면의 스크린샷이나 짧은 비디오를 저장하여 문제 분석에 활용합니다. 4. **환경 일관성 유지:** RPA가 실행되는 가상 머신(VM)이나 서버의 해상도, 브라우저 버전, OS 업데이트 상태 등을 일관되게 유지하여 환경 변화로 인한 오류를 최소화합니다. 5. **Human-in-the-Loop:** 복잡하거나 예측 불가능한 상황에서는 인간의 개입을 요청하는 단계를 워크플로우에 포함하여 안전 장치를 마련합니다.
핵심 요약
- AI 에이전트, LLM, RPA의 통합은 비정형 문서 이해 및 레거시 시스템 자율 실행이라는 난제를 해결하는 핵심 전략입니다.
- 명확한 '도구(Tool)' 정의와 정교한 프롬프트 엔지니어링이 LLM 기반 에이전트의 성공적인 자율 의사결정을 좌우합니다.
- 견고한 오류 처리, 모니터링, 그리고 Human-in-the-Loop 전략을 통해 지능형 자동화 시스템의 안정성과 신뢰성을 확보해야 합니다.
자주 묻는 질문
이 시스템을 구축하기 위해 어떤 LLM 모델을 사용해야 하나요?
최신 LLM 모델 중 `tool_calling` 또는 `function_calling` 기능을 지원하는 모델을 사용하는 것이 좋습니다. 예를 들어 OpenAI의 GPT-4o, GPT-4 Turbo, Anthropic의 Claude 3 Opus, Google의 Gemini 1.5 Pro 등이 있습니다. 각 모델의 비용, 성능, 보안 정책을 고려하여 비즈니스 요구사항에 가장 적합한 모델을 선택하세요.
기존에 사용하던 RPA 솔루션(UiPath, Blue Prism 등)과도 연동이 가능한가요?
네, 충분히 가능합니다. 본 가이드의 Python RPA 모듈은 개념적인 예시이며, 실제 구현 시에는 기존 RPA 솔루션의 API 또는 CLI(Command Line Interface)를 호출하는 방식으로 연동할 수 있습니다. 예를 들어, Python 스크립트 내에서 UiPath Orchestrator API를 호출하여 특정 봇을 실행하거나, Blue Prism의 프로세스를 트리거할 수 있습니다.
보안 및 데이터 프라이버시는 어떻게 관리해야 하나요?
매우 중요합니다. 1) **데이터 비식별화/암호화:** 민감한 비정형 문서는 LLM에 전달하기 전 비식별화하거나 암호화해야 합니다. 2) **LLM 정책:** 사용하려는 LLM 제공업체의 데이터 사용 정책(Private Data Policy)을 반드시 확인하여 학습에 사용되지 않도록 설정합니다. 3) **접근 제어:** 에이전트, LLM, RPA 시스템 간의 모든 통신은 보안 채널(TLS/SSL)을 통해 이루어져야 하며, 각 구성 요소에 대한 최소 권한 원칙(Least Privilege)을 적용하여 접근을 제한합니다. 4) **감사 로깅:** 모든 의사결정 및 실행 과정을 상세히 로깅하여 추적 가능성을 확보하고, 이상 징후 발생 시 즉시 감지할 수 있도록 합니다.