Tool là để hành động. Nhưng nhiều lúc agent chỉ cần đọc dữ liệu làm ngữ cảnh: nội dung tài liệu, cấu hình, một dòng database. Đó là việc của Resources. Bài này cũng giới thiệu Prompts — mẫu prompt tái sử dụng.
Resources: dữ liệu chỉ-đọc, định danh bằng URI
Mỗi resource có một URI (định danh) và trả về nội dung. Khác biệt cốt lõi so với tool:
- Tool: có side effect, do model chủ động gọi khi suy luận.
- Resource: chỉ đọc, thường do ứng dụng/người dùng chọn nạp vào ngữ cảnh (application-controlled).
Ví dụ: phơi bày file hướng dẫn nội bộ
@mcp.resource("docs://policy/refund")
def refund_policy() -> str:
"""Chính sách hoàn tiền hiện hành của công ty."""
return open("/opt/data/refund_policy.md").read()
Agent (hoặc người dùng) có thể nạp docs://policy/refund vào ngữ cảnh trước khi trả lời câu hỏi về hoàn tiền — thay vì để model bịa.
Resource động với tham số (template)
@mcp.resource("orders://{order_id}")
def get_order(order_id: str) -> str:
"""Đọc chi tiết một đơn hàng theo ID."""
row = db.query_one("SELECT * FROM orders WHERE id=%s", order_id)
return json.dumps(row, ensure_ascii=False)
URI orders://4821 sẽ nạp đúng đơn 4821. Đây là resource template — một mẫu URI sinh ra nhiều resource cụ thể.
Khi nào Resource, khi nào Tool?
> Khung quyết định: Hỏi "Việc này có thay đổi gì trong hệ thống không?" > - Không (chỉ đọc, an toàn lặp lại) → cân nhắc Resource. > - Có (ghi, gửi, xóa, gọi API tính phí) → Tool. > > Ngoài ra: cần model tự động quyết định gọi → Tool. Cần người/ứng dụng chủ động chọn nạp ngữ cảnh → Resource.
Lưu ý thực tế: nhiều agent hiện nay điều khiển việc đọc dữ liệu qua tool đọc (ví dụ read_order) vì model dễ tự gọi hơn. Resource mạnh nhất khi host có UI cho người dùng chọn dữ liệu để đính kèm.
Prompts: mẫu prompt dựng sẵn
Prompt là template mà server cung cấp để chuẩn hóa cách hỏi. Ví dụ mẫu "soạn email xin lỗi khách":
@mcp.prompt()
def apology_email(order_id: str, reason: str) -> str:
return f"""Soạn email tiếng Việt xin lỗi khách về đơn {order_id}.
Lý do sự cố: {reason}. Giọng điệu chân thành, đề xuất giải pháp cụ thể."""
Người dùng chọn prompt này trong host, điền tham số, và có ngay câu lệnh chuẩn — không phải gõ lại mỗi lần.
Ai điều khiển cái gì: model, ứng dụng hay người dùng
Một cách phân biệt sạch sẽ ba khối MCP là hỏi ai chủ động kích hoạt:
- Tools — model-controlled: model tự quyết định gọi trong lúc suy luận.
- Resources — application-controlled: host/ứng dụng quyết định nạp dữ liệu nào vào ngữ cảnh (thường có UI cho người dùng chọn).
- Prompts — user-controlled: người dùng chủ động chọn một mẫu để bắt đầu tác vụ.
read_policy) để model tự gọi. Còn nếu dữ liệu chỉ cần khi người dùng chủ động đính kèm (ví dụ chọn một tài liệu cụ thể trong UI), resource là đúng chỗ.Ví dụ kết hợp Tool + Resource trong một tình huống
Agent CSKH trả lời câu hỏi hoàn tiền: (1) người dùng đính kèm resource docs://policy/refund để agent bám đúng chính sách; (2) agent gọi tool orders_query lấy trạng thái đơn; (3) nếu đủ điều kiện, agent gọi tool refund_order (có xác nhận). Ba khối phối hợp: resource cấp ngữ cảnh chuẩn, tool cấp khả năng hành động. Thiết kế tách bạch này khiến hệ thống dễ kiểm soát và audit hơn nhiều so với nhồi tất cả vào một tool vạn năng.
Các bước thêm Resource vào server
- Xác định dữ liệu chỉ-đọc agent cần (tài liệu, cấu hình, bản ghi).
- Thiết kế URI rõ ràng, có namespace (
docs://,orders://). - Với dữ liệu động, dùng template URI kèm tham số.
- Trả nội dung gọn, đúng định dạng (text/JSON/markdown).
- Giới hạn phạm vi: chỉ phơi bày dữ liệu được phép, tránh lộ toàn bộ hệ thống.
- Test qua Inspector:
resources/listrồiresources/read.
Checklist Resource an toàn
- [ ] URI có namespace, không đụng độ.
- [ ] Không phơi bày dữ liệu nhạy cảm ngoài phạm vi cần thiết.
- [ ] Có kiểm tra tham số (chống path traversal như
../../etc/passwd). - [ ] Nội dung trả về đủ nhỏ để không ngốn hết context.
Sai lầm thường gặp
- Dùng Resource cho hành động có side effect (ví dụ resource
orders://cancel/123để hủy đơn). Sai — đó phải là Tool. Đọc phải luôn an toàn, không đổi trạng thái. - URI template không kiểm soát tham số → lỗ hổng path traversal, lộ file hệ thống.
- Trả nguyên cả bảng database làm resource → tràn context.
- Kỳ vọng model tự gọi resource giống tool. Nhiều host cần người dùng chủ động chọn resource; nếu muốn model tự lấy dữ liệu, hãy làm thêm một tool đọc.