AIGC入门,手搓大模型客户端与MCP交互

AIGC工具系列之——基于OpenAI的GPT大模型搭建自己的AIGC工具 GPT大模型,AIGC工具教学,目前热门的AI话题 阅读详情

概述

在现代应用开发中,将大语言模型(LLM)与专用工具服务相结合,可以构建出既能理解自然语言,又能准确执行专业任务的智能代理。本文介绍一个基于 MCP(Model Context Protocol)协议和 Ollama 本地大模型的时间查询系统,它能够智能识别用户查询意图,并动态调用时间服务工具来提供准确的时区时间信息。

系统架构

该系统由两个核心组件构成:

  1. 时间服务器 (time_server.py):基于 MCP 协议实现的专用时间服务,提供获取当前时间和列出常见时区的工具函数
  2. 客户端测试程序 (time_client_test3.py):使用 Ollama 本地大模型分析用户查询,智能决定是否需要调用时间服务工具

核心代码解析

时间服务器实现

from mcp.server.fastmcp import FastMCP
from datetime import datetime
import pytz  # 用于处理时区,如果需要的话可以先安装:uv add pytz / pip install pytz

# 创建 MCP 服务器实例,命名为 "TimeServer"
mcp = FastMCP("TimeServer")

@mcp.tool()
def get_current_time(timezone: str = "UTC") -> str:
    """
    获取指定时区的当前时间。

    参数:
        timezone (str): 时区名称,例如 'Asia/Shanghai', 'UTC', 'America/New_York'。默认为 'UTC'。

    返回:
        str: 格式化后的当前时间字符串,包含时区信息。
    """
    try:
        # 获取指定时区
        tz = pytz.timezone(timezone)
        # 获取该时区的当前时间
        now = datetime.now(tz)
        # 格式化时间字符串
        formatted_time = now.strftime("%Y-%m-%d %H:%M:%S %Z")
        return f"当前时间 ({timezone}) 是: {formatted_time}"
    except pytz.UnknownTimeZoneError:
        return f"错误:未知的时区 '{timezone}'。请提供有效的时区名称,例如 'Asia/Shanghai', 'UTC'。"

# 可选:再添加一个工具,获取所有支持的时区列表(例如列出一些常见的)
@mcp.tool()
def list_common_timezones() -> list:
    """
    获取常见的时区列表。

    返回:
        list: 包含常见时区名称的列表。
    """
    common_timezones = ['UTC', 'Asia/Shanghai', 'Asia/Tokyo', 'America/New_York', 'Europe/London', 'Australia/Sydney']
    return common_timezones

if __name__ == "__main__":
    # 运行 MCP 服务器
    mcp.run(transport='stdio')

关键特性:
● 使用 @mcp.tool() 装饰器将函数暴露为 MCP 工具
● 支持动态时区处理,使用 pytz 库处理全球时区
● 包含完整的错误处理机制,对未知时区提供友好提示

客户端智能代理

import asyncio
import json
import re
from typing import Dict, Any, Optional, Tuple
from mcp import ClientSession, StdioServerParameters
from mcp.client.stdio import stdio_client
import ollama


class OllamaMCPClient:
    def __init__(self, server_script_path: str):
        self.server_params = StdioServerParameters(
            command="python",
            args=[server_script_path],
        )
        self.available_tools = []
        self.tool_info = {}
        self._session = None
        self._stdio_ctx = None

    async def __aenter__(self):
        """异步上下文管理器入口 - 初始化连接"""
        try:
            # 创建 stdio 客户端上下文
            self._stdio_ctx = stdio_client(self.server_params)
            read_stream, write_stream = await self._stdio_ctx.__aenter__()

            # 创建会话
            self._session = ClientSession(read_stream, write_stream)
            await self._session.initialize()

            # 获取可用工具列表
            tools_response = await self._session.list_tools()
            self.available_tools = [tool.name for tool in tools_response.tools]
            print(f"可用工具: {self.available_tools}")

            # 获取每个工具的详细信息
            for tool in tools_response.tools:
                self.tool_info[tool.name] = {
                    "description": tool.description,
                    "inputSchema": tool.inputSchema
                }

            return self
        except Exception as e:
            await self.__aexit__(None, None, None)
            raise Exception(f"初始化 MCP 服务器时出错: {e}")

    async def __aexit__(self, exc_type, exc_val, exc_tb):
        """异步上下文管理器出口 - 清理资源"""
        try:
            if self._session:
                await self._session.close()
            if self._stdio_ctx:
                await self._stdio_ctx.__aexit__(exc_type, exc_val, exc_tb)
        except Exception as e:
            print(f"关闭连接时出错: {e}")

    def extract_tool_call(self, model_response: str) -> Tuple[Optional[str], Optional[Dict[str, Any]]]:
        """
        从模型响应中提取工具调用信息。
        使用多种策略处理不稳定的参数格式。
        """
        # 策略1: 尝试解析整个响应为JSON
        try:
            data = json.loads(model_response.strip())
            if isinstance(data, dict) and "name" in data:
                tool_name = data["name"]
                arguments = data.get("arguments", {})
                if tool_name in self.available_tools:
                    validated_args = self.validate_arguments(tool_name, arguments)
                    return tool_name, validated_args
        except json.JSONDecodeError:
            pass

        # 策略2: 尝试查找JSON片段
        json_patterns = [
            r'\{[^{}]*"name"[^{}]*:[^{}]*"[^"]*"[^{}]*\}',
            r'\{.*"name":\s*"([^"]+)".*"arguments":\s*(\{.*?\}).*\}',
        ]

        for pattern in json_patterns:
            matches = re.finditer(pattern, model_response, re.DOTALL)
            for match in matches:
                try:
                    if match.lastindex == 2:
                        tool_name = match.group(1)
                        arguments = json.loads(match.group(2))
                    else:
                        data = json.loads(match.group(0))
                        tool_name = data.get("name")
                        arguments = data.get("arguments", {})

                    if tool_name and tool_name in self.available_tools:
                        validated_args = self.validate_arguments(tool_name, arguments)
                        return tool_name, validated_args
                except (json.JSONDecodeError, AttributeError):
                    continue

        # 策略3: 基于关键词的启发式匹配
        for tool_name in self.available_tools:
            if tool_name.lower() in model_response.lower():
                arguments = self.extract_arguments_heuristic(model_response, tool_name)
                validated_args = self.validate_arguments(tool_name, arguments)
                return tool_name, validated_args

        return None, None

    def validate_arguments(self, tool_name: str, arguments: Dict[str, Any]) -> Dict[str, Any]:
        """验证参数是否符合工具的要求,并提供默认值"""
        if not arguments:
            arguments = {}

        if tool_name == "get_current_time" and "timezone" not in arguments:
            arguments["timezone"] = "UTC"

        return arguments

    def extract_arguments_heuristic(self, response: str, tool_name: str) -> Dict[str, Any]:
        """使用启发式方法从响应中提取参数"""
        arguments = {}

        if tool_name == "get_current_time":
            timezone_patterns = [
                r'(asia/\w+|europe/\w+|america/\w+|australia/\w+|utc)',
                r'(上海|北京|纽约|伦敦|东京|悉尼)',
                r'(\bUTC\b|\bCST\b|\bEST\b|\bPST\b)'
            ]

            for pattern in timezone_patterns:
                match = re.search(pattern, response, re.IGNORECASE)
                if match:
                    timezone = match.group(1)
                    if timezone == "上海" or timezone == "北京":
                        timezone = "Asia/Shanghai"
                    elif timezone == "纽约":
                        timezone = "America/New_York"
                    elif timezone == "伦敦":
                        timezone = "Europe/London"
                    elif timezone == "东京":
                        timezone = "Asia/Tokyo"
                    elif timezone == "悉尼":
                        timezone = "Australia/Sydney"

                    arguments["timezone"] = timezone
                    break

        return arguments

    async def chat_with_tools(self, user_query: str, model: str = "phi3:mini") -> str:
        """与模型聊天,并处理可能的工具调用"""
        if not self._session:
            return "错误: MCP 会话未初始化"

        # 构建提示
        prompt = f"""
        用户查询: {user_query}

        你可用的工具: {json.dumps(list(self.tool_info.keys()), indent=2)}

        如果需要使用工具来回答问题,请以以下JSON格式回复:
        {{
          "name": "工具名称",
          "arguments": {{
            "参数名": "参数值"
          }}
        }}

        例如,对于查询"现在上海是几点?",你可以回复:
        {{
          "name": "get_current_time",
          "arguments": {{
            "timezone": "Asia/Shanghai"
          }}
        }}

        如果不需要使用工具,请直接回复答案。
        """

        try:
            # 调用Ollama
            response = ollama.chat(model=model, messages=[{"role": "user", "content": prompt}])
            model_response = response['message']['content']
            print(f"模型初始响应: {model_response}")

            # 尝试提取工具调用信息
            tool_name, arguments = self.extract_tool_call(model_response)

            if tool_name and tool_name in self.available_tools:
                print(f"检测到工具调用: {tool_name}, 参数: {arguments}")

                # 调用工具
                try:
                    tool_result = await self._session.call_tool(tool_name, arguments)
                    tool_output = tool_result.content
                    print(f"工具执行结果: {tool_output}")

                    # 将工具结果发送回模型获取最终答案
                    follow_up_prompt = f"""
                    你之前决定调用工具 {tool_name} 来回答问题。
                    工具执行结果: {tool_output}

                    请基于这个结果生成对用户的最终回复。
                    """

                    final_response = ollama.chat(
                        model=model,
                        messages=[
                            {"role": "user", "content": follow_up_prompt}
                        ]
                    )

                    return final_response['message']['content']

                except Exception as e:
                    return f"调用工具时出错: {e}"
            else:
                return model_response
        except Exception as e:
            return f"与模型通信时出错: {e}"


async def main():
    # 替换为您的 time_server.py 的实际路径
    server_script_path = "/Users/mac/work/gitstudy/mcp-helloword/lzc-mcp/time_server.py"

    try:
        # 使用异步上下文管理器创建客户端并进行多次调用
        async with OllamaMCPClient(server_script_path) as client:
            # 测试查询 - 多次调用示例
            test_queries = [
                "现在上海是几点钟?",
                "请问UTC时间现在是多少?",
                "告诉我纽约的当前时间",
                "你好,今天天气怎么样?"
            ]

            for i, query in enumerate(test_queries, 1):
                print(f"\n{'=' * 50}")
                print(f"查询 #{i}: {query}")
                response = await client.chat_with_tools(query)
                print(f"最终回答: {response}")

    except Exception as e:
        print(f"程序执行出错: {e}")


if __name__ == "__main__":
    asyncio.run(main())

智能决策流程:

  1. 提示工程:通过系统提示明确告知模型可用工具和调用格式
  2. 意图识别:模型分析用户查询,判断是否需要调用工具
  3. JSON 解析:从模型响应中提取结构化工具调用指令
  4. 工具执行:通过 MCP 会话调用相应工具并返回结果

工作流程示例

时间查询场景

  1. 用户询问:“纽约现在是什么时间?”
  2. 大模型识别意图,生成工具调用指令:
{
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {"timezone": "America/New_York"}
}
  1. 客户端调用 MCP 工具获取纽约当前时间
  2. 返回结果:“当前时间 (America/New_York) 是: 2024-01-15 10:30:45 EST”

无需工具场景

用户询问:“讲一个关于时间旅行的故事”
● 大模型识别无需调用工具,直接生成创意响应

附:上述客户端智能代理执行日志

处理查询: 现在几点了?(处理失败)

============================================================
处理查询: 现在几点了?
Connected to: <socket.socket fd=3, family=2, type=1, proto=0, laddr=('127.0.0.1', 57699), raddr=('127.0.0.1', 57696)>.
[09/16/25 21:27:36] INFO     Processing request of type            server.py:624
                             ListToolsRequest                                   
已连接到时间服务器,可用工具: ['get_current_time', 'list_common_timezones']
大模型提示词: 
        你是一个AI助手,可以回答用户问题并决定是否需要调用时间服务。

        你可以使用的工具:
        - get_current_time: 获取指定时区的当前时间,参数: timezone (时区名称)
        - list_common_timezones: 获取常见时区列表,无参数

        调用格式:
        如果需要调用工具,请以以下JSON格式回复:
        {
            "action": "call_tool",
            "tool_name": "工具名称",
            "arguments": {参数键: 参数值}
        }

        如果不需要调用工具,请直接回复答案。

        当前可用工具: ['get_current_time', 'list_common_timezones']
        
用户查询: 现在几点了?
询问大模型是否需要调用工具...
大模型初始响应: {
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {
        "timezone": "Asia/Shanghai" // Assuming you're looking for the time in Shanghai, China.
    }
}
解析大模型响应时出错: Expecting ',' delimiter: line 5 column 37 (char 121)

最终响应:
{
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {
        "timezone": "Asia/Shanghai" // Assuming you're looking for the time in Shanghai, China.
    }
}
============================================================

处理查询: 纽约现在是什么时间?(处理成功)


============================================================
处理查询: 纽约现在是什么时间?
Connected to: <socket.socket fd=3, family=2, type=1, proto=0, laddr=('127.0.0.1', 57731), raddr=('127.0.0.1', 57696)>.
[09/16/25 21:27:41] INFO     Processing request of type            server.py:624
                             ListToolsRequest                                   
已连接到时间服务器,可用工具: ['get_current_time', 'list_common_timezones']
大模型提示词: 
        你是一个AI助手,可以回答用户问题并决定是否需要调用时间服务。

        你可以使用的工具:
        - get_current_time: 获取指定时区的当前时间,参数: timezone (时区名称)
        - list_common_timezones: 获取常见时区列表,无参数

        调用格式:
        如果需要调用工具,请以以下JSON格式回复:
        {
            "action": "call_tool",
            "tool_name": "工具名称",
            "arguments": {参数键: 参数值}
        }

        如果不需要调用工具,请直接回复答案。

        当前可用工具: ['get_current_time', 'list_common_timezones']
        
用户查询: 纽约现在是什么时间?
询问大模型是否需要调用工具...
大模型初始响应: 
{
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {
        "timezone": "America/New_York"
    }
}

根据JSON格式回答,你需要获取纽约当前的时间。为此,调用了“get_current_time”工具并指定了时区为“America/New_York”。现在请等待该API调用的结果后,你可以得到纽约当前的时间。


大模型决定调用工具: get_current_time, 参数: {'timezone': 'America/New_York'}
[09/16/25 21:27:44] INFO     Processing request of type            server.py:624
                             CallToolRequest                                    
工具调用结果: 当前时间 (America/New_York) 是: 2025-09-16 09:27:44 EDT

最终响应:
当前时间 (America/New_York) 是: 2025-09-16 09:27:44 EDT
============================================================

处理查询: 给我列出一些常见的时区(处理失败)

============================================================
处理查询: 给我列出一些常见的时区
Connected to: <socket.socket fd=3, family=2, type=1, proto=0, laddr=('127.0.0.1', 57734), raddr=('127.0.0.1', 57696)>.
[09/16/25 21:27:45] INFO     Processing request of type            server.py:624
                             ListToolsRequest                                   
已连接到时间服务器,可用工具: ['get_current_time', 'list_common_timezones']
大模型提示词: 
        你是一个AI助手,可以回答用户问题并决定是否需要调用时间服务。

        你可以使用的工具:
        - get_current_time: 获取指定时区的当前时间,参数: timezone (时区名称)
        - list_common_timezones: 获取常见时区列表,无参数

        调用格式:
        如果需要调用工具,请以以下JSON格式回复:
        {
            "action": "call_tool",
            "tool_name": "工具名称",
            "arguments": {参数键: 参数值}
        }

        如果不需要调用工具,请直接回复答案。

        当前可用工具: ['get_current_time', 'list_common_timezones']
        
用户查询: 给我列出一些常见的时区
询问大模型是否需要调用工具...
大模型初始响应: {
    "action": "call_tool",
    "tool_name": "list_common_timezones",
}

根据常规时区的列表:
北美时区: America/New_York, America/Los_Angeles
澳大利亚时区: Australia/Sydney
东南亚时区: Asia/Shanghai, Asia/Kolkata
澳洲西部时区: Pacific/Noumea, Pacific/Guam
澳洲东部时区: Pacific/Auckland
澳洲北部时区: Pacific/Bougainville
澳洲南部时区: Pacific/Chuuk
澳洲西部时区: Pacific/Kiritimati
澳洲中部时区: Pacific/Pohnpei
澳洲南部时区: Pacific/Majuro
澳洲北部时区: Pacific/Galapagos
澳洲东部时区: Pacific/Enderbury
东盟时区: Asia/Bangkok
华北时区: Asia/Urumqi, Asia/Beijing
华南时区: Asia/Shanghai
中国东部时区: Asia/Chongqing
中国西部时区: Asia/Urumqi
香港时区: Asia/Hong Kong
台湾时区: Asia/Taipei, Asia/Macau
日本时区: Asia/Tokyo
东非时区: Africa/Johannesburg, Africa/Harare, Asia/Kuwait
中东时区: Asia/Riyadh, Europe/London
欧洲时区: Europe/Berlin, Europe/Istanbul
亚太时区: Asia/Dubai, Australia/Sydney
东南亚时区: Asia/Hong Kong, Indochina Time (ICT), Myanmar Standard Time (MST)
日内班岛时区: Asia/Ulan Bator
斯里兰大时区: America/Los_Angeles, Europe/London
澳洲:Asia/Sydney, Australia/Sydney
北美洲:America/New_York, America/Chicago

对于一个非常规的时区,如北京时间(UTC+8),我们可以直接写下回答:
北京时区是北方时间(UTC+8)。
解析大模型响应时出错: Illegal trailing comma before end of object: line 3 column 41 (char 69)

最终响应:
{
    "action": "call_tool",
    "tool_name": "list_common_timezones",
}

根据常规时区的列表:
北美时区: America/New_York, America/Los_Angeles
澳大利亚时区: Australia/Sydney
东南亚时区: Asia/Shanghai, Asia/Kolkata
澳洲西部时区: Pacific/Noumea, Pacific/Guam
澳洲东部时区: Pacific/Auckland
澳洲北部时区: Pacific/Bougainville
澳洲南部时区: Pacific/Chuuk
澳洲西部时区: Pacific/Kiritimati
澳洲中部时区: Pacific/Pohnpei
澳洲南部时区: Pacific/Majuro
澳洲北部时区: Pacific/Galapagos
澳洲东部时区: Pacific/Enderbury
东盟时区: Asia/Bangkok
华北时区: Asia/Urumqi, Asia/Beijing
华南时区: Asia/Shanghai
中国东部时区: Asia/Chongqing
中国西部时区: Asia/Urumqi
香港时区: Asia/Hong Kong
台湾时区: Asia/Taipei, Asia/Macau
日本时区: Asia/Tokyo
东非时区: Africa/Johannesburg, Africa/Harare, Asia/Kuwait
中东时区: Asia/Riyadh, Europe/London
欧洲时区: Europe/Berlin, Europe/Istanbul
亚太时区: Asia/Dubai, Australia/Sydney
东南亚时区: Asia/Hong Kong, Indochina Time (ICT), Myanmar Standard Time (MST)
日内班岛时区: Asia/Ulan Bator
斯里兰大时区: America/Los_Angeles, Europe/London
澳洲:Asia/Sydney, Australia/Sydney
北美洲:America/New_York, America/Chicago

对于一个非常规的时区,如北京时间(UTC+8),我们可以直接写下回答:
北京时区是北方时间(UTC+8)。
============================================================

处理查询: Invalid/Timezone 现在的时间是多少?(处理失败)


============================================================
处理查询: Invalid/Timezone 现在的时间是多少?
Connected to: <socket.socket fd=3, family=2, type=1, proto=0, laddr=('127.0.0.1', 57766), raddr=('127.0.0.1', 57696)>.
[09/16/25 21:27:57] INFO     Processing request of type            server.py:624
                             ListToolsRequest                                   
已连接到时间服务器,可用工具: ['get_current_time', 'list_common_timezones']
大模型提示词: 
        你是一个AI助手,可以回答用户问题并决定是否需要调用时间服务。

        你可以使用的工具:
        - get_current_time: 获取指定时区的当前时间,参数: timezone (时区名称)
        - list_common_timezones: 获取常见时区列表,无参数

        调用格式:
        如果需要调用工具,请以以下JSON格式回复:
        {
            "action": "call_tool",
            "tool_name": "工具名称",
            "arguments": {参数键: 参数值}
        }

        如果不需要调用工具,请直接回复答案。

        当前可用工具: ['get_current_time', 'list_common_timezones']
        
用户查询: Invalid/Timezone 现在的时间是多少?
询问大模型是否需要调用工具...
大模型初始响应: 
{
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {
        "timezone": "Asia/Shanghai" // Assuming the user wants to know the current time in Shanghai, China. You would need to replace this with the correct timezone based on the context of your question or if you are unsure about it ask for a list first using `list_common_timezones`.
    }
}
如果你不确定该哪个时区,可以先调用这个工具来获取常见的时区列表:

{
  "action": "call_tool",
  "tool_name": "list_common_timezones"
}
然后根据你的意愿或需求选择合适的时区,再使用 `get_current_time`。
解析大模型响应时出错: Expecting ',' delimiter: line 5 column 37 (char 121)

最终响应:
{
    "action": "call_tool",
    "tool_name": "get_current_time",
    "arguments": {
        "timezone": "Asia/Shanghai" // Assuming the user wants to know the current time in Shanghai, China. You would need to replace this with the correct timezone based on the context of your question or if you are unsure about it ask for a list first using `list_common_timezones`.
    }
}
如果你不确定该哪个时区,可以先调用这个工具来获取常见的时区列表:

{
  "action": "call_tool",
  "tool_name": "list_common_timezones"
}
然后根据你的意愿或需求选择合适的时区,再使用 `get_current_time`。
============================================================

处理查询: 讲一个关于时间旅行的故事(处理成功)


============================================================
处理查询: 讲一个关于时间旅行的故事
Connected to: <socket.socket fd=3, family=2, type=1, proto=0, laddr=('127.0.0.1', 57770), raddr=('127.0.0.1', 57696)>.
[09/16/25 21:28:02] INFO     Processing request of type            server.py:624
                             ListToolsRequest                                   
已连接到时间服务器,可用工具: ['get_current_time', 'list_common_timezones']
大模型提示词: 
        你是一个AI助手,可以回答用户问题并决定是否需要调用时间服务。

        你可以使用的工具:
        - get_current_time: 获取指定时区的当前时间,参数: timezone (时区名称)
        - list_common_timezones: 获取常见时区列表,无参数

        调用格式:
        如果需要调用工具,请以以下JSON格式回复:
        {
            "action": "call_tool",
            "tool_name": "工具名称",
            "arguments": {参数键: 参数值}
        }

        如果不需要调用工具,请直接回复答案。

        当前可用工具: ['get_current_time', 'list_common_timezones']
        
用户查询: 讲一个关于时间旅行的故事
询问大模型是否需要调用工具...
大模型初始响应: 在黑洞漩曲中,李明和他的朋友小王发现了一个亚特僭的机器。这台机器能够将人们送回任何时代,无论是古老的三国时期还有未来。不久之后,李明和小王决定拓宽他们的视野,去遇见贵公主孙权。

带着机器在古龙时代出行,两人以不可告別的身份和立场与其他同一时代的人物交流,试图改变历史中的不公正事件。在无数次的奇迹里找到了机会—-在一个有关科技知识传递和对未来发展影若的巨大突变时,他们被发现了并逃亡。

不幸的是,他们无法通过这台机器抵御时间流变化,最终被各自的历史中心人物所强大的力量杀死了。然而,他们在其生命中的智慧和对时间旅行的深入了解,未来的科技家们会基于这些原则重新开发时间旅行机器,带来一个更加互联互信的世界。

李明和小王的故事被记录在遗传编码中以后,成为了时间旅行理论和技术发展的一部分。尽管他们无法改变过去,但他们的决心和智慧对于科学界的进步与世界未来发展仍然有着永远的影响。

最终响应:
在黑洞漩曲中,李明和他的朋友小王发现了一个亚特僭的机器。这台机器能够将人们送回任何时代,无论是古老的三国时期还有未来。不久之后,李明和小王决定拓宽他们的视野,去遇见贵公主孙权。

带着机器在古龙时代出行,两人以不可告別的身份和立场与其他同一时代的人物交流,试图改变历史中的不公正事件。在无数次的奇迹里找到了机会—-在一个有关科技知识传递和对未来发展影若的巨大突变时,他们被发现了并逃亡。

不幸的是,他们无法通过这台机器抵御时间流变化,最终被各自的历史中心人物所强大的力量杀死了。然而,他们在其生命中的智慧和对时间旅行的深入了解,未来的科技家们会基于这些原则重新开发时间旅行机器,带来一个更加互联互信的世界。

李明和小王的故事被记录在遗传编码中以后,成为了时间旅行理论和技术发展的一部分。尽管他们无法改变过去,但他们的决心和智慧对于科学界的进步与世界未来发展仍然有着永远的影响。
============================================================

技术亮点

  1. 模块化设计:服务与客户端分离,符合微服务架构理念
  2. 协议标准化:使用 MCP 协议,确保工具调用的规范性和互操作性
  3. 本地化部署:使用 Ollama 和本地模型,保障数据隐私和响应速度
  4. 智能路由:大模型作为智能路由层,动态决定是否需要调用专业工具
  5. 错误恢复:完善的异常处理机制,确保系统稳定性

应用价值

这种架构模式具有广泛的适用性:

  1. 企业级应用:可扩展为包含多种专业工具的企业智能助手
  2. 教育场景:演示如何将 LLM 与专业工具结合的教学案例
  3. 原型开发:快速构建领域特定智能应用的参考架构
  4. 研究平台:探索工具使用和智能代理行为的实验平台

总结

本文介绍的系统展示了如何将大语言模型与专业工具服务通过 MCP 协议有机结合,创建出既能理解自然语言又能准确执行专业任务的智能代理。这种架构模式为构建下一代智能应用提供了可行路径,既发挥了 LLM 的语言理解优势,又保证了专业任务的执行准确性。

从Cherry Studio 入门 MCP:为你的大模型插上翅膀 简单来说,MCP 是一种接口协议,它是连接 API 和大模型的桥梁。通过 MCP,我们可以调用和操作第三方工具,从而扩展大模型的能力边界。MCP 让大模型不再局限于预训练的知识,而是能够实时地与外部世界互动。MCP 协议就像为大模型添加了翅膀,让它们能够突破自身的限制,与外部世界进行互动。通过 Cherry Studio 这样易用的工具,我们可以轻松地为自己的大模型配置各种 MCP 服务,从而解锁更多可能性。 阅读详情

相关推荐

MCP(大模型协议文本)服务 的详细解析

(如阿里云、华为的定制化解决方案),建议提供更多上下文以便精准解析。(模型协作协议),是一种专为。设计的标准化协议或服务框架。若您指的是某个特定厂商的。的详细解析,结合其在。

主攻大数据 人工智能 物联网 安全 低空经济等方向。mtsc 、gtest特邀分享嘉宾 1026

集成AIGC能力的多数据库客户端工具Chat2DB免费试用

Chat2DB一款由阿里巴巴开源免费的多数据库客户端工具,支持windows、mac本地安装,也支持服务器端部署,web网页访问。和传统的数据库客户端软件Navicat、DBeaver 相比Chat2DB集成了AIGC的能力,能够将自然语言转换为SQL, 也可以将SQL转换为自然语言,可以给出研发人员SQL的优化建议,极大的提升人员的效率,是AI时代数据库研发人员的利器, 不懂SQL的运营或业务也可以轻松使用快速查询业务数据、生成报表的能力

weixin_40381772的博客 5359

掌握 AIGC 领域 MCP 模型上下文协议,开启技术新征程

本文旨在系统介绍 AIGC 领域的 MCP 模型上下文协议,包括其设计原理、实现方式和应用价值。内容涵盖从基础概念到高级应用的全方位知识,适合希望在 AIGC 领域深入发展的技术人员阅读。本文将首先介绍 MCP 协议的基本概念,然后深入其技术细节,包括架构设计、核心算法和实现方式。接着我们将探讨实际应用案例和未来发展方向。AIGC:人工智能生成内容(Artificial Intelligence Generated Content),指由 AI 系统自动生成的各种形式的内容MCP。

SuperAGI2025 1095

AIGC入门,手搓大模型客户端与MCP交互第2集

本文针对大语言模型(LLM)与MCP服务交互过程中出现的JSON格式不规范问题,提出了一套鲁棒的参数提取方案。原系统假设模型总是返回完美JSON,但实际响应常包含多余文本、注释或格式错误,导致解析失败。改进方案通过两个核心函数:extract_json_from_response()使用正则表达式清除注释并采用多层解析策略,validate_tool_call()验证JSON结构完整性。该方案显著提升了工具调用的成功率,代码演示了如何从杂乱响应中提取有效JSON并进行验证。

明月专栏 540

AIGC 领域 MCP 模型上下文协议:应用场景大揭秘

在人工智能生成内容(AIGC)领域,模型之间的交互和信息共享变得越来越重要。MCP 模型上下文协议作为一种用于规范模型上下文数据交互的协议,旨在解决不同模型之间上下文信息传递的问题,提高模型的协作效率和生成内容的质量。本文的目的是深入探讨 MCP 模型上下文协议的原理、应用场景以及相关技术细节,为研究人员、开发者和从业者提供全面的参考。本文的范围涵盖了 MCP 模型上下文协议的核心概念、算法原理、数学模型、项目实战案例以及实际应用场景等方面。

SuperAGI2025 991

【aigc】chrome-devtools-mcp怎么玩?

Chrome DevTools MCP 是 Google Chrome 官方推出的 Model Context Protocol (MCP) 服务器,它让 AI 编程助手(如 Claude、Cursor、Copilot 等)能够控制和检查实时运行的 Chrome 浏览器。通过这个工具,AI 可以获得 Chrome DevTools 的全部能力,实现可靠的自动化测试、深度调试和性能分析。

叶子常常随风而落,分享博主日常学习和使用的一些技术 2706

手搓一个与多PPT文档对话的RAG引擎,并封装MCP Server。

本文介绍了一种基于视觉模型的多PPT文档RAG引擎实现方案,并将其封装为MCP Server。系统通过LibreOffice和Pdfium将PPT转换为图片,利用视觉模型解析内容并生成Markdown格式,使用LlamaIndex框架构建向量索引。MCP Server提供文档管理(添加/删除)、状态查询和对话交互功能,支持将解析结果与源PPT页面截图关联,增强回答的可溯源性。该方案实现了PPT文档的深度解析和动态索引管理,并采用缓存机制优化处理效率。源代码见文末。

qkh1234567的博客 760

AIGC驱动Chrome DevTools自动化测试:MCP协议实战指南

浏览器自动化测试是提升Web应用质量和开发效率的关键技术,其核心原理在于通过程序化指令模拟用户操作,实现页面交互、数据抓取和功能验证。传统方案如Selenium和Playwright虽成熟,但脚本编写和维护成本较高。Model Context Protocol(MCP)作为一种新兴的标准化协议,为AI模型与外部工具(如浏览器调试接口)提供了安全、规范的通信桥梁,极大降低了自动化脚本的构建门槛。通过将Chrome DevTools Protocol(CDP)封装为MCP兼容的工具,AI助手(如Claude C

weixin_28836875的博客 325

AIGC时代的新风口!MCP协议引领未来无限可能

MCP是由Anthropic主导推出的一种开放协议,旨在标准化大型语言模型(LLM)与外部数据源和工具之间的通信。它如同AI领域的“USB-C接口”,通过统一协议连接大语言模型与本地文件、数据库、API等资源,打破数据孤岛,实现“即插即用”的智能交互[1][7][8]。MCP主机(MCP Hosts):发起请求的AI应用程序,如聊天机器人、AI驱动的IDE、个人助理等[1][3][8]。MCP客户端(MCP Clients):在主机程序内部,与MCP服务器保持1:1的连接,负责发送请求和接收响应。

程序边界 9256

gephi生成网络关系图_路网拓扑重建专题 (3) 网络图生成

城市道路网建模在获得基础路网之后,需要考虑道路交通网络的描述与表达问题。网络是将现实世界中的事物及其关系进行适当的抽象,构造成由节点和边按照一定规则组成的形式。一个实体网络可以由有限个“节点”集合与“边”集合构成的图表示,即网络表示为。对于一个由个节点组成的无权复杂网络,该图有邻接矩阵,这里。根据研究对象不同,建模方法主要包括原始法[1]和对偶法[2]两种,见图1,字母a-j为交叉口编号...

weixin_39761195的博客 3504

Scipy优化踩坑实录:trust-constr和SLSQP约束定义到底差在哪?

本文深入解析了Scipy优化模块中trust-constr和SLSQP两种方法在约束定义上的差异。通过对比面向对象的trust-constr和字典式定义的SLSQP,揭示了它们各自的优势与适用场景,帮助开发者在有约束优化问题中选择合适的算法,提升计算效率与准确性。

weixin_42573113的博客 271

大模型——MCP快速入门实现

MCP 是一个开放协议,它为应用程序向 LLM 提供上下文的方式进行了标准化。你可以将 MCP 想象成 AI 应用程序的 USB-C 接口。就像 USB-C 为设备连接各种外设和配件提供了标准化的方式一样,MCP 为 AI 模型连接各种数据源和工具提供了标准化的接口。•Hosts是 LLM 应用(如 Claude Desktop 或 IDEs),它们发起连接•Clients在 host 应用中与 servers 保持 1:1 的连接•Servers。

jennycisp的博客 1181

2.13寸电子墨水屏HINK-E0213+esp8266

很久以前买的一块电子墨水屏,运气很好,这个型号HINK-E0213资料很全,而且微雪官网也有相关电路资料等。

梦境虽美,却不长. 3005

AIGC时代的新风口!MCP协议引领未来无限可能_aigc mcp

MCP是由Anthropic主导推出的一种开放协议,旨在标准化大型语言模型(LLM)与外部数据源和工具之间的通信。它如同AI领域的“USB-C接口”,通过统一协议连接大语言模型与本地文件、数据库、API等资源,打破数据孤岛,实现“即插即用”的智能交互[1][7][8]。MCP主机(MCP Hosts):发起请求的AI应用程序,如聊天机器人、AI驱动的IDE、个人助理等[1][3][8]。MCP客户端(MCP Clients)

HUANGXIN9898的博客 1159

智能解决装箱问题:使用优化算法实现高效包装

装箱问题(Bin Packing Problem)是组合优化领域中的一个经典问题,主要涉及如何将一系列对象高效地装入有限数量的容器(或“箱”)中,同时满足特定的约束条件。这个问题的目标是最小化所需使用的箱子数量或者最大化箱子的装载效率,以减少空间或资源的浪费。

MindOpt_003的博客 5552

保姆级教程:用GROMACS的FEP方法计算小分子结合自由能(附完整mdp配置)

本文提供了一份详细的GROMACS自由能微扰(FEP)计算教程,涵盖从系统准备、参数配置到结果分析的全流程。通过具体案例演示如何计算小分子结合自由能,包括λ窗口设计、动力学参数优化及并行化执行技巧,帮助研究者克服FEP计算中的常见问题,获得可靠的自由能数据。

weixin_30598225的博客 354

AIGC浪潮下,风靡全球的Mcp到底是什么?一文讲懂,技术小白都知道!!

上年这个时候,刚拿到录取通知书。哥哥教我用ai智能体,其实就是向我炫技。当时我问他,为什么不能直接给我生成图表,直接给我生成多好,省得我再去复制了。他说,其实很简单,只要做个接口协议什么的就行,只是目前国内没人做。当时说的很高深,我也听不懂。没想到年底,这个功能就实现内测了。在某种程度上,我也算是预言了哈哈。

爱因斯晨的博客 2283

SAP RAP 里的 EML 全解:从语言定位到事务语义,再到真实案例的落地方式

摘要:EML(Entity Manipulation Language)是ABAP RAP模型的核心组件,作为ABAP的子集用于操作业务对象(BO)。它通过声明式语法(READ/MODIFY/EXECUTE/COMMIT)统一访问BO的行为与数据,并由RAP运行时自动处理校验、锁定、草稿管理等生命周期。EML将业务语义融入代码,确保与Fiori应用共享同一套校验逻辑,并通过FAILED/REPORTED/MAPPED管道传递错误与消息。其事务控制(IN LOCAL MODE与COMMIT ENTITIES)

2007 年 ~ 2025 年,深耕 SAP 技术 18 年 528

【混元AIGC+腾讯云智能体+首创Coze核心流思维导图MCP】:打造一个文思通-智能写作助手Agent

"文思通-智能写作助手"是一款基于腾讯混元AIGC大模型和腾讯云智能体平台的AI写作工具,旨在解决内容创作者在写作过程中遇到的灵感枯竭、结构混乱等问题。该工具通过结合自研的思维导图MCP服务,实现了从文本到可视化思维导图的自动转换,帮助用户理清写作思路。其主要功能包括内容生成、结构引导、语言优化和可视化辅助等。开发流程采用了混元AIGC作为核心引擎,腾讯云智能体平台作为操作系统,并集成了思维导图MCP插件。最终构建的工作流能够根据用户需求自动生成大纲、优化文本并输出思维导图,显著提升了写

LucianaiB的博客 13万+

[xboard-ok210] 44 s5pv210开发板介绍和对比

文章目录前言四大S3C6410提供商友坚开发板UT-S5PV210华天正(润尔)real210飞凌开发板ok210九鼎x210友善之臂开发板tiny210mini210smart210天嵌开发板tq210sate210xboardxboardxboard之ok210 前言 四大S3C6410提供商 友坚开发板 UT-S5PV210 华天正(润尔) real210 飞凌开发板 ok210 九鼎 x210 友善之臂开发板 tiny210 mini210 smart210 天嵌开发板 tq210 sate210

鹰之翔 289

SAP采购申请审批策略配置简介

SAP采购申请审批策略配置简介 1、CT04创建特征

我小时候很黑的博客 8163

【AI大模型】手搓一个与多PPT文档对话的RAG引擎,并封装MCP Server

在RAG管道创建时,PPT是一个比较麻烦的文档类型,因为它的信息表达不像纯文本那样直接,也不像表格有固定的结构,之前也介绍过利用第三方的解析工具来完成。本篇我们将直接借助视觉模型构建一个多PPT文档的RAG查询管道,并将其封装到MCP Server中以方便集成到其他客户端或Agent应用。

Gaga246的博客 936

老版QQ原生表情gif动态

这是老版的QQ表情,不过全是动态的的,Windows照片查看器是不会动的,可以右击用浏览器打开查看,再说一遍是老版的,只是分享给宁愿用老版也要动态的人。

【AI大模型教程】手搓一个与多PPT文档对话的RAG引擎,并封装MCP Server,建议收藏!!

在RAG管道创建时,PPT是一个比较麻烦的文档类型,因为它的信息表达不像纯文本那样直接,也不像表格有固定的结构,之前也介绍过利用第三方的解析工具来完成。本篇我们将直接借助视觉模型构建一个多PPT文档的RAG查询管道,并将其封装到MCP Server中以方便集成到其他客户端或Agent应用。

Gaga246的博客 1048

android 蓝牙通讯demo

android 下蓝牙通讯demo,实现了发现蓝牙,使能蓝牙,通过蓝牙发送消息。

Camera2Demo

在Camera2 的基础上进行封装,使得Camera2一堆初始化逻辑与Activity分离,降低耦合度,完成预览拍照并保存的操作

看完这10张动图,你会彻底理解 MCP 的架构原理!

*最近,模型上下文协议(MCP)特别火,你可能已经听说过了。今天,我们来搞懂它到底是个啥。简单来说,。就像 USB-C 提供了一个标准化的方式来连接各种配件一样,。让我们稍微深入一点,。MCP 的核心是客户端-服务器架构,一个主机应用可以连接到多个服务器。。在我们深入之前,先简单了解一下👇主机代表任何 AI 应用(比如:Claude 桌面版,Cursor),它提供了 AI 交互的环境,访问工具和数据,并运行 MCP 客户端。MCP 客户端在主机内部运行,以实现与 MCP 服务器的通信。

jennycisp的博客 3713

华为的C语言编程规范.pdf

华为技术有限公司内部技术规范。本规范制定了编写C语言程序的基本原则、规则和建议。从代码的清晰、简洁、可测试、安全、程序效率、可移植各个方面对C语言编程作出了具体指导。

AI 领域必懂 5 大核心概念:AI、LLM、Prompt、MCP、AIGC 一次讲透

AI 领域必懂 5 大核心概念:AI、LLM、Prompt、MCP、AIGC 一次讲透

youmaob的博客 1429

【小白教程】一文搞懂 AI、LLM、Prompt、MCP、AIGC 是什么,有什么区别?收藏就对了

在 ChatGPT、文心一言、通义千问等这些 AI 工具爆火的时代,你可能经常听到这些词如:AI、LLM、Prompt、MCP、AIGC。那么,它们到底是什么呢?有什么区别呢? 接下来,我们一起来了解一下,不然和别人说起 AI 人工智能时,这些概念不懂就很拉了。

2401_85327249的博客 1277
上一篇: AIGC入门,从理解通信协议sse与streamhttp开始
下一篇: 用AI帮忙,开发刷题小程序,在线答题系统数据库设计文档
明月(Alioo)
博客等级 码龄18年 267粉丝 207原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

当前余额3.43元 前往充值 >
需支付:10.00元
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

明月(Alioo)

你的鼓励将是我创作的最大动力!

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

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

抵扣说明:

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

余额充值