> ## Documentation Index
> Fetch the complete documentation index at: https://docs.sifi.life/llms.txt
> Use this file to discover all available pages before exploring further.

# Lakebase Postgres로 AI 에이전트 오케스트레이션 단순화하기

> Postgres 테이블 두 개를 브로커 없는 견고한 태스크 큐로 만드는 Databricks 네이티브 패턴

> **원문**: [Simplify AI agent orchestration with Lakebase Postgres](https://www.databricks.com/blog/simplify-ai-agent-orchestration-lakebase-postgres)
> **저자**: Li Yu, Michelle Janney Coyle, Jon Cormack, Yarri Bryn, Alec Sorensen, Darshana Nair
> **게시일**: 2026년 7월 22일

## 요약

* **Postgres 위의 확장 가능한 태스크 큐(Scale-Ready Task Queue)**: Lakebase 테이블 한 쌍을 장시간 실행되는 에이전트 태스크를 위한 내구성 있고, 동시성에 안전하며, 크래시에 강인한 큐로 바꾸는 패턴을 깊이 있게 다룹니다 — 브로커, 캐시, 스케줄러 없이.
* **완전한 Databricks 네이티브 아키텍처**: Lakebase, Databricks Apps, Lakeflow Jobs, MLflow, Unity Catalog Volumes를 엮어 에이전트 기반 문서 파싱을 위한 엔드투엔드 파이프라인을 만드는 레퍼런스 설계로, 운영해야 할 외부 인프라가 없습니다.
* **실시간 관측 가능성과 불변식(Invariants)**: Postgres `LISTEN/NOTIFY` 트리거와 Server-Sent Events(SSE)를 결합해, 비용과 태스크를 자동으로 추적하는 저지연 오퍼레이터 대시보드를 오버헤드 없이 구축하는 방법을 깊이 있게 다룹니다.

***

## 서론

전통적으로 감사(auditing)는 상세한 문서 검토와 정보 추출을 요구하는 지루한 과정입니다. 이 과정을 가속하기 위해, 성장하는 글로벌 입지를 가진 선도적 전문 서비스 기업 CLA(CliftonLarsonAllen LLP)는 Databricks Forward Deployed Engineering 팀과 협력하여 에이전트 기반 감사 솔루션을 구축하고 프로덕션화했습니다. 우리는 함께 품질 저하 없이 추출 시간을 몇 시간에서 몇 분으로 줄이는 문서 처리 애플리케이션을 개발했습니다. 이 애플리케이션은 전적으로 Databricks 위에 구축되었으며, [Lakebase Postgres](https://docs.databricks.com/aws/en/oltp/projects/), [Databricks Apps](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/), [Lakeflow Jobs](https://docs.databricks.com/aws/en/jobs/), [MLflow](https://docs.databricks.com/aws/en/mlflow/), [Unity Catalog Volumes](https://docs.databricks.com/aws/en/volumes/)를 사용합니다. 이 블로그에서는 그 시스템의 한 핵심 구성 요소인 Lakebase 기반 오케스트레이션 계층에 초점을 맞춥니다.

오케스트레이션 계층은 장시간 실행되는 태스크를 조율하고, 재시도를 관리하며, 비용을 귀속시키고, 실시간 가시성을 제공하는 역할을 합니다. Lakebase와 Databricks Apps를 통해 우리는 큐잉, 오케스트레이션, 관측 가능성을 위한 별도 인프라의 필요성을 없앱니다.

Lakebase는 또한 스토리지와 컴퓨트를 분리함으로써 이 아키텍처를 대규모에서도 실용적으로 만듭니다. 전통적인 Postgres 배포와 달리, 컴퓨트는 수요에 따라 확장될 수 있는 반면 스토리지는 내구성 있고 독립적으로 유지됩니다. 이러한 역량이 함께 어우러져 Lakebase는 Databricks 위의 장시간 실행 에이전트 워크로드를 위한, 더 단순하고 확장 가능한 오케스트레이션 패턴의 실용적 토대가 됩니다.

## 에이전트 워크로드의 오케스트레이션 과제

문서 파싱은 매우 흔하고 대용량인 에이전트 워크로드입니다. 여러 산업의 기업들은 대량의 계약서, 인보이스, 재무 신고서 및 기타 문서를 구조화된 데이터로 변환해야 합니다. 이를 대규모로 실행하면 다섯 가지 뚜렷한 분산 시스템 문제가 드러납니다.

* **예측 불가능한 태스크별 지연 시간**: 두 페이지짜리 인보이스는 몇 초 만에 처리될 수 있지만, 200페이지짜리 계약서는 몇 분이 걸릴 수 있어 개별 태스크가 얼마나 오래 실행될지 예측하기 어렵습니다.
* **레이트 리밋을 고려한 스로틀링**: LLM 및 비전 모델 엔드포인트는 주어진 기간 동안 처리할 수 있는 요청 수와 토큰 수를 제한합니다. 한 번에 수백 개의 태스크를 보내면 그 한도를 초과하여 스로틀링을 유발하고 반복적인 재시도로 이어질 수 있습니다. 오케스트레이터는 반응적 재시도에만 의존하는 대신, (동시 태스크 수, 토큰 예산, 또는 둘 다로) 진행 중인 작업량을 선제적으로 제한해야 합니다.
* **워크로드 우선순위 지정**: 긴급 제출 건이 대량 배치 뒤에 밀려 지연되어서는 안 됩니다. 태스크별 우선순위는 더 높은 우선순위의 작업(인터랙티브 제출, 프리미엄 등급 요청, 오퍼레이터가 시작한 재처리)이 먼저 디스패치되도록 보장합니다.
* **태스크별 비용 귀속**: 재무 팀은 지출을 특정 태스크, 고객, 에이전트에 귀속시키고, AI 토큰 사용량과 컴퓨트 소비로 나누어 파악해야 합니다.
* **실시간 진행 상황 가시성**: 수백 개의 문서를 업로드하는 사용자는 실시간 진행 상황 뷰를 필요로 합니다.

많은 조직이 오케스트레이션과 관측 가능성을 위해 여러 특화된 시스템을 조합합니다. 각 시스템은 자체 인프라, 인증, 모니터링, 운영 요구사항을 가져오며, 이들을 통합하는 데 필요한 작업도 수반합니다. 장시간 실행되는 독립적인 에이전트 태스크의 경우, 그러한 오버헤드는 실제 스케줄링 복잡성에 비해 지나치게 큽니다.

우리가 개발한 Databricks 네이티브 솔루션은 Lakebase를 토대로 위의 모든 요구사항을 충족합니다.

## 솔루션 아키텍처

![솔루션 아키텍처](https://www.databricks.com/sites/default/files/inline-images/2026-06-blog-Your-Next-Agent-Orchestrator-Runs-on-a-Postgres-Table-Inline-960x734-2x.png)

전체 애플리케이션 스택은 전적으로 Databricks 서비스로 구성됩니다.

* **웹 애플리케이션 (Databricks Apps)**: 사용자가 PDF를 업로드하고(Unity Catalog Volumes에 저장됨) 파싱 요청을 제출하는 FastAPI 기반 사용자 인터페이스입니다. 요청은 Lakebase의 `task` 테이블에 직접 기록됩니다.
* **Lakebase**: 오케스트레이터의 관계형 상태를 관련 테이블에 걸쳐 호스팅하는 오토스케일링 Postgres 데이터베이스입니다. `tasks`(파싱할 문서로, 상태·리스 정보·구조화된 결과를 보관), `task_attempts`(실행 시도당 한 행으로, Databricks Job 실행 ID·MLflow 트레이스 ID·시도별 비용 메타데이터를 캡처)로 구성됩니다. Lakebase는 오케스트레이터 상태에 대한 단일 진실 공급원(single source of truth) 역할을 합니다.
* **오케스트레이터 (Databricks Apps)**: 장시간 실행되는 워커 데몬이자 오퍼레이터 대시보드입니다. 데몬은 Lakebase에서 태스크를 디큐(dequeue)하여 AI Agents 계층으로 디스패치하고, 결과를 다시 기록합니다. 대시보드는 동일한 테이블을 읽어 실시간 상태를 표시합니다.
* **AI Agents (Lakeflow Jobs)**: Lakeflow Jobs가 파싱 작업을 실행합니다. 각 Job은 Unity Catalog Volumes에서 PDF를 읽고, [Intelligent Document Processing](https://docs.databricks.com/aws/en/agents/agent-bricks/intelligent-document-processing) 및 비전/LLM 호출을 통해 이를 처리하며, 파싱된 출력을 Lakebase에 저장하고, 웹훅을 통해 오케스트레이터에게 확인을 보냅니다. MLflow Tracing이 모델 호출, 토큰 사용량, 지연 시간, 비용 메타데이터 같은 실행 세부사항을 캡처합니다.

구성 요소 간 데이터 흐름은 다음과 같습니다. 웹 앱은 PDF를 Unity Catalog Volumes에, 파싱 요청을 Lakebase에 기록합니다. 오케스트레이터는 Lakebase에서 태스크를 디큐하고 Databricks Jobs를 AI Agents 계층으로 디스패치합니다. AI Agents는 문서를 처리하고 결과를 다시 Lakebase에 기록한 뒤, 상태 업데이트와 함께 오케스트레이터로 콜백합니다.

Databricks의 이러한 내장 역량 덕분에, 우리는 외부 메시지 브로커(Kafka, Redis), 별도의 스케줄러(Airflow, Temporal), 또는 전용 캐싱 계층에 의존할 필요가 없었습니다.

## 태스크 큐 구현

태스크 큐는 Lakebase 내 두 개의 Postgres 테이블로 뒷받침됩니다. `tasks` 테이블은 논리적 작업 단위당 한 행을 보관하며, 태스크의 현재 상태, 리스 정보, 에이전트 할당, 상위 추출(parent extraction), 최종 결과를 기록합니다. `task_attempts` 테이블은 실행 시도당 한 행을 보관하며, Databricks Job 실행 ID, MLflow 트레이스 ID, 시도별 비용 메타데이터를 캡처합니다. 부모-자식 관계는 재시도를 지원하고(하나의 태스크가 여러 시도를 가질 수 있음) 비용 귀속과 디버깅을 위한 시도 수준의 관측 가능성을 보존합니다.

Postgres 테이블 한 쌍 그 자체만으로는 아직 태스크 큐가 아닙니다. 네 가지 Postgres 네이티브 패턴이 이들을 장시간 실행 에이전트 워크로드에 적합한, 견고하고 동시성에 안전하며 크래시에 강인하고 레이트 리밋을 고려하는 큐로 변모시킵니다.

### 동시성·우선순위를 고려한 디큐잉

기본적인 디큐 쿼리는 `WHERE status = 'enqueued'`와 `LIMIT batch_size`를 사용해 다음으로 사용 가능한 태스크를 선택할 수 있습니다. 이 쿼리는 인큐된 태스크를 올바르게 식별하지만, 여러 워커가 동시에 디큐할 때는 충분하지 않습니다. 행 잠금(row locking)이 없으면 상태가 갱신되기 전에 여러 워커가 같은 태스크를 선택할 수 있습니다.

`FOR UPDATE SKIP LOCKED`를 추가하면 디큐가 동시성에 안전해집니다. 각 워커는 자신이 선택한 행을 잠그고, 다른 워커는 그 행을 건너뛰어 다음으로 사용 가능한 태스크로 계속 진행합니다. 여기에 `ORDER BY priority DESC, created_at` 절을 더하면, 각 우선순위 수준 내에서 FIFO 순서를 보존하면서도 우선순위가 높은 태스크가 먼저 선택되도록 보장합니다.

동시성에 안전하고 우선순위가 안정적인 완전한 구문은 다음과 같습니다.

```sql theme={null}
-- 우선순위 순 + 동시성 안전 디큐: 잠긴 행은 건너뛰어 워커 간 경합 방지
SELECT *
FROM tasks
WHERE status = 'enqueued'
ORDER BY priority DESC, created_at   -- 우선순위 높은 태스크 우선, 동일 우선순위 내 FIFO
LIMIT batch_size
FOR UPDATE SKIP LOCKED;
```

### 리스 기반 잠금을 통한 크래시 복구

워커는 VM 축출(eviction), 메모리 부족(out-of-memory) 상황, 배포 이벤트로 인해 태스크 도중에 종료될 수 있습니다. 종료된 태스크가 `processing`으로 표시된 채 남아 있으면 무기한 점유될 수 있습니다. 해결책은 디큐 시점에 만료되는 리스(expiring lease)를 기록하는 것입니다.

```sql theme={null}
-- 디큐 시 리스 만료 시각을 기록해, 워커가 죽으면 자동 회수 가능하게 함
UPDATE tasks
SET status = 'processing',
    locked_by = :worker_id,
    lease_expires_at = now() + :lease_duration   -- 리스 유효 기간(초과 시 재인큐 대상)
WHERE id = :task_id;
```

주기적인 스위퍼(sweeper)가 `lease_expires_at`이 지난 모든 태스크를 다시 인큐합니다. 종료된 워커가 점유하던 태스크는 외부 조정 서비스 없이도 몇 분 안에 자동으로 복구됩니다.

### 레이트 리밋을 고려한 스로틀링

LLM 및 비전 모델 엔드포인트는 일반적으로 두 가지 뚜렷한 쿼터를 적용합니다. 초당 요청 수(request-per-second) 상한과 분당 토큰 수(tokens-per-minute, TPM) 상한입니다. 하나의 스로틀링 전략이 둘 모두에 딱 맞는 경우는 드뭅니다. 오케스트레이터는 에이전트별 구성으로 선택되는 세 가지 모드를 지원합니다.

**동시성 상한(Concurrency cap).** `MAX_CONCURRENT_TASKS` 파라미터는 오케스트레이터가 동시에 디스패치하는 태스크 수를 제한합니다. 이 상한은 디큐 시점에 `tasks` 테이블의 현재 `PROCESSING` 행 수를 세어 적용됩니다.

```sql theme={null}
-- 현재 처리 중(PROCESSING) 태스크 수를 세어 동시성 상한 판단
SELECT count(*)
FROM tasks
WHERE status = 'processing';
```

이 개수가 상한 이상이면 새 태스크는 디큐되지 않습니다. 로컬 실행기의 큐 크기가 아니라 데이터베이스 행 수를 기준으로 확인하면, 워커 재시작, 리스 복구, 다중 레플리카 배포에 걸쳐 상한이 정확하게 유지됩니다. 이 모드는 각 태스크의 토큰 사용량이 대체로 균일하고 초당 요청 수 제한에 의해 제약받는 엔드포인트에 적합합니다.

**토큰 예산(Token budget).** `MAX_TPM` 파라미터는 진행 중인 태스크들에 걸친 예상 토큰 비율(token rate)을 제한합니다. 오케스트레이터는 태스크의 토큰 수를 추정하고, 모든 `PROCESSING` 태스크에 걸친 예상 토큰 비율을 합산합니다. 그 합계에 새 태스크의 예상 토큰을 더한 값이 예산 안에 들어올 때만 새 태스크가 디큐됩니다.

**결합 상한(Combined cap).** `MAX_CONCURRENT_TASKS`와 `MAX_TPM`이 모두 구성된 경우, 오케스트레이터는 더 빡빡한 제약을 적용합니다. 이 모드는 한 상황에서는 동시성에 묶이고(짧고 저렴한 태스크가 많은 경우) 다른 상황에서는 토큰에 묶이는(하나의 매우 긴 문서가 분당 쿼터를 포화시키는 경우) 워크로드를 처리합니다.

세 모드 모두에서 스로틀링 결정은 `FOR UPDATE SKIP LOCKED`와 동일한 트랜잭션 안에서, 디큐 시점에 이루어집니다. 현재 쿼터 안에 들어올 수 없는 태스크는 큐에 남아 다음 디큐 주기에 다시 고려됩니다 — 별도의 스케줄링 상태도, 인메모리 대기 큐도, 워커 레플리카 간 조정 계층도 없습니다.

### 멱등적 웹훅 콜백

AI Agents 계층이 태스크를 완료하면 결과와 함께 오케스트레이터로 콜백을 보냅니다. 콜백 전달은 정확히 한 번(exactly-once)이 아닙니다. Databricks가 재시도할 수 있고, 네트워크가 중단될 수 있으며, 프록시가 재전송할 수 있습니다. 콜백 핸들러는 멱등적(idempotent)으로 설계되어, `PROCESSING`과 `ENQUEUED` 상태를 모두 받아들이고 이미 종료 상태(terminal)인 태스크는 무동작(no-op)으로 처리합니다. 동일한 페이로드는 동일한 결과를 만들어내며, 이중 과금이나 중복 처리의 위험을 없앱니다.

이 네 가지 패턴이 결합되어, 동시성 하에서 정확하고, 크래시 하에서 내구성 있으며, 부하 하에서 레이트 리밋을 고려하고, 재시도 하에서 멱등적인 태스크 큐를 만들어냅니다. 실행 중인 시스템에 대한 실시간 가시성은 다음 섹션에서 설명하는 별도의 메커니즘으로 제공됩니다.

## 실시간 오퍼레이터 대시보드

많은 문서가 진행 중일 때, 오퍼레이터는 에이전트 성능, 태스크 상태, 워크로드 비용에 대한 명확한 뷰를 필요로 합니다. 그들은 오케스트레이터를 계속 폴링하거나 별도의 메트릭 플랫폼에 의존해서는 안 됩니다. 오케스트레이터는 이 기능을 워커 데몬을 실행하는 동일한 Databricks App이 표시하는 단일 대시보드에 직접 통합합니다.

### 대시보드 기능

오퍼레이터를 향한 대시보드는 실행 중인 시스템을 함께 특징짓는 일련의 운영 메트릭을 표시합니다. 모든 메트릭은 날짜 범위, 태스크 상태, 에이전트로 필터링할 수 있습니다.

* **상태별 태스크 총계.** 각 상태(enqueued, processing, completed, failed, cancelled)의 태스크 수로, 상태 전이가 발생할 때 실시간으로 갱신됩니다.
* **입력 및 출력 토큰.** MLflow Traces에서 가져온 태스크별 및 집계 토큰 수입니다.
* **LLM 비용.** MLflow Traces에서 나온 모델 방출 추정치(model-emitted estimate)로, 각 모델 호출 후 몇 초 내에 사용 가능합니다.
* **컴퓨트 비용.** `system.billing.usage`에서 가져온, 오케스트레이터의 태스크 실행에 귀속되는 Serverless Jobs 컴퓨트 비용입니다.
* **중앙값 응답 시간.** 완료된 태스크에 걸쳐 계산됩니다. 재시도-백오프 이상값과 포화 상태의 큐잉-테일 지연에 의한 왜곡을 피하기 위해 평균 대신 중앙값을 사용합니다.
* **신뢰도(Confidence).** AI Agents 계층이 반환한 문서별 신뢰도 점수로, 태스크 결과와 함께 표시됩니다.

### 구현

`tasks` 테이블의 상태 변경은 Postgres `LISTEN/NOTIFY` 이벤트를 발생시킵니다. 백엔드는 단일 `LISTEN` 연결을 유지하고, 이벤트를 Server-Sent Events(SSE)를 통해 연결된 대시보드 클라이언트로 팬아웃(fan out)합니다. 브라우저는 `EventSource` 연결을 열고, 의미 있는 상태 변경이 있을 때마다 약 1초 이내에 실시간 업데이트를 받습니다. 이 구현에는 Redis도, WebSocket 서버도, 메시지 버스도 필요하지 않습니다.

폴링은 기본 10초 간격으로 영구적인 폴백(fallback)으로 유지됩니다. 클라우드 인그레스 프록시를 통과하는 스트리밍 연결은 클라이언트 측 오류 이벤트를 발생시키지 않고 조용히 바이트를 누락시킬 수 있으므로, 영구 폴링은 그런 경우에도 대시보드가 최신 상태를 유지하도록 보장합니다. UI 표시기는 실시간(SSE 활성) 채널과 폴링(SSE 불가) 채널을 구분합니다.

대시보드의 데이터는 지연 특성이 서로 다른 세 가지 소스에 걸쳐 있습니다. Postgres(즉각적), MLflow의 트레이스 API(1초 미만), 시스템 빌링 테이블에 대한 웨어하우스 쿼리(때로 수십 초)입니다. 빠른 쿼리는 모든 새로고침 주기에 반영되고, 느린 쿼리는 사용자 액션이 있을 때만 실행되며 결과가 준비될 때까지 로딩 상태로 낙관적으로(optimistically) 반환됩니다.

### 애플리케이션별 비용 귀속

Databricks 시스템 빌링 테이블은 계정 범위(account-scoped)입니다. 모든 잡, 모든 모델 호출, 그리고 다른 모든 애플리케이션이 동일한 `system.billing.usage` 행에 기여합니다. 범위를 지정하지 않으면 애플리케이션 수준의 "OCR 비용" 타일이 워크스페이스 내 모든 모델 호출의 사용량을 합산하게 됩니다.

해결책은 오케스트레이터가 제출한 Databricks Job 실행을 기록하고(`tasks.locked_by`와 `task_attempts.run_id`에 추적됨) 빌링 쿼리를 그 집합으로 필터링하는 것입니다. 하나의 SQL 웨어하우스가 여러 애플리케이션을 뒷받침할 수 있으며, 각 대시보드는 자신의 지출만 표시합니다.

동일한 쿼리 아키텍처는 오퍼레이터가 지정하는 필터와 자연스럽게 조합됩니다. 비용 수치는 다른 모든 대시보드 메트릭과 마찬가지로 날짜 범위, 태스크 상태, 에이전트로 더 좁힐 수 있어, 대시보드를 벗어나지 않고도 "지난 7일간 실패한 태스크에 든 비용은 얼마인가?" 또는 "이번 달 에이전트 X의 태스크당 중앙값 지출은 얼마인가?" 같은 질문에 답할 수 있습니다.

이는 비용 수치를 모니터링하고, 배분하고, 보고하기 쉽게 만듭니다.

## 오케스트레이션의 중추(Backbone)로서의 Lakebase

Postgres를 큐로 활용하는 패턴은 데이터 엔지니어링 커뮤니티에서 잘 확립되어 있습니다. Lakebase는 이 패턴을 Databricks 위의 프로덕션 아키텍처로 실현 가능하게 하는 추가적인 운영 특성을 제공합니다.

* **오토스케일링 컴퓨트.** Lakebase는 워크로드에 맞춰 Postgres 컴퓨트 유닛을 위아래로 확장하여, 오케스트레이터가 최대 용량을 24시간 내내 지불하지 않고도 데이터베이스에 의존할 수 있게 합니다.
* **OAuth 로테이션 인증.** Lakebase는 연결 인증에 수명이 짧은 OAuth 토큰을 사용합니다. 커넥션 풀이 토큰을 자동으로 갱신하여, 애플리케이션 구성에서 정적 자격 증명을 없애고 로테이션 런북(runbook)을 제거합니다.
* **Unity Catalog 통합.** Lakebase는 Databricks의 나머지 부분과 아이덴티티, 권한, 거버넌스를 공유합니다. 오케스트레이터의 서비스 프린시펄(service principal)은 `tasks`와 `results` 테이블에 대한 명시적 권한을 부여받으며, 별도의 IAM 구성이 필요하지 않습니다.
* **브랜칭 및 스냅샷.** 프로덕션 태스크 테이블을 디버깅을 위해 개발 환경으로 복제하는 것은 표준 Lakebase 작업이며, 네이티브로 지원됩니다.

이러한 역량은 태스크 큐잉을 위해 자체 호스팅 Postgres 대신 관리형 메시지 브로커를 채택하도록 팀을 이끄는 운영상의 부담을 없앱니다.

## 임팩트 및 결론

CLA에서 여기에 설명된 오케스트레이션 패턴은 추출 시간을 몇 시간에서 몇 분으로 줄이는 프로덕션 문서 처리 워크플로우를 뒷받침합니다. 이 아키텍처는 Lakebase Postgres를 중심에 둔 Databricks 네이티브 서비스를 사용하여 외부 시스템 없이 큐잉, 스케줄링, 관측 가능성을 관리합니다. 이는 통합 오버헤드를 줄이면서 확장을 위해 만들어진 단일 플랫폼을 최대한 활용합니다.

프로덕션에서 이 패턴은 내구성 있는 태스크 관리, 우선순위 제어, 레이트 리밋을 고려한 스케줄링, 실시간 가시성, 태스크별 비용 추적을 제공합니다. 이러한 역량이 함께 어우러져, 주변 인프라를 단순하게 유지하면서 에이전트 워크로드를 오케스트레이션하는 실용적인 방법을 제공합니다.

단일 플랫폼에서 AI 에이전트 오케스트레이션을 단순화할 준비가 되셨나요? [Databricks Free Edition](https://docs.databricks.com/aws/en/getting-started/free-edition)을 사용해 보고, 첫 Lakebase Postgres 프로젝트와 [Databricks App](https://docs.databricks.com/aws/en/dev-tools/databricks-apps/)을 만든 다음, [MLflow Tracing 10분 데모](https://docs.databricks.com/aws/en/mlflow3/genai/getting-started/tracing/tracing-notebook)를 따라 에이전트 워크플로우에 엔드투엔드 관측 가능성을 추가해 보세요.
