Computer >> Hướng Dẫn Máy Tính >  >> Lập Trình >> Redis

Tăng tốc phát triển MCP với Redis:Giải pháp nhanh chóng, tiết kiệm chi phí

Giao thức bối cảnh mô hình (MCP) đang nhanh chóng trở thành cách tiêu chuẩn để kết nối các mô hình AI với các công cụ và nguồn dữ liệu bên ngoài. Khi việc áp dụng MCP ngày càng phát triển, các nhà phát triển khám phá ra rằng việc xây dựng các triển khai MCP mạnh mẽ, sẵn sàng sản xuất đòi hỏi nhiều thứ hơn là chỉ tuân theo thông số kỹ thuật:Nó đòi hỏi cơ sở hạ tầng phù hợp. Trong bài đăng này, chúng ta sẽ khám phá cách Redis hỗ trợ ba trường hợp sử dụng MCP khác nhau:điều phối các chức năng serverless phân tán trong quá trình triển khai SSE của Vercel, cho phép tiếp tục sự kiện đối với các luồng chạy dài và quản lý luồng OAuth an toàn với Clerk.

Tìm hiểu về truyền tải MCP

Trước khi đi sâu vào các ví dụ của chúng tôi, hãy trình bày ngắn gọn cách MCP xử lý giao tiếp. MCP hỗ trợ hai phương tiện truyền tải:Stdio dành cho máy chủ cục bộ và HTTP có thể phát trực tuyến cho các máy chủ từ xa. Trước đây, cũng có phương thức truyền tải SSE (Sự kiện do máy chủ gửi) dành cho các máy chủ từ xa, hiện không còn được dùng nữa.

Quá trình chuyển đổi từ SSE sang HTTP có thể phát trực tuyến thể hiện sự phát triển trong cách MCP xử lý giao tiếp theo thời gian thực, nhưng nhiều triển khai hiện có vẫn dựa vào mẫu SSE. Hãy xem Redis đã giúp giải quyết một trong những thách thức chính trong mô hình đó như thế nào.

Trường hợp sử dụng 1:SSE với Redis Pub/Sub

Khi Vercel CTO Malte xây dựng trình xử lý MCP của họ, anh ấy đã phải đối mặt với một thách thức kinh điển về serverless:làm cách nào để phối hợp giữa nhiều điểm cuối khi mỗi yêu cầu có thể được xử lý bởi một chức năng serverless khác nhau?

Trong mô hình truyền tải SSE, có hai điểm cuối quan trọng:/sse để duy trì kết nối và /message để nhận tin nhắn của khách hàng. Đây là vấn đề:trong môi trường không có máy chủ như Vercel, các điểm cuối này hoàn toàn bị cô lập. Họ không chia sẻ bộ nhớ và yêu cầu /message có thể được xử lý bởi một phiên bản hàm hoàn toàn khác với phiên bản xử lý /sse .

Giải pháp? Redis Pub/Sub. Như Malte đã giải thích trên X:

Tăng tốc phát triển MCP với Redis:Giải pháp nhanh chóng, tiết kiệm chi phí

Việc triển khai sử dụng các kênh Redis để phối hợp giữa các điểm cuối. Khi khách hàng gửi tin nhắn tới /message , điểm cuối đó xuất bản lên kênh Redis mà /sse điểm cuối được đăng ký. /sse điểm cuối xử lý yêu cầu và xuất bản phản hồi trở lại thông qua một kênh khác /message đang nghe.

Tăng tốc phát triển MCP với Redis:Giải pháp nhanh chóng, tiết kiệm chi phí

Mẫu này biến Redis thành một bus thông báo một cách hiệu quả, giúp thu hẹp khoảng cách giữa các chức năng không có máy chủ bị cô lập, cho phép chúng hoạt động cùng nhau như thể chúng là một phần của cùng một quy trình. Mặc dù SSE hiện không còn được dùng nữa để thay thế cho HTTP có thể phát trực tuyến (có nghĩa là việc triển khai MCP mới nên sử dụng phương tiện truyền tải hiện đại), nhưng đây vẫn là một ví dụ tuyệt vời về việc sử dụng Redis để phối hợp giữa các chức năng không có máy chủ bị cô lập.

Trường hợp sử dụng 2:Lưu trữ sự kiện để có thể tiếp tục

Một trong những tính năng mạnh mẽ nhất của truyền tải HTTP có thể phát trực tuyến của MCP là hỗ trợ khả năng tiếp tục. Tính năng này cho phép khách hàng tiếp tục phát trực tuyến từ nơi nó đã dừng lại trong trường hợp bị ngắt kết nối. Điều này rất quan trọng đối với các ứng dụng sản xuất mà việc gián đoạn mạng là không thể tránh khỏi.

Tìm hiểu luồng MCP

Để hiểu tại sao khả năng nối lại lại quan trọng, chúng ta cần hiểu luồng MCP bao gồm những gì. Một số thao tác, như gọi một công cụ đơn giản, trả về một phản hồi duy nhất. Tuy nhiên, các công cụ cũng có thể trả về nhiều sự kiện trong quá trình thực thi bằng các phương thức như server.sendLoggingMessage. Những luồng nhiều sự kiện này là nơi khả năng tiếp tục trở nên quan trọng. Nếu khách hàng ngắt kết nối giữa chừng, khách hàng có thể tiếp tục từ nơi đã dừng thay vì bắt đầu lại.

Triển khai EventStore bằng Redis

SDK MCP xác định giao diện EventStore yêu cầu hai phương thức:storeEvent để thêm sự kiện và replayEventsAfter để truy xuất các sự kiện bắt đầu từ một ID sự kiện cụ thể. SDK bao gồm việc triển khai trong bộ nhớ, nhưng để sử dụng trong sản xuất, bạn cần có bộ nhớ liên tục.

Đây là cách triển khai EventStore dựa trên Redis:

import { Redis } from '@upstash/redis';
import { JSONRPCMessage } from '@modelcontextprotocol/sdk/types.js';
import { EventStore } from '@modelcontextprotocol/sdk/server/streamableHttp.js';
 
export class RedisEventStore implements EventStore {
 private redis: Redis;
 
 constructor(params: ConstructorParameters<typeof Redis>[0]) {
 this.redis = new Redis(params);
 }
 
 /**
 * Stores an event in a Redis Stream
 * Implements EventStore.storeEvent
 */
 async storeEvent(streamId: string, message: JSONRPCMessage): Promise<string> {
 const eventId = await this.redis.xadd(`stream:${streamId}`, '*', {
 message: JSON.stringify(message),
 });
 return eventId;
 }
 
 /**
 * Replays events that occurred after a specific event ID
 * Implements EventStore.replayEventsAfter
 */
 async replayEventsAfter(
 lastEventId: string,
 { send }: { send: (eventId: string, message: JSONRPCMessage) => Promise<void> }
 ): Promise<string> {
 if (!lastEventId) {
 return '';
 }
 
 // Extract the stream ID from the lastEventId
 const streamId = lastEventId.split('-')[0]; // Assuming the stream ID is part of the key
 if (!streamId) {
 return '';
 }
 
 let nextId = lastEventId;
 while (true) {
 // Fetch events from the stream starting AFTER the next ID (exclusive)
 const events = await this.redis.xrange(`stream:${streamId}`, `(${nextId}`, '+', 10);
 
 // Convert the returned object to an array of entries
 const eventEntries = Object.entries(events);
 
 if (eventEntries.length === 0) {
 break; // No more events to replay
 }
 
 for (const [eventId, fields] of eventEntries) {
 // Ensure fields.message exists and parse it
 if (fields && typeof fields === 'object' && 'message' in fields && typeof fields.message === 'string') {
 const message = JSON.parse(fields.message) as JSONRPCMessage;
 await send(eventId, message);
 nextId = eventId; // Update the next ID to the current event ID
 }
 }
 }
 
 return streamId;
 }
}

Việc triển khai này sử dụng Luồng Redis, luồng này hoàn hảo cho trường hợp sử dụng này.

Một hạn chế

Có một lưu ý quan trọng cần lưu ý:khi một công cụ gửi nhiều sự kiện, StreamId được đặt thành _GET_stream và hằng số này vẫn giữ nguyên trên các luồng và người dùng khác nhau. Điều này có nghĩa là nếu hai người dùng đồng thời sử dụng cùng một công cụ gửi nhiều sự kiện thì các sự kiện của họ có thể bị trộn lẫn trong cùng một luồng.

Tôi đã mở một vấn đề về vấn đề này trên kho lưu trữ chính thức. Tùy thuộc vào độ phân giải, chúng tôi có thể cần điều chỉnh cách triển khai và tôi sẽ cập nhật bài đăng này nếu cần.

Trường hợp sử dụng 3:Triển khai MCP OAuth của Thư ký

Đặc tả MCP bao gồm hỗ trợ xác thực và ủy quyền, cho phép máy chủ MCP xác thực khách hàng một cách an toàn và kiểm soát quyền truy cập vào tài nguyên. Thông số kỹ thuật này hỗ trợ nhiều sơ đồ xác thực, bao gồm OAuth 2.0, đặc biệt hữu ích để tích hợp với các nhà cung cấp danh tính hiện có và cho phép người dùng truy cập vào các công cụ và dữ liệu trong phạm vi người dùng.

Clerk đã xây dựng ứng dụng khách OAuth toàn diện cho MCP bằng cách triển khai giao diện OAuthClientProvider từ MCP SDK. Việc triển khai chúng thể hiện một trường hợp sử dụng quan trọng khác đối với Redis trong các ứng dụng MCP. Nếu bạn muốn bắt đầu với các công cụ MCP của họ, hãy xem kho lưu trữ demo của họ để có điểm khởi đầu tuyệt vời.

Tại sao bộ nhớ lại quan trọng đối với OAuth

Như Thư ký giải thích trong mcp-tools của họ kho lưu trữ, việc lưu trữ liên tục là điều cần thiết để triển khai MCP OAuth vì hai lý do chính:

  1. Luồng OAuth trải rộng trên nhiều điểm cuối - tất cả các yêu cầu khởi tạo, gọi lại OAuth và MCP đều có thể được xử lý bằng các chức năng serverless khác nhau mà không cần bộ nhớ dùng chung
  2. Kết nối MCP hoạt động lâu dài - việc dựa vào bộ nhớ trong bộ nhớ sẽ làm tăng yêu cầu về bộ nhớ khi ứng dụng mở rộng quy mô và bất kỳ lần khởi động lại máy chủ nào cũng sẽ làm mất hiệu lực tất cả các phiên

Những gì được lưu trữ trong Redis

Cửa hàng Redis của Clerk quản lý ba loại dữ liệu, mỗi loại có mục đích cụ thể trong luồng OAuth:

Người xác minh PKCE (pkce_verifier_<...> )Chúng được lưu trữ khi bắt đầu luồng OAuth và đọc lại sau khi người dùng cấp quyền truy cập. Chúng là một phần của luồng PKCE (Khóa chứng minh cho trao đổi mã), cung cấp bảo mật bổ sung cho OAuth trong các máy khách công cộng bằng cách đảm bảo ứng dụng đã bắt đầu luồng cũng chính là ứng dụng hoàn thành luồng đó (như được định nghĩa trong RFC 7636).

{
 "value": "XoYQ...",
 "created_at": "2025-10-03T06:27:06.928Z",
 "updated_at": "2025-10-03T06:27:06.928Z"
}

Dữ liệu phiên (session_<...> )Điều này lưu trữ tất cả cấu hình và trạng thái cho phiên MCP. Ban đầu, nó chứa điểm cuối MCP, cấu hình OAuth và thông tin xác thực ứng dụng khách. Sau khi người dùng cấp quyền truy cập, nó sẽ được cập nhật với mã thông báo truy cập và làm mới. Cuối cùng là authComplete cờ được thêm vào khi luồng kết thúc.

{
 "value": {
 "mcpEndpoint": "http://localhost:3001/mcp",
 "oauthRedirectUrl": "http://localhost:3000/oauth_callback",
 "oauthScopes": "openid profile email",
 "mcpClientName": "Clerk MCP Demo",
 "mcpClientVersion": "0.0.1",
 "oauthClientUri": "http://example.com",
 "oauthPublicClient": false,
 "clientId": "8Yb2...",
 "clientSecret": "64YG..."
 },
 "created_at": "2025-10-03T06:27:06.882Z",
 "updated_at": "2025-10-03T06:27:06.882Z"
}

Thông số trạng thái (state_<...> )Các tham số trạng thái OAuth này ánh xạ tới ID phiên, giúp có thể lấy dữ liệu phiên bằng ID trạng thái:

{
 "value": "dX61...",
 "created_at": "2025-10-03T06:27:03.585Z",
 "updated_at": "2025-10-03T06:27:03.585Z"
}

Kiến trúc này cho phép luồng OAuth hoạt động liền mạch trên các chức năng phi máy chủ phân tán trong khi vẫn duy trì tính bảo mật và tính toàn vẹn của phiên.

Tại sao Redis lại hoàn hảo cho MCP

Qua cả ba ví dụ, chúng tôi thấy các mô hình chung khiến Redis trở thành lựa chọn lý tưởng cho cơ sở hạ tầng MCP:

Độ trễ thấp :Hoạt động MCP thường cần phải nhanh chóng. Kiến trúc trong bộ nhớ của Redis cung cấp thời gian phản hồi cần thiết cho các tương tác AI trong thời gian thực.

Khả năng xuất bản/phụ :Như chúng ta đã thấy với cách triển khai của Vercel, Redis Pub/Sub cho phép phối hợp tinh tế giữa các thành phần được phân phối mà không có sự phức tạp của hàng đợi tin nhắn đầy đủ.

Cấu trúc dữ liệu phong phú :Luồng cho luồng sự kiện, Băm cho dữ liệu phiên và các cặp khóa-giá trị đơn giản cho trạng thái. Redis cung cấp cấu trúc dữ liệu phù hợp cho từng trường hợp sử dụng.

Hết hạn tích hợp :Tự động dọn dẹp thông qua TTL. Mã thông báo OAuth, luồng sự kiện và dữ liệu phiên đều có thể tự động hết hạn mà không cần thu thập rác thủ công.

Thân thiện với máy chủ :Với các giải pháp như Upstash Redis, bạn sẽ có được Redis không máy chủ, được quản lý hoàn toàn và có tỷ lệ về 0 khi không sử dụng. Hoàn hảo cho việc triển khai MCP có thể có khối lượng công việc thay đổi.

Ngoài các tính năng thông số MCP:Redis trong hệ sinh thái AI rộng hơn

Mặc dù chúng tôi tập trung vào các tính năng được xác định rõ ràng trong đặc tả MCP, tiện ích của Redis vượt xa các mẫu mà chúng tôi đã khám phá khi nói đến việc hỗ trợ AI. Các bài đăng trên blog gần đây của chúng tôi giới thiệu một số mẫu sau:

  • Tích hợp SDK AI - Sử dụng Redis để nâng cao Vercel AI SDK
  • Lịch sử trò chuyện - Lịch sử nhắn tin liên tục

Ngoài các ví dụ của chúng tôi, cộng đồng đã xây dựng các công cụ ấn tượng được hỗ trợ bởi Redis cho các ứng dụng AI. Bộ công cụ ai-sdk của Midday bao gồm gói bộ nhớ đệm kết quả công cụ sử dụng Redis để lưu vào bộ nhớ đệm các kết quả của công cụ SDK AI, như trong ví dụ này, cải thiện đáng kể hiệu suất và giảm chi phí:

Tăng tốc phát triển MCP với Redis:Giải pháp nhanh chóng, tiết kiệm chi phí

Cho dù bạn đang xây dựng máy chủ MCP, tác nhân AI hay ứng dụng AI đầy đủ, Redis đều cung cấp lớp cơ sở hạ tầng giúp hệ thống của bạn sẵn sàng sản xuất, có thể mở rộng và hoạt động hiệu quả.

Kết luận

Giao thức bối cảnh mô hình vẫn còn non trẻ nhưng nó nhanh chóng trở thành cơ sở hạ tầng thiết yếu cho các ứng dụng AI. Như chúng ta đã thấy qua ba ví dụ này, Redis đóng một vai trò quan trọng trong việc triển khai MCP một cách mạnh mẽ và sẵn sàng cho sản xuất thông qua:

  • Tốc độ và tính linh hoạt :Sự kết hợp giữa tốc độ, tính linh hoạt và kiến trúc thân thiện với máy chủ
  • Giảm chi phí :Khả năng lưu vào bộ nhớ đệm giúp giảm thiểu các lệnh gọi và tính toán API tốn kém

Nếu bạn đang xây dựng bằng MCP, dù ở phía máy chủ hay phía máy khách, Redis sẽ có trong bộ công cụ của bạn như một người bạn đồng hành hoàn hảo cho các ứng dụng AI hỗ trợ MCP. Với Upstash Redis, bạn có thể bắt đầu sau vài giây ngay hôm nay với Redis không có máy chủ, có sẵn trên toàn cầu và có tỷ lệ về 0 khi không sử dụng.