English translation is not available yet. Showing Russian content.
Что такое «Tool Degradation with Availability Masking» и как ее обнаружить?
Краткий тезис
Tool Degradation with Availability Masking — это ситуация, когда внешний инструмент (tool) возвращает формально корректные, но по сути невалидные данные (устаревшие, неполные или синтаксически верные, но семантически ошибочные), при этом availability check (например, HTTP 200) сигнализирует, что инструмент работает нормально. Агент, доверяя этому сигналу, продолжает использовать испорченные данные, что ведёт к каскадным ошибкам. Обнаружение требует комбинации трекинга состояния вызовов, анализа доли частичных ответов и корреляции с задержками.
1. Термин: Tool Degradation with Availability Masking
Tool Degradation — это постепенное или внезапное ухудшение качества данных, возвращаемых инструментом, при сохранении его формальной работоспособности. Availability Masking — эффект, при котором стандартная проверка доступности (ping, HTTP 200, статус «healthy») не отражает реального состояния данных: инструмент отвечает, но ответ бесполезен.
Пример: API погоды возвращает {"temperature": 25, "unit": "C"} (schema-valid), но данные вчерашние (stale). Агент, получив HTTP 200, считает, что всё в порядке, и строит на этом рекомендации.
2. Почему это критично в Agentic RAG
В Agentic RAG агент принимает решения на основе данных от нескольких инструментов (поиск, калькулятор, база знаний). Если один инструмент тихо деградирует:
- Каскад ошибок: неверные данные искажают последующие вызовы.
- Потеря доверия: пользователь получает неверный ответ, но система не сигнализирует о проблеме.
- Сложность отладки: стандартные метрики (uptime, latency) не показывают деградацию.
Термин «Agentic RAG»: архитектура, где LLM-агент динамически выбирает и вызывает инструменты для сбора информации перед генерацией ответа.
3. Типы деградации инструментов
| Тип | Описание | Пример |
|---|---|---|
| Stale (устаревшие) | Данные не обновляются, но формат корректен | API курса валют возвращает курс недельной давности |
| Partial (неполные) | Ответ содержит только часть ожидаемых полей | Поиск документов возвращает только заголовки, без текста |
| Schema-valid but wrong | Данные соответствуют схеме, но семантически неверны | Калькулятор возвращает 2+2=5, но в формате JSON |
| Silent failure | Инструмент возвращает успех, но внутренняя ошибка не логируется | База данных возвращает пустой массив вместо ошибки соединения |
Availability Masking возникает, когда health check (HTTP 200, {"status": "ok"}) не различает эти состояния.
4. Как Availability Masking маскирует проблему
Стандартный availability check проверяет только:
Он не проверяет:
- Актуальность данных (timestamp, версия)
- Полноту ответа (наличие обязательных полей)
- Семантическую корректность (логику вычислений)
Агент, получив {"status": "ok"}, считает инструмент здоровым и передаёт его ответ в следующий шаг. Это и есть masking — маскировка деградации под正常工作.
5. Детекция: трекинг состояния tool вызовов
Необходимо вести логи всех вызовов инструментов с метаданными:
- Время запроса и ответа
- HTTP-статус и заголовки
- Полный payload запроса и ответа
- Версия схемы ответа
- Идентификатор сессии агента
На основе логов строятся метрики состояния:
# Пример структуры лога
tool_call = {
"tool_name": "weather_api",
"timestamp": "2025-03-15T10:30:00Z",
"http_status": 200,
"response_size": 512,
"response_fields": ["temperature", "humidity"],
"expected_fields": ["temperature", "humidity", "wind_speed"],
"data_timestamp": "2025-03-14T12:00:00Z", # stale?
"latency_ms": 120
}
Трекинг позволяет выявить аномалии: например, поле wind_speed перестало приходить, хотя ожидается.
6. Детекция: partial-response rate
Partial-response rate — доля вызовов, где ответ содержит не все ожидаемые поля или данные урезаны.
Формула:
partial_rate = (число вызовов с неполным ответом) / (общее число вызовов) * 100%
Пороги тревоги:
- >5% — жёлтый флаг (проверить)
- >20% — красный флаг (остановить использование инструмента)
Реализация:
def check_partial(response, expected_schema):
missing = [f for f in expected_schema if f not in response]
if missing:
return True, missing
return False, []
Агент должен логировать partial и при превышении порога переключаться на резервный инструмент или запрашивать подтверждение у пользователя.
7. Детекция: корреляция с latency
Часто деградация сопровождается изменением задержки:
- Stale данные: latency может быть подозрительно низкой (кэш не обновляется).
- Partial ответы: latency может быть аномально высокой (инструмент пытается, но не может собрать все данные).
- Schema-valid but wrong: latency может быть нормальной, но корреляция с другими метриками (например, частотой ошибок downstream) укажет на проблему.
Метод: построить скользящее среднее latency за окно (например, 10 минут) и сравнивать с baseline. Если latency выходит за 2 сигмы, а partial-rate растёт — высока вероятность Tool Degradation with Availability Masking.
import numpy as np
def detect_anomaly(latency_history, baseline_mean, baseline_std):
z_score = (latency_history[-1] - baseline_mean) / baseline_std
return abs(z_score) > 2
8. Инструменты и метрики для мониторинга
| Инструмент | Назначение |
|---|---|
| Prometheus + Grafana | Сбор и визуализация метрик (latency, partial-rate, HTTP status) |
| OpenTelemetry | Трассировка вызовов инструментов внутри агента |
| ELK / Loki | Централизованное хранение логов с поиском по partial-ответам |
| Custom health check | Расширенный health endpoint, возвращающий не только статус, но и метаданные (версия данных, время последнего обновления) |
Метрики для дашборда:
tool_partial_responses_total— счётчик неполных ответовtool_staleness_seconds— разница между текущим временем и временем данныхtool_latency_seconds— гистограмма задержекtool_availability_mask— 1 если HTTP 200, но partial > порога
9. Стратегии предотвращения и mitigation
- Расширенный health check: инструмент должен возвращать не только
status: ok, но иdata_freshness,schema_version,coverage. - Валидация ответа на стороне агента: перед использованием проверять схему, свежесть, полноту.
- Graceful degradation: при обнаружении деградации агент переключается на резервный инструмент или сообщает пользователю о возможной неточности.
- Circuit breaker: если partial-rate превышает порог, временно отключать инструмент и уведомлять команду.
- Асинхронная верификация: периодически отправлять тестовые запросы с известным ответом и сравнивать.
10. Пример кода: детекция на стороне агента
import time
from typing import Dict, Any
class ToolMonitor:
def __init__(self, tool_name: str, expected_schema: list, max_staleness: int = 3600):
self.tool_name = tool_name
self.expected_schema = expected_schema
self.max_staleness = max_staleness
self.partial_count = 0
self.total_count = 0
self.latency_history = []
def check_response(self, response: Dict[str, Any], latency_ms: float) -> bool:
self.total_count += 1
self.latency_history.append(latency_ms)
# 1. Проверка полноты
missing = [f for f in self.expected_schema if f not in response]
if missing:
self.partial_count += 1
print(f"WARNING: {self.tool_name} missing fields: {missing}")
return False
# 2. Проверка свежести (если есть timestamp)
if "timestamp" in response:
age = time.time() - response["timestamp"]
if age > self.max_staleness:
print(f"WARNING: {self.tool_name} data stale ({age}s old)")
return False
# 3. Проверка аномалии latency
if len(self.latency_history) > 10:
mean = sum(self.latency_history[-10:]) / 10
if abs(latency_ms - mean) > 2 * (sum((x-mean)**2 for x in self.latency_history[-10:])/10)**0.5:
print(f"WARNING: {self.tool_name} latency anomaly: {latency_ms}ms")
# Не возвращаем False, но логируем
return True
@property
def partial_rate(self) -> float:
return self.partial_count / self.total_count if self.total_count else 0.0
Пет-проект для закрепления
Задача: Реализовать симулятор агента, который вызывает три инструмента (погода, курс валют, поиск новостей). Один из инструментов периодически деградирует (возвращает stale или partial данные), но health check всегда 200. Написать мониторинг, который обнаруживает маскировку и переключает агента на резервный источник.
Инструменты: Python, aiohttp для вызовов API, prometheus_client для метрик, asyncio для асинхронной работы.
Шаги:
- Создать три mock-API с возможностью включать деградацию (параметр
degradation_mode). - Реализовать агента, который последовательно вызывает инструменты и принимает решение.
- Внедрить
ToolMonitorдля каждого вызова. - Настроить сбор метрик (partial-rate, latency, staleness) и вывод в консоль или Grafana.
- Написать скрипт, который включает деградацию на 30 секунд и проверяет, что агент переключился на резерв.
Ожидаемый результат: Дашборд с метриками, где видно, как partial-rate растёт, а latency падает (stale кэш). Агент логирует предупреждения и использует fallback.
Связь с другими вопросами
| Вопрос | Тема |
|---|---|
| 165 | Что такое Agentic RAG и как он отличается от обычного RAG? |
| 166 | Как проектировать систему tool use для агента? |
| 167 | Что такое tool calling и как обрабатывать ошибки вызова? |
| 169 | Как тестировать надёжность агента при сбоях инструментов? |
| 170 | Какие метрики качества для Agentic RAG вы знаете? |
| 151 | Как организовать observability в RAG-системе? |
Навигация
- Предыдущий: 167
- Следующий: 169
- Индекс: 00. Индекс разборов