当前位置: 首页 > backend >正文

MCP案例 - 数据可视化客户端

在这里插入图片描述

#!/usr/bin/env python3
"""
MCP客户端使用示例
展示大模型如何自主调用工具完成数据可视化任务
"""import asyncio
import json
from typing import List, Dict, Anyclass MCPClient:"""MCP客户端模拟器,展示大模型的自主调用流程"""def __init__(self, server):self.server = serverasync def autonomous_data_analysis(self, user_request: str) -> Dict[str, Any]:"""模拟大模型自主完成数据分析任务的完整流程这就是Tools方式的强大之处 - 大模型可以自主决策和执行"""print(f"🤖 用户请求: {user_request}")print("🚀 大模型开始自主分析...")results = {"user_request": user_request,"workflow_steps": [],"final_output": None}try:# 步骤1: 自主获取可用数据集print("📊 步骤1: 获取可用数据集列表...")datasets_response = await self.server._list_datasets()datasets_info = json.loads(datasets_response[0].text)results["workflow_steps"].append({"step": 1,"action": "list_available_datasets","result": "获取到数据集列表","data": datasets_info})# 步骤2: 智能选择合适的数据集print("🎯 步骤2: 智能选择数据集...")if "销售" in user_request or "sales" in user_request.lower():selected_dataset = "sales"elif "用户" in user_request or "user" in user_request.lower():selected_dataset = "users"elif "股票" in user_request or "stock" in user_request.lower():selected_dataset = "stocks"else:# 默认选择第一个数据集selected_dataset = list(datasets_info["available_datasets"])[0]print(f"✅ 选择数据集: {selected_dataset}")# 步骤3: 自主获取数据print("📋 步骤3: 获取数据内容...")data_response = await self.server._get_dataset(selected_dataset, limit=10)data_info = json.loads(data_response[0].text)results["workflow_steps"].append({"step": 3,"action": "get_dataset","result": f"获取 {selected_dataset} 数据集","data": data_info})# 步骤4: 自主分析数据结构print("🔍 步骤4: 分析数据结构...")structure_response = await self.server._analyze_structure(selected_dataset)structure_info = json.loads(structure_response[0].text)results["workflow_steps"].append({"step": 4,"action": "analyze_data_structure","result": "分析完成数据结构","data": structure_info})# 步骤5: 自主确定分析目标print("🎯 步骤5: 确定分析目标...")if "趋势" in user_request or "trend" in user_request.lower():analysis_goal = "trend"elif "分布" in user_request or "distribution" in user_request.lower():analysis_goal = "distribution"elif "比较" in user_request or "comparison" in user_request.lower():analysis_goal = "comparison"elif "相关" in user_request or "correlation" in user_request.lower():analysis_goal = "correlation"else:# 根据数据特征自动选择if structure_info["column_types"]["datetime"]:analysis_goal = "trend"elif len(structure_info["column_types"]["categorical"]) > 0:analysis_goal = "comparison"else:analysis_goal = "distribution"print(f"✅ 分析目标: {analysis_goal}")# 步骤6: 获取可视化建议print("💡 步骤6: 获取可视化建议...")suggestions_response = await self.server._suggest_visualization(selected_dataset, analysis_goal)suggestions = json.loads(suggestions_response[0].text)results["workflow_steps"].append({"step": 6,"action": "suggest_visualization","result": "获取可视化建议","data": suggestions})# 步骤7: 自主选择图表类型和参数print("📈 步骤7: 创建图表...")chart_type = suggestions["recommended_charts"][0] if suggestions["recommended_charts"] else "bar"# 智能选择列columns = structure_info["basic_info"]["columns"]datetime_cols = structure_info["column_types"]["datetime"]numeric_cols = structure_info["column_types"]["numeric"]categorical_cols = structure_info["column_types"]["categorical"]x_column = Noney_column = Noneif chart_type == "line" and datetime_cols and numeric_cols:x_column = datetime_cols[0]y_column = numeric_cols[0]elif chart_type == "bar" and categorical_cols and numeric_cols:x_column = categorical_cols[0]y_column = numeric_cols[0]elif chart_type == "scatter" and len(numeric_cols) >= 2:x_column = numeric_cols[0]y_column = numeric_cols[1]elif chart_type == "pie" and categorical_cols:x_column = categorical_cols[0]# 创建图表chart_response = await self.server._create_chart(dataset_name=selected_dataset,chart_type=chart_type,x_column=x_column,y_column=y_column,title=f"{selected_dataset.title()} {analysis_goal.title()} Analysis")results["workflow_steps"].append({"step": 7,"action": "create_chart","result": f"创建 {chart_type} 图表","chart_created": True})# 步骤8: 获取数据洞察print("🔬 步骤8: 生成数据洞察...")insights_response = await self.server._get_insights(selected_dataset)insights = json.loads(insights_response[0].text)results["workflow_steps"].append({"step": 8,"action": "get_data_insights","result": "生成数据洞察","data": insights})# 生成最终报告final_report = self._generate_final_report(selected_dataset, analysis_goal, chart_type, insights)results["final_output"] = final_reportprint("✅ 自主分析完成!")return resultsexcept Exception as e:print(f"❌ 自主分析过程中出错: {str(e)}")results["error"] = str(e)return resultsdef _generate_final_report(self, dataset: str, goal: str, chart_type: str, insights: Dict) -> Dict[str, Any]:"""生成最终分析报告"""report = {"executive_summary": f"基于 {dataset} 数据集完成了 {goal} 分析,使用 {chart_type} 图表进行可视化。","key_findings": insights.get("key_findings", []),"recommendations": insights.get("recommendations", []),"methodology": ["自动识别最适合的数据集","智能分析数据结构和特征","基于分析目标选择最佳可视化方式","生成数据驱动的洞察和建议"],"next_steps": ["可以尝试不同的可视化角度","深入分析特定的数据子集","结合业务场景进行进一步解读"]}return report# 使用示例和对比演示
async def demonstrate_tools_vs_resources():"""演示Tools方式 vs Resources方式的区别"""print("=" * 60)print("🚀 MCP Tools方式 vs Resources方式对比演示")print("=" * 60)# 导入服务器(实际使用中需要正确的导入)from __main__ import DataVisualizationServer# 创建服务器和客户端server = DataVisualizationServer()client = MCPClient(server)print("\n" + "=" * 40)print("❌ Resources方式 (需要人工干预)")print("=" * 40)print("用户: 帮我用销售数据画个图")print("助手: 请先从资源列表中选择 'sales' 数据资源...")print("用户: [手动选择sales资源]")print("助手: 请选择'分析数据'提示词...")print("用户: [手动选择提示词]")print("助手: 请选择图表类型...")print("用户: [手动选择图表类型]")print("🔄 需要多次人工交互才能完成任务")print("\n" + "=" * 40)print("✅ Tools方式 (大模型自主完成)")print("=" * 40)# 演示自主完成任务user_requests = ["帮我用销售数据画个趋势图","分析用户数据的分布情况", "对比股票数据的相关性"]for i, request in enumerate(user_requests, 1):print(f"\n--- 示例 {i} ---")result = await client.autonomous_data_analysis(request)print(f"\n📊 完成的工作流程:")for step in result["workflow_steps"]:print(f"  {step['step']}. {step['action']}: {step['result']}")if result.get("final_output"):print(f"\n📋 最终报告:")print(f"  概述: {result['final_output']['executive_summary']}")print(f"  关键发现: {len(result['final_output']['key_findings'])} 项")print(f"  建议: {len(result['final_output']['recommendations'])} 项")print("\n" + "=" * 60)print("🎯 核心优势总结")print("=" * 60)advantages = {"自主性": "大模型可以自己决定使用哪些工具,无需人工干预","智能化": "根据用户需求和数据特征自动选择最佳方案","效率": "一次请求完成整个工作流程,节省时间","一致性": "每次都按照最佳实践执行分析流程","可扩展": "轻松添加新的分析功能,大模型自动学会使用"}for key, value in advantages.items():print(f"✅ {key}: {value}")# 工具设计最佳实践
class ToolDesignBestPractices:"""工具设计最佳实践指南"""@staticmethoddef demonstrate_good_vs_bad_design():"""演示好的和坏的工具设计"""print("\n" + "=" * 60)print("📚 MCP工具设计最佳实践")print("=" * 60)print("\n❌ 错误设计 - 使用Resources (大模型无法自主调用)")print("-" * 50)bad_design = '''# 错误方式:Resource (需要人工选择)server.setRequestHandler(ReadResourceRequestSchema, async (request) => {if (request.params.uri === "data://sales") {return { contents: [{ uri: request.params.uri, text: "销售数据..." }] };}});# 问题:# 1. 大模型无法自主调用# 2. 需要用户手动选择资源# 3. 工作流程被打断'''print(bad_design)print("\n✅ 正确设计 - 使用Tools (大模型可自主调用)")print("-" * 50)good_design = '''# 正确方式:Tool (模型可自主调用)server.setRequestHandler(CallToolRequestSchema, async (request) => {if (request.params.name === "get_sales_data") {return {content: [{type: "text",text: "销售数据..."}]};}});# 优势:# 1. 大模型可以自主决定何时调用# 2. 支持参数传递和条件调用# 3. 完整的自动化工作流程'''print(good_design)print("\n🎯 设计原则")print("-" * 30)principles = ["原则1: 所有需要大模型自主使用的功能都必须设计为Tools","原则2: Tools应该是原子性的,每个工具完成一个明确的任务","原则3: 提供清晰的参数描述,让大模型知道如何使用","原则4: 返回结构化数据,便于大模型进一步处理","原则5: 包含错误处理,提供有用的错误信息"]for principle in principles:print(f"  ✓ {principle}")print("\n🔧 实际应用场景")print("-" * 30)scenarios = {"数据分析": "自动获取数据 → 分析结构 → 选择可视化 → 生成图表","文档处理": "自动读取文档 → 提取关键信息 → 总结内容 → 生成报告", "代码分析": "自动扫描代码 → 识别问题 → 提供建议 → 生成修复方案","业务流程": "自动获取状态 → 执行检查 → 处理异常 → 更新结果"}for scenario, workflow in scenarios.items():print(f"  📋 {scenario}: {workflow}")# 完整的使用演示
async def complete_demo():"""完整的使用演示"""print("🚀 开始完整演示...")# 1. 展示Tools vs Resources对比await demonstrate_tools_vs_resources()# 2. 展示设计最佳实践ToolDesignBestPractices.demonstrate_good_vs_bad_design()print("\n" + "=" * 60)print("✅ 演示完成! 总结:")print("=" * 60)summary = ["1. Tools方式让大模型拥有真正的自主性","2. 用户只需要提出需求,大模型自动完成整个工作流程","3. 相比Resources和Prompts,Tools提供了更好的用户体验","4. 正确的工具设计是实现智能自动化的关键","5. 未来的AI应用应该更多地采用Tools模式"]for point in summary:print(f"  ✓ {point}")print(f"\n🎯 记住核心原则: 想让大模型自己调用,必须写成Tools!")# 主程序入口
if __name__ == "__main__":# 运行完整演示asyncio.run(complete_demo())
http://www.xdnf.cn/news/14460.html

相关文章:

  • Python基础教学:航天工程领域的精确计算和金融领域的精确计算,分别采用的小数保留位数的方法有哪些?有什么区别?-由Deepseek产生
  • 思科基本理论
  • 高标准通信,Ethercat与CANopen网关服务制药工厂生产线实际方案
  • Qt如何生成和使用DLL动态链接库
  • 大语言模型:提示词决定自我反思效果: “检查回答是否错误” “验证回答是否正确”
  • ubuntu 22.04 安装部署logstash 7.10.0详细教程
  • NGINX Plus 管理与上报模块`ngx_mgmt_module`
  • 25年泰康保险养老社招入职统一测评(心理、认知、潜质)北森真题题库、高分攻略
  • leetcode0187. 重复的DNA序列-medium
  • 用Jmeter进行接口测试
  • sql解析,日期 trunc sysdate
  • LangChain智能体之initialize_agent开发实战深度解析
  • 【完整教程】WSL发行版迁移到D盘
  • 【Block总结】NeLU(负斜率线性单元)函数|最新激活函数|独家复现|即插即用
  • 【AI论文】Saffron-1:LLM安全保证的推理缩放范例
  • Redis 6.2.6 安装教程 - 从源码编译到配置启动(Linux环境)
  • 本地访问远程vps中的sqlite数据库中的内容之(二)使用Python和web访问远程sqlite
  • 构建esp-IDF出现的(Git仓库所有权检测)问题
  • linux thermal framework(4)_thermal governor
  • 安卓9.0系统修改定制化____安卓9.0系统精简 了解系统app组件构成 系统app释义 常识篇 一
  • Leetcode 刷题记录 13 —— 图论
  • Qdrant向量数据库的增删改查
  • Java + Spring Boot 后端防抖实现方案
  • nrf52811墨水屏edp_service.c文件学习
  • YOLO优化之双池化下采样融合块、注意力引导逆残差块
  • 【学习笔记】深入理解Java虚拟机学习笔记——第6章 类文件结构
  • CppCon 2016 学习: std::accumulate EXPLORING AN ALGORITHMIC EMPIRE
  • ubuntu 22.04 安装部署elasticsearch 7.10.0详细教程
  • Linux服务器入门教程
  • React forwardRef 与 useImperativeHandle 深度解析