데이터 분석 에이전트 만들기

데이터 분석 에이전트 만들기 (Build a data analysis agent)

데이터 파일을 분석하고, 시각화를 만들고, 결과를 공유하는 에이전트를 구축하는 방법을 보여주는 가이드예요. 데이터 분석은 보통 다단계 추론과 코드 실행, 스크립트·리포트·플롯 같은 산출물 다루기가 필요한데, 딥 에이전트(deep agent)가 이런 작업을 처리하도록 설계돼 있어요.

출처: 공식문서

개요 (Overview)

이 가이드에서 만들 에이전트는 다음 작업을 해요.

  1. 분석할 CSV 파일을 받기
  2. 옵트인(opt-in) 할 일 목록으로 분석 단계를 계획·추적하기
  3. 탐색적 데이터 분석을 수행하고 시각화 생성하기
  4. 결과를 Slack 채널로 공유하기

Slack 통합은 선택사항이에요. 에이전트를 수정해 산출물을 로컬에 저장하거나 다른 채널로 결과를 공유할 수도 있어요.

핵심 개념 (Key concepts)

이 튜토리얼은 다음을 다뤄요.

설정 (Setup)

설치

핵심 의존성 설치:

pip install deepagents

선택 의존성 (Optional dependencies)

이 튜토리얼에서는 다음을 사용해요.

pip install "langsmith[sandbox]" slack-sdk

이 서비스들은 선택이지만, 프로덕션 사용에는 샌드박스 환경을 적극 권장해요. 대안으로 로컬 셸 백엔드(중요한 보안 고려사항 참고)를 쓰거나 백엔드에서 산출물을 직접 다운로드할 수도 있어요.

LangSmith

LangChain으로 만든 많은 애플리케이션은 여러 단계와 여러 LLM 호출을 포함해요. 복잡해질수록 체인/에이전트 내부에서 정확히 무슨 일이 일어나는지 검사하는 게 중요해지죠. 가장 좋은 방법은 LangSmith를 쓰는 거예요.

가입 후 환경 변수를 설정해 트레이스를 기록하세요.

export LANGSMITH_TRACING="true"
export LANGSMITH_API_KEY="..."

Python으로 설정해도 돼요:

import getpass
import os

os.environ["LANGSMITH_TRACING"] = "true"
os.environ["LANGSMITH_API_KEY"] = getpass.getpass()

백엔드 설정 (Set up the backend)

딥 에이전트는 backends를 통해 샌드박스 환경에서 코드를 실행해요.

아래 예제는 LangSmith 샌드박스를 사용해요. 다른 프로바이더는 available providers를 참고하세요.

LangSmith

pip install "langsmith[sandbox]"
uv add "langsmith[sandbox]"
from deepagents.backends.langsmith import LangSmithSandbox
from langsmith.sandbox import SandboxClient

client = SandboxClient()
ls_sandbox = client.create_sandbox()
backend = LangSmithSandbox(sandbox=ls_sandbox)

Local shell

이 백엔드는 무제한 파일시스템·셸 접근을 제공해요. 개발·테스트용 통제된 환경에서만 사용하세요. 보안 고려사항을 참고해요.

from deepagents.backends import LocalShellBackend

backend = LocalShellBackend(
    root_dir=".",
    virtual_mode=True,
    env={"PATH": "/usr/bin:/bin"},
)

AgentCore

pip install langchain-agentcore-codeinterpreter
uv add langchain-agentcore-codeinterpreter
from bedrock_agentcore.tools.code_interpreter_client import CodeInterpreter
from langchain_agentcore_codeinterpreter import AgentCoreSandbox

interpreter = CodeInterpreter(region="us-west-2")
interpreter.start()
backend = AgentCoreSandbox(interpreter=interpreter)

Daytona

pip install langchain-daytona
uv add langchain-daytona
from daytona import Daytona

from langchain_daytona import DaytonaSandbox

sandbox = Daytona().create()
backend = DaytonaSandbox(sandbox=sandbox)

샌드박스 준비 확인:

result = backend.execute("echo ready")
print(result)
# ExecuteResponse(output='ready', exit_code=0, ...)

E2B

pip install langchain-e2b
uv add langchain-e2b
from e2b import Sandbox
from langchain_e2b import E2BSandbox

e2b_sandbox = Sandbox.create()
backend = E2BSandbox(sandbox=e2b_sandbox)
import modal

from langchain_modal import ModalSandbox

app = modal.App.lookup("your-app")
modal_sandbox = modal.Sandbox.create(app=app)
backend = ModalSandbox(sandbox=modal_sandbox)

Runloop

pip install langchain-runloop
uv add langchain-runloop
from runloop_api_client import RunloopSDK

from langchain_runloop import RunloopSandbox

api_key = "..."
client = RunloopSDK(bearer_token=api_key)

devbox = client.devbox.create()
backend = RunloopSandbox(devbox=devbox)

샘플 데이터 업로드

백엔드에 샘플 판매 데이터를 만들고 업로드해요.

import csv
import io

# Create sample sales data
data = [
    ["Date", "Product", "Units Sold", "Revenue"],
    ["2025-08-01", "Widget A", 10, 250],
    ["2025-08-02", "Widget B", 5, 125],
    ["2025-08-03", "Widget A", 7, 175],
    ["2025-08-04", "Widget C", 3, 90],
    ["2025-08-05", "Widget B", 8, 200],
]

# Convert to CSV bytes
text_buf = io.StringIO()
writer = csv.writer(text_buf)
writer.writerows(data)
csv_bytes = text_buf.getvalue().encode("utf-8")
text_buf.close()

# Upload to backend
backend.upload_files([("/root/data/sales_data.csv", csv_bytes)])

커스텀 툴 구현 (Implement custom tools)

데이터 분석 작업은 리포트나 플롯 같은 산출물을 만들 수 있어요. 아래의 간단한 toolbackend.download_files로 그들을 다운로드한 뒤 Slack SDK로 업로드해요. 업로드 대신 관련 파일 경로만 목록으로 보여주고, 관심 있는 사람이 필요할 때 별도로 받게 할 수도 있어요.

import os

from langchain.tools import tool
from slack_sdk import WebClient

slack_token = os.environ["SLACK_USER_TOKEN"]
slack_client = WebClient(token=slack_token)
channel = "C0123456ABC"  # specify your own channel here


@tool(parse_docstring=True)
def slack_send_message(text: str, file_path: str | None = None) -> str:
    """Send message, optionally including attachments such as images.

    Args:
        text: (str) text content of the message
        file_path: (str) file path of attachment in the filesystem.
    """
    if not file_path:
        slack_client.chat_postMessage(channel=channel, text=text)
    else:
        fp = backend.download_files([file_path])
        slack_client.files_upload_v2(
            channel=channel,
            content=fp[0].content,
            initial_comment=text,
        )

    return "Message sent."

자격 증명과 기타 비밀을 샌드박스에 넣지 않는 게 일반적으로 좋은 습관이에요. 여기서는 Slack 토큰을 샌드박스 밖 툴에서 관리해요.

태스크 플래닝 활성화 (Enable task planning)

태스크 플래닝은 옵트인이에요. 데이터 분석은 길고 다단계적인 작업이 많으니, 에이전트를 만들 때 TodoListMiddleware를 넘겨주세요. 그러면 에이전트가 탐색적 분석, 시각화, 공유 단계를 추적하는 write_todos 툴을 가지게 돼요.

from langchain.agents.middleware import TodoListMiddleware

이 미들웨어를 다음 절의 create_deep_agent 호출에 포함시키면 돼요.

에이전트 실행 (Run the agent)

에이전트를 생성해 봅시다.

from langchain_core.utils.uuid import uuid7

from deepagents import create_deep_agent
from langchain.agents.middleware import TodoListMiddleware
from langgraph.checkpoint.memory import InMemorySaver

checkpointer = InMemorySaver()

agent = create_deep_agent(
    model="google_genai:gemini-3.6-flash",
    tools=[slack_send_message],
    backend=backend,
    checkpointer=checkpointer,
    middleware=[TodoListMiddleware()],
)

thread_id = str(uuid7())
config = {"configurable": {"thread_id": thread_id}}

여기 포함된 것들을 정리하면:

이제 에이전트를 호출해 봅시다.

input_message = {
    "role": "user",
    "content": (
        "Analyze ./data/sales_data.csv in the current dir and generate a beautiful plot. "
        "When finished, send your analysis and the plot to Slack using the tool."
    ),
}
stream = agent.stream_events(
    {"messages": [input_message]},
    config,
    version="v3",
)
for snapshot in stream.values:
    snapshot["messages"][-1].pretty_print()

실행하면 에이전트가 다음과 같은 과정을 거쳐요. 먼저 read_file로 CSV를 읽고, pwd/ls로 디렉토리 구조를 확인한 뒤, 분석 스크립트를 작성해서 실행하고, 마지막으로 slack_send_message 툴로 분석 결과와 시각화 대시보드를 Slack에 전송해요. 에이전트가 만든 리포트 요약과 6-패널 시각화 대시보드가 Slack으로 전달돼요.

이 실행의 전체 LangSmith 트레이스를 확인할 수 있어요.

결과 (Results)

에이전트는 데이터를 성공적으로 분석하고 시각화가 포함된 종합 리포트를 Slack으로 공유해요.

Sales analysis results in Slack

외부 툴 없이 백엔드에서 산출물을 직접 다운로드할 수도 있어요.

backend.download_files(list_of_filepaths)

사용 완료 후 샌드박스를 정리하는 방법은 provider guides를 참고하세요.

다음 단계 (Next steps)

데이터 분석 에이전트를 만들었으니, 이제 확장 리소스를 살펴봐요.

  • Backends: 딥 에이전트 백엔드 시스템 알아보기
  • Sandboxes: 샌드박스 코드 실행용 백엔드 검토 (보안 고려사항·고급 구성 포함)
  • Customization: 모델·툴·프롬프트·선택적 태스크 플래닝으로 에이전트 커스터마이징
  • Skills: 재사용 가능한 스킬로 에이전트 장착
  • Human-in-the-loop: 데이터 분석 워크플로우의 중요 작업에 대화형 승인 단계 추가

더 알아보기 (Learn more)