跳转至

提示词

机器翻译

本页由英文文档自动翻译而来,以英文页面为准。如果有读起来不对的地方,翻译页面说明了如何反馈。

提示词是由用户挑选的消息模板。

工具是给模型用的。提示词正好相反:用户在客户端的菜单里(比如斜杠命令或按钮)选一个,填好参数,渲染出来的消息就进入对话,就像是用户自己打出来的一样。

在一个返回文本的函数上加 @mcp.prompt(),就声明了一个提示词。

第一个提示词

server.py
from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"

SDK 从中读取的三样东西和工具一样:

  • 名称就是函数名:review_code
  • 客户端显示的描述是 docstring:Review a piece of code.
  • 参数来自函数的形参。code 没有默认值,所以是必填的。

客户端从 prompts/list 拿到的就是这些:

{
  "name": "review_code",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "required": true}
  ]
}

这里没有 JSON Schema。提示词的参数是一个扁平的具名字符串值列表:是给人填的表单,而不是由模型构造的载荷。

渲染

客户端用 prompts/get 渲染模板,并传入参数。你的函数运行后,返回的 str 会变成一条用户消息

{
  "description": "Review a piece of code.",
  "messages": [
    {
      "role": "user",
      "content": {
        "type": "text",
        "text": "Please review this code:\n\ndef add(a, b): return a + b"
      }
    }
  ],
  "resultType": "complete"
}

提示词的完整流程就是这样:按名称列出,按需渲染,放进对话。

Check

required 的检查发生在你的函数运行之前。渲染 review_code 时不传 code,请求本身就会失败,并返回一个 JSON-RPC 错误(错误码 -32603):

mcp.shared.exceptions.MCPError: Internal server error

这里没有工具那种可以交回给模型的错误结果,因为整个环节里根本没有模型:调用会直接抛出异常。原因(Missing required arguments: {'code'})会记在服务器的日志里。

试一试

用 MCP Inspector 运行服务器:

uv run mcp dev server.py

打开 Prompts 标签页,选择 review_code。Inspector 会画出一个表单,带一个必填的 code 字段。填好、渲染,返回的正是上面那条用户消息。

不止一条消息

代码审查只要一条消息。调试则是一段对话,而提示词可以把整段对话的开头都铺好。

把返回值从 str 换成消息列表:

server.py
from mcp.server import MCPServer
from mcp.server.mcpserver.prompts.base import AssistantMessage, Message, UserMessage

mcp = MCPServer("Code Helper")


@mcp.prompt()
def review_code(code: str) -> str:
    """Review a piece of code."""
    return f"Please review this code:\n\n{code}"


@mcp.prompt()
def debug_error(error: str) -> list[Message]:
    """Start a debugging conversation."""
    return [
        UserMessage("I'm seeing this error:"),
        UserMessage(error),
        AssistantMessage("I'll help debug that. What have you tried so far?"),
    ]
  • UserMessageAssistantMessage 来自 mcp.server.mcpserver.prompts.base。给它们一个 str,它们会替你包装成 TextContent。角色由类名决定。
  • Message 是它们的公共基类。用它作返回值注解。

现在渲染 debug_error 会按顺序产生三条消息:

{
  "description": "Start a debugging conversation.",
  "messages": [
    {"role": "user", "content": {"type": "text", "text": "I'm seeing this error:"}},
    {"role": "user", "content": {"type": "text", "text": "TypeError: 'int' object is not iterable"}},
    {
      "role": "assistant",
      "content": {"type": "text", "text": "I'll help debug that. What have you tried so far?"}
    }
  ],
  "resultType": "complete"
}

注意最后一条。预先填入一轮 assistant 发言,就能引导模型的下一条回复,而不用让用户自己把引导的话敲出来。

标题和参数描述

review_code 是函数名,不是标签。给客户端一个更适合放在按钮上的名字,并给每个参数加上描述,让表单一目了然:

server.py
from typing import Annotated

from pydantic import Field

from mcp.server import MCPServer

mcp = MCPServer("Code Helper")


@mcp.prompt(title="Code review")
def review_code(
    code: Annotated[str, Field(description="The code to review.")],
    language: Annotated[str, Field(description="The language the code is written in.")] = "python",
) -> str:
    """Review a piece of code."""
    return f"Please review this {language} code:\n\n{code}"
  • title="Code review" 是给人看的名称,和工具的 title 一模一样。
  • Annotated[str, Field(description=...)]工具 用来描述工具参数的是同一种写法。这里描述直接落在参数上,而不是写进模式里。
  • language 有默认值,所以不再是必填参数。

现在 prompts/list 里的这一项包含了客户端画好一个表单所需的全部信息:

{
  "name": "review_code",
  "title": "Code review",
  "description": "Review a piece of code.",
  "arguments": [
    {"name": "code", "description": "The code to review.", "required": true},
    {"name": "language", "description": "The language the code is written in.", "required": false}
  ]
}

Info

如果读过 工具,这一页的内容你其实都已经会了。装饰器一样,用 docstring 作描述一样,Annotated/Field 也一样。变的只有两点:由谁触发(用户),以及结果去哪儿(进入对话)。

回顾

  • 在函数上加 @mcp.prompt(),它就成了提示词。名称取自函数名,描述取自 docstring。
  • 提示词由用户控制:客户端列出它们,用户选一个并填好参数。
  • 参数是一个扁平的具名字符串列表(没有模式)。有默认值的形参是可选的。
  • 返回 str,它就变成一条用户消息。返回 UserMessage / AssistantMessage 的列表,可以为多轮对话铺好开头。
  • title=Field(description=...) 是客户端放进 UI 里的内容。
  • 缺少必填参数会让整个请求失败。没有针对单个提示词的错误结果。

要在服务器端为提示词(或资源模板)的参数提供自动补全,见 补全