docs: publish translated docs in twelve languages and the tool that maintains them (#3280)
This commit is contained in:
parent
14aa889992
commit
52ad0a8876
1 changed files with 89737 additions and 54 deletions
177
i18n/uk/pages/servers/tools.md
Normal file
177
i18n/uk/pages/servers/tools.md
Normal file
|
|
@ -0,0 +1,177 @@
|
|||
---
|
||||
translation:
|
||||
sections: [e4cc390d56573409, 8566e2b68594e9ad, 2c97b9f888398951, 048e5471dfa71aea, 3076b1e16ad95950, edbedf2a16e71311, 3d8ef8da89fa87c1, f6c0e02e6ea5a363]
|
||||
tool: 1
|
||||
---
|
||||
# Інструменти {#tools}
|
||||
|
||||
**Інструмент** — це функція, яку може викликати модель.
|
||||
|
||||
Щоб оголосити інструмент, додайте `@mcp.tool()` до звичайної Python-функції. Оце й увесь API.
|
||||
|
||||
## Ваш перший інструмент {#your-first-tool}
|
||||
|
||||
```python title="server.py" hl_lines="6-8"
|
||||
--8<-- "docs_src/tools/tutorial001.py"
|
||||
```
|
||||
|
||||
Погляньте, що ви написали. Жодних схем, жодного JSON, жодного протоколу — просто функція. SDK зчитує з неї три речі:
|
||||
|
||||
* **Ім'я** інструмента — це ім'я функції: `search_books`.
|
||||
* **Опис**, який бачить модель, — це docstring: `Search the catalog by title or author.`
|
||||
* **Аргументи**, які дозволено передавати моделі, беруться з анотацій типів: `query: str` і `limit: int`.
|
||||
|
||||
### Вхідна схема {#the-input-schema}
|
||||
|
||||
З цих анотацій типів SDK генерує JSON Schema і надсилає її клієнту під час `tools/list`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"title": "Query", "type": "string"},
|
||||
"limit": {"title": "Limit", "type": "integer"}
|
||||
},
|
||||
"required": ["query", "limit"],
|
||||
"title": "search_booksArguments"
|
||||
}
|
||||
```
|
||||
|
||||
Обидва аргументи потрапили в `required`, бо жоден не має типового значення. За мить ви це виправите. (Ключі `title` — артефакти Pydantic; контракт складають властивості, їхні типи та `required`.)
|
||||
|
||||
!!! tip
|
||||
Анотації типів тут — не документація. Вони і є **контракт**. Якщо клієнт надішле `"limit": "ten"`,
|
||||
SDK відхилить запит ще до того, як ваша функція запуститься.
|
||||
|
||||
### Що отримує модель у відповідь {#what-the-model-gets-back}
|
||||
|
||||
Викличте інструмент із `{"query": "dune", "limit": 5}` — і результат матиме дві частини:
|
||||
|
||||
```python
|
||||
result.content # [TextContent(text="Found 3 books matching 'dune' (showing up to 5).")]
|
||||
result.structured_content # {'result': "Found 3 books matching 'dune' (showing up to 5)."}
|
||||
```
|
||||
|
||||
`content` — це текст, який читає **модель**. `structured_content` — типізовані дані для **клієнтського застосунку**. Вони там, бо ви оголосили тип повернення як `-> str`.
|
||||
|
||||
Поки що не переймайтеся `structured_content`. Повертайте з інструментів справжні Python-об'єкти — і все відбудеться правильно; цьому цілком присвячена сторінка **[Структурований вивід](structured-output.md)**.
|
||||
|
||||
### Спробуйте самі {#try-it}
|
||||
|
||||
Запустіть сервер через MCP Inspector:
|
||||
|
||||
```console
|
||||
uv run mcp dev server.py
|
||||
```
|
||||
|
||||
Відкрийте URL, який він надрукує, перейдіть на вкладку **Tools** і викличте `search_books`.
|
||||
|
||||
Inspector покаже форму з обов'язковим текстовим полем `query` та обов'язковим числовим полем `limit`. Цю форму він побудував із ваших анотацій типів. Так само зробить і будь-який інший MCP-клієнт.
|
||||
|
||||
## Необов'язкові аргументи {#optional-arguments}
|
||||
|
||||
Дайте параметру типове значення — і він перестане бути обов'язковим. От і все. Це звичайний Python.
|
||||
|
||||
```python title="server.py" hl_lines="7"
|
||||
--8<-- "docs_src/tools/tutorial002.py"
|
||||
```
|
||||
|
||||
Схема змінюється відповідно:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"title": "Query", "type": "string"},
|
||||
"limit": {"default": 10, "title": "Limit", "type": "integer"}
|
||||
},
|
||||
"required": ["query"],
|
||||
"title": "search_booksArguments"
|
||||
}
|
||||
```
|
||||
|
||||
`limit` зник із `required` і отримав `"default": 10`. Клієнт, який його пропустить, отримає `10` — точнісінько як у Python.
|
||||
|
||||
## Багатші схеми з `Field` {#richer-schemas-with-field}
|
||||
|
||||
Анотації типів дають чимало, але іноді хочеться *описати* аргумент або обмежити його.
|
||||
|
||||
Загорніть тип в `Annotated` і додайте `Field` із Pydantic:
|
||||
|
||||
```python title="server.py" hl_lines="12-14"
|
||||
--8<-- "docs_src/tools/tutorial003.py"
|
||||
```
|
||||
|
||||
Три нові речі, усі — на параметрах:
|
||||
|
||||
* `Field(description=...)`: опис окремого аргументу, який модель читає разом із docstring.
|
||||
* `Field(ge=1, le=50)`: числові межі. У схемі вони стають `"minimum": 1, "maximum": 50`.
|
||||
* `Literal["fiction", "non-fiction", "poetry"]`: перелік (enum). Модель може вибрати лише одне з цих значень.
|
||||
|
||||
!!! check
|
||||
Обмеження — не прикраса. Викличте інструмент із `limit=999` — і SDK відповість
|
||||
помилкою інструмента **ще до запуску вашої функції**:
|
||||
|
||||
```text
|
||||
Input should be less than or equal to 50
|
||||
```
|
||||
|
||||
Ця помилка повертається моделі як результат інструмента; модель її читає і повторює виклик
|
||||
із коректним значенням. Ви один раз написали `le=50` і задарма отримали агентів, що самі себе виправляють.
|
||||
|
||||
!!! info
|
||||
Якщо ви користувалися FastAPI чи Pydantic, то все це вже знаєте. Той самий `Field`,
|
||||
той самий `Annotated`, та сама валідація. Нічого специфічного для MCP тут вчити не треба.
|
||||
|
||||
## Модель як параметр {#a-model-as-a-parameter}
|
||||
|
||||
Коли інструмент приймає більше ніж кілька аргументів, згрупуйте їх у Pydantic-модель:
|
||||
|
||||
```python title="server.py" hl_lines="8-11 15"
|
||||
--8<-- "docs_src/tools/tutorial004.py"
|
||||
```
|
||||
|
||||
Схема `Book` вкладається у вхідну схему інструмента (як посилання `$defs`), модель заповнює її як JSON-об'єкт, а ваша функція отримує **справжній екземпляр `Book`**, уже провалідований, з атрибутами `.title`, `.author` і `.year`.
|
||||
|
||||
Можна поєднувати як завгодно: звичайні параметри поруч із параметрами-моделями, вкладені моделі, списки моделей. Це Pydantic аж до самого низу.
|
||||
|
||||
## `async def` {#async-def}
|
||||
|
||||
Якщо інструмент виконує ввід-вивід (викликає API, читає файл, робить запит до бази даних), оголосіть його як `async def` і використовуйте `await` всередині. SDK його дочекається.
|
||||
|
||||
Інструмент зі звичайним `def` теж працює: SDK запускає його в окремому потоці, тож він ніколи не блокує сервер.
|
||||
|
||||
Більше нічого налаштовувати не потрібно.
|
||||
|
||||
## Імена, заголовки й анотації {#names-titles-and-annotations}
|
||||
|
||||
Усе, що SDK виводить сам, можна перевизначити в декораторі:
|
||||
|
||||
```python title="server.py" hl_lines="7-10"
|
||||
--8<-- "docs_src/tools/tutorial005.py"
|
||||
```
|
||||
|
||||
* `title` — зрозуміла людині назва для інтерфейсів. Клієнти показують *«Search the catalog»* замість `search_books`.
|
||||
* `annotations` — поведінкові **підказки** для клієнта:
|
||||
* `read_only_hint=True`: цей інструмент нічого не змінює.
|
||||
* `open_world_hint=False`: він працює із замкненою множиною речей (цим каталогом), а не з відкритим вебом.
|
||||
* Дві інші, `destructive_hint` та `idempotent_hint`, описують інструмент, який *пише*: чи може він
|
||||
щось видалити, і чи два виклики дають те саме, що й один? Специфікація визначає обидві
|
||||
лише для інструментів, що не є read-only, тож на `search_books` вони нічого б не сказали.
|
||||
|
||||
Чемний клієнт використовує їх, щоб вирішувати на кшталт *«чи треба спитати користувача, перш ніж це запускати?»*. Це підказки, а не механізм безпеки. Ніколи не покладайтеся на те, що клієнт їх дотримається.
|
||||
|
||||
!!! tip
|
||||
`@mcp.tool()` також приймає `name=` і `description=`, якщо ви не хочете виводити їх
|
||||
з імені функції та docstring. Зазвичай хочете.
|
||||
|
||||
## Підсумки {#recap}
|
||||
|
||||
* `@mcp.tool()` на функції робить її інструментом. Ім'я — від функції, опис — із docstring.
|
||||
* Анотації типів **і є** вхідною схемою. Типові значення роблять аргументи необов'язковими.
|
||||
* `Annotated[..., Field(...)]` додає описи й обмеження; `Literal` додає переліки.
|
||||
* Параметр — Pydantic-модель — це спосіб прийняти структуроване «тіло».
|
||||
* Некоректні аргументи відхиляються за вас, із помилкою, яку модель може прочитати й після якої здатна відновитися.
|
||||
* `async def` для вводу-виводу, звичайний `def` для всього іншого.
|
||||
|
||||
Що відбувається зі значенням, яке ви повертаєте через `return`, — на сторінці **[Структурований вивід](structured-output.md)**.
|
||||
Loading…
Reference in a new issue