텍스트 업무는 왜 자동화 효과가 큰가
많은 사무 업무는 결국 텍스트를 다루는 일이다. 고객 문의를 읽고 유형을 나눈다. 회의 내용을 정리해 할 일을 뽑는다. 계약서에서 위험해 보이는 문장을 찾는다. 숫자 데이터를 보고 보고서 문장을 작성한다. 사람이 매번 처음부터 읽고 판단하고 다시 쓰기 때문에 시간이 많이 걸리고, 담당자마다 결과 품질도 달라진다.
LLM은 이런 업무에서 강점을 가진다. LLM은 대규모 언어 모델을 뜻하며, 문맥을 읽고 요약하거나 분류하고 초안을 작성하는 데 적합하다. 다만 LLM은 계산기나 데이터베이스처럼 항상 같은 답을 보장하는 도구가 아니다. 그럴듯하지만 틀린 말을 만들 수도 있고, 입력에 없는 내용을 추측할 수도 있다. 그래서 LLM 자동화는 "AI가 알아서 처리한다"가 아니라 "AI가 초안을 만들고, 코드는 형식을 검증하고, 사람은 중요한 결정을 승인한다"는 구조로 설계해야 한다.
이 장에서는 생성형 AI와 파이썬을 연결해 문서와 텍스트 업무를 자동화하는 흐름을 다룬다. 핵심은 네 가지다. 프롬프트를 업무 지시서처럼 작성한다. 출력 형식을 고정한다. JSON과 스키마 검증으로 시스템에 연결한다. 마지막으로 민감정보 보호와 사람 승인 단계를 반드시 넣는다.
AI 생성 이미지
프롬프트는 업무 지시서다
프롬프트는 AI에게 전달하는 지시문이다. 초보자는 보통 "이 문의를 분류해 줘", "이 회의록을 요약해 줘"처럼 짧게 요청한다. 테스트할 때는 괜찮지만 자동화에는 부족하다. 업무 자동화에서는 결과가 매번 비슷한 구조로 나와야 하고, 다음 단계의 파이썬 코드가 그 결과를 읽을 수 있어야 한다.
좋은 프롬프트에는 보통 다음 요소가 들어간다.
역할: AI가 어떤 관점으로 일할지 정한다.
작업: 무엇을 해야 하는지 명확히 쓴다.
기준: 분류 기준, 요약 기준, 금지 사항을 적는다.
입력 데이터: 처리할 실제 텍스트를 구분해 넣는다.
출력 형식: JSON, 표, 목록 등 원하는 형식을 고정한다.
모르면 모른다고 하기: 입력에 없는 사실을 만들지 않도록 제한한다.
예를 들어 고객 문의 분류 프롬프트는 다음처럼 작성할 수 있다.
역할: 너는 고객지원팀의 1차 분류 담당자다.
작업: 고객 문의를 읽고 아래 범주 중 하나로 분류한다.
범주: 결제, 배송, 환불, 기술지원, 기타
기준:
- 고객이 환불 의사를 명확히 표현하면 환불로 분류한다.
- 오류 메시지, 로그인 실패, 기능 장애는 기술지원으로 분류한다.
- 확신이 낮으면 기타로 분류하고 needs_review를 true로 표시한다.
제한:
- 입력에 없는 사실을 추측하지 않는다.
- 고객에게 보낼 답변은 작성하지 않는다.
출력:
JSON만 출력한다.여기서 중요한 점은 "JSON만 출력한다"는 조건이다. 자동화 시스템은 자연스러운 문장보다 구조화된 값이 필요하다. category, urgency, summary, needs_review 같은 필드가 있어야 이후 티켓 생성, 담당자 배정, 알림 발송으로 연결할 수 있다.
고객 문의 분류 자동화
고객 문의 분류는 LLM 자동화를 시작하기 좋은 업무다. 입력은 비정형 텍스트이지만 출력은 정해진 범주다. 또 위험도가 높은 결정을 바로 내리지 않고, 사람이 검토할 항목을 따로 보낼 수 있다.
기본 흐름은 다음과 같다.
이메일, 상담 시스템, 설문 폼에서 문의 텍스트를 가져온다.
이름, 전화번호, 이메일 같은 민감정보를 마스킹한다.
LLM에 분류를 요청한다.
JSON 응답을 파싱한다.
스키마 검증을 통과한 결과만 업무 시스템에 저장한다.
needs_review가 true이면 담당자에게 검토 요청을 보낸다.
파이썬 코드 구조는 다음처럼 잡을 수 있다.
import json
import re
from typing import Literal
from pydantic import BaseModel, Field, ValidationError
class InquiryResult(BaseModel):
category: Literal["결제", "배송", "환불", "기술지원", "기타"]
urgency: Literal["낮음", "보통", "높음"]
summary: str = Field(max_length=300)
confidence: float = Field(ge=0, le=1)
needs_review: bool
def mask_sensitive(text: str) -> str:
text = re.sub(r"[w.-]+@[w.-]+", "[EMAIL]", text)
text = re.sub(r"bd{2,3}-d{3,4}-d{4}b", "[PHONE]", text)
text = re.sub(r"bd{6}-d{7}b", "[ID_NUMBER]", text)
return text
def build_prompt(inquiry_text: str) -> tuple[str, str]:
system_prompt = "너는 고객지원팀의 문의 분류 담당자다. 반드시 JSON만 출력한다."
user_prompt = f"""
다음 고객 문의를 분류하라.
범주: 결제, 배송, 환불, 기술지원, 기타
긴급도: 낮음, 보통, 높음
규칙:
- 확신이 낮으면 needs_review를 true로 한다.
- 입력에 없는 내용을 만들지 않는다.
- summary는 300자 이내로 작성한다.
출력 JSON 형식:
{{
"category": "결제|배송|환불|기술지원|기타",
"urgency": "낮음|보통|높음",
"summary": "문의 요약",
"confidence": 0.0,
"needs_review": true
}}
문의:
{inquiry_text}
"""
return system_prompt, user_prompt
def classify_inquiry(raw_text: str) -> InquiryResult:
safe_text = mask_sensitive(raw_text)
system_prompt, user_prompt = build_prompt(safe_text)
# 실제 구현에서는 사용하는 LLM 서비스의 SDK 호출로 교체한다.
response_text = call_llm(system_prompt, user_prompt)
data = json.loads(response_text)
return InquiryResult.model_validate(data)이 코드에서 중요한 부분은 LLM 호출 자체가 아니다. 민감정보를 먼저 가리고, 출력 형식을 고정하고, pydantic으로 결과를 검증하는 구조가 중요하다. AI가 환불요청처럼 허용되지 않은 범주를 출력하면 검증에서 실패한다. 그러면 자동으로 처리하지 말고 needs_review 상태로 보내야 한다.
회의록 요약은 결론보다 할 일을 뽑아야 한다
회의록 자동화에서 흔한 실수는 긴 대화를 짧게 줄이는 데만 집중하는 것이다. 실무에서 필요한 것은 단순 요약보다 다음 행동이다. 누가, 무엇을, 언제까지 해야 하는지가 정리되어야 한다.
회의록 요약 프롬프트는 다음 항목을 요구하는 것이 좋다.
회의 목적
주요 결정 사항
담당자별 액션 아이템
마감일
남은 쟁점
다음 회의에서 확인할 내용
출력은 JSON이나 마크다운 표로 고정한다. 예를 들어 자동화 흐름은 이렇다. 화상회의 녹취록을 텍스트로 저장한다. LLM이 회의 내용을 요약하고 액션 아이템을 추출한다. 파이썬은 액션 아이템을 협업 도구의 태스크로 등록한다. 등록 전에는 회의 주최자가 검토한다.
class ActionItem(BaseModel):
owner: str
task: str
due_date: str | None
evidence: str
class MeetingSummary(BaseModel):
summary: str
decisions: list[str]
action_items: list[ActionItem]
open_questions: list[str]
def summarize_meeting(transcript: str) -> MeetingSummary:
prompt = f"""
다음 회의 녹취록을 업무용 회의록으로 정리하라.
규칙:
- 결정된 내용과 논의만 구분한다.
- 담당자와 마감일이 명확하지 않으면 null로 둔다.
- action_items의 evidence에는 근거가 된 원문 일부를 짧게 넣는다.
- JSON만 출력한다.
녹취록:
{transcript}
"""
response_text = call_llm("너는 PMO 회의록 작성자다.", prompt)
return MeetingSummary.model_validate(json.loads(response_text))evidence 필드는 작지만 유용하다. AI가 왜 그 액션 아이템을 만들었는지 사람이 빠르게 확인할 수 있기 때문이다. 특히 회의록은 참석자 간 합의의 기록이므로, AI가 추측한 내용을 확정 사항처럼 쓰지 않도록 해야 한다.
계약 조항 검토는 자동 판정이 아니라 위험 신호 탐지다
계약서 검토는 LLM이 유용하지만 조심해야 하는 영역이다. 계약은 법적 책임과 연결된다. 따라서 LLM이 "이 계약은 안전합니다"라고 최종 판정하게 만들면 안 된다. 더 적절한 방식은 위험해 보이는 표현, 빠진 조항, 내부 기준과 다른 문장을 찾아 법무 담당자에게 검토 목록을 제공하는 것이다.
예를 들어 다음 항목을 확인하도록 요청할 수 있다.
자동 갱신 조항 존재 여부
위약금 또는 손해배상 범위
개인정보 처리 관련 문구
비밀유지 기간
해지 통보 기한
관할 법원 또는 준거법
출력은 "문제 있음/없음"보다 "검토 필요 항목" 중심이 좋다.
{
"risk_level": "낮음|보통|높음",
"issues": [
{
"clause": "조항명 또는 위치",
"reason": "검토가 필요한 이유",
"excerpt": "근거 문장",
"recommended_review_owner": "법무|보안|개인정보|사업부"
}
],
"needs_legal_review": true
}이런 구조는 AI의 역할을 명확히 제한한다. AI는 법률 자문을 하는 것이 아니라 내부 검토를 빠르게 시작할 수 있도록 후보를 정리한다. 실제 판단과 승인, 상대방에게 보낼 수정안 확정은 반드시 담당자가 해야 한다.
보고서 초안 작성은 숫자와 문장을 분리한다
보고서 자동화에서는 AI에게 숫자 계산까지 맡기지 않는 편이 안전하다. 매출 합계, 전월 대비 증감률, 고객 수, 전환율 같은 값은 파이썬이나 SQL로 계산한다. LLM은 그 결과를 읽고 자연스러운 문장으로 설명하는 역할을 맡는다.
예를 들어 월간 영업 보고서는 다음 순서로 만들 수 있다.
데이터베이스에서 월간 매출 데이터를 조회한다.
pandas로 지표를 계산한다.
계산 결과를 JSON으로 만든다.
LLM에게 보고서 초안을 작성하게 한다.
생성된 문장에서 금칙어와 숫자 왜곡을 검사한다.
담당자가 검토한 뒤 문서나 협업 도구에 게시한다.
핵심은 "근거 데이터 안에서만 작성하라"는 제약이다.
def build_report_prompt(metrics: dict) -> str:
return f"""
아래 지표만 사용해 월간 영업 보고서 초안을 작성하라.
규칙:
- 제공된 숫자를 바꾸거나 새 숫자를 만들지 않는다.
- 원인 분석은 추정이라고 표시한다.
- 과장된 표현을 쓰지 않는다.
- 형식은 '요약', '주요 변화', '확인 필요 사항', '다음 행동'으로 나눈다.
지표 JSON:
{json.dumps(metrics, ensure_ascii=False, indent=2)}
"""보고서 문장은 사람이 읽기 좋아야 하지만, 근거는 기계적으로 확인할 수 있어야 한다. 따라서 숫자 계산과 문장 생성을 분리하는 습관이 중요하다.
JSON, 함수 호출, 스키마 검증으로 시스템에 연결하기
LLM 결과를 실제 업무 시스템에 연결하려면 자연어 답변만으로는 부족하다. 자동화 시스템은 다음 행동을 결정해야 한다. 티켓을 생성할지, 담당자에게 보낼지, 답변 초안을 만들지, 중단할지를 코드가 판단해야 한다.
이때 사용할 수 있는 방식이 JSON 출력과 함수 호출이다. 함수 호출은 AI가 실제 함수를 직접 실행한다는 뜻이 아니다. AI가 "어떤 함수를 어떤 인자로 호출하면 좋겠다"는 구조화된 제안을 만들고, 파이썬 코드가 검증 후 실행하는 방식이다.
예를 들어 고객 문의 처리에서 허용할 행동을 세 가지로 제한할 수 있다.
ALLOWED_ACTIONS = {"create_ticket", "request_human_review", "draft_reply"}
class NextAction(BaseModel):
action: Literal["create_ticket", "request_human_review", "draft_reply"]
arguments: dict
reason: str
def execute_action(next_action: NextAction):
if next_action.action not in ALLOWED_ACTIONS:
raise ValueError("허용되지 않은 작업입니다.")
if next_action.action == "create_ticket":
return create_ticket(**next_action.arguments)
if next_action.action == "request_human_review":
return request_human_review(**next_action.arguments)
if next_action.action == "draft_reply":
return save_reply_draft(**next_action.arguments)여기서 원칙은 분명하다. AI 응답을 그대로 실행하지 않는다. 허용된 작업인지 확인한다. 인자 형식이 맞는지 검증한다. 위험한 작업은 초안 저장까지만 하고 발송은 사람이 한다. 이 구조를 지키면 LLM을 업무 흐름에 연결하면서도 사고 가능성을 줄일 수 있다.
민감정보, 금칙어, 사람 승인 단계
LLM 자동화는 편리하지만 입력 데이터가 외부 AI 서비스로 전송될 수 있다는 점을 항상 고려해야 한다. 회사 정책, 계약 조건, 개인정보 처리 기준에 따라 사용할 수 있는 데이터와 사용할 수 없는 데이터가 다르다. 특히 고객 이름, 연락처, 계좌번호, 주민등록번호, 의료 정보, 인사 평가, 영업 기밀은 입력 전에 마스킹하거나 내부 승인 절차를 거쳐야 한다.
운영 환경에서는 최소한 다음 안전장치를 둔다.
민감정보 마스킹: API 호출 전에 이메일, 전화번호, 식별번호를 가린다.
입력 크기 제한: 너무 긴 문서는 잘라 보내거나 섹션별로 처리한다.
출력 스키마 검증: JSON 형식과 허용 값을 검사한다.
금칙어 검사: 고객에게 보낼 문장에 부적절한 표현이 없는지 확인한다.
사람 승인: 외부 발송, 계약 검토, 비용 발생, 고객 불이익은 사람이 최종 승인한다.
로그 기록: 모델명, 프롬프트 버전, 처리 시간, 검토자, 결과 상태를 남긴다.
원문 로그 제한: 민감한 원문 전체를 로그에 남기지 않는다.
금칙어 검사는 간단한 규칙 기반 코드로도 시작할 수 있다.
FORBIDDEN_WORDS = ["무조건", "100% 보장", "법적으로 문제없음", "확실히 승인"]
def check_forbidden_words(text: str) -> list[str]:
return [word for word in FORBIDDEN_WORDS if word in text]
def prepare_for_approval(draft: str) -> dict:
violations = check_forbidden_words(draft)
return {
"draft": draft,
"violations": violations,
"status": "needs_review" if violations else "waiting_approval"
}AI가 만든 문장을 다시 AI에게만 검사하게 하면 놓치는 부분이 생길 수 있다. 명확한 금칙어, 숫자 일치, 필수 항목 누락은 규칙 기반으로 확인하는 편이 안정적이다. AI는 의미를 읽는 데 쓰고, 코드는 형식과 규칙을 지키는 데 쓴다.
운영 가능한 LLM 자동화 구조
LLM 자동화를 운영할 때는 이전 장에서 다룬 워크플로 원칙을 그대로 적용한다. 입력을 받고, 전처리하고, AI를 호출하고, 결과를 검증하고, 저장하고, 알림을 보낸다. 실패하면 재시도할지 중단할지 구분한다.
예를 들어 고객 문의 자동화 파이프라인은 다음처럼 구성할 수 있다.
수신함 조회
→ 신규 문의만 선택
→ 민감정보 마스킹
→ LLM 분류
→ JSON 검증
→ 업무 규칙 적용
→ 티켓 생성 또는 검토 요청
→ 실행 이력 저장
→ 담당자 알림이 흐름에서 LLM 호출은 하나의 단계일 뿐이다. 자동화 전체의 안정성은 그 앞뒤의 검증과 기록에서 나온다. 모델이 바뀌거나 프롬프트가 바뀌면 결과 품질도 달라질 수 있으므로 프롬프트 버전을 남겨야 한다. 비용 관리도 필요하다. 처리 건수, 입력 길이, 응답 길이, 실패율을 기록하면 어느 업무에 AI 비용이 많이 쓰이는지 확인할 수 있다.
또한 모든 오류에 재시도를 걸면 안 된다. 일시적인 API 오류는 재시도할 수 있다. 하지만 JSON 형식 오류가 반복되거나 민감정보가 마스킹되지 않은 경우에는 즉시 중단하고 담당자에게 알려야 한다.
LLM 자동화의 적절한 출발점
LLM 자동화는 처음부터 전사 업무를 바꾸려고 하면 실패하기 쉽다. 작고 반복적인 텍스트 업무에서 시작하는 것이 좋다. 고객 문의 1차 분류, 회의록 초안, 내부 보고서 문장 작성, FAQ 답변 초안처럼 사람이 검토할 수 있고 되돌리기 쉬운 업무가 적합하다.
반대로 계약 확정, 인사 평가, 대출 승인, 고객 보상 결정처럼 영향이 큰 업무는 AI가 최종 결정하면 안 된다. 이 경우 AI는 후보를 정리하거나 위험 신호를 표시하는 보조 역할에 머물러야 한다.
LLM을 잘 쓰는 자동화는 AI에게 모든 것을 맡기지 않는다. 규칙이 명확한 부분은 파이썬으로 처리한다. 의미 판단이 필요한 부분만 LLM에 맡긴다. 그리고 중요한 결과는 사람이 승인한다. 이 균형을 지키면 텍스트 업무 자동화는 단순한 편의 기능을 넘어, 조직의 반복 업무를 줄이고 업무 품질을 일정하게 만드는 실질적인 도구가 된다.
이 노트는 보도·비평·교육·연구 목적으로 작성되었습니다. 저작권 문의가 있으시면 에서 알려주세요.