코드 없이 Telegram에서 조달 시스템을 구축한 테크 리드: 에이전틱 개발 사례 연구
팀 내 조달 과정이 요청 분실과 조정되지 않은 문의로 혼란에 빠지자, 테크 리드는 Telegram 기반 시스템을 만들기로 결정했습니다. 코드 한 줄도 작성하지 않고 에이전틱 시스템과 명확한 아키텍처를 활용해 OCR, 검토, 안전한 배포를 갖춘 솔루션을 구축했습니다. 품질 관리를 잃지 않고 이를 구현하는 방법입니다.
문제: 조달 프로세스 대신 혼란
소규모 팀에서 조달은 종종 비공식적인 합의로 시작합니다. 먼저 종이 쪽지, 그다음 메모, 그리고 전용 Telegram 스레드. 프로세스가 생깁니다: 링크, 가격, 수량, 사유를 적어 올리기. 하지만 실제로는 일부 요청이 사라지고, 다른 건 빠져나가며, 가격이나 사유가 누락되고, 사람들은 자신의 요청조차 잊어버립니다. 결과적으로 테크 리드는 조달 관리 대신 혼란과 싸우는 데 시간을 씁니다. 핵심 교훈: 돈이 걸린 프로세스는 자유로운 채팅 형태로 존재해서는 안 됩니다.
인프라 요구사항: '간단한 봇'에서 완전한 시스템으로
초기 아이디어—간단한 Telegram 봇—는 곧 인프라 도전에 부딪혔습니다. VPN 없이 Telegram의 불안정성 때문에 다음이 필요했습니다:
- 해외 VPS
- 맞춤 VPN 설정
- 안정적인 자동 재시작
- 편리한 배포
- 실패한 릴리스에 대한 롤백 메커니즘
이제는 '저녁에 간단히 짜는 스크립트'가 아니라 완전한 엔지니어링 파이프라인입니다. 경험상 '간단한 자동화' 뒤에는 종종 복잡한 인프라가 숨어 있습니다.
에이전틱 개발: 사고를 대체하는 게 아니라 가속화
이 프로젝트는 ChatGPT와 에이전틱 시스템을 사용해 구현되었지만, 테크 리드의 적극적인 개입이 필수적이었습니다. 프로세스는 다음과 같았습니다:
- 작업 수립과 역할 배정
- 비즈니스 로직 명확화
- 시나리오 수동 테스트
- 모순 및 버그 식별
- 대상 수정 반복
- 재테스트
에이전트는 사이클을 가속화했습니다: 문제를 발견하고 새로운 구현을 검증하는 시간을 단축했습니다. 핵심 교훈: 코드 문법은 위임할 수 있지만, 시스템 사고와 아키텍처는 여전히 핵심입니다. 명확한 프로세스 모델 없이 에이전트는 잘못된 로직 구현을 빠르게 할 뿐입니다.
'마법' 포기: 위자드 플로우로 전환
첫 번째 가설—링크에서 자동 데이터 추출—은 다음 이유로 실행 불가능했습니다:
- 사이트 다양성
- 불안정한 페이지 구조
- 모호한 가격
- 복잡한 데이터 렌더링
- 적대적인 마켓플레이스 로직
대신 위자드 플로우를 구현했습니다:
- 스크린샷 첨부
- 링크 제공
- 사유 작성
- 수량 지정
- 필요 시 가격 수동 입력 (OCR 실패 시)
- 확인 전 최종 카드 검토
이 접근은 덜 '와우'하지만, 운영 프로세스의 핵심인 제어 가능성을 보장합니다.
왜 LLM을 시스템 핵심으로 삼지 않았나
요청 처리에 LLM을 사용하는 게 매력적이었지만, 간단한 스택을 선택했습니다:
- Python
- Telegram bot framework
- SQLite
- 로컬 OCR
- 템플릿 기반 HTML 보고서
- 서비스와 타이머를 위한 systemd
이유:
- 저사양 VPS에서 실행
- 외부 API에 대한 런타임 종속성 없음
- 요청당 유료 추론 없음
- 쉬운 디버깅
- 예측 가능한 동작
이 선택은 핵심 원리를 강조합니다: 모든 작업이 AI로부터 이익을 보는 건 아닙니다. 때로는 엄격한 FSM과 검증이 복잡한 모델보다 더 큰 가치를 줍니다.
상태 머신: 신뢰성의 기반
요청은 Draft부터 Sent까지 상태를 포함한 라이프사이클을 가진 엔티티입니다:
- Draft
- Awaiting image
- Awaiting link
- Awaiting justification
- Awaiting confirmation
- Pending moderation
- Returned for revision
- Deferred to next period
- Urgent
- Sent
이 사이클을 관리하기 위해 FSM을 사용했습니다. 코드 예시:
class PurchaseWizard(StatesGroup):
waiting_for_image = State()
waiting_for_link = State()
waiting_for_reason = State()
waiting_for_qty_lots = State()
waiting_for_lot_size = State()
waiting_for_manual_price = State()
waiting_for_confirmation = State()
그리고 도메인 상태:
class PurchaseStatus(str, Enum):
DRAFT = "draft"
AWAITING_IMAGE = "awaiting_image"
AWAITING_LINK = "awaiting_link"
AWAITING_REASON = "awaiting_reason"
AWAITING_QTY = "awaiting_qty_lots"
AWAITING_CONFIRMATION = "awaiting_confirmation"
COMPLETE = "complete"
PENDING_MODERATION = "pending_moderation"
RETURNED_FOR_REVISION = "returned_for_revision"
APPROVED = "approved"
CANCELLED = "cancelled"
SENT = "sent"
역할, 돈, 마감이 걸려 있으면 메시지 처리에서 상태 관리로 전환하세요.
아키텍처: 단순함이 성숙의 표시
시스템 다이어그램:
Telegram user
↓
Bot handlers / FSM
↓
Purchase service
├── SQLite
├── OCR service
├── Moderation logic
├── HTML report builder
└── Reminder / maintenance jobs
↓
systemd service + timers
프로젝트 구조:
purchase_bot/
├── app/
│ ├── bot/
│ ├── db/
│ ├── services/
│ ├── templates/
│ └── main.py
├── data/
│ ├── uploads/
│ ├── reports/
│ └── bot.db
├── scripts/
├── deploy/
└── README.md
첫 버전에서 Docker와 무거운 DB를 생략해 기능에 집중할 수 있었습니다. 내부 도구에서 단순한 아키텍처는 약점이 아니라 성숙의 표시입니다.
Telegram UX: 메시지 스트림 대신 인터페이스
Telegram 작업에서 도전 과제가 드러났습니다:
- 지속되는 오래된 버튼
- 겹치는 카드
- 병렬적인 오래된/새로운 요청 버전
- 알림 지연
- 일관되지 않은 '뒤로' 버튼 동작
- 화면 반복
- 채팅 혼잡
해결: 봇을 화면 기반 상태 시스템으로 설계. 핵심 원리:
- 단일 활성 화면
- 오래된 메시지 삭제
- 오래된 콜백 버튼 안전 처리
- 메뉴, 알림, 작업 카드에 대한 별도 규칙
화려하지 않지만, 매일 사용성을 보장합니다.
실제 프로세스는 대칭을 깨뜨린다
검토, 긴급 요청, 기간 이연 구현에서 실제 프로세스는 깔끔한 다이어그램과 맞지 않음을 알았습니다. 예를 들어 첫 번째 검토가 요청을 완전히 처리했다면 두 번째 단계는 불필요한 마찰을 더할 수 있습니다. 로직은 다이어그램이 아니라 실제 필요에 맞게 재구축해야 했습니다. 테크 리드들은 이 패턴을 압니다: 스키마가 흐름을 방해하면 스키마를 깨뜨리세요.
계층 경계에서 가장 교활한 버그
치명적 오류는 핵심 기능이 아니라 계층 교차점에서 발생했습니다. 예:
- '확인' 버튼이 타임존 인식 vs 비인식 객체 비교로 멈춤
- 모듈 간 데이터 형식 불일치
- 업데이트 시 상태 동기화 문제
이 버그들은 컴포넌트 인터페이스 설계의 중요성을 강조합니다.
핵심 교훈
- 에이전트보다 아키텍처: 에이전틱 시스템이라도 명확한 아키텍처와 시스템 사고가 필수입니다. 에이전트는 구현을 가속화할 뿐 설계를 대체하지 않습니다.
- '똑똑함'보다 제어 가능성: 운영 프로세스에서 신뢰성과 단순함이 복잡한 자동화보다 우위입니다. 위자드 플로우가 완전 자동화 시도보다 종종 우수합니다.
- 메시지가 아닌 상태: 역할, 돈, 마감이 있으면 명시적 상태를 가진 관리된 라이프사이클로 설계하세요.
- 단순함을 전략으로: 내부 도구에서 아키텍처 팽창을 피하세요. 소박한 하드웨어의 최소 스택이 신뢰성과 유지보수를 보장합니다.
- Telegram UX는 규율을 요구: 봇은 메시지 스트림이 아닌 화면 시스템으로 설계하세요. 오래된 요소 삭제와 단일 화면이 사용자 경험의 핵심입니다.
— Editorial Team
아직 댓글이 없습니다.