Skip to content

외부 연동

truloop-assistant가 연동하는 외부 서비스들을 설명합니다.


연동 서비스 개요


Sendbird

역할

사용자와 AI 비서 간의 실시간 채팅 채널입니다.

방향용도
Sendbird → AssistantWebhook으로 사용자 메시지 수신 (POST /sendbird/webhook/{eid})
Assistant → SendbirdAI 응답 메시지 전송, JSON-RPC 요청 전송

통합 구현

src/truloop_assistant/integrations/sendbird/
├── client.py    # SendbirdClient (비동기 HTTP 클라이언트)
└── schemas.py   # Sendbird 데이터 모델

SendbirdClient 기능:

  • 채널 메시지 전송
  • 메시지 이력 조회
  • 사용자 정보 조회
  • custom_type 지정 메시지 발송 (JSON-RPC용)

환경변수

변수설명
SENDBIRD_API_URLSendbird API URL
SENDBIRD_API_TOKENSendbird API 토큰
SENDBIRD_TIMEOUTAPI 타임아웃 (기본: 20초)

truloop Core API

역할

사용자 정보, 룹 정보 등 비즈니스 데이터 조회 및 truloop-core에서 발생하는 Internal Event 수신을 담당합니다.

통합 구현

src/truloop_assistant/integrations/truloop/
├── client.py      # TruloopClient (도메인별 API 메서드)
├── schemas.py     # Pydantic 모델 (appointments, locations, users)
├── exceptions.py  # TruloopError
└── enums.py       # 상태 Enum

아키텍처

패턴설명
Per-Request 인스턴스각 Background task마다 별도의 TruloopClient 생성
httpx.AsyncClientasync with 컨텍스트 매니저로 연결 수명 관리
격리각 Background task가 독립적인 HTTP 클라이언트 보유
python
async with httpx.AsyncClient(
    base_url=settings.truloop_core_api_base_url,
    timeout=settings.truloop_core_timeout,
) as truloop_http:
    truloop_client = TruloopClient(truloop_http)
    deps = AgentDeps(user=user, truloop_client=truloop_client, ...)

Internal Events (truloop-core → assistant)

truloop-core에서 POST /internal/events로 전달되는 이벤트입니다. Discriminated union 기반 자동 검증:

이벤트설명
assistant.selected사용자가 봇을 선택 → 자기소개 메시지 발송
loop.scheduling_requested일정 조율 시작 → 참여자 전원에게 초대 알림
loop.guest_participant_added비회원이 초대 링크로 참여 → 호스트에게 알림
loop.guest_invited호스트가 비회원 추가 → SMS 초대 발송
loop.participant_availability_updated참여자 가용 시간 제출 → 호스트에게 알림

인증

변수설명
TRULOOP_CORE_API_BASE_URLCore API 기본 URL (기본: https://dev-api.truloop.app)
TRULOOP_CORE_TIMEOUTAPI 타임아웃 (기본: 30초)
TRULOOP_CORE_API_KEYInternal API 인증 키 (outgoing 요청 Authorization: Bearer)
INTERNAL_API_KEYInternal 이벤트 수신 인증 (X-Internal-API-Key 헤더 검증)

OpenRouter (LLM)

역할

AI Agent의 추론 엔진입니다. Claude Sonnet 4.6을 기본 모델로 사용합니다.

통합

pydantic-ai의 OpenRouterModel + OpenRouterProvider를 통해 연동합니다:

python
model = OpenRouterModel(
    settings.openrouter_model,          # "anthropic/claude-sonnet-4.6"
    provider=OpenRouterProvider(
        api_key=settings.openrouter_api_key,
    ),
    profile=anthropic_model_profile(model_name),
)

설정

변수기본값설명
OPENROUTER_API_KEY-OpenRouter API 키
OPENROUTER_MODELanthropic/claude-sonnet-4.6사용 모델
MODEL_TEMPERATURE0응답 온도 (0: 결정적, 1: 창의적)
MAX_TOKENS1000최대 응답 토큰 수

Redis

역할

대화 이력Pending tool call을 관리합니다.

용도TTL설명
대화 이력30일사용자별 메시지 기록
Pending tool calls1시간Deferred Tool 호출 추적

서비스

서비스역할
MessageHistoryService대화 이력 저장/조회 (최대 20개 메시지)
PendingCallServiceDeferred Tool 호출 상태 관리
변수기본값설명
REDIS_URLredis://localhost:6379/0Redis 연결 URL
MESSAGE_HISTORY_MAX_LENGTH20최대 대화 이력 수
MESSAGE_HISTORY_TTL_SECONDS2,592,000 (30일)이력 TTL

RAG (Knowledge Base)

역할

Notion 문서 기반의 지식 검색 시스템입니다. Agent가 사용자 질문에 답변할 때 관련 문서를 검색하여 컨텍스트를 보강합니다.

구현

컴포넌트기술역할
RAGService-검색 오케스트레이션
VectorStoreNumPy벡터 저장/검색 (Cosine similarity)
EmbeddingOpenAI text-embedding-3-small텍스트 → 벡터 변환
Vector Store 구조:
/app/vector_db/
├── {collection}_metadata.json   # 문서 메타데이터
└── {collection}_embeddings.npy  # 임베딩 벡터 (NumPy)

정보

RAG는 선택적 기능입니다. OPENAI_API_KEY가 설정되지 않으면 비활성화되며, 관련 Tool은 graceful하게 비활성 상태를 처리합니다.

변수기본값설명
OPENAI_API_KEY-OpenAI API 키 (비어있으면 RAG 비활성화)
VECTOR_DB_PATH/app/vector_db벡터 스토어 디렉토리
RAG_COLLECTION_NAMEnotion_docs컬렉션 이름
RAG_EMBEDDING_MODELtext-embedding-3-small임베딩 모델
RAG_TOP_K3검색 결과 수

Supermemory (장기 기억)

역할

사용자별 장기 기억을 저장하고 검색합니다. Agent가 이전 대화에서 학습한 사용자 선호도, 습관 등을 기억합니다.

데이터 격리

container_tags 패턴으로 사용자별 데이터를 격리합니다:

python
# 사용자별 태그 생성
tags = [
    f"user_{user_eid}",
    f"project_{project_name}",
    f"env_{env}",
]
변수기본값설명
SUPERMEMORY_API_KEY-Supermemory API 키 (비어있으면 비활성화)
SUPERMEMORY_PROJECT_NAMEtruloop-assistant프로젝트 이름

Google Maps

역할

장소 검색 기능을 제공합니다. places_tools.pysearch_places 도구에서 사용합니다.

구현

동기 라이브러리(googlemaps)를 asyncio.to_thread()로 비동기 실행합니다. 사용자 locale에서 region bias를 추출합니다 (예: ko-KRkr).

변수기본값설명
GOOGLE_MAPS_API_KEY`` (빈 문자열)API 키 (비어있으면 장소 검색 비활성화)

정보

Google Maps API는 선택적 기능입니다. GOOGLE_MAPS_API_KEY가 비어있으면 search_places 도구가 에러 메시지를 반환합니다.


Messaging Gateway (비회원)

주의

미구현 기능: SMS two-way 메시징은 향후 구현 예정입니다. 아래 코드 구조(인터페이스, 프로바이더, 스키마)는 scaffolding으로 존재하지만, 현재 프로덕션에서는 stub 프로바이더만 존재하며 실제 SMS 발송/수신은 동작하지 않습니다.

역할

비회원 사용자에게 SMS/RCS/WhatsApp 메시지를 전송하고, 비회원의 응답을 수신하는 것이 목표입니다.

프로바이더

프로바이더환경설명
stub개발/테스트메시지 로깅만 수행 (현재 유일하게 동작하는 프로바이더)
twilio프로덕션SMS 실제 발송 (미구현)

Webhook 수신 (미구현)

비회원의 SMS 응답은 POST /messaging/webhook/{provider} 엔드포인트로 수신될 예정입니다. GuestMessagingProcessorService가 비회원 Agent를 실행하여 가용 시간을 수집하는 구조이나, 현재 프로덕션에서 동작하지 않습니다.

src/truloop_assistant/integrations/messaging/
├── gateway.py            # MessagingGateway 인터페이스
├── providers/            # 프로바이더 구현 (stub.py만 동작)
└── schemas.py            # IncomingMessage 등 메시징 스키마
변수기본값설명
MESSAGING_PROVIDERstub프로바이더 선택 (stub / twilio). 현재 stub만 유효

연동 요약 다이어그램

정보

선택적 연동은 해당 API Key가 비어있으면 자동으로 비활성화됩니다. 서비스 시작이나 기본 기능에는 영향을 미치지 않습니다.


기타 환경변수

변수기본값설명
JWT_SECRET``JWT 토큰 검증 시크릿 (프로덕션에서 32자 이상 필수)
JWT_ALGORITHMHS256JWT 알고리즘
SENTRY_DSN``Sentry DSN (비어있으면 비활성화)
CHUNK_DELAY_MIN_MS400메시지 청킹 최소 딜레이 (ms)
CHUNK_DELAY_MAX_MS800메시지 청킹 최대 딜레이 (ms)

변경 이력

날짜변경 내용
2026-03-11비회원 Agent / SMS two-way 기능을 미구현 상태로 정정
2026-03-10Internal Events, Google Maps, Sentry/Logfire, JWT/청킹 환경변수 추가. Messaging Gateway Webhook 수신 설명 보강