Post

LLM 기반 개인 에이전트 설계기 - LifeRPG 아키텍처와 설계 결정

LLM 기반 개인 에이전트 설계기 - LifeRPG 아키텍처와 설계 결정

프로젝트 소개

LifeRPG는 현실의 자기 성장을 방치형 RPG처럼 느끼게 해주는 개인 성장 에이전트다. 텔레그램으로 “오늘 알고리즘 2문제 풀었어”라고 보고하면, Claude가 맥락을 이해하고 RPG식 전투 결과 + 스탯 변화 + 랜덤 드롭을 돌려준다.

1
2
3
4
5
6
7
8
9
10
11
나: 오늘 NeetCode DP 2문제 풀었어

⚔️  [전투 결과]
메모리 릭 슬라임 x2 처치!

DEV  +4  |  INT  +2  |  경험치 +120
🎲 드롭: [희귀] '재귀 검' — DP 패턴을 꿰뚫는 자에게만

━━━━━━━━━━━━━━━━━━━━━
Lv.14 백엔드 나이트
████████░░  80%  (다음 레벨까지 24 xp)

기존 습관 앱(Habitica 등)과의 차이점:

  • 수동 체크박스가 아니라 자연어 보고 → Claude가 파싱
  • 고정 세계관이 아니라 내 직업 기반 세계관 → “백엔드 개발자”면 레거시 코드 골렘을 처치
  • 단순 +XP가 아니라 맥락 있는 피드백 → “3일 연속 DP네, 슬슬 고급 패턴 보일 때다”

아키텍처

flowchart TD
    A["텔레그램 DM"] -->|자연어 보고| B["텔레그램 봇 API"]
    B --> C["Python 앱"]
    
    subgraph core["핵심 처리"]
        C --> D{"단순 태스크?"}
        D -->|Yes| E["룰베이스 처리<br>(캐싱된 패턴)"]
        D -->|No| F["Claude API<br>(자연어 파싱)"]
        E --> G["보상 엔진<br>(XP/스탯/드롭 계산)"]
        F --> G
        G --> H["Claude API<br>(나레이션 생성)"]
    end
    
    H --> I["텔레그램 결과 메시지"]
    G --> J["SQLite<br>(캐릭터 상태 영속화)"]

핵심 설계 결정: LLM 호출을 3곳으로 제한

Claude API 호출은 비용이 든다. 매번 호출하면 API 비용이 빠르게 증가하고, 응답 시간도 느려진다. 그래서 LLM이 반드시 필요한 3곳에만 호출하고, 나머지는 Python 로직으로 처리한다.

flowchart LR
    subgraph llm["Claude API (3곳만)"]
        A["1. 자연어 파싱<br>'DP 2문제 풀었어'<br>→ {category: algo, count: 2}"]
        B["2. 나레이션 생성<br>전투 결과 텍스트 생성"]
        C["3. 요구 스탯 추천<br>목표 등록 시 필요 스탯 제안"]
    end
    subgraph code["Python 로직 (나머지 전부)"]
        D["XP/스탯 계산"]
        E["레벨업 판정"]
        F["랜덤 드롭 확률"]
        G["준비도 % 계산"]
        H["스트릭 카운터"]
    end
처리 영역방식이유
자연어 파싱LLM“DP 2문제”를 구조화하려면 자연어 이해가 필요
XP/스탯 계산코드공식이 정해져 있으므로 결정론적 처리
나레이션 생성LLM매번 다른 재미있는 텍스트를 만들어야 함
레벨업/드롭코드확률 계산은 정확해야 함
요구 스탯 추천LLM“구글 코테 D-30”에 필요한 스탯은 LLM이 추론
준비도 계산코드현재 스탯 vs 요구 스탯 갭은 단순 산술

이 원칙은 사내에서 진행한 파라미터 변경 자동화 Agent에서도 동일하게 적용했다. 확실한 것은 코드로, 판단이 필요한 것은 LLM으로.


캐릭터 시스템: 2중 레벨 구조

flowchart TD
    subgraph char["캐릭터 시스템"]
        subgraph basic["기본 스탯"]
            A["체력 VIT<br>(운동, 수면)"]
            B["지력 INT<br>(공부, 독서)"]
            C["정신력 WIS<br>(루틴 유지)"]
            D["사회력 CHA<br>(네트워킹)"]
        end
        subgraph job["직업 스탯"]
            E["DEV<br>(알고리즘, 코드리뷰)"]
            F["CAREER<br>(이력서, 면접)"]
            G["DOMAIN<br>(업무 깊이)"]
        end
    end
    H["종합 레벨<br>Lv.14 백엔드 나이트"] --> basic
    H --> job

종합 레벨과 스탯별 개별 레벨이 동시에 존재한다. RPG에서 “전사 Lv.50인데 마법 스탯은 Lv.3”인 것처럼, “종합 Lv.14인데 DEV는 Lv.20이고 CHA는 Lv.5”가 가능하다.


보상 엔진: 즉각적 도파민

flowchart TD
    A["태스크 완료 보고"] --> B["파싱 + 분류"]
    B --> C["XP 계산<br>(난이도 기반)"]
    C --> D["스탯 포인트 배분"]
    D --> E{"레벨업?"}
    E -->|Yes| F["레벨업 연출"]
    E -->|No| G["결과 메시지"]
    D --> H{"랜덤 드롭?"}
    H -->|"확률 히트"| I["희귀 아이템/스킬 획득"]
    H -->|"미스"| G
    F --> G
    I --> G

단순히 “+10 XP”만 주는 것이 아니라:

  • 난이도 기반 XP: “DP 문제”는 “물 마시기”보다 높은 XP
  • 스트릭 보너스: 연속 일수에 따라 보너스 배율
  • 랜덤 드롭: 슬롯머신 원리 — 예측 불가능한 보상이 습관 형성에 가장 효과적
  • 스킬 언락: DP 50문제 달성 시 “DP 해독자” 영구 스킬 획득

준비도 시스템: 목표와 현재의 갭

flowchart LR
    A["목표 등록<br>'Google 코테 D-30'"] --> B["Claude가<br>요구 스탯 추천"]
    B --> C["내가 조정 → 확정"]
    C --> D["현재 스탯 vs<br>요구 스탯 비교"]
    D --> E["준비도 %<br>매일 갱신"]
    E --> F["예상 클리어일<br>표시"]

“지금 나는 목표에 얼마나 가까운가?”를 수치로 보여준다. 매일 태스크를 수행하면 스탯이 오르고, 준비도 %가 올라간다. 목표까지의 거리를 객관적으로 파악할 수 있다.


기술 스택과 선택 근거

레이어선택근거
언어PythonDjango 4년 경험, 빠른 개발
저장소SQLite1인 사용 MVP, 복잡한 DB 불필요
LLMClaude Sonnet (Anthropic API)사내에서 1년+ 사용 경험, prompt caching 활용
인터페이스텔레그램 봇 API모바일/데스크톱 모두 사용, 별도 앱 개발 불필요
스케줄러APScheduler아침/점심 알림, 주간 리포트

왜 텔레그램인가

별도 앱을 만들면:

  • iOS/Android 개발 필요 → MVP 시간 3배 이상
  • 앱 설치 → 사용 장벽 높음
  • 푸시 알림 인프라 구축 필요

텔레그램이면:

  • 봇 API로 30분 만에 인터페이스 완성
  • 이미 설치된 앱에서 바로 사용
  • 푸시 알림 기본 제공
  • 마크다운, 이모지 지원으로 RPG 연출 가능

비용 최적화 전략

flowchart TD
    A["태스크 보고"] --> B{"이전에 같은 패턴?"}
    B -->|Yes| C["캐싱된 파싱 결과 사용<br>(LLM 호출 스킵)"]
    B -->|No| D["Claude API 파싱"]
    D --> E["결과 캐싱"]
    C --> F["보상 계산<br>(Python)"]
    E --> F
    F --> G["나레이션 생성<br>(Claude API)"]

“알고리즘 2문제 풀었어” 같은 반복 패턴은 한 번 파싱하면 결과를 캐싱한다. 매번 LLM을 호출하는 것보다 비용이 줄어든다.

추정 월 비용:

  • 하루 5~10회 보고 기준
  • 파싱: 캐시 히트율 60% 가정 → 월 ~120회 호출
  • 나레이션: 매번 호출 → 월 ~300회
  • Claude Sonnet 기준 월 $5 미만

개발 마일스톤

flowchart LR
    M1["M1: 뼈대 MVP<br>온보딩 → 파싱 → XP → 결과"] --> M2["M2: 게임 느낌<br>드롭, 레벨업 연출, 스킬"]
    M2 --> M3["M3: 보스 & 준비도<br>목표 등록, 준비도 %"]
    M3 --> M4["M4: 알림 & 캘리브레이션<br>자동 알림, 스탯 보정"]
    M4 --> M5["M5: 시각화<br>성장 그래프, 주간 리포트"]

원칙: M1 끝나기 전에 M2 안 본다. Scope creep이 사이드 프로젝트를 죽이는 가장 큰 원인이다.


실무 연결: 사이드 프로젝트에서 배운 것이 업무에 적용되는 방식

이 프로젝트를 설계하면서 만든 원칙들이 사내 프로젝트에도 그대로 적용됐다:

LifeRPG 설계 원칙사내 적용 사례
LLM 호출을 3곳으로 제한AI Agent에서 결정론적/LLM 경계 분리
단순 태스크는 룰베이스정형 패턴 70%는 코드로, 30%만 LLM
파싱 결과 캐싱prompt caching으로 API 비용 최적화
SQLite로 시작 → 필요시 확장pgvector로 시작 → 필요시 전용 벡터 DB

사이드 프로젝트는 “나를 위해 만드는 것”이지만, 설계 사고는 어디에서든 재사용된다.


느낀 점

개인 프로젝트의 가장 큰 장점은 “전체를 소유하는 경험”이다

회사에서는 시스템의 일부를 담당한다. 개인 프로젝트에서는 기획 → 설계 → 구현 → 운영 전체를 경험한다. 이 전체 시야가 회사에서 더 나은 설계 결정을 내리는 데 도움이 된다.

LLM API 비용 최적화는 설계 단계에서 결정된다

구현 후에 비용을 줄이려 하면 어렵다. 처음부터 “어디에 LLM을 쓰고 어디에 안 쓸 것인가”를 결정하면 비용과 성능 모두 잡을 수 있다.

텔레그램 봇은 과소평가된 프로토타이핑 도구다

별도 앱을 만들지 않고도 완전한 대화형 인터페이스를 구현할 수 있다. MVP 단계에서 UI 개발에 시간을 쓰는 것보다 핵심 로직에 집중하는 게 낫다.

This post is licensed under CC BY 4.0 by the author.