Skip to content

사이드 프로젝트 이력서 시각화 서비스 제작기 2편

본격적인 시작: GitHub 레포지토리 생성과 환경 구축

오늘은 욕심내지 않고 딱 프로젝트의 기본 구조를 설계하고, 파일에서 텍스트를 읽어오는 부분까지만 진행해 보려 합니다. Antigravity 에이전트와 함께 첫 삽을 뜨는 단계입니다.

1. GitHub 저장소 만들기

가장 먼저 프로젝트의 뼈대가 될 GitHub 레포지토리를 생성했습니다.

레포지토리 생성 설정 이미지

  • 이름: Antigravity-LifeGraph
  • 라이선스: 누구나 자유롭게 참고할 수 있도록 MIT License를 선택했습니다.
  • 기타: Python 프로젝트에 맞게 .gitignore를 설정하고, 기본적인 README.md도 포함했습니다.

이제 이 레포지토리를 클론하여 Antigravity IDE에서 본격적인 작업을 시작합니다.

2. 프로젝트 폴더 구조 설계

Antigravity 에이전트가 이해하기 쉽고 추후 유지보수가 용이하도록 표준적인 폴더 구조를 잡았습니다.

Antigravity-LifeGraph/
├── uploads/            # 사용자가 업로드한 이력서 임시 저장
├── app.py              # 전체 서비스를 구동할 메인 파일
├── parser.py           # Word, PPT 파일에서 텍스트를 추출하는 로직
├── analyzer.py         # Hugging Face 모델 연동 및 데이터 분석
├── utils.py            # 이미지 저장 및 클립보드 복사 등 유틸리티
└── requirements.txt    # 프로젝트 필요 라이브러리 목록

3. 의존성 관리: requirements.txt 작성

파이썬 프로젝트를 진행할 때는 내가 사용한 외부 라이브러리 목록을 기록해두는 것이 중요합니다. 이를 위해 requirements.txt 파일을 작성합니다.

  • requirements.txt가 필요한 이유
    • 환경 복구: 다른 컴퓨터나 서버에서 내 프로젝트를 실행할 때, pip install -r requirements.txt 명령 한 번으로 필요한 라이브러리를 똑같이 설치할 수 있습니다.
    • 버전 관리: 팀 프로젝트나 배포 시 라이브러리 버전 충돌을 방지합니다.

이제 4번 단계에서 작성할 코드에서 사용할 라이브러리를 requirements.txt에 아래와 같이 작성해둡니다.

python-docx
python-pptx

4. 비정형 데이터에서 텍스트 추출

이력서는 사람마다 형식이 제각각입니다. 어떤 사람은 표를 쓰고, 어떤 사람은 PPT의 텍스트 박스를 활용하죠. 이 모든 데이터에서 텍스트를 긁어오기 위해 python-docx와 python-pptx 라이브러리를 사용하고자 합니다.

이제 Antigravity에게 Fast 모드로 설정하고 아래와 같이 질문을 던져 parser.py 파일을 작성해보겠습니다.

Agent Prompt

사용자가 업로드한 .docx와 .pptx 파일에서 텍스트를 추출하고 싶어. @files:requirements.txt에 기재한 라이브러리를 사용해서, 특정 파이썬 버전의 환경이 아닌 범용적인 파이썬 환경에서 빈 줄은 제외하고 텍스트만 리스트로 반환하는 함수를 `@files:parser.py`에 작성해줘. 단, py 파일 코드의 주석은 한글로 작성해줘

Antigravity 팁: @files 참조 기능

@files:파일명이라고 입력하면 에이전트에게 해당 파일의 위치와 내용을 명시적으로 알려줄 수 있습니다. 만약 같은 이름의 파일이 여러 폴더에 있더라도 혼동 없이 정확한 파일을 참조(cascade)하게 만드는 강력한 기능입니다. 커서를 파일명 끝에 두고 Enter를 누르면 활성화됩니다.

에이전트는 제 요청을 듣고 즉시 아래와 같은 코드를 생성해 주었습니다.

import os
import docx
from pptx import Presentation

def extract_text(file_path):
    """
    다양한 파일 형식(.docx, .pptx)에서 텍스트를 추출합니다.
    각 문자열이 단락 또는 의미 있는 텍스트 블록인 문자열 리스트를 반환합니다.
    빈 줄은 제외됩니다.
    """
    if not os.path.exists(file_path):
        return []

    ext = os.path.splitext(file_path)[1].lower()

    if ext == '.docx':
        return extract_text_docx(file_path)
    elif ext == '.pptx':
        return extract_text_pptx(file_path)
    else:
        # 지원되지 않는 형식이거나 폴백(fallback) 처리
        return []

def extract_text_docx(file_path):
    """
    .docx 파일에서 텍스트를 추출합니다.
    """
    try:
        doc = docx.Document(file_path)
        text_list = []
        for paragraph in doc.paragraphs:
            text = paragraph.text.strip()
            if text:
                text_list.append(text)
        return text_list
    except Exception as e:
        print(f".docx 파싱 중 오류 발생: {e}")
        return []

def extract_text_pptx(file_path):
    """
    .pptx 파일에서 슬라이드별로 텍스트를 추출합니다.
    """
    try:
        prs = Presentation(file_path)
        text_list = []
        for slide in prs.slides:
            for shape in slide.shapes:
                if hasattr(shape, "text") and shape.text.strip():
                    # 텍스트를 포함한 도형에서 텍스트 추출
                    text = shape.text.strip()
                    if text:
                        text_list.append(text)
                elif hasattr(shape, "text_frame"):
                    # 텍스트 프레임이 있는 도형의 경우 모든 단락 수집
                    for paragraph in shape.text_frame.paragraphs:
                        text = paragraph.text.strip()
                        if text:
                            text_list.append(text)
        return text_list
    except Exception as e:
        print(f".pptx 파싱 중 오류 발생: {e}")
        return []

[부록] 환경 설정 트러블슈팅: 빨간 줄과의 전쟁

라이브러리를 설치했지만, IDE에서 import 오류(빨간 줄)가 사라지지 않아 고생을 좀 했습니다. 혹시 비슷한 문제를 겪으실 분들을 위해 해결 과정을 정리합니다.

1. Invalid Python Interpreter & PET 오류

가상환경(lifegraphvenv)을 만들고 경로를 잡았음에도 **"Python Environment Tools (PET) failed"**라는 경고와 함께 인터프리터가 무효하다는 메시지가 떴습니다.

  • 원인: IDE가 자동으로 환경을 인덱싱하는 과정에서 타임아웃이 나거나 경로 인식 오류가 발생한 것이었습니다.
  • 해결: 자동 감지에 의존하지 않고 .vscode/settings.json에 상대 경로를 직접 명시하여 해결했습니다.
{
    "python.defaultInterpreterPath": "./venv/Scripts/python.exe",
    "python.terminal.activateEnvInSelectedTerminal": true
}

2. 경로 설정의 디테일 (절대 경로 vs 상대 경로)

처음에는 D:\local_storage\... 식의 절대 경로를 적었으나, 프로젝트 이동성과 범용성을 고려해 ./로 시작하는 상대 경로로 수정했습니다. 또한 윈도우 환경에서도 경로 구분자를 슬래시(/)로 작성하는 것이 에러 방지에 효과적이었습니다.

3. [object Object]의 마법

모든 설정을 마쳤는데도 변화가 없다면, Ctrl + Shift + P를 눌러 Developer: Reload Window를 실행해 보세요. IDE가 설정을 새로고침하며 비로소 가상환경 내의 라이브러리들을 인식하기 시작합니다.

회고

오늘은 퇴근 후 짧은 시간을 활용해 프로젝트의 뼈대를 잡고, Antigravity 에이전트와 소통하며 텍스트 추출 기능을 구현했습니다.

단순히 "코드 짜줘"가 아니라 @files와 같은 기능을 활용해 에이전트에게 명확한 컨텍스트를 제공하는 과정이 꽤나 흥미로웠습니다. 덕분에 비정형 데이터인 이력서에서 날 것의 데이터를 확보하는 첫 단계를 순조롭게 진행했습니다.

다음 작업에서는 오늘 추출한 이 텍스트 뭉치들을 Hugging Face의 무료 모델에 연결해 보려 합니다. 이 텍스트들에서 어떻게 '연도'를 찾아내고 '성취 점수'를 매길 수 있을지 본격적인 AI 로직을 고민해 보겠습니다.