AI 서비스 계층 구조

3줄 요약

  • AI 서비스는 Controller에서 모델을 직접 호출하는 구조보다 Service, Prompt, Context, Client, Validator, Recorder를 분리하는 구조가 안전하다.
  • 모델 provider는 외부 시스템이고, RAG와 tool은 별도 인프라와 보안 경계를 가진다.
  • 백엔드 아키텍처의 핵심은 AI 기능을 기존 도메인과 운영 경계 안에 넣는 것이다.

핵심 정리

  • Controller는 요청 검증과 응답 계약을 맡고, AI Service는 use case를 조율한다.
  • LLM Client는 provider 호출을 감싸고 timeout, retry, 예외 변환을 담당한다.
  • Context Builder는 권한 있는 데이터만 조립한다.
  • Output Validator는 모델 결과를 검증한다.
  • Usage Recorder와 Trace Recorder는 비용과 장애 분석을 위한 데이터를 남긴다.

헷갈리는 지점

  • AI SDK 호출 코드는 짧아서 Controller에 넣어도 된다고 느끼기 쉽다.
    • 핵심은 짧은 호출 뒤에 비용, 장애, 권한, 검증 책임이 숨어 있다는 점이다.
    • 외부 시스템 호출 경계를 만들어야 한다.
  • AI 기능은 기존 도메인 밖의 별도 기능이라고 생각하기 쉽다.
    • 핵심은 AI 결과가 도메인 상태와 사용자 경험에 영향을 준다는 점이다.

확인 질문

  • AI Service 계층에서 분리하면 좋은 책임은 무엇인가?
    • prompt rendering, context building, model client, output validation, usage recording, trace recording이다.
  • LLM provider를 외부 시스템으로 봐야 하는 이유는 무엇인가?
    • 장애, latency, rate limit, 비용, 응답 형식 변화가 있기 때문이다.

동기 API와 비동기 Worker

3줄 요약

  • 짧고 실패가 단순한 AI 기능은 동기 API로 처리할 수 있지만, 긴 작업과 배치 작업은 worker로 분리하는 편이 안전하다.
  • 비동기 구조에서는 job id, 상태, idempotency, DLQ, retry 정책이 핵심이다.
  • Java/Spring Boot API와 Python worker 조합은 실무적으로 유용한 하이브리드 구조다.

핵심 정리

  • 동기 API는 사용자 즉시 응답이 필요한 짧은 작업에 적합하다.
  • 문서 요약, embedding, RAG 색인, eval batch, agent workflow는 비동기 worker가 적합하다.
  • queue 기반 구조는 API 서버 리소스를 보호하지만 운영 복잡도를 추가한다.
  • job payload에는 tenant, user, trace id, prompt version, idempotency key가 들어가야 한다.
  • worker retry와 provider retry가 중복되지 않게 설계한다.

헷갈리는 지점

  • 비동기 worker를 붙이면 안정성이 자동으로 올라간다고 생각하기 쉽다.
    • 핵심은 queue도 운영 대상이라는 점이다.
    • 적체, 중복 실행, DLQ, 상태 관리가 필요하다.
  • 모든 AI 호출을 비동기로 만들면 된다고 생각하기 쉽다.
    • 핵심은 사용자 경험에 따라 동기 streaming이 더 적합한 경우도 있다는 점이다.

확인 질문

  • 긴 AI 작업을 worker로 분리하는 이유는 무엇인가?
    • API 서버 리소스를 보호하고 재시도, 상태, rate limit을 독립적으로 관리하기 위해서다.
  • 비동기 job 계약에 필요한 핵심 값은 무엇인가?
    • job id, tenant id, user id, trace id, prompt version, idempotency key, 상태다.

Multi Provider와 Vendor Risk

3줄 요약

  • AI 서비스는 provider 장애, 가격 변경, 모델 변경, 데이터 정책 변경에 영향을 받는다.
  • multi-provider 구조는 가용성과 협상력을 높일 수 있지만 품질, schema, 비용 차이를 관리해야 한다.
  • provider 추상화는 완전한 독립이 아니라 변경 비용을 줄이는 경계로 이해해야 한다.

핵심 정리

  • provider마다 모델 성능, tool calling, structured output, rate limit, 데이터 정책이 다르다.
  • fallback provider는 평소에 eval과 integration test를 해둬야 장애 때 쓸 수 있다.
  • model profile을 내부 이름으로 관리하면 provider model 변경을 숨길 수 있다.
  • vendor risk는 기술 문제이면서 보안, 법무, 비용 문제다.
  • 고객 데이터가 provider로 나가는지와 보존 정책을 확인해야 한다.

헷갈리는 지점

  • adapter를 만들면 provider 교체가 쉬워진다고 생각하기 쉽다.
    • 핵심은 prompt, schema, tool behavior, 안전 정책이 provider마다 다르다는 점이다.
    • adapter는 비용을 줄일 뿐 교체를 공짜로 만들지는 않는다.
  • fallback provider는 장애 때 켜면 된다고 생각하기 쉽다.
    • 핵심은 fallback도 품질과 schema를 미리 검증해야 한다는 점이다.

확인 질문

  • multi-provider 구조에서 가장 조심할 것은 무엇인가?
    • provider별 출력 형식, 품질, 안전 정책, token 비용, rate limit 차이다.
  • 내부 model profile을 쓰는 이유는 무엇인가?
    • provider model 이름과 라우팅 정책을 서비스 로직에서 분리하기 위해서다.