5개 사업자등록증을 갖고 있다 보니, 반기마다 찾아오는 부가세 신고가 진짜 싫습니다.
부가세 신고 때마다 반복되는 악몽:
📧 세무사: "6개월치 온라인 결제 내역 보내드려요. 각각 어떤 비용인지 분류해주세요"
📱 나: 토스페이먼츠, 네이버파이넨셜, 한국정보통신(주)... 수백 건 내역 보며 기억 더듬기
🧠 "이건 뭐 샀더라? 비품? 재료? 집기?"
😱 6개월 전 구매 내역은 당연히 기억 안 남
왜 이게 문제였냐면:
오프라인 결제: 세무사가 알아서 처리
온라인 결제: "한국정보통신(주) 25,000원" 이게 끝 : 내역을 알 수가 없음.
진짜 뭘 샀는지 알 길이 없거든요.
그래서 이 업무를 보완하고 직원들의 업무 효율을 위해 자동화했습니다.
사용한 도구 선택 고민:
처음에는 "최신 AI 써서 완벽하게!" 생각했는데, 현실적으로 비용 계산해보니...
방법
월 무료 한도
초과 시 비용
복잡도
Gemini 1.5 Flash
1,500장
5-10원/장
간단
Google Vision + GPT-3.5
1,000장
1-2원/장
복잡
GPT-4o mini
없음
10-20원/장
간단
Google Vision: 월 1,000건 무료 → 5개 매장 합쳐도 충분
GPT-3.5 Turbo: 장당 1-2원, 어차피 스크린샷이라 충분
월 예상 비용 1,000원 이하로 시스템 구축 결정!
워크플로우:
직원이 온라인 구매 → 영수증 스크린샷 촬영
↓
매장별 구글 드라이브 폴더 업로드
↓
Google Vision이 텍스트 추출
↓
GPT-3.5가 품목 분석 후 계정 자동 분류
↓
매장별 구글 시트에 자동 기록
↓
인식하기 좋게 파일명 변경 후 처리완료 폴더로 이동
각 노드별 역할과 선택 이유
1. Google Drive Trigger
역할: 매장 폴더에 새 이미지 업로드 감지
결정: 매장별 5개 워크플로우 따로하자. → 관리 편의성 + 오류 격리
2. Google Drive Download
역할: 업로드된 영수증 이미지 파일 다운로드
결정: Google Drive 노드 → 자동 바이너리 처리
3. Code 노드 (클로드에게 물어봄)
역할: 바이너리 이미지 데이터를 Base64로 변환
왜 필요했나: n8n의 바이너리 데이터가 파일시스템 참조(
filesystem-v2)로 저장됨해결:
getBinaryDataBuffer()→toString('base64')직접 변환
// 실제 바이너리 데이터 읽어서 Base64 변환
const binaryData = await this.helpers.getBinaryDataBuffer(0, 'data');
const base64Data = binaryData.toString('base64');
4. Google Vision OCR
역할: 영수증 이미지에서 텍스트 추출
결정: Google Vision → 월 1,000건 무료
설정: HTTP Request로 직접 API 호출 (n8n 전용 노드 없음)
5. Basic LLM Chain
역할: OCR 텍스트를 구조화된 데이터로 변환
결정: LLM Chain → 프롬프트 템플릿 관리 용이 + 변수 처리 깔끔
핵심: 계정 분류 규칙을 상세하게 정의
계정 분류 기준:
- 비품: 사무용품, 청소용품, 소모품
- 집기: 가구, 전자제품, 조명
- 재료: 카페 원재료, 포장재
- 식대: 식음료, 배달음식
...
6. Set 노드 (JSON 파싱)
역할: LLM이 생성한 JSON 문자열을 실제 객체로 변환
왜 필요했나: LLM Chain 출력이
{text: "JSON문자열"}형태결정: Set 노드 →
JSON.parse()간단 처리
// LLM 출력 텍스트를 실제 JSON 객체로 변환
parsed_data: {{ JSON.parse($json.text) }}
7. Google Sheets (병렬 처리)
역할: 파싱된 데이터를 매장별 시트에 기록
결정: Append → 영수증은 항상 새로 추가 (중복 체크 불필요)
8. Update File → Move File (순차 처리)
역할: 파일명 변경 후 처리완료 폴더로 이동
결정: 순차적 → Update 먼저, Move 나중 (논리적 순서)
네이버페이.png → 2025-07-22_모타바스켓.png → 처리완료 폴더
가장 고민했던 부분: AI 계정 분류
세무사가 매번 물어보는 그 질문을 AI가 알아서 답하게 하는 게 핵심이었어요.
처음 AI 분류 결과:
{
"account": "기타",
"items": "상품"
}
뭐든지 "