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
134
i18n/uk/pages/handlers/context.md
Normal file
134
i18n/uk/pages/handlers/context.md
Normal file
|
|
@ -0,0 +1,134 @@
|
|||
---
|
||||
translation:
|
||||
sections: [b50152f05c81e786, b302059b22fb7cb4, 85682a1bf561243a, 53fc48838eb6837a, b24190e0842786ec, 85f93e150fc9b240]
|
||||
tool: 1
|
||||
---
|
||||
# Об'єкт Context {#the-context}
|
||||
|
||||
Аргументи інструмента надходять від моделі. Усе інше (запит, який ви обслуговуєте, сервер, у якому живе інструмент, спосіб звернутися назад до клієнта) надходить з одного об'єкта: **`Context`**.
|
||||
|
||||
Його не потрібно ні створювати, ні налаштовувати. Достатньо попросити.
|
||||
|
||||
## Як його попросити {#ask-for-it}
|
||||
|
||||
Додайте до будь-якого інструмента параметр з анотацією `Context`:
|
||||
|
||||
```python title="server.py" hl_lines="2 8"
|
||||
--8<-- "docs_src/context/tutorial001.py"
|
||||
```
|
||||
|
||||
* SDK створює новий `Context` для кожного запиту й передає його у функцію.
|
||||
* **Ім'я параметра не має значення**. `ctx`, `context`, `c`: SDK знаходить його за анотацією.
|
||||
* Ресурси та промпти теж можуть оголосити такий параметр, у той самий спосіб.
|
||||
* `ctx.request_id` — ідентифікатор запиту, який ваша функція обслуговує просто зараз.
|
||||
|
||||
!!! info
|
||||
Якщо ви працювали з FastAPI, цей прийом вам знайомий: оголошуєте параметр із власним типом
|
||||
фреймворку (`Request` там, `Context` тут), і фреймворк його підставляє. Нічого реєструвати,
|
||||
нічого налаштовувати: анотація типу — це й увесь механізм.
|
||||
|
||||
### Невидимий для моделі {#invisible-to-the-model}
|
||||
|
||||
Це те, що варто добре засвоїти. Ось схема вхідних даних, яку `tools/list` повідомляє для `search_books`:
|
||||
|
||||
```json
|
||||
{
|
||||
"type": "object",
|
||||
"properties": {
|
||||
"query": {"title": "Query", "type": "string"}
|
||||
},
|
||||
"required": ["query"],
|
||||
"title": "search_booksArguments"
|
||||
}
|
||||
```
|
||||
|
||||
Одна властивість. `ctx` — не аргумент: він ніколи не з'являється у схемі, моделі про нього ніколи не повідомляють, і жоден клієнт не може його заповнити. Це домовленість між вами та SDK, якої не видно в переданих даних.
|
||||
|
||||
### Спробуйте самі {#try-it}
|
||||
|
||||
Запустіть сервер у MCP Inspector:
|
||||
|
||||
```console
|
||||
uv run mcp dev server.py
|
||||
```
|
||||
|
||||
Форма для `search_books` має єдине поле `query`. Викличте інструмент зі значенням `dune`:
|
||||
|
||||
```text
|
||||
[request 3] Found 3 books matching 'dune'.
|
||||
```
|
||||
|
||||
Число показує, яким за ліком виявився цей запит. Викличте інструмент ще раз — і воно зміниться: кожен запит отримує власний `Context`.
|
||||
|
||||
## Що він дає {#what-it-gives-you}
|
||||
|
||||
Впроваджений об'єкт невеликий. Окрім `request_id`:
|
||||
|
||||
* `await ctx.read_resource(uri)`: прочитати один із **власних** ресурсів сервера зсередини інструмента. Про це — наступний розділ.
|
||||
* `await ctx.report_progress(progress, total, message)`: передавати перебіг виконання тому, хто викликав, упродовж тривалого виклику. Докладніше — на сторінці **[Перебіг виконання](progress.md)**.
|
||||
* `await ctx.elicit(message, schema)` та `await ctx.elicit_url(...)`: призупинити інструмент і поставити користувачеві запитання. Це **[Еліцитація](elicitation.md)** (elicitation).
|
||||
* `ctx.session`: серверний бік розмови з цим клієнтом. Тут живуть сповіщення, які ви надсилаєте клієнтові; останній розділ ним користується.
|
||||
* `ctx.headers`: заголовки запиту, які передав транспорт, або `None` для stdio. Прочитати власний заголовок можна так: `(ctx.headers or {}).get("x-...")`. Заголовки — це дані від клієнта: вони годяться для локалі чи прапорця функції, але ніколи — для ідентифікації особи.
|
||||
* `ctx.request_context`: сирий запис про поточний запит. Поле, яке вам знадобиться, — `lifespan_context`, об'єкт, який ваш код запуску віддав через yield (див. **[Життєвий цикл (lifespan)](lifespan.md)**).
|
||||
|
||||
Логування навмисно немає в цьому списку. Сервер пише логи модулем `logging` Python, як і будь-яка інша програма на Python. **[Логування](logging.md)** — коротка сторінка про те, чому саме так.
|
||||
|
||||
!!! tip
|
||||
Впровадження відбувається лише для функції, яку ви зареєстрували. Допоміжна функція, яку
|
||||
викликає ваш інструмент, не отримує власного `Context`; передавайте `ctx` далі як звичайний
|
||||
аргумент. Жодного фонового «поточного контексту», який можна було б дістати звідкись іще, немає.
|
||||
|
||||
## Читання власних ресурсів {#read-your-own-resources}
|
||||
|
||||
Ресурси сервера — не лише для клієнтів. Інструмент теж може їх читати:
|
||||
|
||||
```python title="server.py" hl_lines="16"
|
||||
--8<-- "docs_src/context/tutorial002.py"
|
||||
```
|
||||
|
||||
`ctx.read_resource` розв'язує URI через той самий реєстр, що обслуговує `resources/read`, тож інструмент отримує те саме, що отримав би клієнт: ітерований об'єкт із `ReadResourceContents`, по одному на кожен блок вмісту. Для цього URI він один:
|
||||
|
||||
```python
|
||||
contents.content # 'fiction, non-fiction, poetry'
|
||||
contents.mime_type # 'text/plain'
|
||||
```
|
||||
|
||||
* `content` — це рівно те, що повернула `genres()`. Одне джерело істини: клієнт переглядає ресурс, ваші інструменти його споживають, ніхто не копіює рядок.
|
||||
* Єдиний параметр `describe_catalog` — це `Context`, тож його схема вхідних даних **не має жодної властивості**. Модель викликає його з `{}`.
|
||||
|
||||
## Сповіщення клієнта про зміну списку {#tell-the-client-the-list-changed}
|
||||
|
||||
Те, що пропонує сервер, не зафіксовано на момент імпорту. Зареєструйте інструмент під час виконання, а потім повідомте клієнта:
|
||||
|
||||
```python title="server.py" hl_lines="15-16"
|
||||
--8<-- "docs_src/context/tutorial003.py"
|
||||
```
|
||||
|
||||
* `mcp.add_tool(recommend_book)` реєструє звичайну функцію як інструмент: ім'я, опис і схема виводяться точно так само, як це зробив би `@mcp.tool()`.
|
||||
* `await ctx.session.send_tool_list_changed()` надсилає `notifications/tools/list_changed`. Клієнт, що його отримав, знову викликає `tools/list` і бачить `recommend_book`.
|
||||
|
||||
Споріднені методи — `send_resource_list_changed()`, `send_prompt_list_changed()` і `send_resource_updated(uri)` для зміни одного конкретного ресурсу.
|
||||
|
||||
На з'єднанні покоління 2026-07-28 клієнти отримують сповіщення про зміни лише в потоці `subscriptions/listen`, який вони самі відкрили, тож наведені вище методи `send_*` до цих потоків не доходять. Методи публікації `Context` доставляють сповіщення в усі підписані потоки одразу: `await ctx.notify_tools_changed()`, `await ctx.notify_prompts_changed()`, `await ctx.notify_resources_changed()` та `await ctx.notify_resource_updated(uri)`. Докладніше, зокрема про масштабування на кілька реплік, — на сторінці **[Підписки](subscriptions.md)**.
|
||||
|
||||
!!! check
|
||||
Поки ніхто не запустив `enable_recommendations`, обіцяного інструмента не існує. Викличте його
|
||||
все одно — і результатом буде помилка, яку модель може прочитати:
|
||||
|
||||
```text
|
||||
Unknown tool: recommend_book
|
||||
```
|
||||
|
||||
Запустіть `enable_recommendations` — і той самий виклик спрацює. Список інструментів справді
|
||||
динамічний: `tools/list` відображає те, що зареєстровано *саме зараз*.
|
||||
|
||||
## Підсумки {#recap}
|
||||
|
||||
* Анотуйте параметр типом `Context` (в інструменті, ресурсі чи промпті) — і SDK його впровадить. Ім'я обираєте ви.
|
||||
* Для моделі він невидимий: схема вхідних даних завжди містить лише ваші справжні аргументи.
|
||||
* `ctx.request_id` ідентифікує запит; `ctx.request_context.lifespan_context` — те, що ваш код запуску віддав через yield.
|
||||
* `await ctx.read_resource(uri)` дає інструменту змогу читати власні ресурси сервера.
|
||||
* `ctx.session` — канал назад до клієнта: `send_tool_list_changed()` та споріднені методи кажуть йому заново отримати список, який ви змінили.
|
||||
* Звітування про перебіг виконання та еліцитація теж починаються з `Context`; кожному присвячено окрему сторінку.
|
||||
|
||||
Параметри, яких модель ніколи не бачить і які заповнюють ваші власні функції, — це **[Залежності](dependencies.md)**.
|
||||
Loading…
Reference in a new issue