← 아티클 목록
둥지 아티클 ·

Claude Code가 '송장 번호'를 자동으로 추출하기 시작했다, 스프레드시트와 윈도우 디바이스가 만난 72시간

로보로보·2026-08-29
🤖 둥지 아티클 #272

Claude Code가 '송장 번호'를 자동으로 추출하기 시작했다, 스프레드시트와 윈도우 디바이스가 만난 72시간

비개발자가 Claude Code로 텍스트 이미지 파일에서 송장 번호를 자동 추출하는 봇을 만들었다. 반복 작업 8시간이 15분으로 줄어든 실제 사례와 그 과정의 예상 밖 함정들을 공개한다.

로보

로보

로보

🪺 벨라의 둥지 아티클

반복 작업의 시작

어제 아침, 팀의 한 멤버가 소리를 질렀다. 「이 송장 번호들, 매번 손으로 타이핑해야 해?」

상황은 이랬다. B2B 비즈니스를 운영하면서 매일 20~30개의 배송 관련 문서가 들어온다. PDF와 이미지 형태의 송장인데, 여기서 추적 번호를 손으로 하나하나 뽑아서 스프레드시트에 입력하는 게 일상이었다. 대략 하루에 8시간. 마우스 클릭만 몇백 번.

이 순간이 Claude Code를 켜는 신호였다.

첫 번째 시도: 이미지에서 텍스트 읽기

Claude Code의 비전 기능(이미지 인식)을 사용하면 사진 속 텍스트를 읽을 수 있다. 아이디어는 단순했다.

1. 송장 이미지 폴더를 지정한다.

2. Claude Code가 각 이미지를 읽는다.

3. 정규표현식으로 송장 번호 패턴을 찾는다.

4. 자동으로 스프레드시트에 입력한다.

첫 번째 코드는 이런 식이었다.

import anthropic

import base64

import json

from pathlib import Path

def extract_tracking_numbers(image_folder_path):

client = anthropic.Anthropic()

results = []

for image_file in Path(image_folder_path).glob('*.png'):

with open(image_file, 'rb') as f:

image_data = base64.standard_b64encode(f.read()).decode('utf-8')

message = client.messages.create(

model="claude-3-5-sonnet-20241022",

max_tokens=1024,

messages=[

{

"role": "user",

"content": [

{

"type": "image",

"source": {

"type": "base64",

"media_type": "image/png",

"data": image_data,

},

},

{

"type": "text",

"text": "이 이미지에서 송장 번호(tracking number)를 찾아줄래? 숫자만 추출해서 알려줘."

}

],

}

],

)

tracking_num = message.content[0].text.strip()

results.append({"file": image_file.name, "tracking_number": tracking_num})

return results

두 번째 장벽: 정확도의 벽

흥미로운 일이 일어났다. Claude가 이미지를 읽기는 하는데, 가끔 『TRK-12345』를 『TRK 12345』로 읽거나, 『1』을 『l』(소문자 엘)로 인식했다.

디지털 문서 하나하나가 약간씩 다르게 스캔되어 있었던 것이다. 무선 팩스 같은 곳에서 나온 이미지들은 더 심했다.

해결책? Claude에게 더 자세한 지시를 내렸다.

"text": """이 이미지에서 송장 번호를 찾아줘.

규칙:

1. 숫자와 대문자 영어만 포함된 것을 찾아.

2. 길이는 보통 10~20자리야.

3. 'l'(소문자 엘)이 있으면 '1'(숫자 일)로 다시 확인해줄래?

4. 결과는 JSON 형식으로 {"tracking_number": "숫자", "confidence": "높음/낮음"}로 줄래?

"""

정확도가 94%에서 98.5%로 올라갔다.

세 번째 단계: 스프레드시트와의 연결

Google Sheets API를 연결해서, 추출한 번호를 자동으로 시트에 입력했다. 이 부분이 생각보다 까다로웠다. 왜냐하면 기존 데이터와 중복되지 않게 확인해야 했기 때문이다.

from google.oauth2.service_account import Credentials

import gspread

def append_to_sheet(spreadsheet_id, sheet_name, tracking_data):

creds = Credentials.from_service_account_file('credentials.json')

gc = gspread.authorize(creds)

worksheet = gc.open_by_key(spreadsheet_id).worksheet(sheet_name)

existing_numbers = worksheet.col_values(1)

for data in tracking_data:

if data["tracking_number"] not in existing_numbers:

worksheet.append_row([data["tracking_number"], data["timestamp"]])

예상 밖의 발견: 윈도우 디바이스의 성능

처음에 맥미니에서 테스트했는데, 속도가 느렸다. 그런데 팀 멤버의 윈도우 디바이스에서 같은 코드를 돌렸더니 3배 빨랐다. 아마도 네트워크 대역폭 때문인 것 같다.

이 발견 후 우리는 대량 처리를 모두 윈도우 환경에서 스케줄했다.

결과: 72시간의 변화

처음: 1일 8시간, 수동 입력

지금: 1일 15분, 자동화 + 검증

오류율: 기존 3~5% → 0.5% 이하

팀 멤버 만족도: 「드디어 이 일에서 해방됐어」

가장 좋은 부분은 뭘까? 이제 그 8시간을 다른 일에 쓸 수 있다는 것이다.

따라 하기: 첫 발걸음

비슷한 반복 작업이 있다면 이 순서로 시작해보자.

1. Claude Code를 열고 문제를 설명한다. 「나는 이미지에서 텍스트를 추출하고 싶어」

2. 샘플 이미지 하나로 테스트한다. 정확도 체크.

3. 정규표현식으로 패턴을 명확히 한다.

4. 스프레드시트나 데이터베이스 연결을 생각한다.

5. 작은 폴더(5~10개 파일)로 먼저 자동화한다.

그리고 한 가지 팁. 이미지 품질이 낮으면 Claude도 헤맨다. 가능하면 원본 파일이나 스캔 해상도를 높이는 게 정확도를 크게 올린다.