# Мулти-модална интеграция Мулти-модалните приложения стават все по-важни в изкуствения интелект, позволявайки по-богати взаимодействия и по-сложни задачи. Model Context Protocol (MCP) предоставя рамка за създаване на мулти-модални приложения, които могат да обработват различни типове данни, като текст, изображения и аудио. MCP поддържа не само текстови взаимодействия, но и мулти-модални възможности, позволявайки на моделите да работят с изображения, аудио и други типове данни. ## Въведение В този урок ще научите как да създадете мулти-модално приложение. ## Учебни цели Към края на този урок ще можете да: - Разбирате мулти-модалните възможности - Имплементирате мулти-модално приложение. ## Архитектура за мулти-модална поддръжка Мулти-модалните реализации на MCP обикновено включват: - **Парсъри, специфични за модалността**: Компоненти, които преобразуват различни типове медия във формати, които моделът може да обработва. - **Инструменти, специфични за модалността**: Специални инструменти, предназначени за работа с конкретни модалности (анализ на изображения, обработка на аудио) - **Унифицирано управление на контекста**: Система за поддържане на контекст през различните модалности - **Генериране на отговори**: Възможност за създаване на отговори, които могат да включват няколко модалности. ## Мулти-модален пример: Анализ на изображение В следващия пример ще анализираме изображение и ще извлечем информация. ### Имплементация на C# ```csharp using ModelContextProtocol.SDK.Server; using ModelContextProtocol.SDK.Server.Tools; using ModelContextProtocol.SDK.Server.Content; using System.Text.Json; using System.IO; using System.Threading.Tasks; using System.Collections.Generic; namespace MultiModalMcpExample { // Tool for image analysis public class ImageAnalysisTool : ITool { private readonly IImageAnalysisService _imageService; public ImageAnalysisTool(IImageAnalysisService imageService) { _imageService = imageService; } public string Name => "imageAnalysis"; public string Description => "Analyzes image content and extracts information"; public ToolDefinition GetDefinition() { return new ToolDefinition { Name = Name, Description = Description, Parameters = new Dictionary { ["imageUrl"] = new ParameterDefinition { Type = ParameterType.String, Description = "URL to the image to analyze" }, ["analysisType"] = new ParameterDefinition { Type = ParameterType.String, Description = "Type of analysis to perform", Enum = new[] { "general", "objects", "text", "faces" }, Default = "general" } }, Required = new[] { "imageUrl" } }; } public async Task ExecuteAsync(IDictionary parameters) { // Extract parameters string imageUrl = parameters["imageUrl"].ToString(); string analysisType = parameters.ContainsKey("analysisType") ? parameters["analysisType"].ToString() : "general"; // Download or access the image byte[] imageData = await DownloadImageAsync(imageUrl); // Analyze based on the requested analysis type var analysisResult = analysisType switch { "objects" => await _imageService.DetectObjectsAsync(imageData), "text" => await _imageService.RecognizeTextAsync(imageData), "faces" => await _imageService.DetectFacesAsync(imageData), _ => await _imageService.AnalyzeGeneralAsync(imageData) // Default general analysis }; // Return structured result as a ToolResponse // Format follows the MCP specification for content structure var content = new List { new ContentItem { Type = ContentType.Text, Text = JsonSerializer.Serialize(analysisResult) } }; return new ToolResponse { Content = content, IsError = false }; } private async Task DownloadImageAsync(string url) { using var httpClient = new HttpClient(); return await httpClient.GetByteArrayAsync(url); } } // Multi-modal MCP server with image and text processing public class MultiModalMcpServer { public static async Task Main(string[] args) { // Create an MCP server var server = new McpServer( name: "Multi-Modal MCP Server", version: "1.0.0" ); // Configure server for multi-modal support var serverOptions = new McpServerOptions { MaxRequestSize = 10 * 1024 * 1024, // 10MB for larger payloads like images SupportedContentTypes = new[] { "image/jpeg", "image/png", "text/plain", "application/json" } }; // Create image analysis service var imageService = new ComputerVisionService(); // Register image analysis tools server.AddTool(new ImageAnalysisTool(imageService)); // Register a text-to-image tool services.AddMcpTool(); services.AddMcpTool(); services.AddMcpTool(); // Tool that can generate documents with text and images } } } ``` В предишния пример ние: - Създадохме `ImageAnalysisTool`, който може да анализира изображения, използвайки хипотетичен `IImageAnalysisService`. - Конфигурирахме MCP сървъра да обработва по-големи заявки и да поддържа типове съдържание за изображения. - Регистрирахме инструмента за анализ на изображения в сървъра. - Имплементирахме метод за изтегляне на изображения от URL и анализиране според заявения тип (обекти, текст, лица и др.). - Върнахме структурирани резултати във формат, съвместим със спецификацията на MCP. ## Мулти-модален пример: Обработка на аудио Обработката на аудио е друга често срещана модалност в мулти-модалните приложения. По-долу е пример за това как да се имплементира инструмент за транскрипция на аудио, който може да обработва аудио файлове и да връща транскрипции. ### Имплементация на Java ```java package com.example.mcp.multimodal; import com.mcp.server.McpServer; import com.mcp.tools.Tool; import com.mcp.tools.ToolRequest; import com.mcp.tools.ToolResponse; import com.mcp.tools.ToolExecutionException; import com.example.audio.AudioProcessor; import java.util.Base64; import java.util.HashMap; import java.util.Map; // Audio transcription tool public class AudioTranscriptionTool implements Tool { private final AudioProcessor audioProcessor; public AudioTranscriptionTool(AudioProcessor audioProcessor) { this.audioProcessor = audioProcessor; } @Override public String getName() { return "audioTranscription"; } @Override public String getDescription() { return "Transcribes speech from audio files to text"; } @Override public Object getSchema() { Map schema = new HashMap<>(); schema.put("type", "object"); Map properties = new HashMap<>(); Map audioUrl = new HashMap<>(); audioUrl.put("type", "string"); audioUrl.put("description", "URL to the audio file to transcribe"); Map audioData = new HashMap<>(); audioData.put("type", "string"); audioData.put("description", "Base64-encoded audio data (alternative to URL)"); Map language = new HashMap<>(); language.put("type", "string"); language.put("description", "Language code (e.g., 'en-US', 'es-ES')"); language.put("default", "en-US"); properties.put("audioUrl", audioUrl); properties.put("audioData", audioData); properties.put("language", language); schema.put("properties", properties); schema.put("required", Arrays.asList("audioUrl")); return schema; } @Override public ToolResponse execute(ToolRequest request) { try { byte[] audioData; String language = request.getParameters().has("language") ? request.getParameters().get("language").asText() : "en-US"; // Get audio either from URL or direct data if (request.getParameters().has("audioUrl")) { String audioUrl = request.getParameters().get("audioUrl").asText(); audioData = downloadAudio(audioUrl); } else if (request.getParameters().has("audioData")) { String base64Audio = request.getParameters().get("audioData").asText(); audioData = Base64.getDecoder().decode(base64Audio); } else { throw new ToolExecutionException("Either audioUrl or audioData must be provided"); } // Process audio and transcribe Map transcriptionResult = audioProcessor.transcribe(audioData, language); // Return transcription result return new ToolResponse.Builder() .setResult(transcriptionResult) .build(); } catch (Exception ex) { throw new ToolExecutionException("Audio transcription failed: " + ex.getMessage(), ex); } } private byte[] downloadAudio(String url) { // Implementation for downloading audio from URL // ... return new byte[0]; // Placeholder } } // Main application with audio and other modalities public class MultiModalApplication { public static void main(String[] args) { // Configure services AudioProcessor audioProcessor = new AudioProcessor(); ImageProcessor imageProcessor = new ImageProcessor(); // Create and configure server McpServer server = new McpServer.Builder() .setName("Multi-Modal MCP Server") .setVersion("1.0.0") .setPort(5000) .setMaxRequestSize(20 * 1024 * 1024) // 20MB for audio/video content .build(); // Register multi-modal tools server.registerTool(new AudioTranscriptionTool(audioProcessor)); server.registerTool(new ImageAnalysisTool(imageProcessor)); server.registerTool(new VideoProcessingTool()); // Start server server.start(); System.out.println("Multi-Modal MCP Server started on port 5000"); } } ``` В предишния пример ние: - Създадохме `AudioTranscriptionTool`, който може да транскрибира аудио файлове. - Дефинирахме схемата на инструмента да приема или URL, или аудио данни, кодирани в base64. - Имплементирахме метода `execute` за обработка на аудио и транскрипция. - Конфигурирахме MCP сървъра да обработва мулти-модални заявки, включително аудио и обработка на изображения. - Регистрирахме инструмента за транскрипция на аудио в сървъра. - Имплементирахме метод за изтегляне на аудио файлове от URL или декодиране на base64 аудио данни. - Използвахме услуга `AudioProcessor` за реалната логика на транскрипция. - Стартирахме MCP сървъра да слуша за заявки. ### Мулти-модален пример: Генериране на мулти-модален отговор ### Имплементация на Python ```python from mcp_server import McpServer from mcp_tools import Tool, ToolRequest, ToolResponse, ToolExecutionException import base64 from PIL import Image import io import requests import json from typing import Dict, Any, List, Optional # Image generation tool class ImageGenerationTool(Tool): def get_name(self): return "imageGeneration" def get_description(self): return "Generates images based on text descriptions" def get_schema(self): return { "type": "object", "properties": { "prompt": { "type": "string", "description": "Text description of the image to generate" }, "style": { "type": "string", "enum": ["realistic", "artistic", "cartoon", "sketch"], "default": "realistic" }, "width": { "type": "integer", "default": 512 }, "height": { "type": "integer", "default": 512 } }, "required": ["prompt"] } async def execute_async(self, request: ToolRequest) -> ToolResponse: try: # Extract parameters prompt = request.parameters.get("prompt") style = request.parameters.get("style", "realistic") width = request.parameters.get("width", 512) height = request.parameters.get("height", 512) # Generate image using external service (example implementation) image_data = await self._generate_image(prompt, style, width, height) # Convert image to base64 for response buffered = io.BytesIO() image_data.save(buffered, format="PNG") img_str = base64.b64encode(buffered.getvalue()).decode() # Return result with both the image and metadata return ToolResponse( result={ "imageBase64": img_str, "format": "image/png", "width": width, "height": height, "generationPrompt": prompt, "style": style } ) except Exception as e: raise ToolExecutionException(f"Image generation failed: {str(e)}") async def _generate_image(self, prompt: str, style: str, width: int, height: int) -> Image.Image: """ This would call an actual image generation API Simplified placeholder implementation """ # Return a placeholder image or call actual image generation API # For this example, we'll create a simple colored image image = Image.new('RGB', (width, height), color=(73, 109, 137)) return image # Multi-modal response handler class MultiModalResponseHandler: """Handler for creating responses that combine text, images, and other modalities""" def __init__(self, mcp_client): self.client = mcp_client async def create_multi_modal_response(self, text_content: str, generate_images: bool = False, image_prompts: Optional[List[str]] = None) -> Dict[str, Any]: """ Creates a response that may include generated images alongside text """ response = { "text": text_content, "images": [] } # Generate images if requested if generate_images and image_prompts: for prompt in image_prompts: image_result = await self.client.execute_tool( "imageGeneration", { "prompt": prompt, "style": "realistic", "width": 512, "height": 512 } ) response["images"].append({ "imageData": image_result.result["imageBase64"], "format": image_result.result["format"], "prompt": prompt }) return response # Main application async def main(): # Create server server = McpServer( name="Multi-Modal MCP Server", version="1.0.0", port=5000 ) # Register multi-modal tools server.register_tool(ImageGenerationTool()) server.register_tool(AudioAnalysisTool()) server.register_tool(VideoFrameExtractionTool()) # Start server await server.start() print("Multi-Modal MCP Server running on port 5000") if __name__ == "__main__": import asyncio asyncio.run(main()) ``` ## Какво следва - [5.3 Oauth 2](../mcp-oauth2-demo/README.md) **Отказ от отговорност**: Този документ е преведен с помощта на AI преводаческа услуга [Co-op Translator](https://github.com/Azure/co-op-translator). Въпреки че се стремим към точност, моля, имайте предвид, че автоматизираните преводи могат да съдържат грешки или неточности. Оригиналният документ на неговия роден език трябва да се счита за авторитетен източник. За критична информация се препоръчва професионален човешки превод. Ние не носим отговорност за каквито и да е недоразумения или неправилни тълкувания, произтичащи от използването на този превод.