블로그로 돌아가기

AI 입문가이드

LLM에게 CSV에 대해 묻기: 테이블이 아닌 스키마를 보내세요

열 이름, 타입, 샘플 행 3개를 보내고 pandas 한 줄을 받아 전체 파일에서 실행하세요. 행을 붙여넣는 것보다 저렴하고 숫자를 확인할 수 있습니다.

작성자: CheapTokens Team 게시됨읽는 시간 7분

CSV를 읽고 열 타입과 세 행을 가져와 pandas 한 줄을 요청하는 코드 줄
이 페이지의 내용
  1. 전체 테이블을 붙여넣으면 왜 잘못되는가
  2. 테이블이 아니라 테이블의 형태를 보내세요
  3. 스크립트: 묻고, 줄을 읽고, 실행하기
  4. 비용: 모든 것을 붙여넣기 vs 스키마 + 3행
  5. 신뢰하기 전에 숫자를 확인하세요
  6. 작동하지 않을 경우

5,000개의 행이 있는 sales.csv가 있고 질문은 하나입니다: 10월에 가장 많이 팔린 제품은 무엇인가? 파일을 채팅에 붙여넣지 마세요. 모델에게 열 이름, 타입, 샘플 행 세 개를 보내고 한 줄의 pandas 코드를 요청한 다음, 그 줄을 전체 파일에서 직접 실행하세요. 모델은 5,000개의 행을 읽지 않고, 프롬프트는 아주 작게 유지되며, 얻는 숫자는 다시 실행할 수 있는 코드에서 나옵니다.

왜 이 방법이 더 나은지, 프롬프트가 어떻게 생겼는지, 복사할 수 있는 스크립트, 그리고 모든 것을 붙여넣는 방식과 비교한 비용을 설명합니다.

전체 테이블을 붙여넣으면 왜 잘못되는가#

익숙할 수 있는 이야기가 있습니다. 누군가 200행의 지출 내역을 채팅에 붙여넣고 합계를 요청합니다. 답변은 소수점까지 포함해 자신감 있게 돌아옵니다. 하지만 그것은 틀렸고, 화면에는 아무것도 그 사실을 알려주지 않습니다.

모델은 텍스트를 조각조각 예측합니다(그 조각들은 토큰입니다). 200개의 숫자를 더하는 것은 내부에 계산기가 없는 200개의 작은 단계이며, 한 자리 숫자가 미끄러져도 정답처럼 보입니다. 코드는 다르게 동작합니다: df['amount'].sum()는 매번 모든 행을 더하고, 두 번째 실행에서도 같은 결과를 줍니다.

두 번째 문제는 크기에 관한 것입니다. 테이블은 컨텍스트 윈도우를 빠르게 잡아먹고, 질문할 때마다 모든 행에 비용을 지불합니다. 같은 파일에 대한 열 개의 질문은 전체 테이블의 열 개 복사본을 입력으로 보내는 것을 의미합니다.

빠른 확인

pandas 한 줄이 모델에게 합계를 묻는 것보다 더 안전한 이유는?

정답 보기

정답: 컴퓨터가 모든 행에 대해 코드를 실행하고, 다시 실행하고 확인할 수 있다

모델은 여전히 잘못된 줄을 작성할 수 있습니다. 차이는 그 줄이 눈에 보이고 반복 가능하다는 점입니다: 읽고, 실행하고, 결과를 몇 개의 행과 수동으로 비교합니다.

테이블이 아니라 테이블의 형태를 보내세요#

모델은 코드를 작성하는 데 데이터가 필요하지 않습니다. 테이블이 어떻게 생겼는지 알아야 합니다: 어떤 열이 있는지, 어떤 종류의 값을 담고 있는지, 행이 어떻게 작성되는지. 즉 스키마와 몇 개의 행입니다.

sales.csv에 네 개의 열이 있다고 가정해 봅시다. 이것이 전체 프롬프트입니다:

text
A pandas DataFrame named df has these columns and types:
date        object
product     object
units        int64
price      float64

First 3 rows (CSV):
date,product,units,price
2026-10-01,Oat latte mix,12,4.50
2026-10-01,Cocoa,7,3.20
2026-10-02,Oat latte mix,9,4.50

Question: Which product sold the most units in October 2026?

Reply with ONE line of pandas code that computes the answer from df.
No explanation, no markdown, no imports.

df[df['date'].str.startswith('2026-10')].groupby('product')['units'].sum().idxmax() 형태의 답변을 기대하세요. 정확한 문구는 실행할 때마다 다르므로, 실행하기 전에 줄을 읽어보세요.

왜 열 이름만이 아니라 세 개의 행인가? 날짜 때문입니다. 타입 열은 object라고 되어 있는데, 이는 단지 텍스트라는 뜻입니다. 샘플 행은 날짜가 2026-10-01 형식으로 작성되었음을 보여주므로, 모델은 10/2026나 월 이름이 아닌 텍스트 2026-10와 일치시켜야 함을 알 수 있습니다. 대부분의 잘못된 pandas 줄은 테이블에 없었던 형식을 추측해서 나옵니다.

모든 행을 붙여넣는 것과 스키마 및 세 행을 보내는 것의 비교
같은 질문: 왼쪽 프롬프트는 테이블과 함께 커지고, 오른쪽은 같은 크기를 유지한다

스크립트: 묻고, 줄을 읽고, 실행하기#

아래 스크립트는 파일에서 해당 프롬프트를 구성하므로 스키마를 직접 입력할 필요가 없습니다. OpenAI Python SDK를 통해 CheapTokens API를 호출합니다: 기본 URL https://api.cheaptokens.dev/v1, 모델 ID deepseek-ai/DeepSeek-V4-Flash-0731. 키는 파일이 아닌 환경 변수에 보관하세요.

python
import os
import pandas as pd
from openai import OpenAI

client = OpenAI(
    base_url="https://api.cheaptokens.dev/v1",
    api_key=os.environ["CHEAPTOKENS_API_KEY"],
)

df = pd.read_csv("sales.csv")      # for .xlsx: pd.read_excel("sales.xlsx")

schema = df.dtypes.to_string()
sample = df.head(3).to_csv(index=False)
question = "Which product sold the most units in October 2026?"

prompt = f"""A pandas DataFrame named df has these columns and types:
{schema}

First 3 rows (CSV):
{sample}
Question: {question}

Reply with ONE line of pandas code that computes the answer from df.
No explanation, no markdown, no imports."""

resp = client.chat.completions.create(
    model="deepseek-ai/DeepSeek-V4-Flash-0731",
    messages=[{"role": "user", "content": prompt}],
    max_tokens=500,
)

text = resp.choices[0].message.content.strip()
code = text.removeprefix("```python").removeprefix("```").removesuffix("```").strip()
print("Model's line:", code)
print("Tokens in/out:", resp.usage.prompt_tokens, resp.usage.completion_tokens)

if resp.choices[0].finish_reason != "stop" or "import" in code or "__" in code:
    raise SystemExit("Not running this one. Read the line above and decide.")

print("Answer:", eval(code, {"df": df, "pd": pd}))

마지막 블록은 초보자가 건너뛰는 부분입니다. eval는 모델이 작성한 텍스트를 여러분의 컴퓨터에서 실행하므로, 스크립트는 import 또는 __가 포함된 줄과 잘린 답변(stop가 아닌 finish_reason; 답변이 문장 중간에 멈추는 이유 참조)을 거부합니다. 그리고 여전히 먼저 인쇄된 줄을 읽어야 합니다. 파일, 네트워크 또는 요청하지 않은 것에 접근한다면 실행하지 마세요.

첫 실행은 세 가지를 출력합니다: 모델의 줄, 이 한 요청에 대한 토큰 수, 그리고 답변. 토큰 수는 다음 섹션을 위한 미터입니다.

비용: 모든 것을 붙여넣기 vs 스키마 + 3행#

비교하려면 행의 크기가 필요합니다. 2026-10-01,Oat latte mix,12,4.50 같은 행이 약 20토큰을 차지한다고 가정해 봅시다. 이는 가정입니다: 모델의 토크나이저와 열에 따라 다르며, 보내기 전에 토큰 계산하기로 실제 숫자를 확인할 수 있습니다. 행당 20토큰이면 5,000행은 5,000 × 20 = 100,000 입력 토큰입니다. 스키마와 세 행 프롬프트는 지시사항 포함 약 300토큰입니다. 답변은 두 경우 모두 짧아서 60토큰이라고 하면, 차이는 전적으로 입력 측, 즉 테이블과 함께 커지는 쪽에 있습니다(입력 vs 출력 토큰에서 더 자세히).

DeepSeek-V4-Flash에서 5,000행 테이블에 대한 한 질문, 답변 60토큰
  • 5,000행 모두 붙여넣기$0.0015
  • 스키마 + 3행$0.000011

두 숫자 모두 달러로 작으며, 이는 솔직합니다: 저렴한 모델은 낭비적인 방법조차도 저렴하게 만듭니다. 차이는 커지는 부분입니다. 하루에 20개의 질문을 하면 모든 것을 붙여넣는 프롬프트가 20번 전송됩니다. 테이블을 두 배로 늘리면 비용도 두 배가 되지만, 스키마 프롬프트는 움직이지 않습니다. 그리고 단단한 벽이 있습니다: 380K 토큰 컨텍스트 윈도우로 380,000 ÷ 20 = 19,000행이 답변을 위한 공간을 남기기 전에 붙여넣을 수 있는 최대치입니다. 50,000행 내보내기는 단순히 맞지 않습니다. 스키마 프롬프트는 테이블 크기에 관계없이 맞습니다.

자신의 테이블을 입력하고 일일 비용을 확인하세요:

비용 계산기

테이블 전체를 붙여넣은 경우: 하루 20개 질문

요청당 입력 토큰: 100,000 · 요청당 출력 토큰: 60 · 일일 요청 수: 20

모델일일월간
GLM-5.3-Flash$0.04$1.20
DeepSeek-V4-Flash$0.0301$0.904
MiniMax-M2.7$0.10$3.01

스키마 방식을 보려면 in를 300으로 변경하세요. CheapTokens의 DeepSeek-V4-Flash는 시간에 관계없이 하나의 가격이며, 피크 시간 할증이 없고, 하나의 잔액으로 모든 모델을 커버하므로 두 번째 계정 없이 모델 ID를 zai-org/GLM-5.3-Flash(390K 컨텍스트)로 바꿀 수 있습니다. 현재 가격은 가격 페이지에 있습니다.

신뢰하기 전에 숫자를 확인하세요#

루프는 항상 같습니다. 매번 수행하면 잘못된 답변이 보고서가 아닌 네 번째 단계에서 잡힙니다.

순서대로 배열하기

루프를 순서대로 정리하세요

  1. 테이블 설명: 열 타입과 샘플 행 3개
  2. pandas 한 줄만 요청, 다른 것은 없음
  3. 줄을 읽고 전체 파일에서 실행
  4. 몇 개의 행에서 결과를 수동으로 확인
루프: 테이블, 스키마와 세 행, pandas 한 줄, 당신의 숫자
모델은 중간 단계만 보며, 전체 테이블은 컴퓨터를 떠나지 않습니다

네 번째 단계는 저렴합니다. 파일을 몇 개의 행으로 필터링하고(df[df['product'] == 'Cocoa'].head(10)), 머릿속이나 스프레드시트에서 합산한 후 비교하세요. 모델의 줄이 틀렸다면 보통 명백한 방식으로 틀립니다: units를 합하는 대신 행을 세었거나, 잘못된 월을 선택했습니다.

이와 같은 더 많은 습관은 AI가 사실을 만들어내는 이유와 이를 줄이는 4가지 프롬프트 습관을 참조하세요.

작동하지 않을 경우#

  • KeyError: 'Date'. 모델이 대소문자가 다른 열 이름을 작성했습니다. 실제 헤더 행을 프롬프트에 붙여넣으세요(세 샘플 행이 이미 그렇게 함). 그리고 "열 이름을 표시된 그대로 정확히 사용하세요"를 추가하세요.
  • 답변에 코드 앞에 문장이 있습니다. eval가 SyntaxError로 실패합니다. 프롬프트 끝에 "설명 없이 pandas 코드 한 줄만"을 반복하세요. 마지막 지시사항이 가장 중요합니다.
  • 답변이 숫자가 아닌 테이블입니다. 원하는 형태를 말하세요: "단일 숫자 반환" 또는 "내림차순으로 정렬된 Series 반환".
  • 날짜가 잘못 나옵니다. 샘플 행이 실제 형식을 보여줍니다. 날짜가 14/10/2026 형식이라면 모델이 그것을 봐야 합니다. 프롬프트에 날짜를 읽는 방식으로 pd.to_datetime(df['date'], dayfirst=True)를 추가하세요.
  • finish_reason가 length입니다. 답변이 max_tokens에 의해 잘렸습니다. 한 줄은 500토큰에 맞으므로 프롬프트를 확인하세요: 모델이 길게 설명하고 있을 수 있습니다.

첫 요청을 위한 전체 설정은 키에서 응답까지 CheapTokens 문서에 있습니다.