포스트

LangBot으로 여러 메신저를 함께 운영해도 될까: 이벤트, 세션, Rate Limit 설계

LangBot은 Slack, Discord, Telegram처럼 서로 다른 메신저를 하나의 에이전트 파이프라인에 연결할 때 반복되는 어댑터 코드를 줄여 줍니다. 다만 메시지 형식을 통일했다고 사용자 신원, 플랫폼별 UX, Rate Limit과 장애까지 같아지는 것은 아닙니다. 도입 여부는 지원 채널 수보다 공통 계층과 채널 전용 계층을 어디서 나눌 수 있는지로 판단해야 합니다.

LangBot은 원문 기준 여러 IM 플랫폼, LLM 공급자, RAG, Agent 기능과 MCP 연동을 한 코드베이스에서 다루는 프로젝트입니다. 아래 분석은 저장소와 공식 문서에 소개된 구조를 바탕으로 하며, 지원 플랫폼과 설정 필드는 버전에 따라 바뀔 수 있습니다.

여러 메신저를 묶으면 무엇이 실제로 공통화되는가?

플랫폼 어댑터는 Slack 이벤트, Discord 메시지와 Telegram 업데이트처럼 모양이 다른 입력을 공통 MessageEvent에 가까운 형태로 바꿉니다. 이후 파이프라인은 어느 채널에서 왔는지와 무관하게 세션을 찾고, RAG 문맥이나 도구 목록을 붙인 뒤 LLM을 호출할 수 있습니다. 이 경계가 분명하면 FAQ 검색이나 사내 규정 안내 같은 핵심 로직을 채널마다 복제하지 않아도 됩니다.

그러나 정규화 과정에서 정보가 사라질 수 있습니다. 스레드와 채널, 멘션 범위, 첨부 파일 권한, 버튼 상호작용은 플랫폼마다 의미가 다릅니다. 공통 이벤트에는 원본 이벤트 ID, 채널, 스레드 ID, 회신 주소와 권한 문맥을 함께 남겨야 합니다. 지원하지 않는 필드를 조용히 버리면 개인 메시지의 답이 공개 채널로 나가거나, 같은 이벤트를 재수신했을 때 LLM 호출이 중복되는 문제가 생깁니다.

판단 항목공통 계층이 맡을 일채널 어댑터가 맡을 일
메시지텍스트, 첨부 메타데이터, 대화 ID 정규화길이 제한, 마크다운, 버튼과 스레드 표현
실행RAG, LLM, MCP 호출과 감사 로그빠른 수신 확인, 전송 재시도, API 오류 해석
정책사용자 역할과 도구 허용 범위플랫폼 계정과 내부 주체의 검증된 매핑
출력답변 청크와 최종 상태 생성수정 주기, 분할 전송, 삭제, 편집 권한 처리

세션과 사용자 신원은 어떻게 분리해야 하는가?

플랫폼 사용자 ID를 곧바로 장기 메모리의 키로 쓰면 같은 사람이 채널을 옮길 때 문맥이 끊깁니다. 반대로 이름이나 이메일이 비슷하다는 이유로 계정을 자동 병합하면 다른 사람의 대화와 권한이 섞일 수 있습니다. 안전한 구조는 platform identity → verified principal → conversation session을 분리합니다. 회사 SSO 연결이나 일회성 확인으로 주체를 매핑하고, 확인되지 않은 외부 사용자는 플랫폼 범위의 별도 주체로 유지합니다.

세션 키도 사용자 하나만 보면 부족합니다. 공개 채널의 질문, 개인 메시지와 고객별 지원 스레드는 서로 다른 정보 경계를 가집니다. tenant + principal + channel + thread 조합처럼 대화 범위를 명시하고, RAG가 읽을 수 있는 문서와 MCP 도구 권한을 세션마다 다시 계산해야 합니다. 채널을 옮겨 대화를 이어 주는 기능은 편의 기능이 아니라 정보 공개 정책이므로 사용자의 명시적 선택과 감사 기록이 필요합니다.

예를 들어 Slack 내부 직원은 결제 현황 조회 도구를 쓸 수 있지만 Telegram 커뮤니티 사용자는 공개 FAQ만 조회한다고 가정해 봅시다. 두 채널을 같은 파이프라인에 붙이더라도 검색 인덱스, 도구 allowlist와 응답 로그 보존 기간은 달라야 합니다. 공통 파이프라인은 로직 재사용 단위이지 권한을 합치는 단위가 아닙니다.

스트리밍과 Rate Limit은 어디에서 제어해야 하는가?

LLM은 토큰을 연속으로 내보내지만 메신저 API는 메시지 수정 횟수와 길이에 제한을 둡니다. 토큰마다 메시지를 갱신하면 사용자가 읽기 전에 화면이 흔들리고, 429 응답과 재시도가 겹쳐 더 느려질 수 있습니다. LangBot 같은 중간 계층의 버퍼는 일정 시간이나 문장 경계까지 토큰을 모은 뒤 채널별 속도로 갱신하는 역할을 합니다.

하나의 전역 제한만 적용해서도 안 됩니다. 수신 직후 확인 응답이 필요한 플랫폼은 먼저 짧게 수락하고 실제 LLM 작업을 큐로 넘겨야 하며, 전송 제한은 워크스페이스, 봇, 채널 단위로 따로 계산할 수 있습니다. 같은 이벤트가 재전달될 때는 원본 이벤트 ID를 idempotency key로 삼아 중복 호출을 막습니다. 재시도는 지수 백오프와 최대 횟수를 두고, 끝내 전송하지 못하면 원본 요청과 생성된 답을 재처리 큐나 감사 로그에서 찾을 수 있어야 합니다.

부하 시험은 평균 응답 시간만 보면 부족합니다. 동시 멘션이 몰릴 때 수신 확인 지연, 큐 대기 시간, LLM 동시 호출 수, 429 비율, 중복 답변과 최종 메시지 누락을 측정하세요. 큐가 가득 찼을 때는 무한 대기 대신 새 요청을 거절하거나 짧은 안내를 보내는 실패 모드가 필요합니다. 이 한계가 없으면 메신저 장애가 LLM 비용 폭증으로 번집니다.

설정 예시는 어떻게 읽어야 하는가?

다음은 원문에 제시된 개념적 설정입니다. 실제 필드명과 지원 방식은 설치한 버전의 문서를 확인해야 하며, API 키와 봇 토큰을 파일에 직접 저장해서는 안 됩니다. 비밀 값은 비밀 저장소의 참조로 주입하고, 개발, 운영 계정을 분리해야 합니다.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
{
  "pipeline_id": "enterprise_support_tier_1",
  "llm_provider": {
    "name": "deepseek_r1",
    "type": "llm",
    "model": "deepseek-chat",
    "api_key": "sk-YOUR-API-KEY"
  },
  "adapters": [
    {"platform": "discord", "token": "MTA..."},
    {"platform": "slack", "token": "xoxb..."},
    {"platform": "telegram", "token": "1234..."}
  ],
  "agent_logic": {
    "knowledge_base_id": "internal_faq_embeddings",
    "plugins": ["dify_workflow_trigger", "mcp_internal_api"]
  }
}

설정에서 확인할 것은 연결 성공 여부만이 아닙니다. 각 어댑터의 최소 권한, 토큰 교체 절차, 이벤트 구독 범위와 개발 환경의 테스트 채널을 문서화해야 합니다. 하나의 파이프라인이 세 채널을 공유할 때도 배포는 채널별 canary로 진행하는 편이 낫습니다. 먼저 읽기 전용 FAQ에 붙여 메시지 정규화와 회신을 검증하고, 실패율이 안정된 뒤 다음 채널을 엽니다.

MCP 도구를 연결할 때 승인 경계는 어디인가?

MCP 통합은 사내 API를 일관된 도구 형태로 제공할 수 있지만, 서버 URL을 등록하는 것만으로 안전한 업무 자동화가 완성되지는 않습니다. get_billing() 같은 조회와 approve_payment(id) 같은 상태 변경은 위험도가 다릅니다. 모델에게 두 도구가 모두 보이더라도 서버는 사용자 역할과 대상 자원을 다시 검사하고, 결제 승인에는 계획 미리보기와 사람 승인을 요구해야 합니다.

권장 흐름은 질문 수신, 사용자, 채널 확인, 허용 도구 검색, 읽기 작업 실행, 변경 계획 표시, 승인 후 쓰기 실행, 결과 감사의 순서입니다. 외부 API가 성공했는데 메신저 회신만 실패할 수 있으므로 실행 결과는 별도 상태 저장소에 기록하고 같은 승인 ID의 중복 실행을 막아야 합니다. Dify나 n8n을 함께 쓰더라도 승인과 idempotency 책임을 어느 계층이 가지는지 하나로 정해야 합니다.

LangBot이 맞지 않는 경우는 언제인가?

채널이 하나이고 플랫폼 고유 UI가 제품의 핵심이면 전용 SDK가 더 단순할 수 있습니다. Slack Block Kit이나 Discord 컴포넌트를 깊게 활용할수록 공통 이벤트 위에 예외 계층이 늘어나 추상화의 이점이 줄어듭니다. 작은 알림 봇에 웹 관리 패널, 데이터베이스와 여러 워커를 함께 운영하는 것도 과한 선택일 수 있습니다.

반대로 동일한 지식, 도구를 세 개 이상의 채널에 제공하고, 채널 추가 때 비즈니스 로직을 복제하고 있다면 통합 계층의 가치가 커집니다. 이때도 플랫폼 어댑터, 에이전트 코어와 도구 서버 사이에 자체 인터페이스를 두어 특정 플러그인 API에 핵심 정책이 묶이지 않게 하세요. 내보낼 수 없는 세션 데이터나 전용 플러그인이 많으면 이후 이전 비용이 커집니다.

도입 전 작은 비교 실험을 권합니다. 같은 FAQ 30개를 기존 봇과 LangBot 기반 봇에 보내 채널별 성공률, p95 응답 시간, 429, 재시도, 잘못된 스레드 회신과 운영 변경 시간을 비교합니다. 기능 수보다 장애를 한 채널에 격리할 수 있는지, 권한과 세션 경계가 로그에서 설명되는지, 플랫폼 전용 기능을 예측 가능한 비용으로 추가할 수 있는지가 채택 기준입니다.

원문과 버전 확인

함께 읽으면 이해가 이어지는 글

자주 묻는 질문

LangBot을 쓰면 메신저별 코드를 전혀 작성하지 않아도 되나요?

아닙니다. 공통 텍스트 대화는 어댑터로 줄일 수 있지만 Slack Block Kit, Discord 컴포넌트처럼 플랫폼 고유 UX와 인증, 오류 규칙은 별도 구현과 시험이 필요합니다.

같은 사람이 Slack과 Telegram에서 접속하면 대화를 자동으로 이어도 되나요?

플랫폼 사용자 ID만으로는 동일인임을 확인할 수 없습니다. 회사 계정 연동이나 일회성 확인 절차로 내부 주체와 매핑하고, 채널별 공개 범위와 보존 정책을 함께 적용해야 합니다.

LLM 스트리밍 응답은 모든 메신저에서 그대로 보여 줄 수 있나요?

각 플랫폼의 수정 빈도와 메시지 길이 제한이 달라 그대로 전송하기 어렵습니다. 채널별 버퍼 크기와 갱신 간격을 두고 제한 초과 시 분할, 최종 응답 전환, 재시도 정책을 마련해야 합니다.

THE END / OPSOAI

여기까지 읽었습니다

핵심 장면을 한 번 더 떠올려 보세요. 이해가 남았다면 이 책은 제 역할을 다했습니다.

다른 책 고르기
표지 1 —

←→ 키와 좌우 스와이프를 지원합니다. 읽던 페이지는 이 기기에 저장됩니다.

CONTENTS

이 책의 목차

    10개 장 18 분읽는 시간