데이터 분석 에이전트 구축
CSV 파일과 자연어 질문을 받아 pandas 및 matplotlib 코드를 반복적으로 작성하고 완성도 높은 보고서를 생성하는 종단 간 데이터 분석 에이전트를 만듭니다.
데이터 분석 에이전트 구축은(는) CoddyKit의 무료 AI Engineering Academy 강의입니다. 이것은 4개 중 4번째 강의입니다. 아래에서 전체 강의를 무료로 읽을 수 있으며, 내장 코드 에디터와 24/7 AI 튜터와 함께 브라우저에서 직접 실습할 수 있습니다. 이 강의는 AI Engineering Academy 학습 경로의 일부이며, 진행 상황이 웹과 CoddyKit 앱에 동기화됩니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
데이터 분석 에이전트의 비전
데이터 분석 에이전트는 CSV 파일과 자연어 질문을 받은 다음 데이터를 자율적으로 탐색하고 정리하며, 통계를 계산하고 시각화를 생성한 뒤 완성도 높은 보고서를 작성합니다. 이 모든 과정은 코드를 반복적으로 생성하고 실행하여 이루어집니다. 이는 코드 에이전트의 가장 실용적인 활용 사례 중 하나이며, 사람의 작업을 제외하면 데이터 분석가의 작업 흐름을 그대로 재현합니다.
에이전트의 전체 아키텍처
데이터 분석 에이전트에는 네 가지 개념적 단계가 있습니다. 탐색(데이터의 형태, 유형, 품질 파악), 정리(결측값, 이상치, 유형 변환 처리), 분석(질문에 답하는 지표와 통계 계산), 보고(차트를 생성하고 결과를 글로 요약)입니다. 각 단계는 1~5회의 코드 실행 반복에 해당합니다.
DATA_AGENT_SYSTEM_PROMPT = '''
You are a data analysis agent. Given a CSV file and a question, answer it through iterative Python code.
Phases to follow:
1. EXPLORE: Load the data, print shape, dtypes, head(), describe(), and check for nulls.
2. CLEAN: Handle missing values, fix dtypes, remove outliers.
3. ANALYZE: Compute statistics, groupbys, correlations - whatever answers the question.
4. REPORT: Generate a matplotlib chart saved to /workspace/chart.png and write a text summary.
Rules:
- Write code in ```python ... ``` blocks.
- Save intermediate results to /workspace/ for use in later steps.
- Print key findings after each computation so you can observe them.
- When all phases are done, say TASK COMPLETE and summarize the answer.
'''1단계: 데이터 탐색 코드
탐색 단계에서는 데이터를 로드한 직후 분석 계획에 필요한 모든 정보를 출력합니다. 여기에는 형태, 열 이름과 유형, 샘플 행, 요약 통계, null 개수가 포함됩니다. LLM은 이 출력을 읽고 이후 반복 작업에서 정리와 분석에 관한 판단을 내립니다.
import pandas as pd
import numpy as np
# Load dataset
df = pd.read_csv('/workspace/data.csv')
# Basic exploration
print('=== SHAPE ===' )
print(df.shape)
print('\n=== DTYPES ===')
print(df.dtypes)
print('\n=== HEAD ===')
print(df.head())
print('\n=== DESCRIBE ===')
print(df.describe(include='all'))
print('\n=== NULL COUNTS ===')
print(df.isnull().sum())
print('\n=== UNIQUE VALUES (categorical) ===')
for col in df.select_dtypes(include='object').columns:
print(f'{col}: {df[col].nunique()} unique values: {df[col].unique()[:5]}')
# Save for next iteration
df.to_parquet('/workspace/raw.parquet')
print('\nData saved to workspace.')2단계: 데이터 정리
탐색이 끝나면 에이전트는 관찰한 내용을 바탕으로 대상에 맞는 정리 코드를 작성합니다. 정리 전략은 동적입니다. LLM이 한 열에서 15%의 null을 관찰했다면 삭제할지 대체할지 결정합니다. 음수가 될 수 없는 열에서 음수 값을 발견했다면 해당 값을 필터링합니다. 이러한 적응형의 관찰 기반 정리 덕분에 에이전트는 고정된 파이프라인을 단순히 실행하는 것이 아니라 실제로 유용한 작업을 수행합니다.
import pandas as pd
import numpy as np
# Load from previous iteration
df = pd.read_parquet('/workspace/raw.parquet')
# Fill numeric nulls with median (robust to outliers)
for col in df.select_dtypes(include='number').columns:
if df[col].isnull().sum() > 0:
median_val = df[col].median()
df[col] = df[col].fillna(median_val)
print(f'Filled nulls in {col} with median {median_val:.2f}')
# Drop rows where categorical key columns are null
df = df.dropna(subset=['category', 'date'])
# Fix date column type
df['date'] = pd.to_datetime(df['date'], errors='coerce')
df = df.dropna(subset=['date']) # drop unparseable dates
# Remove clear outliers: revenue > 3 std deviations from mean
if 'revenue' in df.columns:
z_scores = (df['revenue'] - df['revenue'].mean()) / df['revenue'].std()
df = df[z_scores.abs() < 3]
print(f'Removed outliers, rows remaining: {len(df)}')
df.to_parquet('/workspace/cleaned.parquet')
print('Cleaning complete:', df.shape)3단계: 질문에 답하기
분석 단계에서 에이전트는 사용자의 질문에 대한 구체적인 답을 계산하는 데 집중합니다. 질문이 '지난 분기에 어느 제품 범주의 매출이 가장 높았나요?'라면 에이전트는 날짜로 필터링하고, 범주별로 그룹화하고, 매출을 합산하고, 정렬하는 코드를 작성합니다. 분석 코드는 질문과 탐색 중 에이전트가 관찰한 내용을 모두 바탕으로 새롭게 생성되며, 일반적인 템플릿이 아닙니다.
import pandas as pd
import matplotlib
matplotlib.use('Agg') # non-interactive backend for server use
import matplotlib.pyplot as plt
df = pd.read_parquet('/workspace/cleaned.parquet')
# Analysis: revenue by category for last quarter
df['date'] = pd.to_datetime(df['date'])
last_quarter = df[df['date'] >= '2024-10-01']
revenue_by_category = (
last_quarter
.groupby('category')['revenue']
.sum()
.sort_values(ascending=False)
)
print('Revenue by category (last quarter):')
print(revenue_by_category)
print(f'\nTop category: {revenue_by_category.index[0]} (${revenue_by_category.iloc[0]:,.0f})')
# Save analysis result
revenue_by_category.to_json('/workspace/analysis_result.json')4단계: 차트 생성
시각화는 분석 결과를 명확하고 설득력 있게 보여 줍니다. 데이터 분석 에이전트는 matplotlib 차트를 생성하여 작업 공간에 PNG 파일로 저장합니다. 차트 유형, 색상 팔레트, 축 레이블, 제목, 주석과 같은 주요 차트 설계 결정은 데이터의 특성에 따라 LLM이 내립니다. 에이전트는 최종 보고서에 차트를 포함할 수 있도록 항상 /workspace/에 저장합니다.
import pandas as pd
import matplotlib
matplotlib.use('Agg')
import matplotlib.pyplot as plt
import json
with open('/workspace/analysis_result.json') as f:
data = json.load(f)
categories = list(data.keys())
values = [data[k] / 1e6 for k in categories] # convert to millions
fig, ax = plt.subplots(figsize=(10, 6))
bars = ax.barh(categories, values, color='steelblue', edgecolor='white')
# Add value labels on bars
for bar, val in zip(bars, values):
ax.text(bar.get_width() + 0.05, bar.get_y() + bar.get_height()/2,
f'${val:.1f}M', va='center', fontsize=11)
ax.set_xlabel('Revenue ($ Millions)', fontsize=12)
ax.set_title('Revenue by Product Category - Q4 2024', fontsize=14, fontweight='bold')
ax.invert_yaxis() # highest on top
plt.tight_layout()
plt.savefig('/workspace/chart.png', dpi=150, bbox_inches='tight')
print('Chart saved to /workspace/chart.png')작성 보고서 생성
마지막 반복에서는 작성된 요약 보고서를 생성합니다. LLM은 분석 결과와 차트 설명을 읽은 다음 구체적인 수치를 사용하여 원래 질문에 답하는 간결하고 정확한 설명을 작성합니다. 보고서에는 차트가 언급되며, 핵심 통찰, 뒷받침하는 데이터, 비즈니스에 대한 권고 또는 시사점이 포함됩니다.
import json
with open('/workspace/analysis_result.json') as f:
revenue_data = json.load(f)
top_category = max(revenue_data, key=revenue_data.get)
top_revenue = revenue_data[top_category]
total_revenue = sum(revenue_data.values())
share = top_revenue / total_revenue * 100
report = f'''# Q4 2024 Revenue Analysis
## Answer
The **{top_category}** category generated the highest revenue in Q4 2024:
**${top_revenue:,.0f}** ({share:.1f}% of total Q4 revenue).
## Key Findings
- Total Q4 revenue: ${total_revenue:,.0f}
- Top 3 categories: {list(revenue_data.items())[:3]}
- The top category outperformed the average by {top_revenue / (total_revenue / len(revenue_data)):.1f}x
## Chart
See chart.png for the full breakdown by category.
## Recommendation
Consider reallocating marketing budget toward {top_category} to
capitalize on its demonstrated strong performance.
'''
with open('/workspace/report.md', 'w') as f:
f.write(report)
print('TASK COMPLETE')
print(report)에이전트 오케스트레이터 구성
오케스트레이터는 모든 단계를 연결합니다. 작업 공간을 초기화하고, 입력 CSV를 복사하고, 코드 실행 반복을 수행하고, TASK COMPLETE 신호를 모니터링한 다음 출력 파일(report.md, chart.png)을 수집합니다. 또한 오류와 재시도, 중간 파일의 최종 정리도 처리합니다.
import shutil
from pathlib import Path
def run_data_analysis_agent(csv_path: str, question: str) -> dict:
workspace = setup_workspace()
shutil.copy(csv_path, workspace / 'data.csv')
messages = [
{'role': 'system', 'content': DATA_AGENT_SYSTEM_PROMPT},
{'role': 'user', 'content': f'File: /workspace/data.csv\nQuestion: {question}'}
]
state = ExecutionState(task=question)
for iteration in range(15): # max 15 iterations
response = llm.complete(messages)
code = extract_code_block(response)
if not code or 'TASK COMPLETE' in response:
break
stdout, stderr = execute_in_docker(code, workspace=workspace)
observation = format_observation(stdout, stderr)
messages += [
{'role': 'assistant', 'content': response},
{'role': 'user', 'content': observation}
]
state.after_execution(stdout, f'iteration_{iteration}')
return {
'report': (workspace / 'report.md').read_text() if (workspace / 'report.md').exists() else '',
'chart_path': str(workspace / 'chart.png'),
'iterations': state.iteration
}모호한 질문 처리
사용자는 '어떤 제품의 실적이 좋은가요?'와 같이 모호한 질문을 자주 합니다. 견고한 데이터 분석 에이전트는 시작하기 전에 모호성을 명확히 합니다. 먼저 데이터를 탐색하고 사용 가능한 지표를 파악한 다음, 가장 타당한 해석을 추론하거나 사용자에게 명확한 설명을 요청합니다. 이러한 성찰 단계는 에이전트가 기술적으로는 정확하지만 실제로는 쓸모없는 답을 내놓는 일을 방지합니다.
def handle_ambiguous_question(question: str, df_summary: dict) -> str:
clarification_prompt = f'''The user asked: '{question}'
Available data:
- Columns: {df_summary['columns']}
- Date range: {df_summary['date_range']}
- Metrics available: {df_summary['numeric_columns']}
Is the question clear enough to answer definitively?
If yes, restate the specific interpretation you will use.
If no, list the 2-3 clarifications needed to proceed.'''
response = llm.complete([{'role': 'user', 'content': clarification_prompt}])
return response에이전트 출력 품질 검사
에이전트가 작업을 완료한 후에는 출력 품질을 검증하십시오. 보고서 파일이 실제로 생성되었는지, 차트 PNG가 유효한 이미지 파일인지, 보고서의 수치가 analysis_result.json의 데이터와 일치하는지, 그리고 보고서가 원래 질문에 실제로 답하고 있는지 확인하십시오. 두 번째 LLM 호출을 사용하는 자동화된 QA 단계는 에이전트가 전체 과정을 완료했지만 답변의 품질이 낮은 경우를 찾아낼 수 있습니다.
def validate_analysis_output(workspace: str, question: str, report: str) -> dict:
validation_prompt = f'''Original question: {question}
Agent report:
{report[:2000]}
Rate this analysis on a scale of 1-5 for:
1. Does it directly answer the question? (1=No, 5=Yes)
2. Are specific numbers cited? (1=No, 5=Yes)
3. Is the conclusion clearly stated? (1=No, 5=Yes)
Return JSON: {{"question_answered": N, "numbers_cited": N, "clear_conclusion": N, "overall": N}}'''
result = llm.complete([{'role': 'user', 'content': validation_prompt}],
response_format={'type': 'json_object'})
scores = json.loads(result)
passed = scores['overall'] >= 4
return {'scores': scores, 'passed': passed}도메인 도구로 에이전트 확장하기
기본 코드 에이전트는 도메인별 도구를 추가하면 더욱 강력해집니다. 금융 데이터 에이전트에는 실시간 주가를 가져오는 함수를 추가할 수 있습니다. 마케팅 데이터 에이전트에는 Google 애널리틱스 API 액세스 권한을 추가할 수 있습니다. 영업 에이전트에는 세일즈포스 질의를 추가할 수 있습니다. 시스템 프롬프트의 함수 정의나 LangChain의 @tool 데코레이터를 통해 이러한 도구를 LLM에서 사용할 수 있게 됩니다.
빠른 확인
이 수업에서 배운 데이터 분석 에이전트에 대한 이해도를 확인해 보십시오.
수업 요약
이 수업에서는 다음을 배웠습니다. 데이터 분석 에이전트는 탐색, 정리, 분석, 보고의 네 단계를 따르며 각 단계는 코드를 반복적으로 생성하고 실행하는 방식으로 구현됩니다. matplotlib을 사용한 차트 생성과 파일 기반 상태 지속성은 이 단계들을 하나의 일관된 작업 흐름으로 연결하며, 출력 검증은 에이전트의 최종 답변이 실제로 원래 질문에 답하는지 확인합니다. 다음으로 LLM 관측성과 추적을 살펴보겠습니다.
자주 묻는 질문
“데이터 분석 에이전트 구축” 강의는 무료인가요?
네 — “데이터 분석 에이전트 구축” 전체 내용을 이 웹사이트에서 무료로 읽을 수 있습니다. 인터랙티브하게 실습하려면(내장 코드 에디터와 24/7 AI 튜터), CoddyKit PRO로 업그레이드하면 AI Engineering Academy 강의 전체를 잠금 해제할 수 있습니다. AI Engineering Academy 강의에는 총 4개의 강의가 포함되어 있습니다.
“데이터 분석 에이전트 구축”에서 뭘 배우나요?
CSV 파일과 자연어 질문을 받아 pandas 및 matplotlib 코드를 반복적으로 작성하고 완성도 높은 보고서를 생성하는 종단 간 데이터 분석 에이전트를 만듭니다. 브라우저에서 직접 실행하는 실습 코드로 AI Engineering Academy을(를) 배우며, 24/7 AI 튜터가 강의를 진행하면서 질문에 답변해줍니다.
AI Engineering Academy을(를) 시작하는 데 경험이 필요한가요?
사전 경험은 필요하지 않습니다. CoddyKit의 AI Engineering Academy은(는) 초급자부터 고급 학습자까지를 위해 구성되어 있으므로, 여기서 시작하거나 처음부터 시작할 수 있으며 자신의 속도대로 진행할 수 있습니다. 이것은 4개 중 4번째 강의입니다.
“데이터 분석 에이전트 구축” 강의는 얼마나 걸리나요?
대부분의 CoddyKit 강의는 약 5~10분이 소요됩니다. 각 강의는 간결하고 인터랙티브하여 꾸준한 진행이 가능하며, 웹과 앱에서 중단한 부분부터 바로 시작할 수 있습니다.
이 AI Engineering Academy 강의에서 코드를 작성하고 실행할 수 있나요?
네. 모든 AI Engineering Academy 강의에는 내장 코드 에디터가 포함되어 있으므로, 브라우저에서 바로 실제 코드를 작성하고 실행한 후 즉시 AI 피드백을 받을 수 있습니다 — 로컬 설정이 필요 없습니다.
이 강의의 모든 강의
- 코드 실행 루프
- Docker와 RestrictedPython을 활용한 샌드박싱
- 실행 단계 간 상태 관리
- 데이터 분석 에이전트 구축