Overview

  • 크라우드웍스에서 초기 6개월 동안 프로젝트 를 수행하면서 개발자와 비개발자들이 프롬프트 엔지니어링과 서비스 개발에 걸쳐 가지고 있던 요구 사항을 종합하고 AWS 생태계 내에서 지속 가능한 해결책을 도출하려고 노력했습니다.
  • 3단계로 나누어진 프로젝트에서 첫 번째 단계로 Queue consumer service와 프롬프트 운영 프로세스를 Python으로 개발했습니다.
  • 3단계 전체에서 CloudFormation을 기반으로 하는 AWS CDKCopilot CLI 를 조합한 ECS 서비스 2개를 중심으로 다양한 AWS 리소스를 생성했습니다.

enter image description here

Technology

CloudFormation Stacks

Copilot CLI + AWS CDK

  • VPC 구성과 같은 정형화된 초기 설정과, 컨테이너 이미지만을 변경하는 빈번한 코드 배포는 Copilot CLI를 이용했습니다.
    • Copilot CLI는 AWS가 직접 개발에서 권장하는 ECS 서비스 배포 방식입니다.)
  • ECS 서비스가 의존하는 추가적인 AWS 리소스들은 CDK로 정의해서 별도로 배포했습니다.
  • 이때 Copilot CLI로 배포한 CloudFormation stack에 YAML patch override 를 이용해 export를 추가하고, 이를 Fn.importValue() 함수로 import해서 CDK가 의존성을 가질 수 있도록 구성했습니다.

Monorepo & Build settings

Monorepo Layout
# Repository cw-d-service
├── cdk
├── copilot
├── d-chat-api # ECS Service 1
│   ├── chat_api
│   │   ├── __init__.py
│   │   └── main.py # imports models
|   ├── Dockerfile
|   ├── pyproject.toml # installs models
│   └── tests
├── d-worker # ECS Service 2
│   ├── comment
│   │   ├── __init__.py
│   │   └── comment.py # imports models
|   ├── Dockerfile
|   ├── pyproject.toml # installs models
│   └── tests
├── docker-bake.hcl # Builds 3 container images
├── Makefile
└── models # Shared package
   ├── Dockerfile
   ├── models
   │   └── api_model.py
   ├── pyproject.toml # Common dependencies
   └── tests
  • cdk와 copilot 폴더에는 IaaS 구성에 필요한 TypeScript 파일과 YAML 파일이 있음
  • 2개의 Copilot service 의 Python 소스 코드가 worker와 chat-api 폴더에 존재
    • 각각 테스트 폴더를 포함함
    • 각각 컨테이너 이미지를 생성할 수 있음
  • docker-bake.hcl 파일을 이용한 High-level build 기능으로 Monorepo 전체를 빌드하고 3개의 컨테이너 이미지 Artifact를 생성할 수 있음
  • 테스트, 빌드, 배포는 Makefile에 적힌 명령어로 모두 수행할 수 있음

Python Development

  • Strong typing을 강제할 수 있는 pyright language server 설정을 권장하고 TDD를 도입해 프로젝트 전체를 구동하거나 배포하기 전에 기능 단위로 개발할 수 있도록 했습니다. 그 결과 Edge case를 폭넓게 고려하는 개발을 효율적으로 진행할 수 있었으며, 크라우드웍스 최초의 B2C 프로젝트에 안정적인 서비스를 가능케 했습니다: 기사 링크
  • 사용자에게 추천하는 식품들의 후보는 DB화해 고객사가 정확하게 제어할 수 있도록 하는 기능을 개발했습니다.
  • 복수의 LLM API key를 사용해야 할 경우, 키의 Tier를 고려해 사용량을 제거하고 추가/삭제할 수 있는 관리 체계를 개발했습니다. 기존에는 요청마다 API key를 임의로 선택하는 로직을 사용해 애플리케이션 전체에 코드나 설정 변경이 필요했으나, 이 프로젝트에서는 컨테이너 1개 당 API 키를 1개씩만을 할당해 모니터링과 운영을 용이하게 했습니다. ECS 컨테이너는 초기화 시 ECS task metadata API 와 ECS API를 통해 API key의 사용 현황을 확인하고 가장 적게 사용된 것을 선택합니다.
  • AWS X-Ray tracing과 OpenTelemetry를 도입해 dev stage에서의 프롬프트 실험을 용이하게 하고 prod stage를 모니터링했습니다. X-Ray console에서 API Gateway, SQS, ECS task, SNS로 이어지는 구간 별 성능을 파악할 수 있었고, OpenTelemetry instrumentation OpenAI 을 적용해 생성 결과와 토큰 사용량을 추적했습니다: 자세한 사용 방식과 코드

enter image description here

Lessons

  • 신문 PDF 정형화 프로젝트 에서 수백 개 단위의 AWS 리소스를 IaaC 없이 진행하며 많은 어려움을 겪었는데, 이번 프로젝트에서는 dev, prod 환경을 git에 커밋된 그대로 재현할 수 있었습니다.
  • 크라우드웍스에서는 데이터 담당 개발자뿐만 아니라 비개발자들이 기획과 QA를 담당했습니다. 이 팀원들이 개발에 기여할 수 있도록 프로세스를 만들고 고객과 커뮤니케이션하는 데 참여할 수 있었습니다.
  • Python typing을 본격적으로 적용한 첫 프로젝트였는데, TypeScript와 비교해서 장단점이 눈에 보였습니다. Python typing은 TypeScript와 달리 언어 표준에 의한 구현이다 보니 satisfies , const 등의 키워드를 통한 정밀한 제어가 부족하다고 느꼈으나, pydantic 과 같이 사용했을 때의 강력한 기능은 매우 유용했습니다.