Xây dựng AI Data Analyst với PandasAI và Python: Truy vấn dữ liệu CSV/Excel bằng ngôn ngữ tự nhiên

AI tutorial - IT technology blog
AI tutorial - IT technology blog

Vấn đề: Ai cũng muốn có dữ liệu, nhưng không ai muốn viết Pandas

Hình dung thế này: sếp bạn gửi cho bạn một file Excel 50.000 dòng lúc 5 giờ chiều thứ Sáu và hỏi, “Bạn có thể cho tôi biết khu vực nào có doanh thu cao nhất quý vừa rồi, phân theo danh mục sản phẩm không?” Bạn biết câu trả lời ở đâu đó trong bảng tính đó. Nhưng để trích xuất ra, bạn phải viết hàng chục dòng pandas, groupby và matplotlib trước khi thậm chí có thể bắt đầu nghĩ đến câu hỏi thực sự.

Đây là thực tế hàng ngày của bất kỳ ai đứng giữa dữ liệu và những người ra quyết định. Những người cần insight nhất — trưởng nhóm sales, product manager, giám đốc điều hành — hiếm khi biết Python. Và việc để developer trở thành nút cổ chai cho mọi câu hỏi về dữ liệu là điều không thể mở rộng.

Nguyên nhân: Phân tích dữ liệu vẫn đòi hỏi quá nhiều kiến thức cú pháp

Vấn đề cốt lõi không phải là pandas khó. Mà là các câu hỏi về dữ liệu mang tính hội thoại, nhưng các công cụ lại yêu cầu bạn phải dịch chúng thành code trước. “Cho tôi xem xu hướng doanh thu hàng tháng” sẽ trở thành:

df['date'] = pd.to_datetime(df['date'])
monthly = df.groupby(df['date'].dt.to_period('M'))['revenue'].sum()
monthly.plot(kind='line', title='Doanh thu hàng tháng')
plt.show()

Code đó không có gì sai cả. Nhưng nếu bạn phải viết lại từ đầu mỗi lần, cho mỗi biến thể của từng câu hỏi, bạn sẽ dành nhiều thời gian hơn để viết các thao tác DataFrame hơn là thực sự suy nghĩ về dữ liệu.

Các công cụ BI như Tableau hay Power BI giải quyết được một phần vấn đề này — nhưng chúng đắt tiền, đòi hỏi thiết lập và đào tạo, và vẫn không thể trả lời các câu hỏi ngôn ngữ tự nhiên tùy ý trên file CSV thô mà không cần xây dựng dashboard trước.

So sánh các giải pháp: Đâu là lựa chọn thực sự?

Lựa chọn 1: Script Pandas thủ công

Linh hoạt tối đa, không có gì kỳ diệu. Hoạt động hoàn hảo nếu bạn thành thạo pandas. Sẽ trở nên rắc rối khi các thành viên không kỹ thuật cần tự truy cập dữ liệu. Mỗi câu hỏi mới lại trở thành một ticket.

Lựa chọn 2: Công cụ BI (Tableau, Power BI, Metabase)

Tốt cho các dashboard định kỳ và báo cáo có cấu trúc. Không phù hợp cho các câu hỏi ad-hoc trên file thô. Yêu cầu ánh xạ schema, data connector và thường cần một analyst chuyên trách để xây dựng và duy trì dashboard.

Lựa chọn 3: ChatGPT Code Interpreter / Claude Artifacts

Bạn upload file, đặt câu hỏi, nhận lại code và biểu đồ. Hoạt động tốt cho khám phá một lần. Vấn đề là: đây là một vòng lặp thủ công, mang tính hội thoại. Bạn không thể nhúng nó vào ứng dụng hay pipeline của mình. Không có programmatic access, không có automation.

Lựa chọn 4: PandasAI

PandasAI là một thư viện Python mã nguồn mở bao bọc một LLM (OpenAI, Anthropic, Google Gemini, v.v.) xung quanh pandas DataFrame. Bạn truyền vào một câu hỏi bằng ngôn ngữ tự nhiên, và nó tạo ra rồi thực thi code pandas bên trong, trả về kết quả. Bạn vẫn ở trong Python. Bạn vẫn kiểm soát hoàn toàn. Và giao diện chỉ là ngôn ngữ tự nhiên đơn giản.

Đây là cách tiếp cận tôi đã dùng trong môi trường production để cho phép các stakeholder không kỹ thuật tự truy vấn file dữ liệu của họ mà không cần mở terminal. Kết quả nhất quán và ổn định — đủ chính xác cho báo cáo kinh doanh, và dễ kiểm tra vì PandasAI có thể hiển thị code đã tạo ra.

Cách tiếp cận tốt nhất: PandasAI trong thực tế

Bước 1: Cài đặt thư viện

pip install pandasai
pip install pandasai[openai]   # nếu dùng OpenAI
pip install pandasai[google]   # nếu dùng Gemini

PandasAI hỗ trợ nhiều LLM backend. OpenAI GPT-4o và Google Gemini đều hoạt động tốt. Trong hướng dẫn này, chúng ta sẽ dùng OpenAI.

Bước 2: Thiết lập cơ bản với file CSV

Giả sử bạn có một file CSV bán hàng với các cột: date, region, product, revenue, units_sold.

import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI

# Tải dữ liệu
df = pd.read_csv("sales_data.csv")

# Kết nối LLM
llm = OpenAI(api_token="your-openai-api-key")

# Bao bọc DataFrame
sdf = SmartDataframe(df, config={"llm": llm})

Đó là toàn bộ thiết lập. SmartDataframe chỉ là một pandas DataFrame được gắn thêm LLM. Tất cả các thao tác pandas tiêu chuẩn vẫn hoạt động bình thường trên nó.

Bước 3: Truy vấn bằng ngôn ngữ tự nhiên

# Tổng hợp đơn giản
result = sdf.chat("Tổng doanh thu theo từng khu vực là bao nhiêu?")
print(result)

# Lọc dữ liệu
result = sdf.chat("Hiển thị tất cả giao dịch có doanh thu vượt 10000")
print(result)

# Phân tích theo thời gian
result = sdf.chat("Sản phẩm nào có hiệu suất tốt nhất trong Q3?")
print(result)

PandasAI dịch từng câu hỏi thành code pandas, thực thi trên DataFrame của bạn, và trả về một giá trị, một DataFrame đã lọc, hoặc một biểu đồ — tùy thuộc vào những gì phù hợp nhất với câu hỏi.

Bước 4: Tải file Excel

File Excel với nhiều sheet cũng hoạt động tốt không kém:

import pandas as pd
from pandasai import SmartDataframe
from pandasai.llm import OpenAI

# Đọc một sheet cụ thể
df = pd.read_excel("quarterly_report.xlsx", sheet_name="Q3_Sales")

llm = OpenAI(api_token="your-openai-api-key")
sdf = SmartDataframe(df, config={"llm": llm})

result = sdf.chat("Nhân viên bán hàng nào có tỷ lệ chốt đơn cao nhất?")
print(result)

Bước 5: Tự động tạo biểu đồ

Yêu cầu trực quan hóa theo cách bạn hỏi về dữ liệu:

# Đoạn này tạo và lưu biểu đồ
sdf.chat("Vẽ biểu đồ cột doanh thu hàng tháng")

# Cụ thể hơn
sdf.chat("Tạo biểu đồ đường thể hiện số đơn vị bán theo khu vực theo thời gian")

# Với gợi ý tùy chỉnh kiểu dáng
sdf.chat("Hiển thị biểu đồ tròn thể hiện doanh thu phân theo danh mục sản phẩm")

PandasAI sử dụng matplotlib bên dưới. Biểu đồ được lưu vào thư mục charts/ theo mặc định. Bạn có thể cấu hình đường dẫn output:

sdf = SmartDataframe(df, config={
    "llm": llm,
    "save_charts": True,
    "save_charts_path": "/var/www/output/charts"
})

Bước 6: Làm việc với nhiều DataFrame

Tập dữ liệu thực tế hiếm khi chỉ là một bảng duy nhất. PandasAI hỗ trợ kết hợp nhiều DataFrame thông qua SmartDatalake:

from pandasai import SmartDatalake

orders_df = pd.read_csv("orders.csv")
customers_df = pd.read_csv("customers.csv")
products_df = pd.read_csv("products.csv")

lake = SmartDatalake(
    [orders_df, customers_df, products_df],
    config={"llm": llm}
)

result = lake.chat("Phân khúc khách hàng nào tạo ra doanh thu cao nhất trên mỗi đơn hàng?")
print(result)

LLM tự tìm ra bảng nào cần kết hợp và cách kết hợp, dựa trên tên cột và ngữ cảnh.

Bước 7: Kiểm tra code được tạo ra

Một điều tôi luôn làm trong môi trường production là bật code logging. Điều này cho phép bạn xem lại những gì PandasAI thực sự đã thực thi — rất quan trọng để kiểm tra và gỡ lỗi các trường hợp edge case:

sdf = SmartDataframe(df, config={
    "llm": llm,
    "verbose": True,       # in code được tạo ra ra stdout
    "enable_cache": True   # cache câu hỏi giống nhau (tiết kiệm API calls)
})

result = sdf.chat("Doanh thu trung bình trên mỗi giao dịch là bao nhiêu?")
# stdout sẽ hiển thị code pandas được tạo ra cùng với kết quả

Mẹo thực tế cho môi trường Production

  • Kiểm tra tên cột: PandasAI suy luận ý nghĩa của cột từ tên. Hãy đổi tên các cột khó hiểu như col_A thành tên mô tả như monthly_revenue trước khi truyền vào SmartDataframe.
  • Cache tích cực: Bật caching (enable_cache: True) để tránh chạy lại các LLM call giống nhau. Các câu hỏi lặp lại trên cùng tập dữ liệu sẽ dùng cache và không tốn chi phí.
  • Đặt system prompt: Bạn có thể cung cấp context về lĩnh vực cho PandasAI — “đây là dữ liệu bán hàng thương mại điện tử, doanh thu tính bằng USD” — để cải thiện chất lượng câu trả lời cho các câu hỏi mơ hồ.
  • Dùng Gemini để kiểm soát chi phí: Google Gemini Flash rẻ hơn đáng kể so với GPT-4o cho các truy vấn tổng hợp đơn giản. Hãy benchmark cả hai trên các loại câu hỏi thực tế của bạn trước khi chốt một backend.
  • Ghi log và giám sát: Trong môi trường dùng chung nơi nhiều người dùng có thể đặt câu hỏi, hãy ghi log mỗi truy vấn và code được tạo ra. Bạn sẽ cần trail này khi ai đó nghi ngờ về một kết quả.

Sử dụng LLM mã nguồn mở (Không tốn phí API)

Nếu bạn không muốn gửi dữ liệu đến API của bên thứ ba, PandasAI cũng hỗ trợ các model cục bộ thông qua LangChain hoặc Ollama:

ollama pull llama3
pip install pandasai[langchain]
from pandasai.llm.langchain import LangchainLLM
from langchain_community.llms import Ollama

ollama_llm = Ollama(model="llama3")
llm = LangchainLLM(ollama_llm)

sdf = SmartDataframe(df, config={"llm": llm})
result = sdf.chat("Tóm tắt 5 sản phẩm hàng đầu theo doanh thu")
print(result)

Các model cục bộ chậm hơn và kém chính xác hơn trên các truy vấn đa bước phức tạp, nhưng chúng giữ dữ liệu của bạn hoàn toàn on-premise — điều này rất quan trọng với dữ liệu kinh doanh nhạy cảm.

Khi nào PandasAI không đáp ứng được

Đánh giá thẳng thắn: PandasAI không hoàn hảo. Nó gặp khó khăn với các câu hỏi mơ hồ mà context về lĩnh vực đóng vai trò quan trọng (“Thế nào là một đơn hàng thành công?” — LLM không biết quy tắc kinh doanh của bạn). Nó cũng đôi khi tạo ra pandas không chính xác cho các edge case liên quan đến xử lý time-zone phức tạp hoặc sắp xếp category tùy chỉnh.

Giải pháp thực tế: hãy coi PandasAI là một lớp xử lý đầu tiên. Hiển thị code được tạo ra cho người dùng nâng cao để họ có thể phát hiện và sửa các hiểu nhầm. Với các báo cáo định kỳ cần độ chính xác 100%, hãy cố định logic pandas thủ công sau khi PandasAI tạo ra bản nháp đầu tiên hoạt động được.

Quy trình làm việc kết hợp đó — ngôn ngữ tự nhiên để tạo ra, con người kiểm tra để xác nhận — chính là nơi tôi nhận thấy sự cải thiện năng suất thực sự. Không phải thay thế analyst, mà là loại bỏ công việc cú pháp lặp đi lặp lại đang kìm hãm họ.

Share: