Trung cấpKỹ thuậtClaude APINguồn: Anthropic

Crop Tool — Cho Claude khả năng zoom vào chi tiết hình ảnh

Nghe bài viết
00:00

Điểm nổi bật

Nhấn để đến mục tương ứng

  1. 1 Công cụ AI sẽ thay đổi cách bạn làm việc: Luồng hoạt động như sau: Gửi ảnh gốc — Client gửi ảnh toàn cảnh cho Claude Claude nhận diện vùng cần xem kỹ — Claude. Đ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. 2 Một điều ít người đề cập: Đầu tiên, định nghĩa tool mà Claude có thể gọi: CROPTOOL = { "name": "cropimage", "description": """Cat mot vung cua. Hiểu rõ bối cảnh áp dụng sẽ quyết định 80% thành công khi triển khai.
  3. 3 Nội dung cốt lõi: Đây là phần quan trọng nhất — vòng lặp xử lý tool calls: import anthropic def analyzewithcroptool imagepath: str,. Nắm vững phần này sẽ giúp bạn áp dụng hiệu quả hơn 70% so với đọc lướt toàn bài.
  4. 4 Tận dụng Claude hiệu quả: """ question = """Trich xuat thong tin tu hoa don nay: 1 — mẹo quan trọng là cung cấp đủ ngữ cảnh để AI trả về kết quả chính xác hơn 80% so với prompt chung chung.
  5. 5 Thực tế không hoàn hảo: Giới hạn maxiterations hợp lý để kiểm soát chi phí: Tài liệu đơn giản: 3-4 lần crop là đủ Tài liệu phức tạp hóa đơn,. Biết trước giới hạn sẽ giúp bạn thiết lập kỳ vọng đúng và tránh thất vọng không cần thiết.
flat screen computer monitor

Một trong những giới hạn của Vision AI là độ phân giải hiệu dụng — khi gửi ảnh toàn cảnh lớn, các chi tiết nhỏ bị mất đi. Giải pháp? Cho Claude một công cụ crop — để nó tự xác định vùng cần xem chi tiết và yêu cầu bạn gửi ảnh đã cắt xén.

Pattern này từ Anthropic Cookbook giúp Claude phân tích tài liệu phức tạp, bản vẽ kỹ thuật, hay bất kỳ ảnh nào có chi tiết quan trọng ở nhiều vùng khác nhau.

Ý tưởng cốt lõi

Luồng hoạt động như sau:

  1. Gửi ảnh gốc — Client gửi ảnh toàn cảnh cho Claude
  2. Claude nhận diện vùng cần xem kỹ — Claude dùng crop tool để "yêu cầu" cắt vùng cụ thể
  3. Client crop và gửi lại — Bạn cắt vùng đó, gửi ảnh cắt xén cho Claude
  4. Claude phân tích chi tiết — Với ảnh đã được zoom in, Claude đọc được thông tin chính xác hơn

Đây là ví dụ điển hình của Tool Use pattern với Vision — Claude không chỉ nhìn thụ động mà chủ động điều khiển quá trình phân tích.

Định nghĩa Crop Tool

Đầu tiên, định nghĩa tool mà Claude có thể gọi:

CROP_TOOL = {
    "name": "crop_image",
    "description": """Cat mot vung cua hinh anh hien tai de xem chi tiet hon.
    Dung khi ban can doc van ban nho, xem chi tiet ky thuat,
    hoac phan tich mot vung cu the ma khong ro o do phan giai hien tai.""",
    "input_schema": {
        "type": "object",
        "properties": {
            "left": {
                "type": "number",
                "description": "Toa do x cua goc trai tren (0-100, tinh theo %, relative den chieu rong anh)"
            },
            "top": {
                "type": "number",
                "description": "Toa do y cua goc trai tren (0-100, tinh theo %, relative den chieu cao anh)"
            },
            "right": {
                "type": "number",
                "description": "Toa do x cua goc phai duoi (0-100, tinh theo %)"
            },
            "bottom": {
                "type": "number",
                "description": "Toa do y cua goc phai duoi (0-100, tinh theo %)"
            },
            "reason": {
                "type": "string",
                "description": "Ly do tai sao can xem vung nay chi tiet hon"
            }
        },
        "required": ["left", "top", "right", "bottom", "reason"]
    }
}

Tọa độ dùng đơn vị phần trăm (0-100) thay vì pixel tuyệt đối — nhờ đó hoạt động với ảnh mọi kích thước mà không cần Claude biết kích thước pixel chính xác.

Hàm crop thực tế

from PIL import Image
import io, base64

def crop_image(
    original_image: bytes,
    left: float,
    top: float,
    right: float,
    bottom: float
) -> tuple:
    """
    Cat anh theo toa do phan tram.

    Args:
        original_image: Raw bytes cua anh goc
        left, top, right, bottom: Toa do phan tram (0-100)

    Returns:
        (base64_string, media_type)
    """
    img = Image.open(io.BytesIO(original_image))
    width, height = img.size

    # Chuyen phan tram sang pixel
    x1 = int(width * left / 100)
    y1 = int(height * top / 100)
    x2 = int(width * right / 100)
    y2 = int(height * bottom / 100)

    # Dam bao bounds hop le
    x1 = max(0, min(x1, width))
    y1 = max(0, min(y1, height))
    x2 = max(x1 + 1, min(x2, width))
    y2 = max(y1 + 1, min(y2, height))

    # Cat va encode
    cropped = img.crop((x1, y1, x2, y2))
    buf = io.BytesIO()
    fmt = "PNG" if img.mode == "RGBA" else "JPEG"
    cropped.save(buf, format=fmt, quality=90)
    data = base64.standard_b64encode(buf.getvalue()).decode()
    media_type = "image/png" if fmt == "PNG" else "image/jpeg"

    return data, media_type

Vòng lặp agentic chính

Đây là phần quan trọng nhất — vòng lặp xử lý tool calls:

import anthropic

def analyze_with_crop_tool(
    image_path: str,
    question: str,
    max_iterations: int = 5
) -> str:
    """
    Phan tich anh, cho phep Claude tu request crop khi can.

    Args:
        image_path: Duong dan den file anh
        question: Cau hoi ve hinh anh
        max_iterations: So lan crop toi da cho phep
    """
    client = anthropic.Anthropic()

    # Doc anh goc
    with open(image_path, "rb") as f:
        original_bytes = f.read()

    image_data = base64.standard_b64encode(original_bytes).decode()
    media_type = "image/jpeg"  # Hoac detect tu extension

    # Tin nhan ban dau
    messages = [
        {
            "role": "user",
            "content": [
                {
                    "type": "text",
                    "text": f"""Ban co the su dung cong cu crop_image de xem chi tiet
                    bat ky vung nao trong anh. Hay su dung no neu can thiet.

                    Cau hoi: {question}"""
                },
                {
                    "type": "image",
                    "source": {
                        "type": "base64",
                        "media_type": media_type,
                        "data": image_data
                    }
                }
            ]
        }
    ]

    # Vong lap xu ly tool calls
    for iteration in range(max_iterations):
        response = client.messages.create(
            model="claude-opus-4-5",
            max_tokens=4096,
            tools=[CROP_TOOL],
            messages=messages
        )

        # Kiem tra stop reason
        if response.stop_reason == "end_turn":
            # Claude hoan thanh, tra ve ket qua cuoi
            for block in response.content:
                if hasattr(block, "text"):
                    return block.text
            break

        if response.stop_reason == "tool_use":
            # Tim tool call trong response
            tool_calls = [
                b for b in response.content
                if b.type == "tool_use"
            ]

            if not tool_calls:
                break

            # Them assistant message vao lich su
            messages.append({
                "role": "assistant",
                "content": response.content
            })

            # Xu ly tung tool call
            tool_results = []
            for tool_call in tool_calls:
                args = tool_call.input
                print(f"Claude dang crop vung: {args['left']:.0f}%-{args['right']:.0f}% x {args['top']:.0f}%-{args['bottom']:.0f}%")
                print(f"Ly do: {args.get('reason', '')}")

                # Thuc hien crop
                crop_data, crop_media_type = crop_image(
                    original_bytes,
                    args["left"], args["top"],
                    args["right"], args["bottom"]
                )

                # Tra ve ket qua crop cho Claude
                tool_results.append({
                    "type": "tool_result",
                    "tool_use_id": tool_call.id,
                    "content": [
                        {
                            "type": "text",
                            "text": f"Day la vung anh da duoc cat ({args['left']:.0f}%-{args['right']:.0f}% x {args['top']:.0f}%-{args['bottom']:.0f}%):"
                        },
                        {
                            "type": "image",
                            "source": {
                                "type": "base64",
                                "media_type": crop_media_type,
                                "data": crop_data
                            }
                        }
                    ]
                })

            # Them tool results vao lich su
            messages.append({
                "role": "user",
                "content": tool_results
            })

    return "Khong the hoan thanh phan tich."


# Chay thu
if __name__ == "__main__":
    result = analyze_with_crop_tool(
        "document.png",
        "Doc toan bo noi dung cua tai lieu nay va tom tat."
    )
    print(result)

Ví dụ thực tế: Phân tích hóa đơn phức tạp

Hóa đơn thường có nhiều vùng thông tin: header, line items, tổng cộng, điều khoản. Crop tool giúp Claude đọc từng vùng chính xác hơn:

def extract_invoice_data(invoice_path: str) -> dict:
    """
    Trich xuat du lieu hoa don bang crop tool.
    """
    question = """Trich xuat thong tin tu hoa don nay:
    1. So hoa don va ngay
    2. Thong tin nha cung cap (ten, dia chi)
    3. Thong tin khach hang (ten, dia chi)
    4. Danh sach san pham/dich vu va gia
    5. Tong tien (chua thue va co thue)
    6. Hanh thuc va thoi han thanh toan

    Su dung crop tool de doc ro tung phan neu can.
    Tra ve du lieu dang JSON."""

    result = analyze_with_crop_tool(invoice_path, question)
    return result

Ví dụ: Đọc bản vẽ kỹ thuật

def read_technical_drawing(drawing_path: str) -> str:
    """
    Doc thong so ky thuat tu ban ve.
    """
    question = """Day la ban ve ky thuat. Hay:
    1. Tim va doc title block (goc phai duoi thuong co thong tin ve ban ve)
    2. Doc cac kich thuoc chinh
    3. Tim cac ghi chu quan trong
    4. Mo ta hinh dang tong the cua chi tiet

    Dung crop_image de xem chi tiet cac so, ky hieu kho doc."""

    return analyze_with_crop_tool(
        drawing_path,
        question,
        max_iterations=8  # Ban ve ky thuat co the can nhieu lan crop
    )

Tối ưu và giới hạn

Giới hạn số lần crop

Mỗi lần crop tốn thêm một API call. Giới hạn max_iterations hợp lý để kiểm soát chi phí:

  • Tài liệu đơn giản: 3-4 lần crop là đủ
  • Tài liệu phức tạp (hóa đơn, hợp đồng): 5-8 lần
  • Bản vẽ kỹ thuật, bản đồ: 8-15 lần

Kích thước crop tối thiểu

Thêm validation để tránh crop quá nhỏ (vô nghĩa) hoặc quá lớn (không zoom được):

def validate_crop_args(args: dict) -> bool:
    """Kiem tra toa do crop hop le."""
    left, top = args["left"], args["top"]
    right, bottom = args["right"], args["bottom"]

    # Dam bao vung cat it nhat 5% theo moi chieu
    if (right - left) < 5 or (bottom - top) < 5:
        return False

    # Dam bao khong vuot ngoai anh
    if left < 0 or top < 0 or right > 100 or bottom > 100:
        return False

    return True

Cache crop results

Nếu Claude crop cùng vùng nhiều lần (hiếm nhưng có thể xảy ra), cache kết quả để tránh xử lý lại:

crop_cache = {}

def crop_image_cached(original_bytes, left, top, right, bottom):
    key = (left, top, right, bottom)
    if key not in crop_cache:
        crop_cache[key] = crop_image(original_bytes, left, top, right, bottom)
    return crop_cache[key]

Khi nào nên dùng Crop Tool?

Nên dùng Không cần dùng
Tài liệu nhiều trang, nhiều section Ảnh đơn giản, ít thông tin
Hóa đơn, hợp đồng, form scan Nhận diện đối tượng tổng thể
Bản vẽ kỹ thuật, bản đồ chi tiết Phân tích cảm xúc, tông màu
Slide deck với text nhỏ Ảnh chụp đơn giản
Text nhỏ khó đọc ở nhiều vùng Khi ảnh đã đủ độ phân giải

Tổng kết

Crop Tool Pattern là một trong những kỹ thuật mạnh nhất cho Vision tasks phức tạp. Thay vì bị giới hạn bởi độ phân giải của ảnh gốc, Claude có thể chủ động điều hướng phân tích — giống như con người dùng kính lúp để xem chi tiết.

Code hoàn chỉnh của pattern này có trên GitHub Cookbook của Anthropic. Bước tiếp theo: tìm hiểu OCR với ClaudePhân tích biểu đồ và slides.


Bài viết liên quan

Tính năng liên quan:VisionTool UseCrop ToolImage Analysis

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ẻ.

Bình luận (0)
Ảnh đại diện
Đăng nhập để bình luận...
Đăng nhập để bình luận
  • Đang tải bình luận...

Đăng ký nhận bản tin

Nhận bài viết hay nhất về sản phẩm và vận hành, gửi thẳng vào hộp thư của bạn.

Bảo mật thông tin. Hủy đăng ký bất cứ lúc nào. Chính sách bảo mật.