Files
ams-weather/README.md
T

120 lines
5.5 KiB
Markdown
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# AMS Weather Agent
Агент для **AMS (Agent Management System)**: по названию города возвращает короткую
сводку о текущей погоде. Понимает русские (кириллица) и латинские названия.
```
Пользователь: Казань
Агент: В Казани переменная облачность, температура 22,2 °C. Ветер 4,1 м/с,
осадков нет. Возьмите лёгкую ветровку.
```
## Возможности
- Кириллица и латиница: `Казань`, `Нижний Новгород`, `Санкт-Петербург`, `Kazan`.
- Данные о погоде: температура, влажность, ветер (скорость и направление), осадки.
- Ответ формулирует языковая модель, но **только из переданных фактов** — числа не выдумываются.
- **Graceful degradation**: если LLM недоступна, агент отдаёт детерминированную сводку.
- Понятные сообщения об ошибках вместо исключений (диалог в AMS не падает).
- Кэширование геокодинга и переиспользование HTTP-соединений.
- API-ключи не нужны: оба внешних сервиса бесплатные.
## Источники данных
| Этап | Сервис | Ключ |
|---|---|---|
| Город → координаты | [Nominatim (OpenStreetMap)](https://nominatim.openstreetmap.org/) | не нужен |
| Координаты → погода | [MET Norway Locationforecast](https://api.met.no/weatherapi/locationforecast/2.0/documentation) | не нужен |
## Структура
```
agents/custom/weather/
├── config.json # метаданные агента для UI (name, description)
├── schema.py # Pydantic-модель Params (валидация входа в AMS)
├── handler.py # адаптер AMS: экспортирует генератор step(...)
├── system_prompt.txt # правила формулировки ответа для LLM
└── weather.py # сервисный слой: HTTP, модели, маппинг погодных кодов
tests/
└── test_weather.py # unit-тесты (без сети)
```
Разделение ответственности: `weather.py` ничего не знает про AMS и тестируется
отдельно; `handler.py` — тонкий слой интеграции.
## Требования
- AMS 7.005+ (Python 3.12, `requests` и `pydantic-ai` уже в окружении сервиса).
- Доступ к `nominatim.openstreetmap.org` и `api.met.no` с хоста AMS.
## Установка в AMS
Скопировать каталог агента и выдать права пользователю сервиса:
```bash
sudo cp -r agents/custom/weather /opt/ams/agents/custom/weather
sudo chown -R lexicom:lexicom /opt/ams/agents/custom/weather
```
Loader AMS подхватит изменения примерно через 10 секунд. Проверка:
```bash
curl -s http://127.0.0.1:6165/ams/agent/list | jq '.agents.custom'
```
Альтернатива — импорт через API AMS (zip-архив агента).
## Использование (API AMS)
`POST /ams/start/{type}/{agent_id}` с телом в формате JSON. Синхронный стрим
удобнее для клиентов, которые хотят получить ответ в одном запросе
(`async_mode: "no"`):
```bash
curl -sN http://127.0.0.1:6165/ams/start/custom/weather \
-H 'Content-Type: application/json' \
-H 'Accept: text/event-stream' \
-d '{"async_mode":"no","params":{"city":"Казань"}}'
```
Ответ — поток JSON-строк (NDJSON):
```json
{"type": "chunk", "data": "В Казани ", "chat_id": "..."}
{"type": "chunk", "data": "переменная облачность...", "chat_id": "..."}
{"type": "end", "data": "message", "chat_id": "..."}
```
Асинхронный режим (`async_mode: "yes"`) возвращает `chat_id`; далее читать
`GET /ams/stream/{chat_id}`, продолжать диалог `POST /ams/ask/{chat_id}` и
завершать `POST /ams/stop/{chat_id}`.
### Параметры
| Параметр | Тип | Описание |
|---|---|---|
| `city` | string | Название города (кириллица или латиница). |
## Поведение при ошибках
| Ситуация | Ответ |
|---|---|
| Город не найден | «Не удалось получить погоду: город «…» не найден.» |
| Пустой город | «Не удалось получить погоду: не указан город.» |
| Внешний сервис недоступен | «Не удалось получить погоду: внешний сервис погоды недоступен.» |
| LLM недоступна | Детерминированная сводка из полученных данных |
## Тесты
```bash
python -m venv .venv && . .venv/bin/activate
pip install pytest requests
pytest
```
Тесты не обращаются к сети: HTTP-слой подменяется (`monkeypatch`).
## Лицензия
Не задана (все права сохранены).