GOLANG 可以这样用 MCP Server!

在本篇文章中,我们将深入探讨 telegram-deepseek-bot(GitHub 仓库:github.com/yincongcyin...)如何集成 go-client-mcp(GitHub 仓库:github.com/yincongcyin...)来实现模型上下文协议(MCP)服务的注册与管理。telegram-deepseek-bot 通过巧妙地利用 go-client-mcp 的特性,有效地解决了大模型在处理外部工具时面临的上下文长度限制和Token使用效率问题。


什么是 Model Context Protocol (MCP)?

在深入了解集成细节之前,我们首先需要理解 Model Context Protocol (MCP) 。MCP 旨在提供一种统一的方式,让大模型(LLMs)能够与外部工具和服务进行交互。它定义了工具的描述方式、调用接口以及如何将工具的输出反馈给模型,从而扩展了 LLM 的能力,使其能够执行更复杂的任务,例如文件操作、数据库查询等。

github.com/yincongcyincong/mcp-client-go 是一个 Go 语言实现的 MCP 客户端库,其主要特点包括:

  • 集成多个 MCP Server:它能够同时管理多个不同的 MCP 服务。
  • 统一的注册和管理:提供了一套统一的 API 来注册和管理这些 MCP 客户端。
  • 使用简单:设计简洁,易于集成到 Go 项目中。
  • 类 Claude 的配置方式:借鉴了 Anthropic Claude 模型中工具配置的理念。
  • 自动失败重连机制:增强了服务的健壮性。

telegram-deepseek-botgo-client-mcp 的集成核心

telegram-deepseek-bot 集成 go-client-mcp 的核心在于以下几个方面:

1. 配置文件 mcp.json

telegram-deepseek-bot 通过 ./conf/mcp/mcp.json 配置文件来定义和管理 MCP 服务。以下是该文件的一个示例:

JSON

perl 复制代码
{
  "mcpServers": {
    "filesystem": {
      "command": "npx",
      "args": [
        "-y",
        "@modelcontextprotocol/server-filesystem",
        "/Users/yincong/go/src/github.com/yincongcyincong/test-mcp/"
      ],
      "description": "supports file operations such as reading, writing, deleting, renaming, moving, and listing files and directories.\n"
    }
  }
}

值得注意的是,每个 MCP 服务配置中都包含一个 description 字段。这个 description 至关重要,它用于向大模型解释该 MCP 服务的功能。

2. description 字段的重要性

telegram-deepseek-bot 中,许多 MCP 服务可能没有默认的 description。然而,它却被强制要求必须存在。这是因为 /task 命令会利用大模型的分析能力,根据这些 description 来判断需要调用哪个 MCP 服务。这样做有以下显著优势:

  • 优化上下文长度 :大模型的请求通常有严格的上下文(Context)字数限制。如果将所有 MCP 函数的详细信息都塞入上下文,会很快达到上限。通过 description,大模型只需理解服务的概要功能,避免了不必要的细节。
  • 降低 Token 使用量 :将大量的 MCP 函数描述放入上下文会导致 Token 使用量大幅增加,从而增加成本。description 的使用有效地控制了 Token 消耗。

3. 工具管理结构 AgentInfo

telegram-deepseek-bot 定义了一个 AgentInfo 结构体来管理不同大模型所需的工具信息:

Go

go 复制代码
type AgentInfo struct {
    Description string   `json:"description"`
    ToolsName   []string `json:"tools_name"`

    DeepseekTool    []deepseek.Tool   `json:"-"`
    VolTool         []*model.Tool     `json:"-"`
    OpenAITools     []openai.Tool     `json:"-"`
    GeminiTools     []*genai.Tool     `json:"-"`
    OpenRouterTools []openrouter.Tool `json:"-"`
}

这个结构体不仅包含服务的 Description 和工具名称 ToolsName,还为不同的LLM平台(如 Deepseek, VolcEngine, OpenAI, Gemini, OpenRouter)分别维护了其对应的工具格式,方便进行转换和使用。

4. 初始化和注册 MCP 服务

telegram-deepseek-bot 通过 InitToolsConf()EnvToolsConf() 函数来加载 MCP 配置路径,并最终在 InitTools() 函数中完成 MCP 服务的初始化和注册:

Go

go 复制代码
func InitTools() {
    ctx, cancel := context.WithTimeout(context.Background(), 60*time.Second)
    defer func() {
        cancel()
        for name, tool := range TaskTools {
            if len(tool.DeepseekTool) == 0 || len(tool.VolTool) == 0 {
                delete(TaskTools, name)
            }
        }
    }()

    mcpParams, err := clients.InitByConfFile(*McpConfPath)
    if err != nil {
        logger.Error("init mcp file fail", "err", err)
    }

    errs := clients.RegisterMCPClient(ctx, mcpParams)
    if len(errs) > 0 {
        for mcpServer, err := range errs {
            logger.Error("register mcp client error", "server", mcpServer, "error", err)
        }
    }

    for _, mcpParam := range mcpParams {
        InsertTools(mcpParam.Name)
    }
}

clients.InitByConfFile() 会读取 mcp.json 配置文件,并解析出所有定义的 MCP 服务参数。随后,clients.RegisterMCPClient() 会尝试注册这些 MCP 客户端。如果注册过程中出现错误,会进行相应的日志记录。

5. 工具转换与插入 InsertTools()

成功注册 MCP 客户端后,InsertTools() 函数会被调用,负责获取每个 MCP 客户端的工具定义,并将其转换为不同大模型平台所需的格式:

Go

go 复制代码
func InsertTools(clientName string) {
    c, err := clients.GetMCPClient(clientName)
    if err != nil {
        logger.Error("get client fail", "err", err)
    } else {
        dpTools := utils.TransToolsToDPFunctionCall(c.Tools)
        volTools := utils.TransToolsToVolFunctionCall(c.Tools)
        oaTools := utils.TransToolsToChatGPTFunctionCall(c.Tools)
        gmTools := utils.TransToolsToGeminiFunctionCall(c.Tools)
        orTools := utils.TransToolsToOpenRouterFunctionCall(c.Tools)

        if *BaseConfInfo.UseTools {
            DeepseekTools = append(DeepseekTools, dpTools...)
            VolTools = append(VolTools, volTools...)
            OpenAITools = append(OpenAITools, oaTools...)
            GeminiTools = append(GeminiTools, gmTools...)
            OpenRouterTools = append(OpenRouterTools, orTools...)
        }

        if c.Conf.Description != "" {
            TaskTools[clientName] = &AgentInfo{
                Description:     c.Conf.Description,
                DeepseekTool:    dpTools,
                VolTool:         volTools,
                GeminiTools:     gmTools,
                OpenAITools:     oaTools,
                OpenRouterTools: orTools,
                ToolsName:       []string{clientName},
            }
        }
    }
}

mcp-client-go 库中的 utils 包提供了多种 TransToolsToXFunctionCall 函数,用于将标准的 MCP 工具定义转换成 Deepseek、VolcEngine、OpenAI 等大模型 API 所接受的特定function call 格式。

更重要的是,如果 MCP 服务配置中包含 Description,那么该服务将被添加到全局的 TaskTools 映射中。这个 TaskTools 映射是大模型选择工具的关键数据结构,它根据服务的描述来辅助决策。

源码地址:github.com/yincongcyin...


总结

通过上述分析,我们可以看到 telegram-deepseek-bot 如何巧妙地利用 go-client-mcp 库来管理外部工具。它不仅实现了 MCP 服务的统一注册和管理,还通过强制要求 description 字段,有效地解决了大模型在处理外部工具时面临的上下文长度和 Token 消耗问题。这种设计使得 telegram-deepseek-bot 能够更加智能、高效地利用外部工具,从而扩展其功能并提升用户体验。

相关推荐
争不过朝夕,又念着往昔18 分钟前
Go语言反射机制详解
开发语言·后端·golang
绝无仅有2 小时前
企微审批对接错误与解决方案
后端·算法·架构
Super Rookie2 小时前
Spring Boot 企业项目技术选型
java·spring boot·后端
来自宇宙的曹先生2 小时前
用 Spring Boot + Redis 实现哔哩哔哩弹幕系统(上篇博客改进版)
spring boot·redis·后端
expect7g2 小时前
Flink-Checkpoint-1.源码流程
后端·flink
00后程序员2 小时前
Fiddler中文版如何提升API调试效率:本地化优势与开发者实战体验汇总
后端
用户8122199367223 小时前
C# .Net Core零基础从入门到精通实战教程全集【190课】
后端
bobz9653 小时前
FROM scratch: docker 构建方式分析
后端
lzzy_lx_20893 小时前
Spring Boot登录认证实现学习心得:从皮肤信息系统项目中学到的经验
java·spring boot·后端
前端付豪4 小时前
21、用 Python + Pillow 实现「朋友圈海报图生成器」📸(图文合成 + 多模板 + 自动换行)
后端·python