Tại sao ứng dụng MCP của bạn chạy chậm hơn trên ChatGPT so với Claude

07 tháng 4, 2026·6 phút đọc

ChatGPT tạo một phiên MCP mới cho mỗi lần gọi công cụ, trong khi Claude tái sử dụng phiên duy nhất. Điều này gây ra chi phí bắt tay (handshake) thừa và làm mất trạng thái bộ nhớ tạm thời giữa các lần gọi, làm giảm hiệu suất tổng thể.

Tại sao ứng dụng MCP của bạn chạy chậm hơn trên ChatGPT so với Claude

Trong quá trình phát triển mcpr — một proxy mã nguồn mở dành cho các máy chủ MCP (Model Context Protocol) — chúng tôi đã nhận thấy một sự khác biệt khá thú vị thông qua bảng điều khiển (dashboard) giám sát tại cấp độ giao thức.

Khi theo dõi một máy chủ MCP đang vận hành thực tế và phục vụ cả hai nền tảng ChatGPT lẫn Claude, chúng tôi đã phát hiện ra một sự bất thường trong dữ liệu phiên làm việc (session):

  • ChatGPT (openai-mcp): 2 lần gọi công cụ → 2 phiên làm việc riêng biệt.
  • Claude (claude-ai): 2 lần gọi công cụ → 1 phiên làm việc duy nhất.

Cùng một máy chủ, cùng một bộ công cụ, nhưng lại có hành vi phiên làm việc hoàn toàn khác nhau. Vậy điều gì đang thực sự diễn ra ở đây?

Điều gì đang thực sự diễn ra

Dưới đây là dòng thời gian từ bảng điều khiển của chúng tôi cho một tương tác đơn giản mà AI thực hiện hai lần gọi công cụ.

Trường hợp của ChatGPT

Session 1:
  04:02:40 PM  initialize              3ms   ok
  04:02:40 PM  tools/call  create_matching_question  12ms  ok
  ── session ended ──

Session 2:
  04:03:47 PM  initialize              3ms   ok
  04:03:47 PM  tools/call  submit_answer            12ms  ok
  ── session ended ──

ChatGPT đã tạo hai phiên, thực hiện hai lần bắt tay (initialize). Mỗi phiên chỉ tồn tại trong khoảng một giây.

Biểu đồ phiên ChatGPTBiểu đồ phiên ChatGPT

Trường hợp của Claude

Session 1:
  02:03:06 PM  initialize              30ms  ok
  02:03:07 PM  tools/list              11ms  ok
  02:03:08 PM  resources/list          14ms  ok
  02:03:38 PM  resources/read           4ms  ok
  02:03:41 PM  tools/call  create_cloze_question    35ms  ok
  02:03:45 PM  tools/call  get_latest_answer         6ms  ok
  ── session ended ──

Claude chỉ tạo một phiên duy nhất với một lần bắt tay (initialize). Thậm chí, Claude còn thực hiện các bước khám phá (như tools/list, resources/list) trước khi gọi công cụ — tất cả đều nằm trong cùng một phiên. Tổng thời gian duy trì phiên là 39 giây.

Biểu đồ phiên ClaudeBiểu đồ phiên Claude

Tại sao sự khác biệt này lại quan trọng?

1. Việc khởi tạo (Initialize) không hề miễn phí

Mỗi lệnh gọi initialize trong MCP là một quá trình bắt tay đầy đủ: máy khách gửi khả năng của nó, máy chủ phản hồi lại và hai bên thống nhất phiên bản giao thức. Một số máy chủ thậm chí còn tải cấu hình, thiết lập kết nối cơ sở dữ liệu hoặc làm nóng cache trong giai đoạn này.

ChatGPT phải trả chi phí này cho mọi lần gọi công cụ, trong khi Claude chỉ trả một lần.

Ví dụ, với một cuộc hội thoại kích hoạt 10 lần gọi công cụ, bạn sẽ có 10 lần bắt tay trên ChatGPT so với 1 lần trên Claude. Nếu quá trình khởi tạo của bạn mất 30-50ms, bạn đang lãng phí 300-500ms độ trễ thuần túy.

2. Trạng thái trong bộ nhớ sẽ bị mất

Đây là vấn đề khó phát hiện nhất. Nếu máy chủ MCP của bạn lưu trữ bất kỳ thứ gì trong bộ nhớ cho mỗi phiên — như ngữ cảnh người dùng, lịch sử hội thoại, phản hồi API đã lưu trong cache hoặc trạng thái đã tính toán — ChatGPT sẽ làm mất tất cả sau mỗi lần gọi công cụ.

# Cách làm này SẼ KHÔNG HOẠT ĐỘNG trên ChatGPT
session_cache = {}

async def handle_initialize(session_id):
    session_cache[session_id] = {"user": None, "history": []}

async def handle_tool_call(session_id, tool, args):
    # Trên ChatGPT, đây là một session_id MỚI mỗi lần
    cache = session_cache.get(session_id)  # Kết quả sẽ là None!

Trên Claude, session_id giữ nguyên qua các lần gọi công cụ. Nhưng trên ChatGPT, đó là một ID hoàn toàn mới mỗi lần.

3. Khám phá công cụ diễn ra khác nhau

Bạn có thể nhận thấy Claude gọi tools/listresources/list trong phiên. Nó khám phá những gì có sẵn trước khi hành động.

Ngược lại, ChatGPT bỏ qua bước này — nó đi thẳng từ initializetools/call. Điều này gợi ý rằng ChatGPT lưu trữ schema công cụ ở bên ngoài và không cần khám phá lại nó cho mỗi phiên.

Cách xây dựng để tối ưu trên cả hai nền tảng

Nếu bạn muốn máy chủ MCP của mình hoạt động tốt trên cả hai nền tảng, hãy hãy tính đến kịch bản tồi tệ nhất (tương tự như ChatGPT):

Làm cho việc khởi tạo nhanh chóng

ChatGPT sẽ gọi nó rất nhiều lần. Đừng thực hiện các thiết lập nặng nề — hãy sử dụng cách tải lười (lazy-load) thay thế.

# Tệi: khởi tạo nặng nề
async def handle_initialize(session_id):
    await load_database_schema()      # 200ms
    await warm_embedding_cache()       # 500ms
    await fetch_user_preferences()     # 100ms

# Tốt: hoãn mọi thứ
async def handle_initialize(session_id):
    return {"capabilities": {...}}     # < 5ms

Xây dựng theo hướng không trạng thái (Stateless)

Đừng dựa vào trạng thái phạm vi phiên (session-scoped). Hãy sử dụng tính bền vững bên ngoài (Redis, cơ sở dữ liệu) được khóa theo một thứ gì đó ổn định như ID người dùng — thay vì ID phiên.

# Tệi: trạng thái phiên
session_state = {}

# Tốt: trạng thái bên ngoài khóa theo người dùng
async def get_state(user_id):
    return await redis.get(f"user:{user_id}")

Truyền ngữ cảnh một cách rõ ràng

Nếu công cụ B phụ thuộc vào đầu ra của công cụ A, đừng lưu nó trong bộ nhớ phiên. Hãy trả về nó dưới dạng đầu ra có cấu trúc để máy khách AI có thể truyền lại nó làm đầu vào.

Làm thế nào chúng tôi phát hiện ra vấn đề này

Một proxy ngược HTTP thông thường (như nginx hay HAProxy) sẽ coi các yêu cầu này là các yêu cầu HTTP bình thường. Nó không thể cho bạn biết liệu hai yêu cầu đó có thuộc về các phiên MCP khác nhau hay không, hay phương thức khởi tạo đã được gọi hai lần thay vì một lần.

mcpr phân tích cú pháp MCP JSON-RPC ở cấp độ giao thức. Nó hiểu ý nghĩa của initialize, theo dõi ID phiên, nhóm các lần gọi công cụ theo phiên và đo độ trễ cho từng công cụ. Đó là lý do tại sao một mô hình như thế này hiện lên trên bảng điều khiển thay vì bị ẩn trong các nhật ký HTTP thô.

Nếu bạn đang vận hành các máy chủ MCP trong môi trường sản xuất (production), loại khả năng hiển thị cấp độ giao thức này sẽ giúp bạn hiểu không chỉ máy chủ của bạn đang làm gì, mà còn là các máy khách khác nhau đang sử dụng nó như thế nào.

Lời khuyên cốt lõi

ChatGPT và Claude có các mô hình phiên MCP về cơ bản là khác nhau. ChatGPT coi các phiên là "dùng một lần" — một lần gọi công cụ, một phiên. Claude coi chúng là "liên tục" — khởi tạo một lần, gọi nhiều lần.

Hãy thiết kế theo mô hình "dùng một lần". Máy chủ của bạn sẽ hoạt động tốt trên cả hai nền tảng.


mcpr là một proxy MCP mã nguồn mở (giấy phép Apache 2.0). Bạn có thể truy cập bảng điều khiển đám mây tại cloud.mcpr.app.

Bài viết được tổng hợp và biên soạn bằng AI từ các nguồn tin tức công nghệ. Nội dung mang tính tham khảo. Xem bài gốc ↗