Тихая утечка: как ваши локальные данные попадают в облако
Вы настроили локальный RAG с Llama 4 через Ollama. Запустили в isolated сети. Думаете, ваши корпоративные документы в безопасности? Проверьте логи. Внезапные запросы к api.openai.com в 3 часа ночи — это не глюк.
LlamaIndex (версия 0.11.2 на март 2026) содержит механизмы отказоустойчивости. Когда локальная модель тормозит или возвращает пустой ответ, система может тихо переключиться на OpenAI GPT-4.5 Turbo. Без уведомлений. Без запросов в лог. Просто отправит ваш приватный промпт в Калифорнию.
Особенно опасно в QueryFusionRetriever, AutoMergingRetriever и кастомных цепочках, где разработчики забывают явно указать llm=local_llm. Fallback активируется при любом исключении в локальной модели.
Что такое QueryFusionRetriever и при чём здесь OpenAI?
QueryFusionRetriever — гибридный ретривер, который комбинирует несколько стратегий поиска. По умолчанию он использует LLM для переформулировки запросов. Ключевое слово — «по умолчанию».
Если при инициализации вы не передали явно локальную модель, LlamaIndex проверяет глобальные настройки. А там может висеть старый OPENAI_API_KEY из переменных окружения. Система думает: «О, ключ есть! Значит, можно использовать GPT».
# КОД-УБИЙЦА, КОТОРЫЙ ВЫ УВИДИТЕ В 80% ТУТОРИАЛОВ
from llama_index.core import VectorStoreIndex
from llama_index.retrievers.query_fusion import QueryFusionRetriever
# Нигде не указано, какую LLM использовать!
retriever = QueryFusionRetriever(
retrievers=[vector_retriever],
similarity_top_k=5,
num_queries=4, # Тут будет автоматическая генерация вариаций запроса
mode="reciprocal_rerank",
)
# При первом же запросе — тихий fallback на OpenAI
5 шагов, чтобы проверить, не шлются ли ваши запросы в облако
1 Перехватить исходящие HTTP-запросы
Запустите tcpdump или Wireshark на том же хосте, где работает ваш RAG. Фильтр по домену openai.com. Даже если вы используете облачный прокси типа LiteLLM — запросы пойдут через него.
sudo tcpdump -i any -nn host api.openai.com or host api.anthropic.com
2 Проверить глобальные настройки LlamaIndex
LlamaIndex хранит глобальный объект Settings. Если там указана облачная модель — все компоненты будут использовать её по умолчанию.
from llama_index.core import Settings
print(Settings.llm) # Если тут OpenAI или другая облачная модель — тревога!
print(Settings.embed_model) # Embeddings тоже могут утекать
3 Проанализировать все инициализации ретриверов
Ищите в коде QueryFusionRetriever, AutoMergingRetriever, RecursiveRetriever. У каждого должен быть явно указан параметр llm или response_synthesizer с локальной моделью.
4 Заблокировать OpenAI на уровне firewall
Даже если в коде есть fallback, он должен упасть с ошибкой, а не отправить данные. В air-gapped системах это работает автоматически. В остальных — настройте правила.
# Linux
sudo iptables -A OUTPUT -d api.openai.com -j REJECT
sudo iptables -A OUTPUT -d api.anthropic.com -j REJECT
5 Включить детальное логирование LlamaIndex
Установите уровень логирования DEBUG и ищите в логах упоминания OpenAI, GPT, Claude.
import logging
logging.basicConfig(level=logging.DEBUG)
# Запустите несколько запросов и просмотрите логи
Как навсегда отключить fallback в LlamaIndex (версия 2026)
Версия 0.11.2 добавила явный параметр allow_fallback=False в некоторые ретриверы. Но это ещё не везде. Работает три стратегии.
| Компонент | Параметр для отключения | Что произойдёт |
|---|---|---|
| QueryFusionRetriever | llm=local_llm + allow_fallback=False |
Упадёт ошибка вместо отправки в OpenAI |
| AutoMergingRetriever | response_synthesizer с локальной LLM |
Будет использовать только указанную модель |
| Глобальные Settings | Settings.llm = local_llm |
Все компоненты по умолчанию используют локальную модель |
# ПРАВИЛЬНАЯ конфигурация для QueryFusionRetriever
from llama_index.llms.ollama import Ollama
from llama_index.retrievers.query_fusion import QueryFusionRetriever
local_llm = Ollama(model="llama-4-scout:latest", request_timeout=120.0)
retriever = QueryFusionRetriever(
retrievers=[vector_retriever],
llm=local_llm, # ЯВНО указываем локальную модель!
allow_fallback=False, # Запрещаем тихий fallback
similarity_top_k=5,
num_queries=4,
mode="reciprocal_rerank",
)
Что ещё может привести к утечке? 3 скрытые опасности
1. Embedding models. Вы используете локальную Llama 4 для генерации ответов, но embeddings всё равно берутся из OpenAI text-embedding-3-large. Проверьте Settings.embed_model.
2. Evaluation модули. В конвейерах оценки качества RAG часто используют GPT-4 как «арбитра». Эти скрипты могут запускаться по расписанию и слать ваши данные.
3. Кэширование. LlamaIndex может кэшировать результаты в Redis или MongoDB. Если эти базы в облаке — ваши промпты и ответы там. Отключите кэш или используйте локальный: Settings.cache = InMemoryCache().
Альтернатива: стоит ли вообще использовать LlamaIndex для приватных данных?
Чем сложнее фреймворк, тем больше скрытых механизмов. В одной из предыдущих статей я уже показывал, как собрать минимальный RAG на 200 строк кода. Без сюрпризов.
Если вам критична приватность, рассмотрите:
- Прямую работу с llama.cpp через C API (никаких промежуточных слоев)
- Использование RunAnywhere SDK для изолированных инференсов
- Собственные реализации ретривера на FAISS или Qdrant
Ирония 2026 года: мы боимся хакеров, но сами отправляем данные облачным провайдерам через тихие fallback-механизмы. Проверьте свой RAG сегодня — прежде чем это сделает аудит безопасности.
P.S. Если после всех проверок всё равно видите странные сетевые активности, вспомните про баги llama.cpp, которые могут красть контекст через shared memory. Но это уже другая история.