Skip to content

Repository files navigation

title Data Analysis Agent
emoji 📊
colorFrom blue
colorTo purple
sdk docker
app_port 7860
pinned false
license mit
short_description LangGraph + RAG + Critic으로 만든 데이터 분석 agent

📊 Data Analysis Agent

CSV를 업로드하고 분석 목표를 자연어로 적으면, 스스로 분석 계획을 세우고 → 코드를 실행하고 → 결과를 자가검증(Critic)하며 → 인사이트 리포트를 작성하는 LangGraph 기반 에이전트.

🔗 라이브 데모 (Hugging Face Spaces) · GitHub


무엇을 하나

  • 자동 EDA → 목표 지향 분석: 데이터 품질 검사부터 시작해 univariate → bivariate → multivariate 순으로, 사용자 목표에 직접 답하는 분석까지 스스로 진행.
  • 자가검증 루프 (Critic): 매 step 후 결과를 검토해 continue / replan(전략 수정) / done을 판단. 목표가 수치로 답변되기 전엔 종료하지 않음.
  • RAG로 보강된 판단: 30개 분석 지식 문서(함정·에러 패턴·done criteria)를 검색해 Executor/Critic에 주입 → LLM 자체 지식에만 의존하지 않음.
  • 환각 방지 리포트: 실행 출력에 실제로 나온 수치만 인용하도록 강제. 실패한 step도 숨기지 않고 한계로 명시.
  • 멀티 프로바이더 + 트레이싱: Groq / Gemini / OpenRouter / OpenAI / Ollama를 환경변수로 전환. LangSmith 트레이싱 자동 연동.

아키텍처

START
  ↓
inspect ─→ planner ─→ human_review (HITL: plan 승인/수정)
                           ↓
                       executor ─→ critic ─┐
                           ↑                │  continue (다음 step)
                           └────────────────┤  replan   (plan에 교정 step 추가 후 continue)
                                            │  done
                                            ↓
                                        summarize ─→ END
단계 역할
inspect CSV의 schema/head/describe만 요약해 state에 저장 (df 전체는 context에 넣지 않음)
planner 목표+스키마 기반 5~7개 분석 step 생성 (function calling으로 구조화 출력 강제)
human_review HITL — 사용자가 plan을 보고 승인/수정 (interrupt + checkpointer)
executor step별 코드 생성 → 격리 실행 → 실패 시 stderr 보고 자가수정(최대 3회). RAG 가이드 주입
critic 결과 검토 + RAG 검색 후 continue/replan/done 결정. max_iter 연동 안전망
summarize 실제 출력 수치만으로 markdown 리포트 작성

프로젝트 구조

├── app.py                     Streamlit UI (HF Spaces 배포 진입점)
├── run_demo.py                CLI 데모 (HITL / --no-hitl / --interactive)
├── agent/
│   ├── llm.py                 Provider 추상화 + 요청별 config 주입 (get_client_from_config)
│   ├── state.py               AgentState (TypedDict, SSoT)
│   ├── graph.py               critic loop + HITL interrupt + checkpointer
│   ├── retry.py               LLM 호출 지수 백오프 재시도 (503/429/timeout)
│   ├── schema_utils.py        Pydantic 스키마 → 멀티프로바이더 호환 tool schema
│   └── nodes/                 inspect / planner / executor / critic / summarize
├── tools/
│   ├── python_exec.py         subprocess 격리 + timeout + import 화이트리스트
│   └── rag.py                 Qdrant in-memory + bge-small-en + section chunking
├── knowledge_base/            30 markdown docs / 7 categories (eda, bivariate,
│                              multivariate, pitfalls, visualization, ml_diagnostics, timeseries)
├── evals/                     데이터셋 5종 + 3 메트릭 (accuracy / trajectory / insight)
├── tests/                     36 tests / 8 files (API 키 없이 통과)
├── Dockerfile                 HF Spaces (Docker SDK) 배포
└── requirements.txt

핵심 설계 결정 (면접 답변용)

결정 이유
df 전체를 state에 넣지 않음 context 폭발 방지. schema/head/describe 요약만 전달
OpenAI SDK 호환 인터페이스 provider lock-in 회피. groq↔gemini↔ollama 환경변수로 전환
LLM 설정을 요청별 config로 주입 os.environ 대신 그래프 config로 전달 → 프로세스를 공유하는 배포 환경에서 사용자 간 키 누수 차단
구조화 출력 = function calling JSON parse 실패 zero. Pydantic 스키마 → tool schema 자동 변환
Plan-and-Execute (한 step씩) trajectory가 명시적 → eval/디버깅 용이. 재시도와 재계획 책임 분리
재시도 vs 재계획 분리 Executor: 같은 step 코드 자가수정(전술). Critic: 전략 변경(replan)
Critic + RAG LLM 자체 지식에 의존 X. Simpson's paradox·leakage·에러 패턴을 KB가 명시
Qdrant in-memory 동일 API로 prod-Qdrant 전환 1줄. Docker 없이 dev 가능
bge-small-en-v1.5 로컬 임베딩 API 비용 0, 오프라인, 결정적
Section 단위 chunking 의미 단위 보존 (naive split 대비 recall↑)
HITL interrupt + checkpointer 사용자 통제권. 영속화(PostgresSaver)로 확장 가능
python_exec subprocess 격리 OOM/segfault에서 agent 보호. 프로덕션은 E2B/Modal
Import 화이트리스트 (AST) os.system 등 위험 호출 차단 (※ 파일시스템 완전 격리는 아님 — v1 한계)
iter_count + max_iter + recursion_limit 3중 안전망 무한 critic loop 방지

평가 (Evaluation)

python -m evals.run_eval — sklearn 데이터셋 5종(iris, wine, breast_cancer, diabetes, titanic)에 대해 3개 메트릭 자동 채점:

  • Accuracy (결정적, 비-LLM): ground-truth 수치를 agent 출력에서 추출해 tolerance 비교
  • Trajectory (LLM-as-judge): 품질검사 → univariate → multivariate → 종합의 논리적 진행 여부
  • Insight (LLM-as-judge): 단순 수치 나열 vs 근거 있는 결론 도출

예시 (iris): Trajectory 1.00 / Insight 1.00. Accuracy 메트릭은 현재 키워드-근접 숫자 추출 휴리스틱이라 한국어 리포트에서 under-count되는 알려진 한계가 있음(개선 대상). 상세는 evals/results.md.

빠른 시작

# 1. 의존성
pip install -r requirements.txt

# 2. 환경 (Groq 무료 키)
cp .env.example .env
# .env 에 GROQ_API_KEY=gsk_... 입력

# 3. 테스트 (API 키 없이 통과; 첫 실행 시 임베딩 모델 ~133MB 다운로드)
python -m tests.smoke_test
python -m tests.test_day2

# 4a. CLI 데모
python run_demo.py                  # HITL on, plan 자동 승인
python run_demo.py --interactive    # plan 검토 후 코멘트 입력
python run_demo.py --no-hitl        # HITL 끔 (배치/CI)

# 4b. 웹 UI
streamlit run app.py

Provider 전환

LLM_PROVIDER=groq   python run_demo.py                          # Llama 3.3 70B (기본)
LLM_PROVIDER=gemini python run_demo.py                          # Gemini 2.5 Flash (1M context)
LLM_PROVIDER=ollama LLM_MODEL=qwen2.5:7b python run_demo.py     # 로컬

기술 스택

LangGraph · OpenAI SDK (멀티프로바이더) · Pydantic · Qdrant · sentence-transformers (bge-small-en) · pandas/matplotlib/seaborn/scikit-learn · Streamlit · LangSmith · Docker (HF Spaces)

About

No description, website, or topics provided.

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages