나는 10개 이상의 AI 워커를 Bash 스크립트로 실행한다 — 내가 Python을 사용하지 않는 이유
요약
자율형 AI 에이전트 워커를 구축할 때 Python 대신 Bash 스크립트를 사용하는 실용적인 이유와 장점을 설명합니다. 의존성 관리의 단순함, 시스템 타이머 활용, 파이핑의 강력함 등을 강조합니다.
핵심 포인트
- 의존성 제로: 가상 환경이나 추가 패키지 설치 없이 시스템 기본 도구만으로 실행 가능
- 네이티브 스케줄링: Systemd 타이머를 활용해 별도의 라이브러리 없이 작업 예약 가능
- 강력한 파이핑: 데이터 흐름을 직관적이고 간결하게 처리할 수 있는 파이프라인 구축
- 간편한 디버깅: set -x 명령어를 통해 실행 과정을 즉각적으로 확인 가능
나는 10개 이상의 AI 워커를 Bash 스크립트로 실행한다 — 내가 Python을 사용하지 않는 이유
모두가 나에게 미쳤다고 말했습니다.
"자율형 AI 에이전트 (Autonomous AI agents)를... _bash_로 만든다고요?"
네. 그리고 그것들은 몇 주 동안 24시간 내내 실행되며 프리랜서 제안서를 관리하고, 수익을 추적하며, GitHub 리포지토리 (repos)를 모니터링하고, 콘텐츠를 게시하고 있습니다. 이 모든 과정에서 단 한 번의 pip install도 없었습니다.
Python이 실제로 더 나음에도 불구하고 왜 내가 bash를 선택했는지, 그리고 도구를 선택하는 것에 대한 진짜 교훈은 무엇인지 소개합니다.
설정 (The Setup)
나는 여러 "워커 (workers)"를 조정하는 koi라는 AI 에이전트를 실행합니다. 각 워커는 특정 작업을 처리하는 작은 프로그램입니다:
- koi-worker-openwork: 프리랜서 플랫폼을 검색하고 제안서를 제출합니다.
- koi-github-fork-worker: 리포지토리 (repos)를 포크 (fork)하고, 개선 사항을 생성하며, PR (Pull Requests)을 생성합니다.
- koi-metrics: 모든 플랫폼에 걸쳐 주간 지표 (metrics)를 수집합니다.
- koi-finance: CSV 파일에 수입과 지출을 추적합니다.
각 워커는 bash 스크립트 (script)입니다. 어떤 것은 50줄 정도이며, 가장 큰 것은 약 200줄 정도입니다.
왜 Bash가 승리했는가
1. 의존성 제로 (Zero Dependencies)
#!/bin/bash
# 이 코드는 어떤 Linux 머신에서도 작동합니다. 끝.
curl -s "https://api.github.com/repos/owner/repo" | python3 -c "import json,sys; print(json.load(sys.stdin)['stargazers_count'])"
가상 환경 (virtual environments)도 필요 없습니다. requirements.txt도 필요 없습니다. "내 컴퓨터에서는 되는데" 같은 문제도 없습니다. 시스템에 bash, curl, 그리고 (JSON 파싱을 위한) python3가 있다면 실행됩니다.
2. Systemd 타이머 (Timers)는 네이티브입니다
# /etc/systemd/system/koi-worker.timer
[Unit]
Description=Run koi worker every 15 minutes
...
Systemd는 bash를 네이티브로 지원합니다. Celery도, APScheduler도 필요 없습니다. 기억해야 할 cron 문법도 없습니다. 그저 스크립트를 실행하는 타이머 유닛 (timer unit)만 있으면 됩니다.
3. 파이핑 (Piping)은 초능력입니다
# 트렌딩 리포지토리 (trending repos) 가져오기 → 필터링 → 포맷팅 → Telegram에 게시
curl -s "$API/search/repositories?q=topic:ai&sort=stars" \
| python3 -c "import json,sys; [print(f'{i[0]}: {i[1]}⭐') for i in [(r['full_name'], r['stargazers_count']) for r in json.load(sys.stdin)['items'][:5]]]" \
...
Python에서 동일한 가독성으로 이 작업을 해보려고 시도해 보세요. 한번 해보시죠.
4. 디버깅 (Debugging)은 그저... 읽는 것입니다
set -x # 디버그 모드 활성화
# 모든 명령어가 실행되기 전에 출력됩니다
...
pdb도, 중단점 (breakpoints)도, IDE도 필요 없습니다. 스크립트가 정확히 무엇을 하고 있는지 알려줍니다.
Python이 승리하는 경우
제가 Bash 광신도는 아닙니다. Python은 객관적으로 다음과 같은 상황에서 더 낫습니다:
복잡한 데이터 구조 (Complex Data Structures)
# Bash에서 이걸 유지 관리하려고 시도해 보세요
workers = {
"openwork": {"interval": 900, "last_run": 1718601600, "status": "ok"},
...
Bash에도 연관 배열 (associative arrays)이 있습니다. 하지만 형편없습니다. Python을 사용하세요.
인증이 포함된 API 클라이언트 (API Clients with Auth)
import requests
from requests_oauthlib import OAuth1Session
...
예외 처리 (Error Handling)
try:
result = risky_operation()
except RateLimitError:
...
Bash의 예외 처리는 set -e를 설정하고 기도하는 것뿐입니다.
테스트 (Testing)
def test_worker_parses_response():
mock_response = {"items": [{"full_name": "test/repo"}]}
result = parse_trending(mock_response)
...
Bash를 테스트할 수는 있습니다. 하지만 즐겁지는 않을 겁니다.
하이브리드 접근 방식 (내가 실제로 하는 방식)
비결은 이겁니다: 둘 다 사용하는 것입니다.
#!/bin/bash
# Bash를 이용한 워커 오케스트레이터 (Worker orchestrator)
# 무거운 작업은 Python으로 수행
...
규칙:
- Bash: 글루 코드 (glue code), 오케스트레이션 (orchestration), 파일 작업, 시스템 호출 (system calls) 용도
- Python: 데이터 처리, API 클라이언트, 복잡한 로직이 포함된 모든 작업 용도
- Systemd: 스케줄링 용도 (cron이나 Celery가 아님)
진짜 교훈
최고의 도구는 가장 우아한 도구가 아닙니다. 다음과 같은 도구입니다:
- 문제를 해결하는 도구 — "해결할 수도 있는" 것이 아니라 "해결하는" 도구
- 새벽 3시에도 디버깅할 수 있는 도구 — 문제가 발생했을 때 (만약이 아니라) 말이죠
- 어디서나 실행되는 도구 — 설정도, 의존성 (dependencies)도 필요 없는 도구
- 6개월 뒤에도 읽을 수 있는 도구 — 유지보수가 중요합니다
제 워커들에게는 Bash가 이 네 가지 조건을 모두 충족합니다. 제 데이터 파이프라인에는 Python이 충족합니다.
언어에 대해 논쟁하는 것을 멈추세요. 문제를 해결하기 시작하세요.
자율 에이전트 (autonomous agents)를 구축하는 것은 무질서하고, 반복적이며, 겸손해지는 과정입니다. 여러분도 같은 여정에 있다면, 저는 코드, 실패, 수치 등 모든 것을 공개적으로 공유합니다.
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기