Đọc biểu đồ, đồ thị và slide deck với Claude Vision
Điểm nổi bật
Nhấn để đến mục tương ứng
- 1 Công cụ AI sẽ thay đổi cách bạn làm việc: Claude hiểu được hầu hết các loại biểu đồ thông dụng: Bar chart — Cột dọc/ngang so sánh giá trị Line chart — Đường xu. Điểm mấu chốt là biết cách đặt prompt đúng để nhận kết quả có thể sử dụng ngay.
- 2 Một điều ít người đề cập: Bar Chart — Trích xuất giá trị từng cột def readbarchartimagepath: str -> str: """Doc gia tri cac cot trong bar. Hiểu rõ bối cảnh áp dụng sẽ quyết định 80% thành công khi triển khai.
- 3 Không thể bỏ qua: Bước 1: Chuyển PowerPoint/PDF thành ảnh import subprocess from pathlib import Path def pptxtoimagespptxpath: str,. Đây là kiến thức nền tảng mà mọi người làm việc với AI đều cần hiểu rõ.
- 4 Để đạt hiệu quả tối đa: Args: format: "markdown", "csv", hoac "json" """ with openimagepath, "rb" as f: data =. Nhiều người bỏ qua bước này và mất thời gian gấp đôi để đạt cùng kết quả.
- 5 Thành thật mà nói: def analyzebusinessreportpdfpath: str -> dict: """Phan tich bao cao kinh doanh PDF day du.""" Chuyen PDF sang anh. Phương pháp này hiệu quả trong hầu hết trường hợp, nhưng bạn cần điều chỉnh cho phù hợp ngữ cảnh riêng.
Bạn nhận được một deck 40 slides cần tóm tắt, hoặc một báo cáo PDF đầy biểu đồ cần lấy số liệu? Claude Vision có thể đọc và phân tích trực tiếp — không cần copy-paste thủ công hay dùng phần mềm phức tạp.
Bài viết này hướng dẫn cách phân tích các loại biểu đồ phổ biến, xây dựng pipeline xử lý slide deck, và trích xuất dữ liệu theo cấu trúc.
Phân tích biểu đồ cơ bản
Claude hiểu được hầu hết các loại biểu đồ thông dụng:
- Bar chart — Cột dọc/ngang so sánh giá trị
- Line chart — Đường xu hướng theo thời gian
- Pie/Donut chart — Phần trăm phân phối
- Scatter plot — Tương quan giữa hai biến
- Heatmap — Mật độ hoặc cường độ theo vùng
- Combo chart — Kết hợp nhiều loại
Hàm phân tích biểu đồ tổng quát
import anthropic
import base64
import json
def analyze_chart(image_path: str, chart_type: str = "auto") -> dict:
"""
Phan tich bieu do va trich xuat du lieu.
Args:
image_path: Duong dan den anh bieu do
chart_type: Loai bieu do ("bar", "line", "pie", "scatter", "auto")
Returns:
Dict chua thong tin phan tich
"""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
type_hint = f"Day la bieu do loai {chart_type}. " if chart_type != "auto" else ""
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": f"""{type_hint}Phan tich bieu do nay va tra ve JSON voi cau truc:
{{
"chart_type": "loai bieu do",
"title": "tieu de bieu do hoac null",
"x_axis": {{"label": "nhan", "unit": "don vi hoac null"}},
"y_axis": {{"label": "nhan", "unit": "don vi hoac null"}},
"series": [
{{
"name": "ten series",
"data": [
{{"label": "nhan x", "value": gia_tri_so}}
]
}}
],
"key_insights": ["nhan xet 1", "nhan xet 2"],
"trend": "mo ta xu huong chinh",
"data_quality": "cao/trung binh/thap - giai thich ngan"
}}
Chi tra ve JSON. Neu khong chac chan gia tri chinh xac, dung null."""
}
]
}
]
)
try:
return json.loads(message.content[0].text)
except json.JSONDecodeError:
return {"raw_analysis": message.content[0].text}
Phân tích từng loại biểu đồ
Bar Chart — Trích xuất giá trị từng cột
def read_bar_chart(image_path: str) -> str:
"""Doc gia tri cac cot trong bar chart."""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": """Doc gia tri tung cot trong bar chart nay.
Tra ve bang Markdown theo format:
| Danh muc | Gia tri | Don vi |
|----------|---------|--------|
Sau do them 2-3 nhan xet ve:
- Gia tri cao nhat / thap nhat
- So sanh giua cac nhom
- Bat ky pattern dang chu y nao"""
}
]
}
]
)
return message.content[0].text
Line Chart — Phân tích xu hướng theo thời gian
def analyze_trend(image_path: str) -> str:
"""Phan tich xu huong trong line chart."""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=1024,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": """Phan tich xu huong trong line chart nay:
1. KHOANG THOI GIAN: Tu dau den cuoi?
2. DU LIEU CHINH: Cac diem data quan trong nhat (dinh, day, diem gap, dot bien)
3. XU HUONG: Tang/Giam/On dinh? Co seasonal pattern khong?
4. DOT BIEN: Co thoi diem nao bat thuong? Nguyen nhan co the la gi?
5. DU BAO: Neu xu huong tiep tuc, se di theo huong nao?
Tra ve phan tich ngan gon, tap trung vao insight thuc te."""
}
]
}
]
)
return message.content[0].text
Pie Chart — Đọc phần trăm
def read_pie_chart(image_path: str) -> dict:
"""Doc ty le phan tram trong pie chart."""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-haiku-4-5",
max_tokens=512,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": """Liet ke tat ca thanh phan trong pie chart voi ty le phan tram.
Tra ve JSON: {"segments": [{"label": "ten", "percentage": so}, ...], "total_check": tong_cong}
Chi tra ve JSON."""
}
]
}
]
)
try:
return json.loads(message.content[0].text)
except json.JSONDecodeError:
return {"raw": message.content[0].text}
Phân tích Slide Deck
Đây là ứng dụng thực tế nhất — tóm tắt một bài thuyết trình nhiều slides.
Bước 1: Chuyển PowerPoint/PDF thành ảnh
import subprocess
from pathlib import Path
def pptx_to_images(pptx_path: str, output_dir: str = "slides") -> list:
"""
Chuyen file PowerPoint thanh danh sach anh PNG.
Can cai LibreOffice va ImageMagick.
"""
Path(output_dir).mkdir(exist_ok=True)
# Buoc 1: PPTX -> PDF bang LibreOffice
subprocess.run([
"libreoffice", "--headless", "--convert-to", "pdf",
"--outdir", output_dir, pptx_path
], check=True)
# Buoc 2: PDF -> PNG bang pdftoppm (poppler-utils)
pdf_path = Path(output_dir) / (Path(pptx_path).stem + ".pdf")
subprocess.run([
"pdftoppm", "-r", "150", "-png",
str(pdf_path), str(Path(output_dir) / "slide")
], check=True)
# Lay danh sach file PNG theo thu tu
slides = sorted(Path(output_dir).glob("slide-*.png"))
return [str(s) for s in slides]
def pdf_to_images(pdf_path: str, output_dir: str = "slides", dpi: int = 150) -> list:
"""Chuyen PDF thanh danh sach anh."""
Path(output_dir).mkdir(exist_ok=True)
subprocess.run([
"pdftoppm", "-r", str(dpi), "-png",
pdf_path, str(Path(output_dir) / "page")
], check=True)
pages = sorted(Path(output_dir).glob("page-*.png"))
return [str(p) for p in pages]
Bước 2: Phân tích từng slide
def analyze_slide(image_path: str, slide_number: int) -> dict:
"""Phan tich mot slide don le."""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-haiku-4-5", # Haiku du toc do cho batch slides
max_tokens=512,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": f"""Day la slide {slide_number} cua mot bai thuyet trinh.
Phan tich ngan gon, tra ve JSON:
{{
"slide_number": {slide_number},
"type": "title/content/chart/table/image/blank",
"title": "tieu de slide hoac null",
"key_points": ["diem chinh 1", "diem chinh 2"],
"has_chart": true_or_false,
"has_table": true_or_false,
"summary": "tom tat 1-2 cau"
}}
Chi tra ve JSON."""
}
]
}
]
)
try:
return json.loads(message.content[0].text)
except json.JSONDecodeError:
return {"slide_number": slide_number, "raw": message.content[0].text}
Bước 3: Tổng hợp toàn bộ deck
def summarize_deck(slide_analyses: list) -> str:
"""
Tong hop phan tich toan bo deck thanh bao cao.
Dung Sonnet de synthesis (chat luong cao hon Haiku).
"""
# Format tat ca phan tich slide thanh text
slides_summary = json.dumps(slide_analyses, ensure_ascii=False, indent=2)
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=[
{
"role": "user",
"content": f"""Duoi day la phan tich tung slide cua mot bai thuyet trinh.
Hay tao bao cao tong hop gom:
## 1. Tong quan
- Chu de chinh cua bai thuyet trinh
- So slides va cau truc tong the
## 2. Noi dung chinh
- Cac y chinh theo tung section
- Data / so lieu quan trong
## 3. Bieu do va du lieu
- Tom tat cac bieu do co trong bai (neu co)
## 4. Ket luan
- Message chinh ma dien gia muon truyen dat
---
Du lieu phan tich cac slides:
{slides_summary}"""
}
]
)
return message.content[0].text
# Pipeline hoan chinh
def process_presentation(file_path: str) -> str:
"""
Xu ly day du mot bai thuyet trinh PPTX/PDF.
Tra ve bao cao tong hop.
"""
import time
# Xac dinh loai file va chuyen thanh anh
if file_path.endswith(".pdf"):
slide_paths = pdf_to_images(file_path)
else:
slide_paths = pptx_to_images(file_path)
print(f"Tim thay {len(slide_paths)} slides")
# Phan tich tung slide (Haiku - nhanh va re)
analyses = []
for i, path in enumerate(slide_paths):
print(f"Dang phan tich slide {i+1}/{len(slide_paths)}...")
analysis = analyze_slide(path, i + 1)
analyses.append(analysis)
time.sleep(0.3) # Rate limiting
# Tong hop bang Sonnet
print("Dang tao bao cao tong hop...")
report = summarize_deck(analyses)
return report
Trích xuất bảng số liệu từ ảnh
def extract_table_from_image(image_path: str, format: str = "markdown") -> str:
"""
Trich xuat bang so lieu tu anh.
Args:
format: "markdown", "csv", hoac "json"
"""
with open(image_path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
format_instructions = {
"markdown": "Tra ve bang Markdown voi header ro rang.",
"csv": "Tra ve CSV (dau phay phan cach), dong dau la header.",
"json": 'Tra ve JSON array: [{"col1": val1, "col2": val2, ...}, ...]'
}
client = anthropic.Anthropic()
message = client.messages.create(
model="claude-sonnet-4-5",
max_tokens=2048,
messages=[
{
"role": "user",
"content": [
{
"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}
},
{
"type": "text",
"text": f"""Trich xuat toan bo du lieu bang trong hinh anh nay.
{format_instructions.get(format, format_instructions["markdown"])}
Dam bao:
- Giu nguyen so lieu chinh xac
- Khong them hoac bot hang/cot
- Xu ly merge cells bang cach lap lai gia tri
Chi tra ve du lieu, khong them nhan xet."""
}
]
}
]
)
return message.content[0].text
Ví dụ thực tế: Báo cáo kinh doanh
def analyze_business_report(pdf_path: str) -> dict:
"""Phan tich bao cao kinh doanh PDF day du."""
# Chuyen PDF sang anh
page_paths = pdf_to_images(pdf_path, dpi=200) # DPI cao hon cho text nho
results = {
"pages": len(page_paths),
"charts": [],
"tables": [],
"key_metrics": [],
"summary": ""
}
client = anthropic.Anthropic()
for i, path in enumerate(page_paths):
with open(path, "rb") as f:
data = base64.standard_b64encode(f.read()).decode()
# Phan tich tung trang
response = client.messages.create(
model="claude-haiku-4-5",
max_tokens=1024,
messages=[{
"role": "user",
"content": [
{"type": "image",
"source": {"type": "base64", "media_type": "image/png", "data": data}},
{"type": "text",
"text": f"""Trang {i+1} cua bao cao kinh doanh. Phan tich JSON:
{{
"page": {i+1},
"contains_chart": bool,
"contains_table": bool,
"key_metrics": ["KPI hoac so lieu quan trong"],
"chart_description": "mo ta bieu do neu co, null neu khong",
"section_title": "tieu de section hoac null"
}}"""}
]
}]
)
try:
page_data = json.loads(response.content[0].text)
if page_data.get("contains_chart"):
results["charts"].append(page_data)
if page_data.get("contains_table"):
results["tables"].append(page_data)
results["key_metrics"].extend(page_data.get("key_metrics", []))
except Exception:
pass
return results
Giới hạn và lưu ý
Độ chính xác số liệu
Claude đọc số liệu từ biểu đồ với độ chính xác khoảng 80-95% tùy chất lượng ảnh và loại biểu đồ. Với bar chart có nhãn số rõ ràng: rất chính xác. Với pie chart không có nhãn phần trăm: có thể sai 3-5%.
Luôn yêu cầu Claude báo cáo mức độ chắc chắn:
# Them vao prompt
"Voi moi gia tri, cho biet muc do tu tin: [Chinh xac / Uoc tinh / Khong ro]"
Biểu đồ 3D
Biểu đồ 3D khó đọc hơn biểu đồ 2D — cả với người và AI. Nếu có thể, dùng ảnh 2D flat view.
Nhiều biểu đồ trên một trang
Nếu một slide có nhiều biểu đồ nhỏ, dùng Crop Tool để yêu cầu Claude phân tích từng biểu đồ riêng.
Tổng kết
Claude Vision là công cụ mạnh để tự động hóa việc đọc và tổng hợp thông tin từ báo cáo và trình bày:
- Bar/Line/Pie chart — Trích xuất số liệu và insight tự động
- Slide deck — Pipeline Haiku (phân tích từng slide) + Sonnet (tổng hợp)
- Bảng số liệu — Xuất ra Markdown, CSV, hoặc JSON
- Báo cáo PDF — Tách trang, phân tích, tổng hợp
Tiếp theo: Xem Sub-Agent Pattern để tối ưu chi phí khi xử lý tài liệu lớn với hàng chục đến hàng trăm trang.
Bai viet co huu ich khong?
Bản quyền thuộc về tác giả. Vui lòng dẫn nguồn khi chia sẻ.




