이벤트 트리거 시스템
트리거의 세 종류
1. 시간 기반
캘린더 이벤트 N분 전
매일 특정 시각
매주 특정 요일
2. 이벤트 기반
새 캘린더 이벤트 생성
이벤트 제목에 키워드 포함
이벤트 수정
3. 조건 기반
이벤트에 첨부파일 있음
참석자 N명 이상
특정 캘린더 카테고리
구현 구조 — 두 레이어
레이어 1: Watcher (감지)
class CalendarWatcher:
def evaluate(self, event) -> list[Trigger]:
triggered = []
# 시간 기반
if start - now <= timedelta(minutes=30):
if not already_triggered(event.id, "30min"):
triggered.append(Trigger(event, "before_30min"))
# 키워드 기반
if any(kw in event.title for kw in ["리뷰", "회의"]):
triggered.append(Trigger(event, "meeting_keyword"))
return triggered
레이어 2: Router (라우팅)
TRIGGER_SKILL_MAP = {
"before_30min": "research_before_meeting",
"has_attachment": "download_and_index",
}
class TriggerRouter:
def route(self, trigger):
# 단순 → 즉시 매핑
if trigger.type in TRIGGER_SKILL_MAP:
return TRIGGER_SKILL_MAP[trigger.type]
# 복잡 → LLM 판단
return llm.decide_skill(trigger.event, available_skills)
전체 흐름
캘린더 이벤트
↓
Watcher 감지
↓
Trigger 생성 (type + event 정보)
↓
Router → Skill 선택
단순: 즉시 매핑
복잡: LLM 판단
↓
Agent → Skill 실행
트리거 중복 방지
같은 이벤트에 트리거가 여러 번 발생하면 안 됨 → 실행 기록 저장 필요.
def already_triggered(event_id, trigger_type) -> bool:
return db.exists(
"SELECT 1 FROM triggers WHERE event_id=? AND type=?",
(event_id, trigger_type)
)
사용자별 트리거 설정
# 사용자 A
triggers:
- condition: "before_30min"
skill: "research_before_meeting"
filter: "title contains '논문'"
# 사용자 B
triggers:
- condition: "before_60min" ← 다른 시간
skill: "prepare_brief" ← 다른 Skill
filter: "calendar == 'work'"
사용자별로 다른 것: 트리거 조건, 필터, 연결된 Skill
관련 개념
- skill-composition-model — Skill 조합 구조
- skill-selection-mechanism — LLM이 Skill 선택하는 방법
- tool-registry-architecture — Tool Registry 전체 구조