데이터베이스 설계의 기본 전제를 깨는 에이전트 AI
기존 데이터베이스는 인간이 작성하고 검토한 예측 가능한 쿼리를 처리한다는 암묵적인 전제하에 설계되었습니다. 그러나 스스로 추론하여 비정형 쿼리를 생성하고 무자비하게 쓰기 작업을 수행하는 에이전트 AI는 이 전제를 완전히 깨버립니다. 이 글은 개발자들이 에이전트로 인한 데이터베이스 장애를 막기 위해 세션 타임아웃 설정 및 소프트 삭제(Soft Delete) 도입 등 어떤 조치를 취해야 하는지 실무적인 관점에서 조언합니다.
데이터베이스는 이것을 위해 설계되지 않았습니다 - Arpit Bhayani (엔지니어링, 데이터베이스 및 시스템. 항상 무언가를 만드는 사람)
지금까지 내렸던 모든 데이터베이스 아키텍처 결정의 기반에는 암묵적인 계약(contract)이 있습니다. 아마도 이를 문서로 적어본 적은 없을 것입니다. 아무도 그렇게 하지 않죠. 그냥… 당연하게 존재했을 뿐입니다.
그 계약은 대략 이렇습니다: 호출하는 주체(caller)는 인간이 작성한 애플리케이션이며, 결정론적인(deterministic) 코드를 실행하고, 배포 전에 개발자가 검토한 예측 가능한 쿼리를 발행합니다. 쓰기(Write) 작업은 의도적입니다. 데이터베이스 연결은 짧습니다. 문제가 발생하면 인간이 이를 인지합니다. 애플리케이션 계층이 똑똑하고 주의 깊기 때문에 데이터베이스는 멍청하고 빠르기만 하면 됩니다.
40년 동안 이 계약은 유효했습니다. 이는 우리가 스키마를 설계하고, 커넥션 풀의 크기를 결정하며, 권한을 부여하고, 장애 모드에 대해 생각하는 방식을 형성했습니다. 이 가정이 올바랐기 때문에 모든 것이 잘 작동했습니다.
하지만 이제 이 가정은 더 이상 옳지 않습니다.
에이전트 AI(Agentic AI) 시스템은 모든 계층에서 이 계약을 동시에 위반합니다. 이 글에서는 정확히 어떤 가정이 실패하고 있는지, 왜 그것이 중요한지, 그리고 이를 해결하기 위해 구체적인 패턴과 코드로 무엇을 해야 하는지 분석해 보겠습니다. 바로 시작해 보겠습니다...
가정 - 결정론적인 호출자 (Deterministic Caller)
에이전트 이전에 배포한 모든 애플리케이션에서 데이터베이스를 때리는 쿼리는 인간이 작성했습니다. 개발자가 SQL을 작성하고, 코드 리뷰를 하고, 테스트한 뒤 배포했습니다. 이 가정은 매우 깊이 자리 잡고 있어 우리가 사용하는 도구에도 자동으로 반영됩니다. Postgres 쿼리 플래너는 관찰된 쿼리 패턴을 기반으로 통계를 구축하고, 캐싱 계층은 반복되는 쿼리로 워밍업되며, 커넥션 풀은 알려진 복잡도의 예상 동시 쿼리 수에 맞춰 튜닝됩니다.
에이전트는 다르게 작동합니다. 이들은 스스로 추론하여 쿼리를 만들어냅니다. 다른 추론 경로는 동일한 테이블에 대해 전혀 다른 쿼리를 생성합니다. 고객 분석 작업을 수행하는 에이전트는 한 번도 실행된 적 없는 5개 테이블에 대한 조인(join)을 발행할 수 있고, 그 결과를 고민하는 동안 연결을 유지한 다음 완전히 다른 후속 쿼리를 발행할 수 있습니다. 인덱스는 정상 경로(happy path)만 다룹니다. 커넥션 풀은 관찰된 최고치에 맞게 크기가 조정됩니다. 에이전트가 필요한 데이터에 따라 어떤 쿼리든 만들어낼 수 있을 때는 이러한 것들이 더 이상 유효하지 않습니다.
명령문 타임아웃 (Statement Timeouts)
명령문 타임아웃은 첫 번째 방어선입니다. 30초가 걸리는 인간이 작성한 쿼리는 누군가가 발견할 버그입니다. 반면 30초가 걸리는 에이전트 쿼리는 아무도 지켜보지 않는 추론 루프(reasoning loop)일 수 있습니다. 따라서 애플리케이션 수준뿐만 아니라 역할(role) 수준에서 타임아웃을 설정해야 합니다.
CREATE ROLE agent_worker; ALTER ROLE agent_worker SET statement_timeout = '5s'; ALTER ROLE agent_worker SET idle_in_transaction_session_timeout = '10s';
이때 idle_in_transaction_session_timeout 설정은 매우 중요합니다. 열려 있는 트랜잭션을 보유한 채로 추론을 잠시 멈추는 에이전트는 합법적인 상황일 수 있기 때문입니다.
가정 - 쓰기 작업은 의도적이다 (Writes are Intentional)
데이터베이스 아키텍처에서 가장 위험한 가정은 모든 쓰기 작업이 발생하기 전에 인간의 검토를 거쳤다는 것입니다. 이는 당신의 경력 전반에 걸쳐 기본적으로 사실이었지만, 이제는 더 이상 그렇지 않습니다.
에이전트는 자율적으로 쓰기 작업을 수행합니다. 에이전트는 현재 작업에 대한 자신의 이해를 바탕으로 쓰기를 수행하며, 이는 틀릴 수 있습니다. 에이전트는 도구가 예상치 못한 결과를 반환할 때 루프에 빠져 계속 쓰기를 수행합니다. 일시적인 네트워크 오류로 인해 첫 번째 시도가 실패했다고 '생각'할 때 재시도하며 쓰기를 수행합니다. 에이전트는 뭔가 이상하다는 Slack 알림을 받을 시간조차 없이 수천 개의 행을 써버릴 수도 있습니다.
다음은 실제로 기록된 장애 패턴입니다. 레거시 API를 호출한 에이전트가 빈 결과 셋과 함께 HTTP 200을 수신했습니다. 하위 데이터베이스 커넥션 풀이 고갈되어 API가 조용히 실패한 것입니다. 에이전트는 '데이터 없음'을 '문제 없음'으로 해석하고 불완전한 데이터로 500개의 트랜잭션을 계속 처리했습니다. 예외는 발생하지 않았고, 경고도 울리지 않았습니다. 로그에는 모든 레코드에 대해 '결정: 승인됨'이라고만 표시되었습니다.
이에 대한 핵심 해결책은 호출자가 잘못될 수도 있고, 재시도할 수도 있으며, 결과를 지켜보지 않을 수 있다고 가정하고 쓰기 경로(write path)를 설계하는 것입니다.
모든 곳에 소프트 삭제(Soft Deletes) 적용하기
절대 에이전트가 데이터를 하드 삭제(hard-delete)하지 못하게 하...