
Stripe의 Kai 아키텍처: LangChain 및 Deep Agents를 활용한 전사적 에이전트 프레임워크 설계
요약
Stripe가 공개한 전사적 에이전트 프레임워크 'Kai'의 아키텍처를 분석합니다. LangChain과 Deep Agents를 활용하여 상태 관리, 보안 코드 실행, 중앙 집중식 거버넌스 문제를 해결하는 4계층 구조를 제안합니다.
핵심 포인트
- LangChain 기반의 오케스트레이션 계층을 통한 에이전트 생명주기 관리
- 에이전트, 스키마, 도구의 재사용을 위한 중앙 집중식 레지스트리 구축
- 보안과 자원 격리를 위한 실행 런타임과 오케스트레이션의 분리
- 비용 추적 및 보안 정책 집행을 위한 전용 API 게이트웨이 활용
🏗️ Stripe Kai 플랫폼의 아키텍처적 기둥
기업이 단순한 검색 증강 생성 (RAG, Retrieval-Augmented Generation) 파이프라인에서 자율적인 에이전트 시스템 (Agentic Systems)으로 전환할 때, 아키텍처의 복잡성은 비선형적으로 증가합니다. Stripe가 공개한 내부 지식 AI 플랫폼인 Kai는 이러한 변화를 잘 보여줍니다. 전사적 에이전트 프레임워크 역할을 수행하도록 구축된 Kai는 LangChain과 함께 다단계 추론 (Multi-step Reasoning), 자기 수정 (Self-correction), 그리고 동적 코드 실행 (Dynamic Code Execution)이 가능한 시스템인 "Deep Agents"를 활용합니다.
엔지니어링 리더들에게 Kai가 흥미로운 이유는 단순히 빠르게 구축되었기 때문이 아니라, 상태 관리 (State Management), 보안 코드 실행 (Secure Code Execution), 그리고 중앙 집중식 거버넌스 (Centralized Governance)와 같은 기업용 에이전트 배포의 근본적인 과제들을 어떻게 해결했는가에 있습니다. 에이전트 아키텍처를 분석하면서 저는 대부분의 조직이 이 지점에서 실패한다는 것을 발견했습니다. 그들은 제약 없는 환경에서 실행되는 취약하고 일회성인 에이전트들을 구축하며, 이는 보안 취약점, 통제 불가능한 토큰 비용, 그리고 유지보수가 불가능한 코드베이스로 이어집니다.
Kai를 이해하기 위해서는 먼저 그 거시적 아키텍처 (Macro-architecture)를 살펴보아야 합니다. 전사적 에이전트 프레임워크는 각자 자신의 LLM 클라이언트를 실행하는 고립된 마이크로서비스 (Microservices)의 집합체로 존재할 수 없습니다. 대신, 에이전트 정의, 오케스트레이션 (Orchestration), 그리고 실행을 분리하는 중앙 집중식 플랫폼으로 구조화되어야 합니다. 저는 기업용 에이전트 플랫폼의 핵심 아키텍처를 네 가지 별개의 계층으로 분류합니다:
- 오케스트레이션 계층 (The Orchestration Layer, 제어 평면 (The Control Plane)): 이 계층은 에이전트의 생명주기를 관리하고, 들어오는 요청을 라우팅하며, 상태 전이 (state transitions)를 조정합니다. Kai의 경우, 이 계층은 LangChain을 기반으로 구축되었으며, 상태 유지 그래프 구조 (stateful graph structures)를 활용하여 에이전트가 계획 (planning), 도구 실행 (tool execution), 응답 합성 (response synthesis) 사이를 어떻게 전환할지 정의합니다.
- 에이전트 레지스트리 및 카탈로그 (The Agent Registry and Catalog): 팀들이 자신들의 에이전트, 스키마 (schemas), 그리고 도구 정의를 등록하는 중앙 집중식 저장소입니다. 이는 중복 개발을 방지하고, 도구(예: 데이터베이스 커넥터 또는 내부 API 래퍼 (API wrappers))가 서로 다른 비즈니스 부서 전반에서 재사용될 수 있도록 보장합니다.
- 실행 런타임 (The Execution Runtime, 데이터 평면 (The Data Plane)): 실제 LLM 호출, 도구 실행, 그리고 코드 컴파일이 발생하는 곳입니다. 결정적으로, 이 런타임은 자원 고갈을 방지하고 보안 리스크를 격리하기 위해 오케스트레이션 계층과 분리되어야 합니다.
- 거버넌스 및 관측 가능성 게이트웨이 (The Governance and Observability Gateway): LLM을 위해 특별히 설계된 API 게이트웨이입니다. 이는 시맨틱 캐싱 (semantic caching), 속도 제한 (rate limiting), 비용 추적, 그리고 정책 집행(예: 프롬프트 인젝션 (prompt injection) 또는 데이터 유출 방지)을 처리합니다.
이러한 계층들을 중앙 집중화함으로써, 에이전트 개발을 위한 통합 인터페이스가 구축됩니다. 개발자가 새로운 에이전트(예: 가맹점 이탈을 분석하는 어시스턴트)를 구축할 때, LLM에 연결하거나 메모리를 관리하기 위한 상용구 코드 (boilerplate code)를 작성할 필요가 없습니다. 대신, 레지스트리에 선언적 에이전트 설정 (declarative agent configuration)을 등록하고 필요한 도구를 정의하기만 하면, 플랫폼이 오케스트레이션, 보안 및 상태 관리를 처리합니다.
이러한 관심사의 분리 (separation of concerns)는 매우 중요합니다. 이를 통해 플랫폼 팀은 개별 에이전트 구현을 깨뜨리지 않고도 LLM 제공업체 교체, 샌드박스 환경 (sandboxed environments) 업그레이드, 또는 캐싱 전략 튜닝과 같은 기반 인프라를 최적화할 수 있습니다. 또한 보안 정책이 개별 개발자가 올바르게 구현하기를 기다리는 대신, 전역적으로 강제되도록 보장합니다.
Stripe의 Kai 플랫폼에 대한 심층적인 아키텍처 분석입니다. LangChain, 보안 샌드박스 코드 실행 런타임(sandboxed code execution runtimes), 그리고 강력한 거버넌스(governance)를 사용하여 중앙 집중식 기업용 에이전트 프레임워크를 설계하는 방법을 알아보세요.
Deep Agents 구현: 상태(State), 메모리(Memory), 그리고 도구 호출 루프(Tool-Calling Loops)
단순한 에이전트들은 선형적인 "react" 루프를 기반으로 작동합니다. 즉, 입력을 받고, 도구를 호출하며, 출력을 반환합니다. Kai 아키텍처에서 개념화된 "Deep Agents"는 복잡하고 비선형적인 상태 머신(state machines) 위에서 작동합니다. 이들은 복잡한 프롬프트를 하위 작업들의 유향 비순환 그래프(DAG, Directed Acyclic Graph)로 분해하고, 해당 작업들을 병렬 또는 순차적으로 실행하며, 중간 결과들을 평가하고, 도구가 에러를 반환할 경우 동적으로 계획을 재수립(replanning)할 수 있어야 합니다.
이러한 수준의 자율성을 구현하기 위해, 저는 LangGraph와 같은 상태 유지 그래프 프레임워크(stateful graph framework)를 활용할 것을 권장합니다. LangGraph는 에이전트 워크플로우를 상태 머신으로 모델링하며, 여기서 노드(nodes)는 작업(LLM 호출 또는 도구 실행 등)을 나타내고, 엣지(edges)는 해당 작업의 출력에 기반한 상태 전이(state transitions)를 나타냅니다.
Deep Agent 아키텍처에서는 상태(state)가 명시적으로 정의되고 지속(persist)되어야 합니다. 이는 단순한 "채팅 기록"이 아닙니다. 에이전트의 현재 계획, 완료된 작업 목록, 해당 작업들의 출력, 그리고 발생한 모든 에러를 추적하는 구조화된 스키마(structured schema)입니다.
다음은 LangGraph를 활용하여 상태를 유지하는 Deep Agent 루프의 구체적인 Python 구현 예시입니다. 이 패턴은 에이전트가 코드 실행 도구의 출력을 평가하고, 실패할 경우 자동으로 코드를 다시 작성하는 자기 수정 루프(self-correction loop)를 어떻게 구현하는지 보여줍니다.
import json
from typing import Dict, List, TypedDict, Union
from langgraph.graph import StateGraph, END
...
이 패턴은 Deep Agents의 핵심적인 힘인 회복 탄력성(resilience)을 보여줍니다. 자기 수정 루프(self-correction loop)를 그래프 상태(graph state)에 직접 인코딩함으로써, 에이전트는 인간의 개입 없이도 구문 오류(syntax errors), API 타임아웃(API timeouts), 또는 논리적 버그(logical bugs)로부터 복구할 수 있습니다.
하지만 이러한 상태 머신(state machine)을 구현하려면 강력한 상태 지속성(state persistence)이 필요합니다. 프로덕션 환경(production environment)에서 인메모리(in-memory) 상태만으로는 불충분합니다. 만약 노드 실행에 30초가 걸리는 동안 서버가 재시작된다면, 에이전트 실행 전체를 잃게 됩니다. 저는 LangGraph의 체크포인터(checkpointer) 인터페이스를 사용하여 Redis나 PostgreSQL과 같은 지속성 저장소(persistent store)로 그래프 상태를 백업할 것을 권장합니다. 이를 통해 에이전트 실행을 일시 중지하고, 고위험 도구(high-risk tool)가 호출될 경우 인간 참여형(human-in-the-loop) 승인을 기다린 뒤, 실행을 원활하게 재개할 수 있습니다.
⚙️ 동적 코드 실행을 위한 보안 샌드박싱 (Secure Sandboxing)
아마도 Stripe의 Kai 아키텍처에서 기술적으로 가장 도전적인 측면은 LLM이 생성한 코드를 안전하게 실행하는 것입니다. Deep Agents는 데이터를 분석하거나, 파일을 파싱하거나, API와 상호 작용하기 위해 임의의 코드를 작성하고 실행할 수 있을 때 믿을 수 없을 정도로 강력해집니다. 그러나 LLM이 내부 네트워크에서 임의의 코드를 실행하도록 허용하는 것은 극도로 높은 보안 리스크를 초래합니다.
만약 에이전트가 프롬프트 인젝션(prompt injection)을 통해 침해될 경우, 공격자는 환경 변수를 읽거나 내부 데이터베이스에 접근하거나 다른 내부 서비스에 대한 공격을 시작하는 코드를 작성할 수 있습니다. 따라서 보안이 확보된 격리된 샌드박스(sandbox)는 모든 엔터프라이즈 에이전트 플랫폼의 타협할 수 없는 필수 요구 사항입니다.
저는 에이전트 런타임(agent runtimes)을 위한 여러 샌드박싱 전략을 평가해 보았습니다. 표준 Docker 컨테이너는 호스트 커널(host kernel)을 공유하기 때문에 그 자체만으로는 불충분합니다. 컨테이너 탈출(container breakout) 취약점이 발생하면 기반이 되는 VM이 위험에 처할 수 있기 때문입니다. 이를 완화하려면 다층 격리 전략(multi-layered isolation strategy)을 구현해야 합니다. 아래 표는 에이전트 워크로드(agentic workloads)에 사용할 수 있는 주요 실행 샌드박싱 기술들을 비교한 것입니다:
| 샌드박싱 기술 (Sandboxing Technology) | 격리 메커니즘 (Isolation Mechanism) | 시작 지연 시간 (Startup Latency) | 리소스 오버헤드 (Resource Overhead) | 최적의 사용 사례 (Best Use Case) |
|---|---|---|---|---|
| Standard Docker | Linux Namespaces / cgroups | 낮음 (100ms - 1s) | 낮음 | 내부의 신뢰할 수 있는 코드 실행 전용. |
| ... |
Kai와 같은 엔터프라이즈 에이전트 플랫폼을 위해서는 gVisor 또는 Firecracker MicroVMs를 활용할 것을 강력히 권장합니다. Stripe의 아키텍처는 각 에이전트 세션에 대해 일시적이고 격리된 샌드박스 (sandbox)를 생성하는 것에 의존합니다.
에이전트가 코드를 실행하기로 결정하면, 오케스트레이션 계층 (orchestration layer)은 코드를 패키징하여 전용 샌드박스 서비스 (Sandbox Service)로 전송합니다. 이 서비스는 MicroVM 또는 gVisor로 보안이 강화된 컨테이너를 프로비저닝하고, 엄격한 시간 제한(예: 5초) 내에서 코드를 실행하며, 표준 출력(standard output) 및 에러(error)를 캡처한 후 즉시 환경을 파괴합니다. 이를 안전하게 구현하려면 다음과 같은 네트워크 및 보안 경계 (boundaries)를 반드시 강제해야 합니다:
- 네트워크 액세스 차단 (Zero Network Access): 에이전트가 특별히 인터넷 접속을 필요로 하지 않는 한, 샌드박스는 네트워크가 비활성화된 상태(
--network none)로 실행되어야 합니다. 인터넷 접속이 필요한 경우, 사전에 승인된 도메인 화이트리스트 (whitelist)로의 연결만 허용하는 매우 제한적인 이그레스 프록시 (egress proxy)를 통해 라우팅되어야 합니다. - 읽기 전용 루트 파일시스템 (Read-Only Root Filesystem): 컨테이너 파일시스템은 읽기 전용이어야 하며, 임시 파일 처리를 위해 작고 일시적인 인메모리 tmpfs 마운트를 사용해야 합니다.
- 엄격한 리소스 제한 (Strict Resource Limits): 무한 루프나 디스크를 가득 채우는 코드로 인한 서비스 거부 공격 (denial-of-service attacks)을 방지하기 위해 CPU (예: 0.5 vCPU), 메모리 (예: 256MB), 디스크 I/O에 대해 하드 제한 (hard limits)을 적용해야 합니다.
- 비밀 정보 노출 방지 (No Secrets Exposure): 데이터베이스 자격 증명이나 API 키를 샌드박스 환경에 직접 전달해서는 안 됩니다. 코드가 데이터베이스를 쿼리해야 하는 경우, 샌드박스는 데이터를 샌드박스로 반환하기 전에 행 수준 보안 (row-level security) 및 컬럼 마스킹 (column masking)을 강제하는 보안 데이터 프록시 (secure data proxy)와 통신해야 합니다.
중앙 집중식 거버넌스, 가드레일 및 평가 (Centralized Governance, Guardrails, and Evaluation)
에이전트 플랫폼을 수백 명의 개발자와 수백만 번의 실행 규모로 확장할 때, 거버넌스(Governance)는 주요한 운영 병목 현상이 됩니다. 중앙 집중식 가드레일(Guardrails)이 없다면, 천문학적인 API 비용, 성능 저하, 그리고 예측 불가능한 에이전트 동작에 빠르게 직면하게 될 것입니다.
Stripe의 Kai 아키텍처는 오케스트레이션 프레임워크(Orchestration framework)와 LLM 제공업체 사이에 위치하는 중앙 집중식 거버넌스 계층을 구현함으로써 이 문제를 해결합니다. 저는 이 계층을 LLM 트래픽에 특화되어 설계된 지능형 API 게이트웨이(API Gateway)로 구조화할 것을 권장합니다.
1. 토큰 예산 책정 및 속도 제한 (Token Budgeting and Rate Limiting)
루프(Loop) 내에서 실행되는 딥 에이전트(Deep agents)는 무한 계획 루프(Infinite planning loop)에 빠질 경우 몇 분 만에 수백만 개의 토큰을 쉽게 소비할 수 있습니다. 이를 방지하기 위해 플랫폼은 여러 수준에서 엄격한 토큰 예산을 강제해야 합니다:
- 실행당 예산 (Per-Run Budgets): 단일 에이전트 실행에 허용되는 최대 LLM 호출 횟수(예: 20회)와 총 토큰 수(예: 100,000개)를 제한합니다. 예산을 초과하면 플랫폼은 실행을 종료하고 사용자에게 알림을 보냅니다.
- 사용자/팀당 예산 (Per-User/Per-Team Budgets): 각 비즈니스 유닛별로 LLM 지출에 대한 일일 또는 월간 재무 한도를 구현합니다.
2. 가드레일 및 프롬프트 인젝션 완화 (Guardrails and Prompt Injection Mitigation)
에이전트로 들어오는 모든 입력과 LLM에서 나오는 모든 출력은 자동화된 가드레일 파이프라인을 통과해야 합니다. 실시간으로 트래픽을 검사하기 위해 빠르고 로컬에서 동작하는 모델(Llama-Guard와 같은 모델)과 정규 표현식(Regex) 기반의 패턴 매처(Pattern matcher)를 조합하여 사용할 것을 권장합니다:
- 입력 가드레일 (Input Guardrails): 들어오는 사용자 프롬프트를 스캔하여 프롬프트 인젝션(Prompt injection) 공격, 탈옥(Jailbreak) 시도, 개인 식별 정보(PII)를 검사합니다. PII가 감지되면 LLM으로 보내기 전에 이를 마스킹(Redact) 처리합니다.
- 출력 가드레일 (Output Guardrails): LLM 출력을 스캔하여 기대하는 형식(예: 유효한 JSON 또는 구조화된 도구 호출)을 준수하는지, 그리고 사용자가 볼 권한이 없는 민감한 내부 데이터를 포함하고 있지는 않은지 확인합니다.
🤖 3. 지속적 평가 (LLM-as-a-Judge)
전통적인 소프트웨어와 달리, 단순한 단위 테스트 (Unit Test)만으로는 에이전트의 동작을 검증할 수 없습니다. LLM의 출력은 확률적 (Probabilistic)이기 때문에, 지속적인 평가 파이프라인 (Continuous Evaluation Pipeline)을 구현해야 합니다. 저는 대표적인 사용자 프롬프트와 그에 따른 예상 도구 호출 (Tool Call) 및 최종 답변을 포함하는 '골든 세트 (Golden Set)' 형태의 평가 데이터셋을 구축할 것을 권장합니다. 개발자가 에이전트의 프롬프트, 시스템 지침 (System Instructions) 또는 도구 정의 (Tool Definitions)를 업데이트할 때마다, 플랫폼은 이 평가 데이터셋을 대상으로 에이전트를 자동으로 실행해야 합니다.
"LLM-as-a-Judge" 패턴을 사용하여, 강력한 모델 (GPT-4o 또는 Claude 3.5 Sonnet 등)이 다음 세 가지 핵심 지표를 기반으로 테스트 실행 결과를 평가합니다:
- 충실도 (Faithfulness): 에이전트가 제공된 컨텍스트 (Context)를 엄격히 준수했는가, 아니면 사실을 환각 (Hallucination)했는가?
- 답변 관련성 (Answer Relevance): 최종 응답이 사용자의 프롬프트를 직접적으로 해결했는가?
- 도구 선택 정확도 (Tool Selection Accuracy): 에이전트가 올바른 인자 (Arguments)와 함께 정확한 순서로 도구를 호출했는가?
이러한 평가 파이프라인을 CI/CD 프로세스에 내장함으로써, 회귀 (Regression)를 방지하고 시간이 지나도 에이전트의 성능이 안정적으로 유지되도록 보장할 수 있습니다.
🎯 결론
AI 자동 생성 콘텐츠
본 콘텐츠는 Dev.to AI tag의 원문을 AI가 자동으로 요약·번역·분석한 것입니다. 원 저작권은 원저작자에게 있으며, 정확한 내용은 반드시 원문을 확인해 주세요.
원문 바로가기