학습 목표
여러분, 2026년 현재, 비정형 텍스트 데이터는 기업의 의사 결정과 서비스 개선에 필수적인 자원입니다. 하지만 방대한 양의 텍스트를 수동으로 분류하고 핵심 정보를 추출하는 것은 비효율적이며 오류 발생 가능성이 높습니다. 본 강의는 이러한 문제를 해결하기 위해 ChatGPT API를 활용하여 비정형 텍스트 데이터를 자동으로 분류하고 핵심 정보를 추출하는 파이썬 스크립트를 직접 개발하는 것을 목표로 합니다. 여러분은 다음을 학습하게 됩니다:
- ChatGPT API의 기본 원리 및 활용 방법
- 효과적인 프롬프트 엔지니어링을 통한 텍스트 분류 전략
- JSON 형식으로 핵심 정보를 구조화하여 추출하는 기법
- 파이썬을 이용한 전체 자동화 파이프라인 구축
- 실제 업무에 적용 가능한 실용적인 스크립트 작성 능력 배양
이 강의를 통해 여러분은 복잡한 텍스트 처리 작업을 자동화하고, 데이터 기반의 인사이트를 신속하게 도출하는 강력한 도구를 얻게 될 것입니다.
사전 준비 사항
본 실습을 원활하게 진행하기 위한 개발 환경 및 필수 도구들을 먼저 설정해야 합니다. 정확한 환경 설정은 성공적인 학습의 첫걸음입니다.
개발 환경
- 통합 개발 환경 (IDE): Visual Studio Code (VS Code) 최신 안정 버전 (권장)
- 운영체제 (OS): Windows 10/11, macOS (Ventura 이상), Linux (Ubuntu 22.04 LTS 이상)
- 파이썬 (Python) 버전: Python 3.9 이상 (Python 3.10, 3.11, 3.12 권장)
필수 라이브러리 설치
터미널 또는 명령 프롬프트를 열고 다음 명령어를 실행하여 필요한 파이썬 라이브러리를 설치합니다. 가상 환경을 활성화한 후 설치하는 것을 강력히 권장합니다.
# 가상 환경 생성 (선택 사항이지만 권장)
python -m venv .venv
# 가상 환경 활성화
# Windows
.venv\Scripts\activate
# macOS/Linux
source .venv/bin/activate
# 필수 라이브러리 설치
pip install openai python-dotenvopenai: ChatGPT API와 상호작용하기 위한 공식 라이브러리입니다.python-dotenv: 환경 변수(.env 파일)를 통해 API 키와 같은 민감한 정보를 안전하게 관리하는 데 사용됩니다.
OpenAI API 키 발급
ChatGPT API를 사용하려면 OpenAI 플랫폼에서 API 키를 발급받아야 합니다. 다음 단계를 따르세요:
- OpenAI 플랫폼 웹사이트 (platform.openai.com)에 접속하여 로그인합니다.
- 좌측 사이드바에서 ‘API keys’ 메뉴로 이동합니다.
- ‘Create new secret key’ 버튼을 클릭하여 새로운 API 키를 생성합니다.
- 생성된 API 키는 한 번만 표시되므로 반드시 안전한 곳에 복사하여 저장합니다. 이 키는 스크립트에서 OpenAI API를 인증하는 데 사용됩니다.
보안 경고: API 키는 절대 코드에 직접 노출하거나 버전 관리 시스템(Git 등)에 커밋하지 마십시오. .env 파일을 사용하여 환경 변수로 관리하는 것이 보안상 가장 안전한 방법입니다.
단계별 실습 과정
이제 본격적으로 스크립트를 작성해 보겠습니다. 각 단계를 차근차근 따라오시면 됩니다.
1단계: 프로젝트 설정 및 API 키 보안
먼저 프로젝트 폴더를 생성하고, API 키를 안전하게 관리할 수 있도록 설정합니다.
- 원하는 위치에
chatgpt_text_processor라는 이름의 새 폴더를 생성합니다. - VS Code를 열고, ‘파일 > 폴더 열기’를 통해 생성한 폴더를 엽니다.
- 새 파일
.env를 생성하고, 발급받은 OpenAI API 키를 다음과 같이 저장합니다.
OPENAI_API_KEY="여기에_발급받은_API_키를_붙여넣으세요"- 새 파일
main.py를 생성하고,.env파일에서 API 키를 불러오는 코드를 작성합니다.
import os
from dotenv import load_dotenv
import openai
# .env 파일에서 환경 변수 로드
load_dotenv()
# OpenAI API 키 설정
openai.api_key = os.getenv("OPENAI_API_KEY")
# API 키가 제대로 로드되었는지 확인 (보안상 실제 키는 출력하지 않습니다)
if openai.api_key:
print("OpenAI API 키가 성공적으로 로드되었습니다.")
else:
print("오류: OpenAI API 키를 찾을 수 없습니다. .env 파일을 확인해주세요.")
# 모델 설정 (현재 시점의 최신 모델을 사용합니다)
MODEL_NAME = "gpt-4o" # 또는 "gpt-3.5-turbo" 등2단계: ChatGPT API 연동 기본 함수 구현
ChatGPT API와 통신하기 위한 기본 함수를 정의합니다. 이 함수는 프롬프트를 받아 ChatGPT에게 전달하고 응답을 반환합니다.
def get_completion(prompt, model=MODEL_NAME, temperature=0.7):
messages = [
{"role": "system", "content": "당신은 유용한 AI 비서입니다."},
{"role": "user", "content": prompt}
]
try:
response = openai.ChatCompletion.create(
model=model,
messages=messages,
temperature=temperature # 창의성 정도를 조절 (0.0: 보수적, 1.0: 창의적)
)
return response.choices[0].message["content"]
except openai.error.OpenAIError as e:
print(f"API 호출 중 오류 발생: {e}")
return None
temperature: 이 값은 모델의 응답에 대한 창의성 또는 무작위성을 제어합니다. 0.0에 가까울수록 일관적이고 보수적인 응답을, 1.0에 가까울수록 다양하고 창의적인 응답을 생성합니다. 분류 및 추출과 같이 정밀함이 요구되는 작업에서는 낮은 값을 사용하는 것이 좋습니다.messages: API 호출 시 대화의 컨텍스트를 제공합니다.system역할은 AI의 전반적인 행동을 지시하고,user역할은 사용자의 입력을 전달합니다.
3단계: 비정형 텍스트 데이터 분류 로직 구현
이제 ChatGPT API를 사용하여 텍스트를 특정 카테고리로 분류하는 기능을 구현합니다. 프롬프트 엔지니어링이 핵심입니다.
def classify_text(text):
prompt = f"""다음 고객 피드백을 '제품 문의', '결함 보고', '기능 요청', '기타' 중 하나의 카테고리로 분류하세요.
카테고리만 출력하세요.
피드백: """{text}"""
"""
print(f"분류 중: '{text[:50]}...' ")
category = get_completion(prompt, temperature=0.0)
return category.strip()
# 분류 예시 텍스트
feedback_texts = [
"새로운 다크 모드 테마를 추가해주시면 좋겠습니다.",
"최근 업데이트 이후 앱이 자주 강제 종료됩니다.",
"이메일 인증이 안 되는데 어떻게 해야 하나요?",
"배송이 너무 느려요. 주문한지 일주일이 넘었습니다."
]
classified_results = []
for text in feedback_texts:
category = classify_text(text)
classified_results.append({"text": text, "category": category})
print("\n--- 텍스트 분류 결과 ---")
for item in classified_results:
print(f"텍스트: {item['text']}\n분류: {item['category']}\n")
이 단계에서는 피드백 텍스트를 기반으로 명확한 분류 기준을 제시하는 프롬프트가 중요합니다. temperature=0.0을 사용하여 모델이 가장 확률 높은, 즉 가장 일관적인 답변을 생성하도록 유도합니다.
정확한 분류를 위해서는 다양한 예시와 함께 원하는 출력 형식을 명확히 지정하는 것이 좋습니다.
4단계: 핵심 정보 추출 로직 구현
다음으로, 분류된 텍스트에서 특정 핵심 정보를 추출하는 기능을 구현합니다. 이 역시 프롬프트 엔지니어링이 중요하며, JSON 형식으로 출력을 요청하여 구조화된 데이터를 얻는 것이 일반적입니다.
import json
def extract_info(text, category):
if category == '결함 보고':
prompt = f"""다음 결함 보고 텍스트에서 '결함 유형', '영향 받는 기능', '심각도'를 추출하여 JSON 형식으로 반환하세요.
심각도는 '높음', '중간', '낮음' 중 하나로 판단하세요.
텍스트: """{text}"""
예시 JSON:
{{
"결함_유형": "",
"영향_받는_기능": "",
"심각도": ""
}}
"""
elif category == '기능 요청':
prompt = f"""다음 기능 요청 텍스트에서 '요청 기능', '기능 설명', '예상 효과'를 추출하여 JSON 형식으로 반환하세요.
텍스트: """{text}"""
예시 JSON:
{{
"요청_기능": "",
"기능_설명": "",
"예상_효과": ""
}}
"""
else:
return None # 다른 카테고리는 추출 로직 없음
print(f"정보 추출 중 (카테고리: {category}): '{text[:50]}...' ")
raw_json = get_completion(prompt, temperature=0.0)
try:
# JSON 문자열 파싱
extracted_data = json.loads(raw_json)
return extracted_data
except json.JSONDecodeError as e:
print(f"JSON 파싱 오류: {e}\n원문: {raw_json}")
return None
# 추출 예시
extraction_texts = [
{"text": "로그인 버튼을 누르면 앱이 멈춥니다. 매번 재시작해야 해요. 매우 불편합니다.", "category": "결함 보고"},
{"text": "클라우드 동기화 기능을 추가해 주시면 여러 기기에서 작업하기 편리할 것 같습니다.", "category": "기능 요청"}
]
extracted_results = []
for item in extraction_texts:
extracted_info = extract_info(item['text'], item['category'])
if extracted_info:
extracted_results.append({"text": item['text'], "category": item['category'], "info": extracted_info})
print("\n--- 핵심 정보 추출 결과 ---")
for item in extracted_results:
print(f"텍스트: {item['text']}\n분류: {item['category']}\n추출 정보: {json.dumps(item['info'], indent=2, ensure_ascii=False)}\n")
핵심 정보 추출에서는 모델에게 원하는 정보 필드와 그에 대한 설명을 명확히 제공하고, JSON 형식으로 출력을 요구하는 것이 중요합니다. json.loads()를 사용하여 모델이 반환한 JSON 문자열을 파이썬 딕셔너리로 변환합니다.
오류 발생 시 예외 처리를 통해 안정성을 확보하는 것도 잊지 마세요.
5단계: 전체 파이프라인 통합 및 실행
이제 분류와 추출 로직을 하나의 파이프라인으로 통합하여, 새로운 비정형 텍스트 데이터에 대해 자동으로 두 가지 작업을 수행하는 스크립트를 완성합니다.
# main.py 파일에 모든 함수와 로직을 통합합니다.
# (이전 단계의 코드들을 모두 main.py에 복사하여 붙여넣으세요)
print("\n--- 전체 텍스트 처리 파이프라인 시작 ---")
# 처리할 새로운 비정형 텍스트 데이터
new_data = [
"주문 내역에서 배송지 주소를 변경하고 싶은데, 메뉴를 찾을 수가 없네요.",
"앱 실행 시 간헐적으로 검은 화면이 나타나고 아무것도 작동하지 않습니다.",
"캘린더와 연동하여 일정을 자동으로 등록하는 기능이 있다면 정말 유용할 것 같아요.",
"결제 시스템에 오류가 있어서 결제가 진행되지 않습니다. 확인 부탁드립니다."
]
final_processed_results = []
for text_item in new_data:
print(f"\n처리 중 텍스트: '{text_item[:70]}...' ")
# 1. 텍스트 분류
category = classify_text(text_item)
print(f" - 분류 결과: {category}")
# 2. 핵심 정보 추출 (분류된 카테고리에 따라)
extracted_info = extract_info(text_item, category)
if extracted_info:
print(f" - 추출 정보: {json.dumps(extracted_info, indent=2, ensure_ascii=False)}")
else:
print(" - 추출된 정보 없음 (해당 카테고리에 대한 추출 로직이 없거나 오류 발생)")
final_processed_results.append({
"original_text": text_item,
"classified_category": category,
"extracted_data": extracted_info
})
print("\n--- 전체 텍스트 처리 파이프라인 완료 ---")
print("최종 처리 결과:")
for result in final_processed_results:
print(json.dumps(result, indent=2, ensure_ascii=False))
이 코드는 new_data 리스트의 각 텍스트에 대해 먼저 classify_text 함수를 호출하여 카테고리를 분류하고, 그 다음 extract_info 함수를 호출하여 해당 카테고리에 맞는 핵심 정보를 추출합니다. 전체 과정이 자동화되어 일괄적으로 처리됩니다.
결과 확인
main.py 파일을 실행하면, 터미널에 각 텍스트 데이터에 대한 분류 결과와 추출된 핵심 정보가 순차적으로 출력되는 것을 확인할 수 있습니다.
python main.py실행 결과는 다음과 유사할 것입니다 (실제 출력은 모델의 응답에 따라 약간 다를 수 있습니다).
--- 전체 텍스트 처리 파이프라인 시작 ---
처리 중 텍스트: '주문 내역에서 배송지 주소를 변경하고 싶은데, 메뉴를 찾을 수가 없네요.'
분류 중: '주문 내역에서 배송지 주소를 변경하고 싶은데, 메뉴를 찾을 수가 없네요.'
- 분류 결과: 제품 문의
정보 추출 중 (카테고리: 제품 문의): '주문 내역에서 배송지 주소를 변경하고 싶은데, 메뉴를 찾을 수가 없네요.'
- 추출된 정보 없음 (해당 카테고리에 대한 추출 로직이 없거나 오류 발생)
처리 중 텍스트: '앱 실행 시 간헐적으로 검은 화면이 나타나고 아무것도 작동하지 않습니다.'
분류 중: '앱 실행 시 간헐적으로 검은 화면이 나타나고 아무것도 작동하지 않습니다.'
- 분류 결과: 결함 보고
정보 추출 중 (카테고리: 결함 보고): '앱 실행 시 간헐적으로 검은 화면이 나타나고 아무것도 작동하지 않습니다.'
- 추출 정보: {
"결함_유형": "앱 강제 종료/멈춤",
"영향_받는_기능": "앱 실행",
"심각도": "높음"
}
처리 중 텍스트: '캘린더와 연동하여 일정을 자동으로 등록하는 기능이 있다면 정말 유용할 것 같아요.'
분류 중: '캘린더와 연동하여 일정을 자동으로 등록하는 기능이 있다면 정말 유용할 것 같아요.'
- 분류 결과: 기능 요청
정보 추출 중 (카테고리: 기능 요청): '캘린더와 연동하여 일정을 자동으로 등록하는 기능이 있다면 정말 유용할 것 같아요.'
- 추출 정보: {
"요청_기능": "캘린더 연동 자동 일정 등록",
"기능_설명": "캘린더와 연동하여 일정을 자동으로 등록하는 기능",
"예상_효과": "여러 기기에서 작업 편리, 일정 관리 효율성 증대"
}
처리 중 텍스트: '결제 시스템에 오류가 있어서 결제가 진행되지 않습니다. 확인 부탁드립니다.'
분류 중: '결제 시스템에 오류가 있어서 결제가 진행되지 않습니다. 확인 부탁드립니다.'
- 분류 결과: 결함 보고
정보 추출 중 (카테고리: 결함 보고): '결제 시스템에 오류가 있어서 결제가 진행되지 않습니다. 확인 부탁드립니다.'
- 추출 정보: {
"결함_유형": "결제 오류",
"영향_받는_기능": "결제 시스템",
"심각도": "높음"
}
--- 전체 텍스트 처리 파이프라인 완료 ---
최종 처리 결과:
[
{
"original_text": "주문 내역에서 배송지 주소를 변경하고 싶은데, 메뉴를 찾을 수가 없네요.",
"classified_category": "제품 문의",
"extracted_data": null
},
{
"original_text": "앱 실행 시 간헐적으로 검은 화면이 나타나고 아무것도 작동하지 않습니다.",
"classified_category": "결함 보고",
"extracted_data": {
"결함_유형": "앱 강제 종료/멈춤",
"영향_받는_기능": "앱 실행",
"심각도": "높음"
}
},
{
"original_text": "캘린더와 연동하여 일정을 자동으로 등록하는 기능이 있다면 정말 유용할 것 같아요.",
"classified_category": "기능 요청",
"extracted_data": {
"요청_기능": "캘린더 연동 자동 일정 등록",
"기능_설명": "캘린더와 연동하여 일정을 자동으로 등록하는 기능",
"예상_효과": "여러 기기에서 작업 편리, 일정 관리 효율성 증대"
}
},
{
"original_text": "결제 시스템에 오류가 있어서 결제가 진행되지 않습니다. 확인 부탁드립니다.",
"classified_category": "결함 보고",
"extracted_data": {
"결함_유형": "결제 오류",
"영향_받는_기능": "결제 시스템",
"심각도": "높음"
}
}
]
이 결과는 ChatGPT API가 비정형 텍스트를 성공적으로 분류하고, 정의된 카테고리에 따라 핵심 정보를 구조화된 JSON 형태로 추출했음을 보여줍니다.
이제 여러분은 이 스크립트를 기반으로 고객 피드백 분석, 뉴스 기사 요약, 문서 분류 등 다양한 실무 시나리오에 적용할 수 있습니다. 프롬프트와 추출 필드를 유연하게 조정하여 여러분의 특정 요구사항에 맞는 강력한 텍스트 처리 시스템을 구축해 보세요.

