กลับไปที่บล็อก

AI สำหรับผู้เริ่มต้นคู่มือ

ถาม LLM เกี่ยวกับ CSV: ส่งสคีมา ไม่ใช่ตาราง

ส่งชื่อคอลัมน์ ชนิดข้อมูล และตัวอย่าง 3 แถว รับหนึ่งบรรทัด pandas กลับมา รันกับไฟล์เต็ม ถูกกว่าการวางแถว และคุณตรวจตัวเลขได้

โดย CheapTokens Teamเผยแพร่เมื่อ ใช้เวลาอ่าน 6 นาที

บรรทัดโค้ดที่อ่าน CSV รับชนิดคอลัมน์และสามแถว และขอหนึ่งบรรทัด pandas
ในหน้านี้
  1. ทำไมการวางทั้งตารางจึงผิดพลาด
  2. ส่งรูปร่างของตาราง ไม่ใช่ตัวตาราง
  3. สคริปต์: ถาม อ่านบรรทัด รันมัน
  4. ค่าใช้จ่าย: วางทุกอย่างเทียบกับสคีมา + 3 แถว
  5. ตรวจตัวเลขก่อนเชื่อ
  6. หากมันไม่ทำงาน

คุณมี sales.csv ที่มี 5,000 แถวและมีคำถามเดียว: สินค้าใดขายได้มากที่สุดในเดือนตุลาคม อย่าวางไฟล์ลงในแชท ส่งชื่อคอลัมน์ ชนิดข้อมูล และตัวอย่างสามแถวให้โมเดล ขอ หนึ่งบรรทัดของ 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 ดังนั้นโมเดลจึงรู้ว่าต้องจับคู่กับข้อความ 2026-10 ไม่ใช่ 10/2026 หรือชื่อเดือน บรรทัด pandas ที่ผิดส่วนใหญ่มาจากการเดารูปแบบที่ตารางไม่เคยมี

การวางทุกแถวเทียบกับการส่งสคีมาและสามแถว
คำถามเดียวกัน: พรอมต์ซ้ายโตตามตาราง พรอมต์ขวาขนาดคงเดิม

สคริปต์: ถาม อ่านบรรทัด รันมัน#

สคริปต์ด้านล่างสร้างพรอมต์นั้นจากไฟล์ของคุณ คุณจึงไม่ต้องพิมพ์สคีมาด้วยมือ มันเรียก CheapTokens API ผ่าน OpenAI Python SDK: base URL https://api.cheaptokens.dev/v1, model 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 หรือ __ และคำตอบที่ถูกตัด (finish_reason อื่นที่ไม่ใช่ stop; ดู ทำไมคำตอบจึงหยุดกลางประโยค) และคุณยังต้องอ่านบรรทัดที่พิมพ์ก่อน หากมันแตะไฟล์ เครือข่าย หรือสิ่งใดที่คุณไม่ได้ขอ อย่ารันมัน

การรันครั้งแรกพิมพ์สามอย่าง: บรรทัดของโมเดล จำนวนโทเคนสำหรับคำขอนี้ และคำตอบ จำนวนโทเคนคือมิเตอร์ของคุณสำหรับส่วนถัดไป

ค่าใช้จ่าย: วางทุกอย่างเทียบกับสคีมา + 3 แถว#

เพื่อเปรียบเทียบ เราต้องมีขนาดของแถว สมมติว่าแถวอย่าง 2026-10-01,Oat latte mix,12,4.50 ใช้ประมาณ 20 โทเคน นั่นคือสมมติฐาน: มันขึ้นอยู่กับ tokenizer ของโมเดลและคอลัมน์ของคุณ และ การนับโทเคนก่อนส่ง แสดงตัวเลขจริงของคุณ ด้วย 20 โทเคนต่อแถว 5,000 แถวคือ 5,000 × 20 = 100,000 อินพุตโทเคน พรอมต์สคีมาและสามแถวอยู่ที่ประมาณ 300 โทเคน รวมคำสั่ง คำตอบสั้นในทั้งสองกรณี สมมติ 60 โทเคน ดังนั้นความแตกต่างอยู่ที่ฝั่งอินพุตทั้งหมด ฝั่งที่โตตามตารางของคุณ (เพิ่มเติมใน อินพุตเทียบกับเอาต์พุตโทเคน)

หนึ่งคำถามเกี่ยวกับตาราง 5,000 แถวบน DeepSeek-V4-Flash คำตอบ 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 เพื่อดูวิธีสคีมา DeepSeek-V4-Flash บน CheapTokens มีราคาเดียวทุกชั่วโมง ไม่มีค่าธรรมเนียมช่วงพีค และยอดคงเหลือเดียวครอบคลุมทุกโมเดล คุณจึงสลับ model 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