Databricks Apps 에이전트를 부하 테스트하세요

부하 테스트는 성능이 저하되기 전에 Databricks Apps 에이전트가 유지할 수 있는 QPS(초당 최대 쿼리)를 찾습니다. 이 페이지에서는 다음을 수행하는 방법을 보여줍니다.

  1. 에이전트의 모의 버전을 배포하여 LLM 대기 시간으로부터 인프라 처리량을 격리합니다.
  2. Locust를 사용하여 점진적 부하-포화 테스트를 실행합니다.
  3. 대화형 대시보드를 사용하여 결과를 분석합니다.

Claude Code 기술을 사용하여 AI 지원 경로를 따르거나 각 단계를 수동으로 설정할 수 있습니다.

컴퓨팅 구성 전반의 QPS, 대기 시간 및 램프 진행 차트를 보여 주는 부하 테스트 대시보드의 애니메이션 미리 보기입니다.

Requirements

Claude Code를 /load-testing 사용하는 경우 기술은 워크플로를 자동화합니다. 에이전트 코드를 읽고, 모의 코드를 생성하고, 부하 테스트 스크립트를 만들고, 배포를 안내합니다.

팁 (조언)

클로드 코드에게 다음을 수행하도록 지시합니다.

Clone https://github.com/databricks/app-templates and run the /load-testing skill against the {your-template} template.

또는 아래 단계를 수행합니다.

1단계: 에이전트 템플릿 복제

/load-testing 기술은 최상위 기술로 데이터agent-load-testing 리포지토리에 포함되며 모든 개별 에이전트 템플릿에 미리 동기화됩니다. 이미 프로젝트를 app-templates에서 받으셨다면 해당 기술을 이미 보유하고 계십니다.

리포지토리를 복제하고 테스트를 로드하려는 에이전트의 템플릿 디렉터리로 변경합니다.

git clone https://github.com/databricks/app-templates.git
cd app-templates/{your-template}

2단계: 부하 테스트 기술 실행

Claude Code에서 다음을 실행합니다.

/load-testing

이 기술은 대화형으로 다음 단계를 안내합니다. 모의 작업을 건너뛰어 실제 에이전트를 테스트하거나 앱이 이미 실행 중인 경우 배포를 건너뛸 수 있습니다.

  1. 매개 변수 수집: 배포 상태, 컴퓨팅 크기, 작업자 구성 및 OAuth 자격 증명에 대해 묻습니다.
  2. 부하 테스트 스크립트 만들기: 프로젝트에 맞게 조정된 locustfile.py, run_load_test.py, dashboard_template.py를 생성합니다.
  3. 당신의 LLM 모방하기: 실제 LLM 호출을 구성 가능한 스트리밍 지연으로 대체하는 SDK(OpenAI Agents SDK, LangGraph 또는 사용자 지정)에 맞추어 특정 모의 클라이언트를 생성합니다.
  4. 테스트 앱 배포: 컴퓨팅 크기 및 작업자 수가 다른 여러 앱 구성을 배포하는 단계를 안내합니다.
  5. 테스트 실행: M2M OAuth 인증 및 램프-포화를 사용하여 부하 테스트를 실행합니다.
  6. 결과 생성: QPS, 대기 시간 및 실패 메트릭을 사용하여 대화형 HTML 대시보드를 생성합니다.

수동 설정

다음 단계에 따라 AI 지원 없이 부하 테스트를 설정하고 실행합니다.

1단계: 에이전트의 LLM 호출을 모의로 테스트하기 (선택 사항)

실제 LLM 대기 시간이 포함된 엔드 투 엔드 결과를 원하는 경우 이 단계를 건너뜁니다. Databricks Apps 인프라 처리량을 격리된 상태로 측정하려면 요청당 대기 시간(일반적으로 1-30초)이 병목 상태가 되지 않도록 LLM을 모의합니다.

모의 작업은 구성 가능한 스트리밍 지연으로 통조림 응답을 반환하고, 전체 요청/응답 파이프라인(SSE 스트리밍, 도구 디스패치, SDK 실행기)을 유지하고 LLM만 교환합니다. 이는 Databricks Apps 플랫폼이 제공할 수 있는 최대 QPS를 표시하고 부하 테스트 중에 Foundation Model API 토큰 비용을 방지합니다.

모의 타이밍은 다음 두 환경 변수에 의해 제어됩니다.

변수 기본값 Description
MOCK_CHUNK_DELAY_MS 10 스트리밍된 텍스트 청크 간 지연 시간(밀리초)
MOCK_CHUNK_COUNT 80 응답당 텍스트 청크 수

기본값을 사용하면 각 모의 응답은 실제 LLM 응답(3-15초)보다 훨씬 빠른 약 800ms(10ms x 80 청크)를 사용합니다. 그러면 처리량 번호는 모델이 아닌 플랫폼을 반영합니다.

실제 LLM 클라이언트를 대체하는 모의 클라이언트를 만듭니다. 나머지 에이전트 코드는 변경되지 않고 접근 방식은 SDK에 따라 달라집니다. OpenAI의 경우 .의 mock_openai_client.py 참조 구현 을 참조하세요 databricks/app-templates. 동일한 패턴이 다른 SDK에 맞게 조정됩니다.

OpenAI 에이전트 SDK

agent_server/mock_openai_client.py의 스트리밍 구현을 위한 MockAsyncOpenAI 클래스를 생성합니다chat.completions.create(). 도구 호출 청크를 즉시 반환하고(도구를 호출할지 결정하는 LLM을 시뮬레이션함) MOCK_CHUNK_DELAY_MSMOCK_CHUNK_COUNT 환경 변수로 구성할 수 있는 지연을 통해 텍스트 응답 청크를 반환합니다.

에이전트로 교환:

from agent_server.mock_openai_client import MockAsyncOpenAI
from agents import set_default_openai_client, set_default_openai_api

set_default_openai_client(MockAsyncOpenAI())
set_default_openai_api("chat_completions")

에이전트 코드의 나머지 부분(처리기, 도구, 스트리밍 논리)은 변경되지 않은 상태로 유지됩니다.

LangGraph

ChatDatabricks 모델을 미리 빌드된 AIMessage 개체를 반환하는 모의 개체로 바꿉다.

# Before:
# model = ChatDatabricks(endpoint="databricks-claude-sonnet-4")

# After:
from agent_server.mock_llm import MockChatModel
model = MockChatModel()

모의 개체는 첫 번째 호출에서 도구 호출과 함께 AIMessage 개체를 반환하고, 후속 호출에서는 텍스트 콘텐츠를 반환해야 하며, 스트리밍 지연은 구성 가능합니다.

사용자 지정 에이전트

에이전트가 LLM, 벡터 검색, 도구 API와 같은 외부 API 호출을 할 때, 모의 구현으로 래핑하여 실제적인 응답 형태와 구성이 가능한 지연 시간을 반환하도록 합니다.

2단계: 부하 테스트 스크립트 설정

load-test-scripts/ 프로젝트에서 디렉터리를 만듭니다. 부하 테스트 프레임워크는 프레임워크에 구애받지 않으며 Databricks Apps 에이전트와 함께 작동하는 세 가지 스크립트로 구성됩니다.

<project-root>/
  agent_server/                  # Your existing agent code
  load-test-scripts/             # Load testing scripts (create this)
    run_load_test.py             #   CLI orchestrator
    locustfile.py                #   Locust test with SSE streaming + TTFT tracking
    dashboard_template.py        #   Interactive HTML dashboard generator
  load-test-runs/                # Results (auto-created per run)
    <run-name>/
      dashboard.html             #   Interactive dashboard
      test_config.json           #   Test parameters for reproducibility
      <label>/                   #   Per-config Locust CSV output

프레임워크에는 다음 파일이 포함됩니다.

  • locustfile.py: POST /invocations 요청을 stream: true와 함께 보내고, SSE 스트림을 구문 분석하며 TTFT(첫 번째 토큰 시간)를 사용자 지정 메트릭으로 추적합니다. M2M OAuth 토큰 교환을 자동 새로 고침과 함께 사용하고, 각 수준을 StepRampShape초 동안 유지하면서, 사용자를 step_size에서 max_users로 증가시키는 step_duration를 구현하는 메뚜기 부하 테스트입니다.
  • run_load_test.py: 구성당 격리된 메트릭을 사용하여 각 앱 URL을 순차적으로 테스트하는 CLI 오케스트레이터입니다. OAuth 토큰 새로 고침을 처리하고, 각 테스트 전에 상태 검사 및 준비 작업을 실행하고, 결과를 load-test-runs/<run-name>/<label>/저장합니다.
  • dashboard_template.py: Chart.js를 사용하여 KPI 카드, QPS와 대기 시간, 구성별 TTFT를 포함한 가로 막대형 차트, QPS 램프 진행률 꺾은선형 차트 및 전체 결과 테이블이 있는 자체 포함 HTML 대시보드를 생성합니다. 독립 실행형 uv run dashboard_template.py ../load-test-runs/<run-name>/으로 실행할 수 있습니다.

종속성 설치

부하 테스트 스크립트는 에이전트의 프로덕션 종속성을 오염시키는 것을 방지하기 위해 자체 내부 pyproject.toml 를 사용합니다load-test-scripts/. load-test-scripts/pyproject.toml을 만듭니다.

[project]
name = "load-test-scripts"
version = "0.1.0"
requires-python = ">=3.10"
dependencies = [
  "locust>=2.32,<2.40",
  "urllib3<2.3",
  "requests",
]

메모

locust을(를) <2.40에 고정합니다. 최신 버전(>=2.43)에는 긴 부하 테스트를 중단하는 알려진 RecursionError 버전이 있습니다.

디렉터리 내에서 load-test-scripts/ 설치합니다.

cd load-test-scripts/
uv sync

3단계: 다양한 구성을 사용하여 테스트 앱 배포

다양한 컴퓨팅 크기 및 작업자 수를 사용하여 여러 Databricks 앱을 배포하여 워크로드에 대한 최적의 구성을 찾습니다.

아래 구성은 이전 테스트에서 확인된 스위트 스팟에 초점을 맞춥니다. 더 넓은 범위를 원하는 경우 양쪽에 하나의 구성을 추가합니다(예: medium-w1 또는 large-w12). 하지만 아래 6개는 일반적으로 충분합니다.

컴퓨팅 크기 작업자 제안된 앱 이름
중간 2 <your-app>-medium-w2
중간 3 <your-app>-medium-w3
중간 4 <your-app>-medium-w4
라지 6 <your-app>-large-w6
라지 8 <your-app>-large-w8
라지 10 <your-app>-large-w10

컴퓨팅 크기 구성

Databricks CLI를 사용하여 앱을 만들거나 업데이트할 때 컴퓨팅 크기를 설정합니다.

# Create a new app with Medium compute
databricks apps create <app-name> --compute-size MEDIUM

# Update an existing app to Large compute
databricks apps update <app-name> --compute-size LARGE

선언적 자동화 번들을 사용하여 작업자 수 구성

start-serverAgentServer.run()를 통해 --workers 플래그를 직접 설정합니다. DAB 변수를 사용하여 배열의 command 작업자 수를 전달합니다.

variables:
  app_name:
    default: 'my-agent-medium-w2'
  workers:
    default: '2'

resources:
  apps:
    load_test_app:
      name: ${var.app_name}
      source_code_path: .
      config:
        command: ['uv', 'run', 'start-server', '--workers', '${var.workers}']
        env:
          - name: MOCK_CHUNK_DELAY_MS
            value: '10'
          - name: MOCK_CHUNK_COUNT
            value: '80'

targets:
  medium-w2:
    default: true
    variables:
      app_name: 'my-agent-medium-w2'
      workers: '2'
  large-w8:
    variables:
      app_name: 'my-agent-large-w8'
      workers: '8'

배포 및 확인

Databricks CLI를 사용하여 각 대상을 배포합니다.

databricks bundle deploy --target medium-w2
databricks bundle run load_test_app --target medium-w2

부하 테스트를 실행하기 전에 앱이 활성 상태인지 확인합니다.

databricks apps get <app-name> --output json | jq '{app_status, compute_status, url}'

메모

계속하기 전에 모든 앱이 상태에 도달할 ACTIVE 때까지 기다립니다. 아직 시작 중인 앱은 잘못된 결과를 생성합니다.

4단계: 부하 테스트 실행

인증 설정

실행하려는 기간에 따라 인증을 선택합니다.

  • 짧은 테스트(~1시간 미만): 기존 사용자 자격 증명을 databricks auth login사용합니다. 추가 설정이 필요하지 않습니다.
  • 긴 테스트(1시간 이상(예: 야간 실행): 서비스 주체와 함께 M2M OAuth를 사용합니다. U2M 토큰이 만료되고 테스트 중간 실행이 중단됩니다. 서비스 주체를 만들려면 작업 영역 관리자 액세스 권한이 필요합니다.

M2M OAuth의 경우 테스트를 실행하기 전에 서비스 주체 자격 증명을 내보냅니다.

export DATABRICKS_HOST=https://your-workspace.cloud.databricks.com
export DATABRICKS_CLIENT_ID=<your-client-id>
export DATABRICKS_CLIENT_SECRET=<your-client-secret>

매개 변수 참조

매개 변수 필수 기본값 Description
--app-url Yes 테스트할 앱 URL(반복 가능)
--client-id 긴 테스트의 경우 DATABRICKS_CLIENT_ID 환경 서비스 주체 클라이언트 ID(M2M OAuth)
--client-secret 긴 테스트의 경우 DATABRICKS_CLIENT_SECRET 환경 서비스 주체 클라이언트 암호(M2M OAuth)
--label No URL에서 자동 파생 앱당 사람이 읽을 수 있는 레이블(반복 가능)
--compute-size No 자동 검색 또는 medium 앱당 컴퓨팅 크기 태그: medium, large (반복 가능)
--max-users No 300 최대 동시 시뮬레이션된 사용자
--step-size No 20 램프 단계당 추가된 사용자
--step-duration No 30 램프 단계당 초
--spawn-rate No 20 사용자 생성 속도(사용자/초)
--run-name No <timestamp> 이 실행의 이름 - 결과를 에 저장 load-test-runs/<run-name>/
--dashboard No 끄기 테스트가 완료된 후 대화형 HTML 대시보드 생성

예제 명령

빠른 싱글 앱 테스트(단기간 실행 - databricks auth login 세션 사용):

cd load-test-scripts/

uv run run_load_test.py \
    --app-url https://my-app.aws.databricksapps.com \
    --dashboard --run-name quick-test

권장되는 6개 구성의 전체 행렬(장기 실행 - M2M 자격 증명 전달). 플래그를 --compute-size--app-url와 같은 순서로 전달합니다.

uv run run_load_test.py \
    --app-url https://my-app-medium-w2.aws.databricksapps.com \
    --app-url https://my-app-medium-w3.aws.databricksapps.com \
    --app-url https://my-app-medium-w4.aws.databricksapps.com \
    --app-url https://my-app-large-w6.aws.databricksapps.com \
    --app-url https://my-app-large-w8.aws.databricksapps.com \
    --app-url https://my-app-large-w10.aws.databricksapps.com \
    --compute-size medium --compute-size medium --compute-size medium \
    --compute-size large --compute-size large --compute-size large \
    --client-id $DATABRICKS_CLIENT_ID \
    --client-secret $DATABRICKS_CLIENT_SECRET \
    --dashboard --run-name overnight-sweep

통계 일관성을 위한 여러 실행:

for RUN in r1 r2 r3 r4 r5; do
  uv run run_load_test.py \
      --app-url https://my-app.aws.databricksapps.com \
      --client-id $DATABRICKS_CLIENT_ID \
      --client-secret $DATABRICKS_CLIENT_SECRET \
      --max-users 1000 --step-size 20 --step-duration 10 \
      --run-name my_test_${RUN} --dashboard || break
done

실행 중에 발생하는 작업

  1. Healthcheck: 앱 스트림을 올바르게 확인합니다(수신 [DONE]).
  2. 준비: 앱을 준비하기 위해 순차적 요청을 보냅니다.
  3. 램프-채도: 초마다 step_duration 동시 사용자를 한 단계씩 강화합니다.
  4. 채도 감지: QPS(초당 쿼리 수)가 더 많은 사용자를 추가했음에도 불구하고 일정해질 때, 처리량 한도에 도달한 것입니다.

예상 소요 시간

테스트 중인 각 앱은 자체 램프를 통해 실행되므로 총 런타임은 행렬의 구성 수로 확장됩니다. 아래 수식을 사용하여 실행 창을 계획합니다.

앱당 기간: (max_users / step_size) * step_duration 초.

기본값 사용(--max-users 300 --step-size 20 --step-duration 30):

  • 15단계 x 30초 = 앱당 약 7.5분
  • 권장되는 6 구성 매트릭스의 경우: 실행당 약 45분

5단계: 결과 보기 및 해석

  1. 대시보드를 엽니다.

    open load-test-runs/<run-name>/dashboard.html
    
  2. (선택 사항) 템플릿을 업데이트한 후와 같이 기존 데이터에서 대시보드를 다시 생성합니다.

    cd load-test-scripts/
    uv run dashboard_template.py ../load-test-runs/<run-name>/
    

대시보드 섹션

대화형 대시보드에는 다음이 포함됩니다.

  • KPI 카드: 최상의 구성(최고 성공 QPS별), 전체 최고 QPS, 가장 낮은 대기 시간 및 총 요청이 처리되었습니다.
  • 구성별 QPS: 중간 QPS, 실패를 제외한 최대 QPS 및 각 구성에 대한 최대 QPS를 나란히 표시하는 그룹화된 가로 막대형 차트입니다.
  • 구성별 대기 시간: p50 및 p95 대기 시간을 보여 주는 그룹화된 막대입니다.
  • 구성별 TTFT: 첫 번째 토큰까지의 시간(p50 및 p95).
  • 총 요청 처리: 구성당 요청 수입니다.
  • QPS 증가 진행 상황: QPS, 오류를 제외한 QPS, 반응 시간 및 오류에 대한 탭이 있는 꺾은선형 차트입니다. 낮은 동시성 범위를 확대할 최대 사용자 슬라이더를 포함합니다. 차트는 컴퓨팅 규모에 따라 중간 및 큰 크기끼리 나란히 그룹화됩니다.
  • 전체 결과 테이블: 최대 QPS, 최대 사용자, 대기 시간 백분위수 및 실패율이 있는 모든 구성입니다.
  • 테스트 매개 변수: 재현성을 위한 구성 요약입니다.

결과를 해석하는 방법

  • 최고 QPS: 모든 램프 단계에서 달성된 최대 QPS입니다. 이는 해당 구성에 대한 처리량 한도입니다.
  • 최고 수준의 사용자: 최대 QPS가 달성되었을 때의 동시 사용자 수입니다. 이 시점을 넘어 사용자를 더 추가해도 처리량은 증가하지 않습니다.
  • 실패율: 0% 또는 매우 낮아야 합니다. 높은 실패율은 앱이 해당 동시성 수준에서 오버로드됨을 의미합니다.
  • QPS 램프 차트: 선이 평면화되는 위치를 찾습니다. 이것이 포화 지점입니다. 더 많은 사용자를 추가해도 처리량이 증가하지는 않습니다.

Troubleshooting

Issue 해결 방법
테스트 중간에 인증 토큰이 만료됨 1시간을 초과하는 테스트의 경우 --client-id--client-secret 를 전달하여 U2M에서 M2M OAuth로 전환합니다.
상태 검사 실패 앱이 활성 상태인지 확인합니다. databricks apps get <name> --output json
0 QPS 또는 결과 없음 load-test-runs/<run-name>/<label>/locust_output.log를 오류가 있는지 확인하세요
높은 사용자 수에도 불구하고 낮은 QPS 앱이 포화 상태입니다. 더 많은 작업자 또는 더 큰 컴퓨팅을 사용해 보세요.
높은 실패율 앱이 오버로드됩니다. 작업자 수--max-users나 컴퓨팅 자원을 줄이거나 늘립니다.
대시보드에 램프 데이터가 표시되지 않음 각 결과 하위 디렉터리에 존재하는지 확인 results_stats_history.csv

다음 단계

  • 실제 LLM 호출을 사용하여 테스트: 모의 단계를 건너뛰고 실제 에이전트를 배포하여 LLM 응답 시간을 포함하여 엔드 투 엔드 대기 시간을 측정합니다.
  • 작업자 수 조정: 테스트 매트릭스 결과를 사용하여 컴퓨팅 크기에 대한 최적의 작업자 수를 찾습니다.
  • 자습서: GenAI 애플리케이션을 평가하고 개선 하여 처리량과 함께 정확도, 관련성 및 안전을 측정합니다.
  • AI 게이트웨이를 포함하여 전체 프로덕션 준비 시퀀스에 대해 Databricks Apps 에이전트를 프로덕션화합니다.