23.06.15
DEVOTEE를 활성화 시키면
지금 작성한 커뮤니티 글에 대해 1개의 댓글을 달아줍니다.
버튼을 누르면 글 수정 시 ChatGPT가 작성한 댓글이 수정됩니다.
| 컨텐츠 유형 | 제목 | 저장일 | 삭제 |
|---|
본인인증 로그인에 실패하였습니다.
회원이 아니시거나 본인인증 등록이
완료되지 않은 사용자입니다.
지금까지 AWS Lambda로 웹 서비스를 운영할 때 인프라 담당자와 백엔드 엔지니어를 가장 괴롭힌 지표는 CPU 사용량이 아니었습니다. 데이터베이스 질의를 기다리거나 외부 API 응답을 받는 동안에도 밀리초 단위로 올라가는 청구서, 그리고 생성형 AI의 토큰 스트리밍처럼 길게 열려 있는 HTTP 연결 하나마다 실행 환경이 통째로 복제되던 구조였습니다.
2026년 10월 12일 공개된 AWS Lambda Web Functions는 컨테이너 기반 실행 환경 하나가 최대 128개의 요청을 동시에 받아내도록 바꾸었습니다. 대기 시간(I/O Wait) 과금을 덜어내고 표준 HTTP 서버를 그대로 띄우는 이 변화는, 단순히 서버리스 비용을 깎는 기술에 머물지 않습니다. 시스템이 대기 상태에 머물 때 발생하는 비용을 줄이고 런타임 제어권을 확보하려는 흐름은 AI 에이전트 아키텍처에서도 정확히 똑같이 나타납니다.
LLM(대규모 언어 모델)이 도구를 호출하고 결과를 검증하는 과정에서 무한 루프를 방지하고 파괴적인 작업에 사람의 개입을 요구하는 원칙 역시, 불필요하게 낭비되는 컴퓨팅 자원과 통제 불가능한 실행 흐름을 붙잡기 위한 작업입니다. 오늘은 이 두 소식을 나란히 두고, 클라우드 인프라와 에이전트 개발 실무에서 런타임을 다루는 기준을 짚어봅니다.
AWS Lambda Web Functions 실전 가이드 1부에 따르면, 기존 AWS Lambda 환경에서 Express나 Next.js 같은 웹 프레임워크를 운영하려면 항상 이벤트 변환 계층이 필요했습니다. API Gateway나 Application Load Balancer가 전달하는 JSON 형식의 이벤트를 Node.js 표준 요청(http.IncomingMessage) 객체로 바꾸고, 다시 프레임워크의 응답을 JSON으로 직렬화하는 어댑터 라이브러리(aws-serverless-express 등)를 중간에 두어야 했습니다.
이 구조는 두 가지 고질적인 문제를 남겼습니다. 첫째는 단일 동시성(Single Concurrency) 모델입니다. Lambda는 하나의 인스턴스(실행 환경)가 동시에 오직 단 하나의 요청만 처리하도록 설계되었습니다. 짧은 API 호출이라면 큰 문제가 없지만, LLM 응답을 Server-Sent Events(SSE)나 웹소켓으로 수십 초 동안 흘려보내는 스트리밍 연결이 1,000개 들어오면 1,000개의 샌드박스 인스턴스가 즉시 프로비저닝되어야 했습니다. 이는 극심한 콜드 스타트(Cold Start, 함수 최초 실행 지연)와 동시성 한도 고갈을 불렀습니다.
둘째는 과금 방식이었습니다. 실행 환경이 외부 데이터베이스 트랜잭션 완료를 기다리거나 결제 게이트웨이의 웹훅 응답을 대기하는 동안에도 메모리 할당량에 따른 실행 시간이 그대로 과금되었습니다. CPU는 아무 일도 하지 않고 잠들어(Idle) 있는데도 지갑이 열리는 셈이었습니다.
표 1. 기존 Lambda와 Lambda Web Functions의 실행 방식 비교
Lambda Web Functions는 이 병목을 세 가지 방식으로 걷어냅니다.
http.createServer나 Next.js 독립형(standalone) 서버를 그대로 실행합니다. 런타임 내부의 역방향 프록시가 요청을 변환 없이 소켓 레벨로 전달합니다.다음은 Lambda Web Functions 환경에서 실행할 수 있는 표준 Node.js HTTP 스트리밍 서버 예시입니다. 어댑터 래핑 없이 기본 모듈만으로 구성할 수 있습니다.
import http from 'node:http';
const PORT = process.env.PORT || 8080;
// 표준 HTTP 서버 생성: Lambda Web Functions 런타임이 이 포트로 직접 트래픽을 라우팅합니다.
const server = http.createServer(async (req, res) => {
if (req.method === 'GET' && req.url === '/health') {
res.writeHead(200, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ status: 'healthy' }));
return;
}
if (req.method === 'POST' && req.url === '/api/stream') {
res.writeHead(200, {
'Content-Type': 'text/event-stream',
'Cache-Control': 'no-cache',
'Connection': 'keep-alive',
});
// 외부 AI 모델 응답 대기 및 청크 전송 시뮬레이션
for (let step = 1; step <= 5; step++) {
await new Promise((resolve) => setTimeout(resolve, 500));
res.write(`data: ${JSON.stringify({ step, message: `토큰 처리 중 (${step}/5)` })}\n\n`);
}
res.write('data: [DONE]\n\n');
res.end();
return;
}
res.writeHead(404, { 'Content-Type': 'application/json' });
res.end(JSON.stringify({ error: 'Not Found' }));
});
server.listen(PORT, () => {
console.log(`Web Functions HTTP 서버가 포트 ${PORT}에서 대기 중입니다.`);
});
여기부터는 DEVOTEE의 해석입니다. 이 변화는 서버리스와 컨테이너(ECS/Fargate)의 경계를 허뭅니다. 과거에는 "동시 요청을 여러 개 받아야 하니 Fargate로 가자"고 결정했던 경량 웹 애플리케이션들이 다시 서버리스의 관리 편의성 안으로 들어올 수 있게 되었습니다.
판단: 지금 써볼 만합니다. Express, Fastify, Next.js 기반으로 구축되어 있으면서 외부 I/O 비중이 높거나 AI 스트리밍 응답을 서빙하는 백엔드 서비스라면 즉시 비용 절감과 콜드 스타트 완화 성과를 거둘 수 있습니다. 다만 메모리 공유로 인한 상태 오염(State Leak)이나 전역 변수 동시성 접근 버그를 사전에 점검해야 합니다.
인프라 레벨에서 불필요한 대기 자원을 정리하는 것과 마찬가지로, 애플리케이션 레벨에서는 AI 에이전트의 불필요한 실행과 통제 불가능한 행동을 통제하는 아키텍처가 요구되고 있습니다.
블로그 발행 MCP를 직접 만들며 확인한 AI 에이전트 실무 원칙에 따르면, 에이전트를 실무 환경에 안착시키기 위해서는 단순히 프롬프트에 도구 명세를 채워 넣는 수준을 넘어 '아키텍처' 관점의 제어 체계가 필수적입니다. 원문 작성자는 에이전트를 구성하는 네 가지 기본 요소로 LLM, 도구 호출(Tool Calling), 실행 루프(Execution Loop), 메모리를 정의합니다.
실무에서 가장 흔히 마주치는 실패는 두 가지입니다. 첫째는 실행 루프의 고갈입니다. 모델이 도구의 반환값을 이해하지 못해 같은 도구를 조금씩 파라미터만 바꾸어 호출하다가 컨텍스트 윈도우 한도에 도달하거나 무한 루프에 빠지는 현상입니다. 이는 불필요한 API 토큰 비용을 발생시킬 뿐 아니라 전체 작업을 지연시킵니다.
둘째는 비가역적(파괴적) 작업의 무단 실행입니다. 읽기 전용 작업(데이터 조회, 초안 생성)과 달리, 데이터베이스 쓰기, 이메일 발송, 블로그 배포와 같은 변경 작업은 모델의 추론 오류가 발생하는 순간 복구 비용이 발생합니다.
원문이 제시하는 해결책은 결정론적 자동화(Rule-based System) 위에 판단 지점을 얹고, 변경 작업 직전에 '사람의 승인(Human-in-the-loop)' 단계를 강제하는 것입니다. 에이전트가 도구를 호출할 때 무조건 실행하는 것이 아니라, MCP(Model Context Protocol, AI 모델과 도구 간의 표준 통신 규약) 서버가 도구의 위험도를 분류하여 실행 통제권을 유지해야 합니다.

그림 1. MCP 서버가 위험도에 따라 도구 실행을 통제하는 흐름
아래는 위험도가 높은 도구 호출 요청을 중간에서 가로채 사람의 명시적 확인 토큰이 없으면 거부하는 MCP 도구 핸들러 설정 예시입니다.
// MCP 도구 실행 요청 인터페이스
interface ToolExecutionRequest {
toolName: string;
arguments: Record<string, unknown>;
approvalToken?: string;
}
interface ToolExecutionResult {
success: boolean;
message: string;
data?: unknown;
}
// 발행과 같은 비가역 작업 도구 목록
const DESTRUCTIVE_TOOLS = new Set(['publish_blog_post', 'delete_draft', 'update_dns']);
// 위험 작업 실행 전 검증 함수
export async function executeToolSecurely(
request: ToolExecutionRequest,
validTokens: Set<string>
): Promise<ToolExecutionResult> {
const isDestructive = DESTRUCTIVE_TOOLS.has(request.toolName);
// 파괴적 작업인데 유효한 승인 토큰이 없는 경우 실행을 차단합니다.
if (isDestructive) {
if (!request.approvalToken || !validTokens.has(request.approvalToken)) {
return {
success: false,
message: `[승인 거부] '${request.toolName}' 도구는 비가역 작업입니다. 사람의 승인 토큰이 필요합니다.`,
};
}
}
// 실제 도구 실행 로직
console.log(`도구 실행 승인됨: ${request.toolName}`);
return {
success: true,
message: `${request.toolName} 작업이 안전하게 완료되었습니다.`,
data: { executedAt: new Date().toISOString() },
};
}
여기부터는 DEVOTEE의 해석입니다. 에이전트를 도입할 때 '완전자율'을 목표로 삼는 것은 실무에서 위험합니다. 가장 성과가 좋은 방식은 데이터 수집과 포맷 변환 같은 지루한 반복 작업은 에이전트가 처리하되, 외부로 데이터가 전송되거나 상태가 바뀌는 마지막 관문에는 관리자 확인 인터페이스를 심어두는 단계적 모델입니다.
판단: 조건부로 유효합니다. 도구 호출 결과를 파싱하는 단계에 최대 반복 횟수(Max Iterations) 제한을 두고, 데이터 변경 API 앞단에 승인 파이프라인을 구축할 수 있는 환경이라면 프로덕션 도입 가치가 충분합니다. 반면 프롬프트 제어에만 의존하는 완전 자율 구조라면 도입을 보류해야 합니다.
Lambda Web Functions의 동시성 확장과 MCP 에이전트 루프를 결합하여 백엔드 BFF(Backend For Frontend)나 에이전트 중계 서버를 구축할 때는 새로운 설계 조건이 붙습니다.
과거 Lambda 환경에서는 인스턴스 하나당 요청 하나만 들어왔기 때문에 메모리에 글로벌 변수를 임시 캐시로 두어도 다른 사용자의 요청과 섞일 위험이 적었습니다. 하지만 단일 인스턴스가 128개의 요청을 동시에 수용하는 환경에서는 이야기가 완전히 달라집니다. 모듈 스코프에 선언된 객체에 특정 사용자의 세션 정보나 에이전트 대화 맥락(Context)을 저장하면 심각한 데이터 유출 사고로 이어질 수 있습니다. 모든 상태는 함수 호출 스택 내부의 지역 변수로 닫아두거나 외부 저장소(Redis, DynamoDB 등)에 명시적으로 위임해야 합니다.
또한 동시 요청 수가 128개까지 늘어날 수 있다는 말은, 내부에서 호출하는 하위 데이터베이스나 외부 API의 커넥션 풀(Connection Pool)이 순식간에 마를 수 있다는 뜻이기도 합니다. Lambda 인스턴스 10개가 각각 128개 요청을 처리하면 동시 하위 요청은 최대 1,280개에 달합니다. 인스턴스 개수 기반으로 커넥션 한도를 산정해 두었던 데이터베이스 프록시 설정을 동시성 기준으로 다시 계산해야 장애를 피할 수 있습니다.
Lambda Web Functions와 에이전트 거버넌스를 아키텍처에 적용하기 전, 다음 항목들을 먼저 점검하시기 바랍니다.
DEVOTEE를 활성화 시키면
지금 작성한 댓글에 AI가 댓글을 달아줍니다.