feat: агент «Погода» для AMS (Open-Meteo + met.no)
This commit is contained in:
@@ -0,0 +1,119 @@
|
||||
# AMS Weather Agent
|
||||
|
||||
Агент для **AMS (Agent Management System)**: по названию города возвращает короткую
|
||||
сводку о текущей погоде. Понимает русские (кириллица) и латинские названия.
|
||||
|
||||
```
|
||||
Пользователь: Казань
|
||||
Агент: В Казани переменная облачность, температура 22,2 °C. Ветер 4,1 м/с,
|
||||
осадков нет. Возьмите лёгкую ветровку.
|
||||
```
|
||||
|
||||
## Возможности
|
||||
|
||||
- Кириллица и латиница: `Казань`, `Нижний Новгород`, `Санкт-Петербург`, `Kazan`.
|
||||
- Данные о погоде: температура, влажность, ветер (скорость и направление), осадки.
|
||||
- Ответ формулирует языковая модель, но **только из переданных фактов** — числа не выдумываются.
|
||||
- **Graceful degradation**: если LLM недоступна, агент отдаёт детерминированную сводку.
|
||||
- Понятные сообщения об ошибках вместо исключений (диалог в AMS не падает).
|
||||
- Кэширование геокодинга и переиспользование HTTP-соединений.
|
||||
- API-ключи не нужны: оба внешних сервиса бесплатные.
|
||||
|
||||
## Источники данных
|
||||
|
||||
| Этап | Сервис | Ключ |
|
||||
|---|---|---|
|
||||
| Город → координаты | [Open-Meteo Geocoding](https://open-meteo.com/en/docs/geocoding-api) | не нужен |
|
||||
| Координаты → погода | [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` уже в окружении сервиса).
|
||||
- Доступ к `geocoding-api.open-meteo.com` и `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`).
|
||||
|
||||
## Лицензия
|
||||
|
||||
Не задана (все права сохранены).
|
||||
Reference in New Issue
Block a user