← 전체 프로젝트
프로토타입 G-Man Auto Parts · 2026

카탈로그 데이터용 LangGraph 에이전트

데이터팀은 외부 카탈로그 데이터를 손으로 적재했고, 이 일은 느렸습니다. 저는 짧은 요청을 받아 그에 맞는 부품 데이터를 가져오고, 정리해서 카탈로그에 써 넣는 에이전트 워크플로를 만들었습니다. 작업은 예약된 일정에 따라 실행되고, 실패한 뒤에도 이어서 진행되며, 누구나 확인할 수 있는 리포트로 끝납니다.

역할
혼자 만들었습니다. 리서치, 아키텍처, 에이전트, 일정 관리, 데모 UI까지 모두 맡았습니다.
상태
데이터팀을 위한 데모 UI를 갖춘 작동하는 프로토타입입니다. 2026년 7월 제가 퇴사할 때는 프로덕션에 적용되지 않은 상태였습니다.
기술 스택
Python, LangGraph, OpenAI API, APScheduler, PostgreSQL
범위
회사가 취급하는 7개 차량 브랜드의 브랜드, 모델, 연식, 지역 요청

문제

외부 차량·부품 데이터를 회사 카탈로그에 적재하는 일은 반복적인 수작업이었습니다. 담당자가 여러 파라미터를 고르고, 데이터를 내려받아 정리한 뒤, 각 레코드를 알맞은 카탈로그 테이블에 매핑해야 했습니다.

목표는 이 과정을 자동화해 데이터팀이 더 이상 손으로 하지 않아도 되게 하는 것이었습니다.

작동 방식

  1. 요청 드롭다운 목록에서 브랜드, 모델, 연식, 지역을 선택합니다.
  2. 세부 모델 확인 일치하는 모든 차량 세부 모델을 찾고, 가져올 카탈로그 범위로 확장합니다.
  3. 가져오기 캐싱과 재시도를 적용해 외부 카탈로그 API를 호출합니다.
  4. 정규화와 매핑 레코드를 정리하고 알맞은 카탈로그 테이블에 매핑합니다.
  5. 저장 체크포인트를 두고 PostgreSQL에 배치로 저장하므로, 작업을 안전하게 재개하거나 취소할 수 있습니다.
  6. 리포트 각 배치가 어떻게 정규화되고 매핑되었는지 보여 주어, 데이터팀이 확인할 수 있게 합니다.
  • 스케줄러예약 실행과 수동 실행을 위한 작은 UI를 갖춘 APScheduler
  • 캐시카탈로그 데이터를 그룹 단위까지 캐싱
  • 제어범위 제한, 작업 상태, API 사용량 표시
에이전트 워크플로입니다.

구축한 내용

  • 단순하게 시작해 예측 가능하게. 첫 버전은 자연어 요청을 받고, 요청을 명확히 하는 단계를 거쳤으며, 디버깅을 위해 에이전트의 모든 단계를 추적했습니다. 워크플로가 안정된 뒤에는 자유 텍스트 대신 드롭다운 입력을 사용해 실행을 반복 가능하게 만들었습니다.
  • LangGraph를 선택한 이유. LLM이 맡는 일은 전체 작업의 작은 부분입니다. 그래도 LangGraph는 충분히 가치가 있습니다. 워크플로가 구조화되고, 점검하기 쉬우며, 실패 후에도 재개할 수 있습니다.
  • 대규모 작업 대응. 저장은 청크 단위로 나뉘고 재개할 수 있으므로, 변형이 10만 개 이상인 차량 모델도 실패한 뒤 처음부터 다시 시작하지 않습니다.
  • 일정 관리. APScheduler가 작은 UI에서 작업을 예약 실행하거나 요청 즉시 실행합니다.
  • 사람이 검토할 수 있는 결과물. 자동 리포트가 각 배치의 정규화와 매핑 과정을 보여 주므로, 엔지니어가 아닌 사람도 결과를 검토할 수 있습니다.
  • 문서화. 에이전트가 읽는 테이블과 쓰는 테이블을 정리한 카탈로그 스키마 참고 문서를 작성했습니다.

엔지니어링 판단

개발에 앞서 직접 만들지, 기존 도구를 도입할지 비교했습니다. 기존 AI 데이터 수집 도구와 Airflow, Prefect, Celery 같은 워크플로 엔진을 검토한 뒤, 프로젝트 단계에 맞고 나중에 키울 수 있는 가벼운 방식을 선택했습니다.

또한 작업 범위와 과금되는 API 사용량을 자율 동작 뒤에 숨기지 않고 눈에 보이게 했습니다. 이 설계는 수작업을 줄이면서도 비용과 데이터에 대한 통제권을 사람에게 남겨 둡니다.

상태

프로토타입은 작동하며, 예약 실행과 데이터팀용 데모 UI를 갖췄고, 하나의 내부 관리자 도구로 통합되는 중이었습니다. 2026년 7월 제가 퇴사할 때는 프로덕션에 적용되지 않은 상태였습니다.

이 페이지에는 회사 코드, 내부 데이터, 비공개 URL을 싣지 않았습니다.