Resources và Prompts: Hai yếu tố cơ bản còn lại trong MCP

Tools thường nhận được nhiều sự chú ý nhất, nhưng MCP có ba thành phần cơ bản vì một lý do. Resources cung cấp dữ liệu mà không thực thi code. Prompts cung cấp cho người dùng các điểm khởi đầu có cấu trúc. Biết khi nào nên sử dụng từng loại là điều phân biệt một nhà phát triển MCP giỏi với một nhà phát triển xuất sắc.

🔄 Tóm tắt nhanh: Trong bài học trước, bạn đã nắm vững Tools — các hàm mà AI gọi để thực hiện những hành động. Bây giờ bạn sẽ học hai thành phần cơ bản khác: Resources (cho dữ liệu) và Prompts (cho các template).

Resources: Dữ liệu mà AI có thể đọc

Resources hiển thị dữ liệu và ngữ cảnh cho các trợ lý AI. Không giống như Tools, vốn thực thi các hành động, Resources chỉ đơn giản là cung cấp thông tin.

Khi nào nên sử dụng Resources thay vì Tools?

Khi nào sử dụng Resources Khi nào sử dụng Tools
Cung cấp dữ liệu tĩnh hoặc thay đổi chậm Thực hiện một hành động hoặc phép tính
Đang load ngữ cảnh khi bắt đầu cuộc trò chuyện Nhận dữ liệu thời gian thực theo yêu cầu
Hiển thị cấu hình hoặc tài liệu Thực hiện các cuộc gọi API hoặc ghi dữ liệu vào cơ sở dữ liệu
Client nên quyết định thời điểm lấy dữ liệu Mô hình AI nên quyết định khi nào cần kích hoạt nó

Ví dụ: Schema cơ sở dữ liệu là một Resource (ngữ cảnh tĩnh mà AI cần). Một truy vấn cơ sở dữ liệu là một Tool (một hành động mà AI thực hiện).

Định nghĩa Resources

Resources sử dụng URI để tự nhận dạng:

from mcp.server.fastmcp import FastMCP

mcp = FastMCP("Data Server")

@mcp.resource("config://app-settings")
def get_app_settings() -> str:
    """Current application configuration."""
    return """
    Database: PostgreSQL 16
    Cache: Redis 7
    API Rate Limit: 100 req/min
    Debug Mode: Off
    """

@mcp.resource("docs://api-reference")
def get_api_docs() -> str:
    """API endpoint documentation."""
    return open("api-docs.md").read()

📍 Nơi dán: Mở ChatGPT (chat.openai.com), Claude (claude.ai) hoặc Gemini (gemini.google.com) và bắt đầu một cuộc trò chuyện mới.

📋 Cách sao chép prompt này: Nhấp chuột vào bất kỳ đâu bên trong khối màu xám, nhấn Cmd+A rồi Cmd+C (Mac) hoặc Ctrl+A rồi Ctrl+C (Windows). Hoặc sử dụng biểu tượng sao chép xuất hiện.

URI scheme (config://, docs://) cho client biết đây là loại dữ liệu gì. Các scheme phổ biến:

Scheme Trường hợp sử dụng Ví dụ
file:// Các file cục bộ file:///var/log/app.log
db:// Bản ghi cơ sở dữ liệu db://users/schema
config:// Cấu hình config://app-settings
docs:// Tài liệu docs://api-reference

Kiểm tra nhanh: Bạn có một schema bảng cơ sở dữ liệu hiếm khi thay đổi và một API trả về số lượng người dùng trực tiếp. Cái nào là Resource và cái nào là Tool?

Đáp án: Schema bảng là Resource — đó là ngữ cảnh tĩnh mà AI cần để viết truy vấn. Số lượng người dùng trực tiếp là Tool — nó yêu cầu thực thi một truy vấn để lấy dữ liệu hiện tại.

Resources động với template

Đối với các resource phụ thuộc vào tham số, hãy sử dụng template URI:

✏️ Cách điền thông tin chi tiết của bạn: Thay thế mỗi [] và trình giữ chỗ trong ngoặc vuông bằng các thông tin cụ thể từ tình huống thực tế của bạn. Đầu vào mơ hồ sẽ tạo ra đầu ra mơ hồ — hãy cụ thể.

👀 Những gì bạn sẽ thấy: Trong vòng vài giây, AI sẽ trả về một phản hồi có cấu trúc dựa trên prompt ở trên. Hãy đọc kỹ và coi đó là bản nháp, không phải là câu trả lời cuối cùng.

📌 Phải làm gì với kết quả: Lưu phản hồi vào file Notes. Chọn đề xuất có tác động cao nhất và thực hiện nó trong tuần này — đừng cố gắng làm mọi thứ cùng một lúc.

⚠️ Nếu thấy không ổn: Nếu các đề xuất có vẻ chung chung, hãy dán nội dung sau: "Hãy cụ thể hơn với ngữ cảnh thực tế của tôi. Bỏ qua những lời khuyên chung chung đi." Nếu nó bỏ qua các chi tiết quan trọng bạn đã cung cấp, hãy hỏi: "Bạn đã bỏ sót [X] trong ngữ cảnh của tôi — hãy thực hiện lại với điều đó làm ràng buộc chính."

python
@mcp.resource("db://users/{user_id}/profile")
def get_user_profile(user_id: str) -> str:
    """User profile data."""
    user = database.get_user(user_id)
    return f"Name: {user.name}\nEmail: {user.email}\nRole: {user.role}"

Biểu tượng giữ chỗ {user_id} biến đây thành một template — client có thể yêu cầu hồ sơ của bất kỳ người dùng nào bằng cách điền ID.

Danh sách resource

Server có thể cung cấp danh sách các resource có sẵn để client biết cần lấy gì:

@mcp.resource("file://logs/{filename}")
def get_log_file(filename: str) -> str:
    """Read a log file."""
    return open(f"/var/log/{filename}").read()

Khi client liệt kê các resource, nó sẽ phát hiện những file nhật ký có sẵn và có thể lấy các file cụ thể khi cần. Sự khác biệt chính so với Tools: Ứng dụng client quyết định khi nào lấy Resources (thường là khi bắt đầu cuộc hội thoại), trong khi mô hình AI quyết định khi nào gọi Tools (trong suốt cuộc hội thoại).

Prompts: Template tương tác có thể tái sử dụng

Prompts là các câu mở đầu cuộc hội thoại được xác định trước mà người dùng chọn một cách rõ ràng. Chúng cung cấp cấu trúc cho các quy trình làm việc lặp đi lặp lại.

Khi nào nên sử dụng Prompts?

Prompts phát huy hiệu quả nhất trong các tương tác có cấu trúc và lặp lại:

  • Kiểm tra code: Luôn phân tích cùng một khía cạnh (bảo mật, hiệu suất, khả năng đọc hiểu)
  • Họp nhóm hàng ngày: Luôn thu thập trạng thái, các vấn đề cản trở và kế hoạch
  • Phân tích dữ liệu: Luôn bắt đầu với cùng các bước khám phá
  • Tạo báo cáo: Luôn tuân theo cùng một định dạng

Định nghĩa Prompts

from mcp.server.fastmcp import FastMCP
from mcp.types import UserMessage, AssistantMessage

mcp = FastMCP("Workflow Server")

@mcp.prompt()
def code_review(language: str, code: str) -> list:
    """Perform a structured code review."""
    return [
        UserMessage(
            content=f"""Review this {language} code for:
1. **Bugs** — Logic errors, edge cases, null handling
2. **Security** — Input validation, injection risks, auth issues
3. **Performance** — Unnecessary allocations, O(n²) loops, missing indexes
4. **Readability** — Naming, structure, comments where needed

Code to review:
```{language}
{code}

Cung cấp các tham chiếu dòng cụ thể và đề xuất sửa lỗi cho từng vấn đề được tìm thấy.

When a user selects this prompt in their AI client, they fill in the `language` and `code` parameters. The structured template ensures every code review covers the same aspects.

### Multi-Turn Prompts

Prompts can include multiple messages to set up a conversation context:

```python
@mcp.prompt()
def debug_session(error_message: str, stack_trace: str) -> list:
    """Start a structured debugging session."""
    return [
        UserMessage(
            content=f"I'm getting this error:\n\n{error_message}\n\nStack trace:\n```\n{stack_trace}\n```"
        ),
        AssistantMessage(
            content="I'll help you debug this. Let me analyze the error and stack trace systematically. First, let me identify the root cause..."
        ),
        UserMessage(
            content="Please: (1) identify the root cause, (2) explain why it happens, (3) suggest a fix with code, (4) recommend how to prevent this class of error."
        )
    ]

Điều này tạo ra một ngữ cảnh hội thoại ba thông báo trước khi AI phản hồi — thiết lập quy trình gỡ lỗi hiệu quả.

Kiểm tra nhanh: Người dùng chọn một MCP Prompt cho "Tối ưu hóa truy vấn SQL". Ai kiểm soát khi nào prompt này được sử dụng — mô hình AI, ứng dụng client hay người dùng?

Đáp án: Người dùng. Prompts do người dùng kiểm soát — người dùng chọn chúng một cách rõ ràng làm điểm bắt đầu hội thoại. Điều này trái ngược với Tools (do mô hình kiểm soát) và Resources (do ứng dụng kiểm soát).)

Kết hợp cả ba thành phần cơ bản

Một MCP server được thiết kế tốt sẽ sử dụng cả ba thành phần cơ bản cùng nhau:

mcp = FastMCP("Project Assistant")

# RESOURCE: Static project context
@mcp.resource("project://readme")
def get_readme() -> str:
    """Project README documentation."""
    return open("README.md").read()

@mcp.resource("project://schema")
def get_db_schema() -> str:
    """Database schema for the project."""
    return open("schema.sql").read()

# TOOL: Dynamic actions
@mcp.tool()
async def query_database(sql: str) -> str:
    """Execute a read-only SQL query."""
    # ... execute and return results

@mcp.tool()
async def create_issue(title: str, body: str) -> str:
    """Create a GitHub issue for this project."""
    # ... create and return issue URL

# PROMPT: Structured workflows
@mcp.prompt()
def feature_planning(feature_name: str) -> list:
    """Plan a new feature with structured analysis."""
    return [UserMessage(
        content=f"Plan the '{feature_name}' feature. Analyze: "
                f"1) database changes needed, "
                f"2) API endpoints, "
                f"3) testing strategy, "
                f"4) rollout plan."
    )]

Cách chúng hoạt động cùng nhau:

  1. Client load Resources (README, schema) làm ngữ cảnh hội thoại
  2. Người dùng chọn Prompts "lập kế hoạch tính năng" để bắt đầu workflow có cấu trúc
  3. AI gọi Tools (truy vấn cơ sở dữ liệu, tạo vấn đề) khi cần thiết trong suốt cuộc hội thoại

Cách đưa ra quyết định

Cách quyết định sử dụng thành phần nào:

  • AI có cần thực hiện một hành động không? → Có → Sử dụng Tools
  • Đó có phải là dữ liệu tĩnh mà AI nên có làm ngữ cảnh không? → Có → Sử dụng Resources
  • Đây có phải là một cách bắt đầu cuộc trò chuyện có thể tái sử dụng không? → Có → Sử dụng Prompts
Thành phần Ai kiểm soát Khi nào sử dụng Mục đích
Tool Mô hình AI Trong suốt cuộc trò chuyện Thực hiện các hành động
Resource Ứng dụng client Trước/trong cuộc trò chuyện Cung cấp ngữ cảnh
Prompt Người dùng Bắt đầu cuộc trò chuyện Cấu trúc quy trình làm việc

Bài tập thực hành

Tạo một MCP server cho "trợ lý tài liệu" sử dụng cả ba thành phần cơ bản:

  1. Resources: Hiển thị tài liệu README và API của dự án
  2. Tools: Tìm kiếm tài liệu theo từ khóa và trả về các phần phù hợp
  3. Prompts: "Giải thích API endpoint này" — một template cấu trúc các yêu cầu giải thích endpoint

Kiểm tra với Claude Desktop. Thử load các resource, sử dụng prompt và gọi công cụ tìm kiếm trong cùng một cuộc hội thoại.

Những điểm chính cần ghi nhớ

  • Resources hiển thị dữ liệu và ngữ cảnh — được client tìm nạp, không phải do mô hình AI gọi
  • Resources sử dụng URI với schema tùy chỉnh (file://, db://, config://)
  • Prompts là các template hội thoại do người dùng chọn với hỗ trợ tham số
  • Prompts đảm bảo tính nhất quán cho các quy trình làm việc lặp lại (xem xét code, gỡ lỗi, lập kế hoạch)
  • Sử dụng cả ba thành phần cơ bản cùng nhau: Resources cho ngữ cảnh, Tools cho hành động, Prompts cho cấu trúc
  • Quy tắc quyết định: hành động → Tool, dữ liệu → Resource, template → Prompt
  • Câu 1:

    MCP Resources sử dụng URI scheme nào?

    GIẢI THÍCH:

    MCP Resources được xác định bằng các URI với scheme tùy chỉnh mô tả nguồn dữ liệu. Ví dụ: file:///logs/app.log cho một file, postgres://database/users cho một bảng cơ sở dữ liệu hoặc config://settings cho dữ liệu cấu hình. URI cho client biết cả tài nguyên đó là gì và nó đến từ đâu.

  • Câu 2:

    Khi nào bạn nên sử dụng MCP Prompt thay vì chỉ viết hướng dẫn trong cuộc trò chuyện?

    GIẢI THÍCH:

    MCP Prompt là các template do máy chủ định nghĩa mà người dùng có thể chọn làm điểm bắt đầu. Chúng đảm bảo tính nhất quán (mọi đánh giá code đều tuân theo cùng một cấu trúc), hỗ trợ những tham số (điền tên kho lưu trữ) và có thể được chia sẻ giữa các nhóm. Chúng lý tưởng cho các quy trình làm việc lặp đi lặp lại, giống như một template 'đánh giá code' luôn đặt ra những câu hỏi đúng.

  • Câu 3:

    Điểm khác biệt chính giữa MCP Tools và MCP Resources là gì?

    GIẢI THÍCH:

    Tools được điều khiển bởi mô hình — AI quyết định khi nào gọi chúng trong cuộc hội thoại. Resources được điều khiển bởi ứng dụng — client truy xuất chúng một cách rõ ràng để load ngữ cảnh. Hãy nghĩ theo cách này: Tools thực hiện các hành động, Resources nắm bắt thông tin (dữ liệu).

Thứ Ba, 02/06/2026 10:01
51 👨
Xác thực tài khoản!

Theo Nghị định 147/2024/ND-CP, bạn cần xác thực tài khoản trước khi sử dụng tính năng này. Chúng tôi sẽ gửi mã xác thực qua SMS hoặc Zalo tới số điện thoại mà bạn nhập dưới đây:

Số điện thoại chưa đúng định dạng!
Số điện thoại này đã được xác thực!
Bạn có thể dùng Sđt này đăng nhập tại đây!
Lỗi gửi SMS, liên hệ Admin
0 Bình luận
Sắp xếp theo