FastMCP进度报告:实时反馈与用户体验优化

FastMCP进度报告:实时反馈与用户体验优化

【免费下载链接】fastmcp The fast, Pythonic way to build Model Context Protocol servers 🚀 【免费下载链接】fastmcp 项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp

在FastMCP开发过程中,进度报告功能扮演着至关重要的角色,它能够让用户实时了解长时间运行操作的状态,极大地提升了用户体验。本文将详细介绍FastMCP中进度报告功能的实现方式、使用方法以及用户体验优化策略。

进度报告功能概述

FastMCP的进度报告功能允许服务器在长时间运行的操作过程中向客户端发送进度更新。这一功能通过MCP上下文(Context)实现,能够为用户提供直观的操作进度反馈,有效减少用户等待时的不确定性。

官方文档中对进度报告功能的详细描述可参考:docs/servers/progress.mdx

服务器端进度报告实现

在服务器端,我们可以通过ctx.report_progress()方法来实现进度报告功能。下面是一个基本的使用示例:

from fastmcp import FastMCP, Context
import asyncio

mcp = FastMCP("ProgressDemo")

@mcp.tool
async def process_items(items: list[str], ctx: Context) -> dict:
    """Process a list of items with progress updates."""
    total = len(items)
    results = []
    
    for i, item in enumerate(items):
        # Report progress as we process each item
        await ctx.report_progress(progress=i, total=total)
        
        # Simulate processing time
        await asyncio.sleep(0.1)
        results.append(item.upper())
    
    # Report 100% completion
    await ctx.report_progress(progress=total, total=total)
    
    return {"processed": len(results), "results": results}

ctx.report_progress()方法的参数说明:

  • progress: 当前进度值(例如:24, 0.75, 1500)
  • total: 可选的总值(例如:100, 1.0, 2000)。提供此参数时,客户端可以计算进度百分比。

根据不同的应用场景,我们可以采用不同的进度报告模式:

基于百分比的进度报告

适用于已知操作总量的场景,进度值范围通常为0-100:

@mcp.tool
async def download_file(url: str, ctx: Context) -> str:
    """Download a file with percentage progress."""
    total_size = 1000  # KB
    downloaded = 0
    
    while downloaded < total_size:
        # Download chunk
        chunk_size = min(50, total_size - downloaded)
        downloaded += chunk_size
        
        # Report percentage progress
        percentage = (downloaded / total_size) * 100
        await ctx.report_progress(progress=percentage, total=100)
        
        await asyncio.sleep(0.1)  # Simulate download time
    
    return f"Downloaded file from {url}"

绝对进度报告

适用于可以明确量化进度的场景:

@mcp.tool
async def backup_database(ctx: Context) -> str:
    """Backup database tables with absolute progress."""
    tables = ["users", "orders", "products", "inventory", "logs"]
    
    for i, table in enumerate(tables):
        await ctx.info(f"Backing up table: {table}")
        
        # Report absolute progress
        await ctx.report_progress(progress=i + 1, total=len(tables))
        
        # Simulate backup time
        await asyncio.sleep(0.5)
    
    return "Database backup completed"

不确定进度报告

适用于无法预知操作总量的场景:

@mcp.tool
async def scan_directory(directory: str, ctx: Context) -> dict:
    """Scan directory with indeterminate progress."""
    files_found = 0
    
    # Simulate directory scanning
    for i in range(10):  # Unknown number of files
        files_found += 1
        
        # Report progress without total for indeterminate operations
        await ctx.report_progress(progress=files_found)
        
        await asyncio.sleep(0.2)
    
    return {"files_found": files_found, "directory": directory}

多阶段操作进度报告

对于复杂的多步骤操作,可以分阶段报告进度:

@mcp.tool
async def data_migration(source: str, destination: str, ctx: Context) -> str:
    """Migrate data with multi-stage progress reporting."""
    
    # Stage 1: Validation (0-25%)
    await ctx.info("Validating source data")
    for i in range(5):
        await ctx.report_progress(progress=i * 5, total=100)
        await asyncio.sleep(0.1)
    
    # Stage 2: Export (25-60%)
    await ctx.info("Exporting data from source")
    for i in range(7):
        progress = 25 + (i * 5)
        await ctx.report_progress(progress=progress, total=100)
        await asyncio.sleep(0.1)
    
    # Stage 3: Transform (60-80%)
    await ctx.info("Transforming data format")
    for i in range(4):
        progress = 60 + (i * 5)
        await ctx.report_progress(progress=progress, total=100)
        await asyncio.sleep(0.1)
    
    # Stage 4: Import (80-100%)
    await ctx.info("Importing to destination")
    for i in range(4):
        progress = 80 + (i * 5)
        await ctx.report_progress(progress=progress, total=100)
        await asyncio.sleep(0.1)
    
    # Final completion
    await ctx.report_progress(progress=100, total=100)
    
    return f"Migration from {source} to {destination} completed"

客户端进度处理

客户端需要设置进度处理器来接收和处理服务器发送的进度更新。以下是客户端实现进度处理的示例代码:

from fastmcp import Client

async def my_progress_handler(
    progress: float, 
    total: float | None, 
    message: str | None
) -> None:
    if total is not None:
        percentage = (progress / total) * 100
        print(f"Progress: {percentage:.1f}% - {message or ''}")
    else:
        print(f"Progress: {progress} - {message or ''}")

client = Client(
    "my_mcp_server.py",
    progress_handler=my_progress_handler
)

客户端进度处理的详细说明可参考:docs/clients/progress.mdx

此外,客户端还可以为特定的工具调用单独设置进度处理器:

async with client:
    # Override with specific progress handler for this call
    result = await client.call_tool(
        "long_running_task", 
        {"param": "value"}, 
        progress_handler=my_progress_handler
    )

用户体验优化策略

为了进一步提升用户体验,我们可以结合进度报告功能实施以下优化策略:

1. 提供有意义的进度信息

不仅仅报告进度数值,还应提供描述性消息,帮助用户了解当前正在执行的操作阶段。例如:

await ctx.report_progress(progress=30, total=100, message="正在分析数据")

2. 进度可视化

在客户端实现直观的进度条展示,而不仅仅是文本输出。可以使用进度条库如tqdm来美化进度展示:

from tqdm import tqdm
import asyncio

async def visual_progress_handler(progress: float, total: float | None, message: str | None):
    if total is not None:
        pbar = tqdm(total=total, desc=message or "Processing")
        pbar.update(progress - pbar.n)
        if progress >= total:
            pbar.close()

3. 预估剩余时间

根据已用时间和当前进度,估算剩余完成时间并展示给用户。这需要客户端记录进度更新的时间戳,然后通过简单的计算来预估剩余时间。

4. 错误处理与恢复提示

当操作出现异常或进度停滞时,提供友好的错误提示和可能的恢复建议。这可以通过结合ctx.report_progress()ctx.error()方法实现。

实际应用示例

以下是一个综合运用进度报告功能的实际示例,展示了如何在数据处理应用中实现良好的用户体验:

@mcp.tool
async def analyze_large_dataset(file_path: str, ctx: Context) -> dict:
    """Analyze a large dataset with detailed progress reporting."""
    total_steps = 5
    
    # Step 1: Loading data (0-20%)
    await ctx.report_progress(progress=1, total=total_steps, message="Loading dataset")
    await asyncio.sleep(1)  # Simulate loading
    
    # Step 2: Cleaning data (20-40%)
    await ctx.report_progress(progress=2, total=total_steps, message="Cleaning data")
    await asyncio.sleep(1.5)  # Simulate cleaning
    
    # Step 3: Analyzing trends (40-70%)
    await ctx.report_progress(progress=3, total=total_steps, message="Analyzing trends")
    await asyncio.sleep(2)  # Simulate analysis
    
    # Step 4: Generating visualizations (70-90%)
    await ctx.report_progress(progress=4, total=total_steps, message="Generating visualizations")
    await asyncio.sleep(1.5)  # Simulate visualization
    
    # Step 5: Compiling report (90-100%)
    await ctx.report_progress(progress=5, total=total_steps, message="Compiling final report")
    await asyncio.sleep(1)  # Simulate report generation
    
    return {
        "status": "completed",
        "insights": 12,
        "visualizations": 4,
        "recommendations": 3
    }

这个示例展示了一个数据处理工具,它将整个操作分为5个明确的步骤,并为每个步骤提供了清晰的进度更新和状态消息。

总结与展望

FastMCP的进度报告功能为长时间运行的操作提供了有效的实时反馈机制,显著提升了用户体验。通过灵活运用ctx.report_progress()方法和客户端进度处理器,开发者可以构建出交互友好的MCP应用。

未来,我们计划进一步增强进度报告功能,包括:

  1. 支持更丰富的进度元数据,如操作预估时间
  2. 提供内置的进度可视化组件
  3. 增强进度报告的可靠性,支持断点续传场景
  4. 实现跨设备的进度同步

通过不断优化进度报告和用户体验,FastMCP将继续为开发者提供更友好、更强大的MCP服务器构建工具。

更多关于FastMCP的使用和开发指南,请参考项目的官方文档和示例代码:

【免费下载链接】fastmcp The fast, Pythonic way to build Model Context Protocol servers 🚀 【免费下载链接】fastmcp 项目地址: https://gitcode.com/GitHub_Trending/fa/fastmcp

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值