155 lines
8.6 KiB
Markdown
155 lines
8.6 KiB
Markdown
---
|
||
translation:
|
||
sections: [d65c098f37f5b6c3, dd0c2724d6f2877e, 6835bb3570c6714c, ffe823cb0fedd488, f33651add1b59094]
|
||
tool: 1
|
||
---
|
||
# Промпти {#prompts}
|
||
|
||
**Промпт** — це шаблон повідомлення, який обирає користувач.
|
||
|
||
Інструменти призначені для моделі. Промпт — навпаки: користувач обирає його з меню у своєму клієнті (слеш-команда, кнопка), заповнює аргументи, і згенеровані повідомлення потрапляють у розмову так, ніби він набрав їх сам.
|
||
|
||
Щоб оголосити промпт, поставте `@mcp.prompt()` над функцією, яка повертає текст.
|
||
|
||
## Ваш перший промпт {#your-first-prompt}
|
||
|
||
```python title="server.py" hl_lines="6-9"
|
||
--8<-- "docs_src/prompts/tutorial001.py"
|
||
```
|
||
|
||
SDK зчитує ті самі три речі, що й з інструмента:
|
||
|
||
* **Ім'я** — це ім'я функції: `review_code`.
|
||
* **Опис**, який показує клієнт, — це docstring: `Review a piece of code.`
|
||
* **Аргументи** беруться з параметрів. `code` не має типового значення, тому він обов'язковий.
|
||
|
||
Ось що клієнт отримує у відповідь на `prompts/list`:
|
||
|
||
```json
|
||
{
|
||
"name": "review_code",
|
||
"description": "Review a piece of code.",
|
||
"arguments": [
|
||
{"name": "code", "required": true}
|
||
]
|
||
}
|
||
```
|
||
|
||
Тут немає JSON Schema. Аргументи промпту — це плоский список **іменованих рядкових значень**: форма, яку заповнює людина, а не дані, які конструює модель.
|
||
|
||
### Генерування {#rendering-it}
|
||
|
||
Клієнт генерує повідомлення за шаблоном через `prompts/get`, передаючи аргументи. Ваша функція виконується, і повернутий `str` стає **одним повідомленням користувача**:
|
||
|
||
```json
|
||
{
|
||
"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`):
|
||
|
||
```text
|
||
mcp.shared.exceptions.MCPError: Internal server error
|
||
```
|
||
|
||
Результату з помилкою на кшталт інструмента, який можна було б передати моделі, тут немає, бо моделі в цьому ланцюжку немає взагалі:
|
||
виклик викидає виняток. Причина (`Missing required arguments: {'code'}`) потрапляє в лог вашого сервера.
|
||
|
||
### Спробуйте самі {#try-it}
|
||
|
||
Запустіть сервер із MCP Inspector:
|
||
|
||
```console
|
||
uv run mcp dev server.py
|
||
```
|
||
|
||
Відкрийте вкладку **Prompts** і виберіть `review_code`. Inspector намалює форму з одним обов'язковим полем `code`. Заповніть його, згенеруйте промпт — і отримаєте точно те повідомлення користувача, що наведене вище.
|
||
|
||
## Більше ніж одне повідомлення {#more-than-one-message}
|
||
|
||
Рев'ю коду — це одне повідомлення. Сеанс налагодження — це розмова, і промпт може закласти її цілком.
|
||
|
||
Поверніть список повідомлень замість `str`:
|
||
|
||
```python title="server.py" hl_lines="2 13-20"
|
||
--8<-- "docs_src/prompts/tutorial002.py"
|
||
```
|
||
|
||
* `UserMessage` і `AssistantMessage` імпортуються з `mcp.server.mcpserver.prompts.base`. Передайте їм `str`, і вони самі загорнуть його в `TextContent`. Роль — це ім'я класу.
|
||
* `Message` — їхній спільний базовий клас. Використовуйте його як анотацію типу результату.
|
||
|
||
Генерування `debug_error` тепер дає три повідомлення по порядку:
|
||
|
||
```json
|
||
{
|
||
"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` — це спосіб спрямувати *наступну* відповідь моделі, не змушуючи користувача набирати ці настанови самому.
|
||
|
||
## Заголовки та описи аргументів {#titles-and-argument-descriptions}
|
||
|
||
`review_code` — це ім'я функції, а не підпис. Дайте клієнту щось краще для напису на кнопці й опишіть кожен аргумент, щоб форма пояснювала себе сама:
|
||
|
||
```python title="server.py" hl_lines="10-13"
|
||
--8<-- "docs_src/prompts/tutorial003.py"
|
||
```
|
||
|
||
* `title="Code review"` — це зрозуміла людині назва, точно як `title` в інструмента.
|
||
* `Annotated[str, Field(description=...)]` — той самий шаблон, яким на сторінці **[Інструменти](tools.md)** описано параметри інструмента. Тут опис потрапляє на аргумент, а не в схему.
|
||
* `language` має типове значення, тому перестає бути обов'язковим.
|
||
|
||
Запис у `prompts/list` тепер містить усе, що потрібно клієнту, щоб намалювати хорошу форму:
|
||
|
||
```json
|
||
{
|
||
"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
|
||
Якщо ви читали сторінку **[Інструменти](tools.md)**, то вже знаєте все, що є на цій. Той самий декоратор, той самий
|
||
docstring як опис, ті самі `Annotated`/`Field`. Змінюється лише те, хто
|
||
його запускає (користувач) і куди йде результат (у розмову).
|
||
|
||
## Підсумки {#recap}
|
||
|
||
* `@mcp.prompt()` над функцією робить її промптом. Ім'я — з функції, опис — з docstring.
|
||
* Промптами **керує користувач**: клієнт показує їхній список, користувач обирає один і заповнює аргументи.
|
||
* Аргументи — це плоский список іменованих рядків (без схеми). Параметр із типовим значенням необов'язковий.
|
||
* Поверніть `str` — і він стане одним повідомленням користувача. Поверніть список `UserMessage` / `AssistantMessage`, щоб закласти багатоходову розмову.
|
||
* `title=` і `Field(description=...)` — це те, що клієнт показує у своєму інтерфейсі.
|
||
* Відсутній обов'язковий аргумент провалює весь запит. Окремого результату з помилкою для промпту немає.
|
||
|
||
Серверне автодоповнення аргументів промпту (або шаблону ресурсу) — це **[Автодоповнення](completions.md)**.
|