[AI 시대의 백엔드] REST API의 한계와 토큰 기반 동시성 제어

궁금하면 500원·2025년 12월 27일

MSA&아키텍처

목록 보기
47/50

REST API는 정말 AI에게 친절할까?

LLM을 위한 API 설계와 토큰 정책

AI와 API 설계에 관한 학습을 하게되었는데요.
쉬는 시간도 없이 화면 속으로 빨려 들어갈 만큼 엄청난 인사이트가 쏟아진 시간이었습니다.
저 역시 피곤한 줄도 모르고 몰입해서 학습하게되었네요.

오늘은 그 강의에서 얻은 깨달음, 특히 "기존의 REST API가 과연 AI에게도 좋은 도구일까?"라는 근본적인 물음과 그에 대한 해답을 여러분과 나누고자 합니다.


1. 자율주행차가 마차 도로에서 달릴 수 없는 이유

우리는 그동안 철저하게 '사람'과 '클라이언트'를 기준으로 API를 설계해 왔습니다.
익숙한 하늘이 존재하는 게 당연하듯, REST API의 리소스와 엔티티 중심의 설계가 진리라고 믿어왔죠.

그런데 개발중 이런 비유가 나왔습니다.

"자율주행차가 제 성능을 내지 못하는 이유는, 인간이 운전하도록 설계된 도로에서 달리기 때문입니다. LA 지하에 뚫은 전용 터널에서는 200km/h로 가뿐히 달리잖아요."

이 말이 정말 머리를 한 대 맞은 것 같았습니다.
AI가 제 기능을 못 하는 이유는 AI가 멍청해서가 아니라, 우리가 제공하는 인프라가 철저히 '인간 전용'이기 때문이었습니다.

LLM은 기본적으로 자연어를 기반으로 작동합니다.
따라서 AI 친화적인 API는 다음 세 가지 기준을 만족해야 합니다.

  • NLP적일 것
  • 컨텍스트 소비를 최소화하면서 핵심 정보를 제공할 것
  • 복잡한 추론 없이도 바로 사용할 수 있을 것

때로는 리소스 중심의 REST API보다, 행위 중심의 Remote Procedure Call 방식이 LLM이 도구를 호출하고 이해하는 데 훨씬 직관적일 수 있습니다.


2. LLM의 한계, 그리고 서비스 레이어의 역할

LLM은 마법의 지팡이가 아닙니다.
기본적으로 무상태이며, 긴 컨텍스트가 주어지면 지시를 무시하거나 왜곡하는 현상이 발생합니다.
멀티턴 대화 역시 실제로는 서비스 레이어가 이전 대화 기록을 컨텍스트로 욱여넣어 주는 것에 불과하죠.

그렇다면 어떻게 해야 할까요? 프로그램와 LLM의 장점을 철저히 분리해야 합니다.

  • LLM의 장점: 문맥에 따라 자연어의 유연한 해석
  • 서비스 레이어 의 장점: 한 가지 의미를 오직 한 가지로만 해석

결국 라우팅, 조건 분기, 필터링, 데이터 정합성 검증 같은 '상태와 논리'에 기반한 작업은 서비스 레이어가 꽉 잡고 통제해야 합니다.
LLM에게 모든 것을 맡기면 시스템은 필연적으로 붕괴합니다.


3. 부분 업데이트의 함정과 컨텍스트 불일치

API 추상화 과정에서 발생하는 가장 무서운 문제는 '컨텍스트 에러'입니다.
예를 들어 하나의 게시글을 본다고 가정해 봅시다.

  • 기존 상태: (제목) 오늘 면접 분위기 좋음 / (내용) 질문도 잘 대답했고 느낌이 쎄하다.
  • 클라이언트 A의 수정 시도: 면접 합격 통보를 받고 제목을 [합격] 오늘 면접 결과 나옴으로 수정하려고 준비 중.
  • 클라이언트 B의 동시 수정: 그사이 치킨을 먹으러 가서 내용을 기분 좋아서 치킨 먹는 중으로 부분 수정해 버림.

만약 클라이언트 A가 '제목'만 부분 업데이트 Patch 를 해버리면 어떻게 될까요?
제목은 [합격] 오늘 면접 결과 나옴인데, 내용은 기분 좋아서 치킨 먹는 중이 되어버립니다.
물리적인 런타임 에러는 없지만, 비즈니스 로직상 문맥이 완전히 파괴된 심각한 에러입니다.


4. Git Push 방식의 토큰 정책 낙관적 락

이러한 동시성 문제와 컨텍스트 불일치를 막기 위해 사용하는 것이 바로 'Projection 토큰 정책'입니다.
첨부한 시퀀스 다이어그램의 흐름을 예시와 함께 살펴보겠습니다.

  1. 조회: 클라이언트 1과 2가 동시에 데이터를 조회합니다. 서버는 데이터와 함께 현재 상태를 증명하는 초기 토큰을 내려줍니다.

  2. 클라이언트 2의 선제 수정: 클라이언트 2가 데이터를 수정하며 자신이 가진 토큰 a12를 함께 보냅니다. 서버는 현재 토큰과 요청 토큰이 일치하므로 업데이트를 승인하고, 서버 토큰을 a13으로 갱신합니다.

  3. 클라이언트 1의 지각 수정: 클라이언트 1이 뒤늦게 데이터를 수정하며 아까 받은 토큰 a12를 보냅니다.

  4. 충돌 발생: 서버는 현재 토큰이 a13인데 요청 토큰이 a12이므로, "네가 모르는 사이에 데이터가 변경되었으니 다시 확인해!"라며 업데이트를 거부합니다.

  5. 재조회 및 수정: 클라이언트 1은 최신 데이터와 새로운 토큰 a13을 다시 조회한 후, 안전하게 데이터를 수정하고 서버 토큰은 a14로 갱신됩니다.

이 구조는 마치 Git에서 누군가 먼저 Push를 하면, 나는 Pull을 받아서 충돌을 해결해야만 내 코드를 Push 할 수 있는 것과 완벽히 같은 원리입니다.
이를 통해 AI가 잘못된 컨텍스트를 기반으로 데이터를 훼손하는 것을 원천 차단할 수 있습니다.


5. 비동기 작업과 독립적인 트랜잭션

AI와 통신하거나 대용량 데이터를 다룰 때는 비동기 작업이 필수적입니다.
작업 시간이 길어지면 클라이언트가 이탈할 확률도 높아지죠.

이때 핵심은 '비파괴적인 작업 바탕의 빠른 취소 구조'입니다.
대용량 파일 업로드를 예로 들어볼까요?

  1. 협상: 클라이언트가 "나 1GB 보낼 건데, 청크 사이즈는 얼마로 쪼갤까?" 제안합니다.
  2. 수락: 서버가 "ID는 777번, 사이즈는 10MB씩 쪼개서 임시 폴더로 보내"라고 응답합니다.
  3. 병렬 전송: 클라이언트가 청크 단위로 병렬 전송합니다.
  4. 독립적 조립: 서버는 원본 데이터에 손대지 않고 임시 폴더에서 조립하다가, 모두 도착하면 그때 완료 처리를 합니다.

이렇게 하면 중간에 네트워크가 끊겨도 원본 데이터는 전혀 오염되지 않으며, 이가 빠진 특정 청크만 재전송받으면 되므로 리소스 낭비를 극적으로 줄일 수 있습니다.


느낀점

발자로 일하면서 API 설계라면 산전수전 다 겪었다고 자부했는데, 완전히 새로운 관점을 가지게 된 충격적인 시간이었습니다.

지금까지 저는 굉장히 경직된 사고를 하고 있었더라고요.
항상 '사람'이 쓰기 편한 명확한 엔티티 중심의 RESTful 함을 추구해 왔는데, 다가오는 AI 시대에는 'AI가 추론을 덜 하고도 쉽게 사용할 수 있는 도구'를 쥐여주는 것이 백엔드 개발자의 새로운 과제가 될 것 같습니다.

NoSQL에서 강제되던 값 객체의 완결성이나, 엔티티 간의 관계 분석을 온톨로지 관점으로 치환하여 생각하는 부분 등 공부해야 할 영역이 무궁무진하게 열린 기분입니다.
AI로 인한 트래픽 증가와 메모리 소비 문제도 다가올 미래의 재미있는 챌린지가 되겠죠.
앞으로 우리의 API가 AI에게 얼마나 더 친절해질 수 있을지, 고민하게 될것같습니다.

profile
그냥 코딩할래요 재미있어요

0개의 댓글