核心内容:
- go-zero 的 MCP SDK 支持动态 Prompts,允许 AI 应用在运行时生成基于上下文、参数驱动的 Prompts。
- MCP Prompts 具有标准化、可重用性、用户控制、动态参数和上下文感知等优点。
- 通过定义配置、实现 Prompts 处理器,并向 MCP 服务器注册 Prompts,可以实现动态 Prompts 的功能。
源自 | kevwan 微服务实践 2025-05-12 09:36
在当今 AI 应用越来越复杂、需求越来越高的情况下,单纯靠模型本身已经远远不够了。要想让AI 真正成为一个有"行动力"的智能体,它必须能够动态调用外部工具、实时访问最新数据,并与用户持续交互。
这就是 Model Context Protocol(MCP) 想要解决的问题。
理解 MCP 中的 Prompts

MCP Prompts 的优点是标准化和优化LLM交互
标准化和可重用性:
- MCP Prompts 允许开发者创建一致的、可重用的交互模式。这意味着常见的LLM交互(如代码审查、数据分析或内容生成)可以标准化并共享,减少重复开发工作。
用户控制:
动态参数和上下文:
- Prompts 可以接受动态参数,并结合资源上下文(如日志、代码文件)。这使交互更具定制性和上下文感知。
多步骤工作流:
- Prompts 支持多步骤工作流,允许复杂的顺序交互。例如,调试错误时,可以先通过 Prompts 识别问题,然后建议解决方案。
MCP Prompts 的发现、调用和集成
发现:
• 通过 prompts/list 端点获取可用 Prompts 的列表。该端点返回 Prompts 的名称、描述和所需参数。
使用:
• 通过 prompts/get 请求使用 Prompts,用户可以提供参数进行定制。例如,一个名为“create-greeting” 的 Prompts 可能接受name和style参数。
资源集成:
• Prompts 可以与资源(如数据源)结合,增强上下文感知能力。例如,Prompts 可以引用日志或代码文件。
通知:
• 服务器通过 notifications/prompts/list_changed 通知客户端 Prompts 列表的变化。
• 客户端可通过 prompts/list 重新获取更新后的列表,确保同步。
go-zero 的 MCP SDK 最关键的特性之一就是对动态 Prompts 的支持,它允许你的 AI 应用在运行时生成基于上下文、参数驱动的 Prompts。与硬编码的静态 Prompts 不同,MCP 中的动态 Prompts 可以基于用户输入、系统状态或外部数据源生成。
MCP 中的 Prompts 类型
go-zero MCP 框架支持:
-
静态 Prompts,固定的 Prompts 模板
-
动态 Prompts,基于输入参数在运行时生成的 Prompts
使用 MCP Prompts 的好处
| |
| |
| |
| |
| 使用 JSON-RPC 的一致 Prompts 结构 |
在 go-zero MCP 中实现动态 Prompts
步骤 1:定义配置
为 MCP 服务器创建配置文件:
1
2
|
name: prompt-service
port: 8080
|
步骤 2:实现 Prompts 处理器
在你的 Go 应用中,注册基于输入参数生成动态 Prompts 的处理器:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
|
package main
import (
"flag"
"fmt"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/mcp"
)
var configFile = flag.String("f", "etc/config.yaml", "配置文件")
func main() {
flag.Parse()
var c mcp.McpConf
conf.MustLoad(*configFile, &c)
// 创建并启动 MCP 服务器
server := mcp.NewMcpServer(c)
// 注册你的 Prompts 处理器
registerMyPrompt(server)
// 启动服务器
logx.Info("正在启动带有 SSE 传输的 MCP 服务器")
server.Start()
}
// registerMyPrompt 注册动态 Prompts 处理器
func registerMyPrompt(server mcp.McpServer) {
server.RegisterPrompt(mcp.Prompt{
Name: "get_custom_prompt",
Description: "基于输入参数生成自定义提示词",
Arguments: []mcp.PromptArgument{
{
Name: "user_query",
Description: "用户的原始查询",
Required: true,
},
{
Name: "context_id",
Description: "可选的上下文标识符",
Required: false,
},
},
Handler: func(ctx context.Context, args map[string]string) ([]mcp.PromptMessage, error) {
// 解析参数
var req struct {
UserQuery string `json:"user_query"`
ContextID string `json:"context_id,optional"`
}
if err := mcp.ParseArguments(args, &req); err != nil {
return nil, fmt.Errorf("参数解析失败: %w", err)
}
// 基于输入参数生成动态提示词
return []mcp.PromptMessage{
{
Role: mcp.RoleUser,
Content: mcp.TextContent{
Text: fmt.Sprintf(`你是一个有帮助的助手。
请回答以下问题: %s
%s`, req.UserQuery, getContextInstructions(req.ContextID)),
},
},
}, nil
},
})
}
func getContextInstructions(contextID string) string {
if contextID == "" {
return ""
}
// 在实际应用中,你可能会基于 contextID 从数据库或外部服务
// 获取特定上下文的指令
return fmt.Sprintf("\n回答时,请考虑 ID 为 %s 的上下文", contextID)
}
|
实际案例:Golang 代码审查助手
让我们看一个使用 go-zero MCP Prompts 的实际案例 - 一个帮助进行 Golang 代码审查的智能助手。
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
|
package main
import (
"context"
"flag"
"fmt"
"github.com/zeromicro/go-zero/core/conf"
"github.com/zeromicro/go-zero/core/logx"
"github.com/zeromicro/go-zero/mcp"
)
var configFile = flag.String("f", "etc/config.yaml", "配置文件")
func main() {
flag.Parse()
var c mcp.McpConf
conf.MustLoad(*configFile, &c)
// 创建并启动 MCP 服务器
server := mcp.NewMcpServer(c)
// 注册你的提示词处理器
registerCodeReviewPrompt(server)
// 启动服务器
logx.Info("正在启动带有 SSE 传输的 MCP 服务器")
server.Start()
}
// registerCodeReviewPrompt 注册代码审查提示词处理器
func registerCodeReviewPrompt(server mcp.McpServer) {
server.RegisterPrompt(mcp.Prompt{
Name: "get_code_review_prompt",
Description: "获取一个用于审查 Go 代码的提示词,提供最佳实践和改进建议",
Arguments: []mcp.PromptArgument{
{
Name: "code_snippet",
Description: "要审查的代码片段",
Required: true,
},
{
Name: "focus_areas",
Description: "审查重点领域,如性能、并发、安全等",
Required: false,
},
},
Handler: func(ctx context.Context, args map[string]string) ([]mcp.PromptMessage, error) {
var req struct {
CodeSnippet string `json:"code_snippet"`
FocusAreas string `json:"focus_areas,optional"`
}
if err := mcp.ParseArguments(args, &req); err != nil {
return nil, fmt.Errorf("参数解析失败: %w", err)
}
// 创建并返回带有详细指令的提示词消息
return []mcp.PromptMessage{
{
Role: mcp.RoleUser,
Content: mcp.TextContent{
Text: `你是一位经验丰富的 Go 语言专家,精通代码审查和最佳实践。`,
},
},
{
Role: mcp.RoleUser,
Content: mcp.TextContent{
Text: fmt.Sprintf(`请审查以下 Go 代码,并提供改进建议:
<go-code>
%s
</go-code>
请按以下方面进行评估:
1. 代码质量和可读性
2. Go 语言最佳实践的遵循情况
3. 潜在的错误或边缘情况
4. 性能优化机会
5. 并发安全性考虑
%s
请提供具体、可行的改进建议,并解释每个建议的理由。如果有必要,提供修改后的代码示例。`,
req.CodeSnippet,
getFocusAreasInstructions(req.FocusAreas)),
},
},
}, nil
},
})
}
func getFocusAreasInstructions(focusAreas string) string {
if focusAreas == "" {
return "6. 如有额外需要关注的方面,也请列出"
}
return fmt.Sprintf("6. 特别关注以下方面:%s", focusAreas)
}
|
交互流程如下图:

高级 Prompts 技术
1. 多消息 Prompts
你可以返回多个 Prompts 消息来创建更复杂的对话:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
|
return []mcp.PromptMessage{
{
Role: mcp.RoleSystem,
Content: mcp.TextContent{
Type: mcp.ContentTypeText,
Text: "你是一个专注于代码审查的 AI 助手。",
},
},
{
Role: mcp.RoleUser,
Content: mcp.TextContent{
Type: mcp.ContentTypeText,
Text: fmt.Sprintf("请审查这段代码: %s", codeSnippet),
},
},
}, nil
|
MCP Prompts 的最佳实践
- 具体明确:在 Prompts 中提供清晰、详细的指令
- 包含上下文:添加相关上下文以帮助模型理解任务
- 使用参数:利用动态参数使 Prompts 具有适应性
- 保持安全:注意不要在 Prompts 中包含敏感信息
- 全面测试:使用各种输入测试你的 Prompts,确保它们按预期工作
开始使用
要开始使用 go-zero MCP Prompts:
下一篇我们将介绍 go-zero MCP Resources,敬请关注。有关更多信息和高级用法,请访问 go-zero 官方文档。
项目仓库
https://github.com/zeromicro/go-zero
请使用 go-zero 并 star 该仓库以支持我们的工作!