주요 컨텐츠로 이동

데이터 엔지니어를 위한 Databricks Assistant 활용 팁과 요령

잭키 장
라피 쿨란식
Richard Tomlinson
이 포스트 공유하기

생성형 AI 혁명은 팀의 업무 방식을 변화시키고 있으며, Databricks Assistant는 이러한 발전의 이점을 최대한 활용합니다. 대화형 인터페이스를 통해 데이터를 쿼리할 수 있으므로 Databricks Workspace 내에서 생산성을 높일 수 있습니다. 이 어시스턴트는 Databricks용 데이터 인텔리전스 엔진인 DatabricksIQ로 구동되므로 데이터를 안전하게 보호하고 기업의 특성에 맞게 정확하고 맞춤화된 응답을 제공할 수 있습니다. Databricks Assistant 를 사용하면 자연어로 작업을 설명하여 개발자 경험을 방해하지 않고 복잡한 코드를 생성, 최적화 또는 디버깅할 수 있습니다.

이 포스트에서는 Databricks Assistant를 활용하는 5가지 팁 블로그를 확장하여, 지루한 반복 작업을 없애고 생산성과 몰입도를 높이며 가치 창출 시간을 단축하여 데이터 엔지니어의 삶을 개선하는 방법에 대해 집중적으로 다룹니다. 다양한 데이터 실무자 페르소나에 초점을 맞춘 후속 포스팅이 이어질 예정이니, 데이터 과학자, SQL 분석가 등에 초점을 맞춘 다음 포스팅을 기대해 주세요.

데이터 수집

데이터 엔지니어로서 데이터브릭스에서 작업할 때, 데이터를 델타 레이크 테이블로 수집하는 것이 첫 번째 단계인 경우가 많습니다. 어시스턴트가 API에서, 그리고 클라우드 저장소의 파일에서 데이터를 로드하는 데 어떻게 도움이 되는지 두 가지 예를 살펴보겠습니다. 각각에 대해 프롬프트와 결과를 공유하겠습니다. 5가지 팁 블로그에서 언급했듯이 프롬프트를 구체적으로 작성하면 최상의 결과를 얻을 수 있으며, 이 문서에서 일관되게 사용되는 기법입니다.

datausa.io API에서 데이터를 가져와서, Python으로 Delta Lake 테이블에 적재하기 위해 다음 프롬프트를 사용했습니다:

Help me ingest data from this API into a Delta Lake table: https://datausa.io/api/data?drilldowns=Nation&measures=Population

Make sure to use PySpark, and be concise! If the Spark DataFrame columns have any spaces in them, make sure to remove them from the Spark DF.

비슷한 프롬프트를 사용하여 클라우드 스토리지의 JSON 파일을 델타 레이크 테이블로 수집할 수 있으며, 이번에는 SQL을 사용합니다:

I have JSON files in a UC Volume here: /Volumes/rkurlansik/default/data_science/sales_data.json

Write code to ingest this data into a Delta Lake table.  Use SQL only, and be concise!

 

데이터를 비정형에서 정형으로 변환하기

정돈된 데이터 원칙에 따라, 테이블의 모든 셀에는 적절한 데이터 유형의 단일 관측값이 포함되어야 합니다. 복잡한 문자열이나 중첩된 데이터 구조는 이 원칙과 상충되는 경우가 많기 때문에 데이터 엔지니어링 작업은 비정형 데이터에서 정형 데이터를 추출하는 것으로 구성됩니다.  어시스턴트가 이 작업을 탁월하게 수행하는 두 가지 예, 즉 정규식 사용과 중첩된 데이터 구조 추출을 살펴보겠습니다. 

정규 표현식

정규 표현식은 복잡한 문자열에서 정형 데이터를 추출하는 수단이지만, 올바른 정규식을 찾는 데는 시간이 걸리고 지루한 작업입니다. 이런 점에서 어시스턴트는 정규식으로 어려움을 겪는 모든 데이터 엔지니어에게 큰 도움이 됩니다. 

IMDb dataset의 Title 열을 사용하는 이 예제를 살펴보겠습니다:


이 열에는 영화 제목과 개봉 연도라는 2개의 정보 항목이 포함되어 있습니다. 다음 프롬프트를 통해 어시스턴트는 문자열을 여러 열로 구문 분석하는 데 적합한 정규식을 찾아 냅니다.

Here is an example of the Title column in our dataset: 1. The Shawshank Redemption (1994). The title name will be between the number and the parentheses, and the release date is between parentheses. Write a function that extracts both the release date and the title name from the Title column in the imdb_raw DataFrame.

 

프롬프트에 예시 문자열을 제공하면 어시스턴트가 올바른 결과를 찾는 데 도움이 됩니다.  민감한 데이터로 작업하는 경우 동일한 패턴을 따르는 가짜 예제를 만드는 것이 좋습니다. 어쨌든 이제 데이터 엔지니어링 작업에서 걱정할 문제가 하나 줄었습니다.

중첩된 구조체, 배열(JSON, XML 등)

API, 스토리지의 JSON 파일 또는 noSQL 데이터베이스를 통해 데이터를 수집할 때, 결과 Spark 데이터프레임이 깊게 중첩되어 올바르게 평탄화(flatten)하기 까다로울 수 있습니다.  아래 JSON 형식의 모의 판매 데이터를 살펴 봅시다:

 

데이터 엔지니어는 중첩된 배열을 평탄화(flatten)하고 각 제품에 대한 매출 지표를 추출하라는 요청을 받을 수 있습니다.  일반적으로 이 작업은 데이터가 비교적 간단한 경우라도 상당한 시행착오를 거쳐야 합니다.  하지만 어시스턴트는 메모리에 있는 데이터프레임의 스키마를 상황에 맞게 인식하여 작업을 완료하기 위한 코드를 생성합니다.  간단한 프롬프트를 통해 몇 초 만에 원하는 결과를 얻을 수 있습니다.

Write PySpark code to flatten the df and extract revenue for each product and customer

Displaying nestedJSON.gif

 

리팩터링, 디버깅 및 최적화

데이터 엔지니어가 직면하는 또 다른 시나리오는 후배 또는 퇴사한 다른 팀원이 작성한 코드를 재작성하는 경우입니다.  이러한 경우, 어시스턴트는 문맥과 의도를 이해하여 잘못 작성된 코드를 분석하고 설명할 수 있습니다. 더 효율적인 알고리즘을 제안하고, 가독성을 높이기 위해 코드를 리팩터링하고, 주석을 추가할 수 있습니다. 

문서화 및 유지보수성 개선

이 Python 코드는 온라인 쇼핑 카트에 있는 품목의 총 비용을 계산합니다.

def calculate_total(cart_items):
    total = 0
    for i in range(len(cart_items)):
        if cart_items[i]['type'] == 'book':
            discount = cart_items[i]['price'] * 0.05
            total += cart_items[i]['price'] - discount
        else:
            total += cart_items[i]['price']
    return total

cart_items = [{'name': 'Python Programming', 'type': 'book', 'price': 50},
              {'name': 'Laptop', 'type': 'electronics', 'price': 800}]
total_price = calculate_total(cart_items)

이 코드에서 사용된 조건부 구문은 가독성이 떨어지고 규모가 커지면 비효율적으로 동작합니다. 또한 무슨 일이 일어나고 있는지 설명하는 주석이 없습니다. 어시스턴트에게 코드를 단계별로 설명해 달라고 요청하는 것이 좋은 시작점입니다. 데이터 엔지니어가 코드를 이해하면 어시스턴트는 다음과 같은 프롬프트를 통해 코드를 변환하여 성능과 가독성을 향상시킬 수 있습니다:

Rewrite this code in a way that is more performant, commented properly, and documented according to Python function documentation standards

아래 생성된 예제는 코드를 적절하게 문서화하고 조건부 블록 대신 generator 표현식을 사용하여 대규모 데이터 세트에서 메모리 사용률을 개선합니다.

def calculate_total(cart_items):
    """
    Calculate the total price of items in the shopping cart.

    Apply a 5% discount to book items. The total is calculated by summing
    the prices, taking into account the discount for books.

    Parameters:
    cart_items (list of dict): A list of dictionaries, where each dictionary
                               represents an item in the cart with keys 'name',
                               'type', and 'price'.

    Returns:
    float: The total price of all items in the cart after discounts.
    """
    # Use a generator expression to iterate over cart items, applying a 5% discount to books.
    return sum(item['price'] * 0.95 if item['type'] == 'book' else item['price'] for item in cart_items)

# Example usage
cart_items = [{'name': 'Python Programming', 'type': 'book', 'price': 50},
              {'name': 'Laptop', 'type': 'electronics', 'price': 800}]
total_price = calculate_total(cart_items)

오류 진단

데이터 엔지니어는 불가피하게 디버깅을 해야 할 때가 있습니다.  어시스턴트를 사용하면 코드에서 오류의 원인을 파악하기 위해 여러 브라우저 탭을 열거나 컨텍스트를 전환할 필요가 없으며, 집중력을 유지할 수 있어 생산성이 크게 향상됩니다.  어시스턴트가 어떻게 작동하는지 이해하기 위해 간단한 PySpark 데이터 프레임을 만들고 오류를 만들어 보겠습니다.

 

 

위의 예에서는 데이터프레임에 새 열을 추가할 때 오타가 발생했습니다.  '10'의 0은 실제로는 문자 'O'로, 잘못된 십진수 리터럴 구문 오류가 발생합니다.  어시스턴트가 즉시 오류 진단을 제공합니다.  오타를 정확하게 식별하고 현재 셀의 편집기에 삽입할 수 있는 수정된 코드를 제안합니다.  이러한 방식으로 오류를 진단하고 수정하면 디버깅에 소요되는 시간을 절약할 수 있습니다.

pandas 를 PySpark 으로 번역하기

Pandas는 Python에서 가장 성공적인 데이터 랭글링 라이브러리 중 하나이며 모든 데이터 과학자들이 사용하고 있습니다. JSON 매출 데이터를 가지고 초보 데이터 과학자가 pandas를 사용해 데이터를 평탄화(flatten)하려고 최선을 다한 상황을 상상해 봅시다.  보기 좋지는 않고 모범 사례를 따르지는 않지만 올바른 결과를 생성합니다:

import pandas as pd
import json

with open("/Volumes/rkurlansik/default/data_science/sales_data.json") as file:
    data = json.load(file)

# Bad practice: Manually initializing an empty DataFrame and using a deeply nested for-loop to populate it.
df = pd.DataFrame(columns=['company', 'year', 'quarter', 'region_name', 'product_name', 'units_sold', 'product_sales'])

for quarter in data['quarters']:
    for region in quarter['regions']:
        for product in region['products']:
            df = df.append({
                'company': data['company'],
                'year': data['year'],
                'quarter': quarter['quarter'],
                'region_name': region['name'],
                'product_name': product['name'],
                'units_sold': product['units_sold'],
                'product_sales': product['sales']
            }, ignore_index=True)

# Inefficient conversion of columns after data has been appended
df['year'] = df['year'].astype(int)
df['units_sold'] = df['units_sold'].astype(int)
df['product_sales'] = df['product_sales'].astype(int)

# Mixing access styles and modifying the dataframe in-place in an inconsistent manner
df['company'] = df.company.apply(lambda x: x.upper())
df['product_name'] = df['product_name'].str.upper()

기본적으로 Pandas는 단일 머신에서 실행하도록 제한되어 있습니다. 데이터 엔지니어는 이 코드를 PySpark로 변환하기 전까지는 프로덕션 환경에 투입하여 수십억 행의 데이터에서 실행해서는 안 됩니다.  이 변환 프로세스에는 데이터 엔지니어가 코드를 이해하고 유지 관리, 테스트, 성능이 보장되는 방식으로 코드를 다시 작성하는 것이 포함됩니다. 다시 한 번 어시스턴트가 몇 초 만에 더 나은 솔루션을 제시합니다. 

 

생성된 코드에는 데이터브릭스에서는 필요하지 않은 SparkSession 생성이 포함되어 있다는 점에 유의하세요.  때때로 어시스턴트는 다른 LLM과 마찬가지로 틀린 답변을 내거나 환각(hallucination)을 일으킬 수 있습니다.  데이터 엔지니어는 코드의 최종 작성자이므로 다음 작업을 진행하기 전에 생성된 모든 코드를 검토하고 이해하는 것이 중요합니다. 이러한 유형의 동작을 발견하면 그에 따라 프롬프트를 조정하세요.

테스트 작성

데이터 엔지니어링에서 가장 중요한 단계 중 하나는 데이터 프레임 변환 로직이 올바른지 확인하고 파이프라인을 통해 흐르는 손상된 데이터를 잠재적으로 포착하기 위한 테스트를 작성하는 것입니다.  JSON 매출 데이터의 예를 계속 이어서, 어시스턴트를 사용하면 매출 열 중 음수인 열이 있는지 쉽게 테스트할 수 있습니다. 매출 열의 값이 0보다 작지 않다면 이 경우 데이터와 변환이 올바른지 확신할 수 있습니다.

Displaying writetest.gif다음 프롬프트를 사용하여 어시스턴트에게 PySpark의 기본 테스트 기능에 테스트를 통합하도록 하는 방법으로 이 로직을 구축할 수 있습니다: 

Write a test using assertDataFrameEqual from pyspark.testing.utils to check that an empty DataFrame has the same number of rows as our negative revenue DataFrame. 

어시스턴트는 위 프롬프트에 따라 테스트 작업을 부트스트랩하기 위한 실행 가능 코드를 제공합니다.

 

이 예는 프롬프트에 구체적으로 세부 사항을 추가하면 더 나은 결과를 얻을 수 있다는 사실을 강조합니다.  어시스턴트에게 세부 사항 없이 단순히 테스트를 작성해 달라고 요청하면 결과의 품질이 더 다양하게 나타납니다.  원하는 것을 구체적이고 명확하게 말하면, 즉 작성한 로직을 기반으로 PySpark 모듈을 사용하라고 테스트를 지정하면 어시스턴트가 우리의 의도를 정확하게 추측할 수 있다고 가정하는 것보다 일반적으로 더 나은 성능을 발휘합니다. 

도움말 보기

어시스턴트는 코드를 개선하고 이해하는 일반적인 기능 외에도 전체 데이터브릭스 문서와 지식창고(Knowledge Base)에 대한 지식을 보유하고 있습니다.  이 정보는 정기적으로 색인되며 RAG 아키텍처를 통해 어시스턴트를 위한 추가 컨텍스트로 제공됩니다.  이를 통해 사용자는 데이터브릭스 플랫폼을 벗어나지 않고도 제품 기능 및 구성을 검색할 수 있습니다. 

예를 들어 사용 중인 데이터브릭스 런타임 버전의 시스템 환경에 대한 세부 정보를 알고 싶다면 어시스턴트가 데이터브릭스 문서의 해당 페이지로 안내할 수 있습니다.

 

어시스턴트는 단순하고 설명적인 대화형 질문을 처리할 수 있어 데이터브릭스 기능을 탐색하고 문제를 해결하는 데 있어 사용자 경험을 향상시킵니다. 심지어 사용자가 지원 티켓(support ticket)을 제출하는 데 도움을 줄 수도 있습니다!  자세한 내용은 공지 문서를 참조하세요.

결론

Databricks Assistant를 통한 생성형 AI의 힘 덕분에 고품질 데이터 엔지니어링의 진입 장벽이 낮아졌습니다.  복잡한 데이터 구조로 작업하는 방법에 대한 도움을 찾고 있는 초보자든, 정규식을 작성해 주길 원하는 노련한 베테랑이든, 어시스턴트는 삶의 질을 향상시켜 줄 것입니다. 코드를 이해하고, 생성하고, 문서화하는 핵심 역량으로 모든 기술 수준의 데이터 엔지니어의 생산성을 높여줍니다.  자세한 내용은 Databricks Assistant를 시작하는 방법에 대한 데이터브릭스 설명서를 참조하고, Databricks Assistant를 최대한 활용하기 위한 5가지 팁 블로그를 확인하세요. 또한 이 동영상을 통해 Databricks Assistant가 실제로 작동하는 모습을 볼 수도 있습니다.

 

(번역: Youngkyong Ko) Original Post

Databricks 무료로 시작하기
모든 제품 포스트 보기