惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

雷峰网
雷峰网
月光博客
月光博客
S
Security Affairs
宝玉的分享
宝玉的分享
D
DataBreaches.Net
MongoDB | Blog
MongoDB | Blog
Cloudbric
Cloudbric
PCI Perspectives
PCI Perspectives
B
Blog RSS Feed
腾讯CDC
Application and Cybersecurity Blog
Application and Cybersecurity Blog
Attack and Defense Labs
Attack and Defense Labs
N
News and Events Feed by Topic
T
The Blog of Author Tim Ferriss
H
Help Net Security
Vercel News
Vercel News
W
WeLiveSecurity
U
Unit 42
S
SegmentFault 最新的问题
Microsoft Azure Blog
Microsoft Azure Blog
Google Online Security Blog
Google Online Security Blog
云风的 BLOG
云风的 BLOG
Google DeepMind News
Google DeepMind News
S
Schneier on Security
The Register - Security
The Register - Security
酷 壳 – CoolShell
酷 壳 – CoolShell
Recent Announcements
Recent Announcements
博客园 - Franky
H
Hacker News: Front Page
WordPress大学
WordPress大学
I
Intezer
M
MIT News - Artificial intelligence
博客园 - 叶小钗
The Last Watchdog
The Last Watchdog
T
Troy Hunt's Blog
Stack Overflow Blog
Stack Overflow Blog
Microsoft Security Blog
Microsoft Security Blog
L
Lohrmann on Cybersecurity
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
I
InfoQ
cs.AI updates on arXiv.org
cs.AI updates on arXiv.org
Schneier on Security
Schneier on Security
P
Proofpoint News Feed
V
V2EX
Help Net Security
Help Net Security
小众软件
小众软件
Cyber Security Advisories - MS-ISAC
Cyber Security Advisories - MS-ISAC
大猫的无限游戏
大猫的无限游戏
The GitHub Blog
The GitHub Blog
F
Fortinet All Blogs

Все публикации подряд на Хабре

Ловим музу за клавиатуру: как айтишнику стать автором Что умеет Midjourney в 2026? Мой немного грустный разбор этого шикарного инструмента Никто не любит писать тесты, но ИИ может исправить это IPv8 выглядит как мечта. Поэтому почти наверняка не взлетит Производители вернули в продажу материнки с DDR3. Что происходит? Управление агентом с телефона через Telegram теперь в KodaCode От координации к лидерству: как меняется роль руководителя разработки Я сделала родителям бизнес вместо пенсии: зарабатываем 70 тысяч, мама не даёт продать В три раза быстрее приемка товара и оптимизация трудозатрат на 73%: как «РСТ-Инвент» помог Gulliver Group ИИ-шечный мир победил? О влиянии искусственного интеллекта на игропром Кремль снижает давление на Телеграмм пока Европа строит интернет по паспорту Как CEO, CTO и CIO за 8 часов собрали ИИ-директора, который умеет держать позицию под давлением Как (не) потерять домен за выходные Вместо 8 разных VPS: как я организовал практику студентам на одном сервере Почему твой Open Source проект не замечают? R&D: искусство управления неопределенностью в разработке AI-дефляция: вакансий для разработчиков больше, а рост зарплат — худший за 15 лет Мы отдали управление роботами OpenClaw. Что из этого вышло Галактический ID: система идентификации для всех форм разумной жизни Шесть основ бизнес-анализа: начинаем с вопроса «Кто в игре?» Код-ревью, в котором дело не в коде Данные переехали. Команда — нет Системной подход к сдаче OSWE в 2025 Почему комната управления реактором покрашена в цвет морской пены 4 YAML-файла вместо PySpark: как аналитикам строить пайплайны без разработчиков LLM-агент для поиска свободных доменов: автоматизируем подбор Когда, зачем и как правильно начинать новую сессию в Claude Code? Как я заставил нейросеть писать макросы для FreeCAD Анатомия ИИ‑агента для подбора персонала. От тысячи резюме к топ‑10 за минуты Опыт разработчика как экономика внимания Автономность как точка невозврата: кто будет субъектом в цифровом будущем Обучение ИИ в «диких» условиях: как рутинные действия превращаются в датасеты Как измерить LLM для задач кибербеза: обзор открытых бенчмарков Где хранить код? Сравнение GitHub, GitLab и Bitbucket Математика объясняет, почему нормальное распределение встречается повсюду Почему ваш FinOps не работает: 12 тезисов от практиков Как подписать проектную документацию УКЭП с использованием бесплатных лицензий Pilot Адаптивное администрирование Sigla Vision Я грузил уран в бочки, а потом 20 лет строил ИТ в атомной отрасли Чем позвонить с Эвереста? История и обзор спутниковой связи. Часть 2 Как языковая модель помогает контролировать качество инструктажей по охране труда в металлургии Как не передать на desktop свой IP в РКН Анатомия SAP Privileges: как устроено управление правами в macOS MoneyDev: Сказка про три главных слова Обновлённый токенизатор видео K-VAE 2.0 от Сбера Как сделать диспетчеризацию дома на 1284 квартиры почти бесплатно Как мы разогнали железную дорогу Мы дали агентам рутину. Теперь надо решить — что делать с освободившимся временем Токсичный контент, промпт-хакинг и защита ИИ — всё о Guardrails для LLM Умный город начинается с точного взгляда: как «Фалькон Тех» меняет пространство к лучшему Навайбкодил приложение для анализа графов Почему Дюну так интересно читать? Упрощаем работу с рутиной или как стать Гендальфом Белым Деконструкция Go: CPU, RAM и что там происходит. Go Assembler база. Часть 1.1 Какие профессии исчезнут из-за ИИ, а какие появятся? И что с этим делать Как мы построили IT-отдел, где хочется расти: архитектурные встречи, прозрачные метрики и книжные подарки Rufler: Делаем из Claude Code автономный рой через один YAML-конфиг Sing-box и белый список приложений Как построить надёжный обмен сообщениями в микросервисах: лучшие практики для enterprise OpenAI строит MLM-пирамиду, а McKinsey и Accenture помогают ей в этом Дом, который не построил Фишер (Часть 2) «Сверхзвуковой математик» против «Вдумчивого логиста»: битва алгоритмов 3D-упаковки Мультимодальные модели – грубый и дорогой инструмент Разговоры ничего не стоят. Код тоже Проверки физических лиц: с кого начнет ФНС Топ-10 бесплатных нейросетей для создания видео в 2026 году Первые слои кода: как наши решения сегодня определяют архитектуру ИИ на десятилетия Разработка нового статического анализатора: PVS-Studio JavaScript Поиск уязвимостей ПО: базовый минимум или роскошный максимум Почему оценка персонала не работает как инструмент управления Как мы разработали ИИ-ассистента и сократили рутину продуктовой команды на 50% Как я ушел из найма, нажарил косточек и продал на маркетплейсах на 168 млн в год Когда 1С:ERP уже внедрена, а нормального производственного плана всё ещё нет Как я сделал Claude мультимодальным, подключив к нему Qwen Omni Как приглашение на вакансию мечты превращается в атаку Infrastructure as Code: философия и лучшие практики IaC Тестируем Yandex Code Assistant на задаче, в которой нужно хранить секреты nxs-universal-chart v3.0: новое поколение универсального Helm-чарта Callback Injection: Техника, которая отправила Microsoft Defender в глухой нокаут «Все идеи на стол»: митап как способ вывести проект из тупика Сегодня я узнал нечто новое о GPU благодаря багу в своей игре Как заставить LLM ̶ ̶г̶а̶л̶л̶ю̶ ̶ эволюционировать Карта событий как фундамент аналитики: практический кейс для E-commerce Что выбрать для AI: x86, ARM или RISC-V? Дайджест железа за март Роль соматических мутаций в развитии аутоиммунных заболеваний: путь к избирательной терапии Mythos от Anthropic — тревожный сигнал для всех, а не только для банков Guardrails для LLM на Java: как приручить промпт‑инъекции и токсичные ответы Green-VLA: как мы собрали VLA-модель для реального антропоморфного робота и не потеряли обобщение Финансовая гонка вооружений: почему умные люди добровольно в ней участвуют Эра ИИ-агентов наступила: выбираем лучшего цифрового сотрудника # Практический опыт внедрения WinCC Redundancy на производственном предприятии Сделал MVP за 3 дня, а потом неделю прикручивал оплату. Оно того стоило? Физика против Маска: почему Starship V3 может оказаться ещё одной катастрофой Нефть Венесуэлы: крупнейшие запасы в мире, но не крупнейшая нефтяная держава JPA 4. Переосмысление Hibernate Почему зеркальная фотокамера Nikon D5 десятилетней давности идеально подошла для миссии «Артемида-2» Проект «Уровень-Спутник» или как мы сделали платформу для гидрологов «Замедлиться, чтобы ускориться»: почему ИИ повышает цену ошибок в требованиях и архитектуре Как с нуля поднять трафик IT-компании на 1657% при бюджете 55 тыс. и выжить Pixel-perfect Downsampling — идеальная отрисовка 50 миллионов точек без потерь
Практический ИИ-агент Python: LangGraph + Qdrant
evia · 2026-05-22 · via Все публикации подряд на Хабре

Уровень сложностиСредний

Время на прочтение9 мин

Охват и читатели1.1K

Кейс

При разработке ИИ-агента для базы знаний, мне казалось, что задача почти типовая: складываем информацию в Qdrant, находим информацию через векторный поиск и поиск в интернете и формируем красивый ответ через LLM. На деле ИИ-агент начал уверенно галлюцинировать, приносить не только нерелевантные ответы, но и тупить с короткими пользовательскими запросами. И самое неприятное, при всем при этом метрика «похожести» similarity выглядела достаточно высокой, что сильно вводило в заблуждение.

После серии экспериментов и улучшений пришло понимание, что промышленный ИИ-агент — это не столько про LLM, сколько про качество извлечения информации и гибкую оркестрацию компонентов ИИ-агента. Что в итоге полностью поменяло архитектуру моей системы.

В статье расскажу, как я пришла от «просто добавь LLM» к промышленному графовому ИИ-агенту на LangGraph + Qdrant.

Многие обучающие материалы в интернете создают впечатление, что для создания ИИ-агента достаточно подключить LLM к векторной базе данных. Однако на практике такой подход оказался слишком поверхностным. Я сделала ИИ-агента для базы знаний и довольно быстро столкнулась с типичными проблемами:

  • пользовательский запрос в его первичной формулировке плохо ищется по базе, особенно с учетом специфической терминологии и сленга;

  • векторный поиск ставит высокие метрики совсем не подходящим ответам;

  • много шумных ответов из-за нерелевантной сегментации вопроса;

  • на таких неполных и шумных данных LLM фантазирует, что совсем не подходит для продакшена.

Когда геометрия подводит

Здесь всплывает ключевая проблема, которую не стоит недооценивать при проектировании ИИ-агента: разница между человеческой «инклюзивной семантикой» и векторной «геометрией близости формулировок». Например, вопрос «Какое время торгов и расчетов в будни?» может привести к совершенно неожиданным ответам про регламент расчетов или формирование отчетов. На уровне метрики similarity всё выглядит корректно, тексты действительно «похожи». Но с точки зрения пользователя ответ часто оказывается неполным или вообще нерелевантным.

Проблема становится еще более очевидной при сравнении рейтинга выдачи по этой метрике, например, расширенная формулировка «Какое время торгов и расчетов в будни, выходные и праздничные дни?» получила в выборке только 11 место.

Так происходит, потому что векторное представление текста работает не как логический фильтр, а как геометрическая функция: каждый вопрос превращается в точку в многомерном пространстве смыслов так, что семантически близкие вопросы оказываются близко друг к другу. Однако модель не способна определить, является ли один запрос подмножеством другого, и не может оценить, достаточно ли найденного контекста для ответа. Также следует заметить, что в повседневной речи человек часто использует неформальные выражения, профессиональный сленг, сокращения и опускает важные детали вопроса, подразумевая их как само собой разумеющиеся.

В результате один и тот же смысл может быть передан множеством разных способов. Это приводит к тому, что система по-разному интерпретирует одинаковые по содержанию вопросы, и, соответственно, ухудшается стабильность слоя retrieval. Поэтому каждую формулировку следует привести к стандартной, канонической форме, устранить вариативность языка и выделить основные сущности и ограничения перед подачей в наши модели.

Но дело тут не только в нормализации формулировок. Все несколько глубже: система возвращает не ответы на заданные вопросы, а похожие по смыслу фрагменты, а LLM, получая такой контекст, дальше уверенно достраивает недостающую информацию, что приводит к классическим галлюцинациям на неполных данных. А значит нужно достроить ограничения вопроса, сделав его более емким и полным и как-то «сузить» смысловое поле поиска.

Привести вопрос к более полному и однозначному виду можно через предварительный процесс смыслового достраивания (semantic completion), когда недостающая информация восполняется на основе общей семантической информации. Вопрос из моего примера представляет собой короткий набор смыслов «время, торги, расчеты, будни», который заставляет модель искать все ответы, связанные с терминами «регламент», «клиринг», «отчетность». На самом же деле пользователь имеет в виду более конкретную информацию о графике работы платформы.

Слишком короткий вопрос порождает слишком широкое семантическое поле, из-за чего в top-k попадают нерелевантные ответы, что ухудшает качество слоя поиска и извлечения информации из базы данных (далее – слоя retrieval). Практическое решение этой проблемы, которое дало заметный прирост качества — это использование техники расширения запроса (query expansion) перед векторным поиском, когда исходный запрос расширяется дополнительными словами, связанными терминами, синонимами, уточнениями или альтернативными формулировками. В моем примере вопрос может превратиться в «расписание сессий и расчетов в будние дни, часы работы платформы, время начала и окончания сессии, расписание расчетов».

Итого, дополнительный слой предобработки пользовательского вопроса, включающий нормализацию запроса, его смысловое достраивание и расширение при разработке систем становится критически важным наряду с требованиями устойчивости к шуму и обеспечения безопасности.

Relevance vs Completeness: разделяем понятия

После тюнинга векторного поиска слоем предобработки казалось, что основная часть системы уже работает: ИИ-агент стабильно выдает хорошую метрику похожести действительно «достаточно близким» ответам. Но на практике быстро выяснилось: высокое качество векторного поиска с технологическими улучшениями не гарантирует финальную релевантность ответа в целом.

Например, на мой вопрос выше модель выдавала следующий топ-3 ответов  про уточнения по расписанию в летнее время (score: 0.92), про порядок расчетов в нестандартные дни (score: 0.88) и реально полезный ответ про расписание торгов (score: 0.71), который оказался ниже из-за шумных, но семантически близких результатов. Ну и ответ LLM на основе этой выборки был очень близким, но размытым и с второстепенными уточнениями, хотя точный ответ лежал в третьем ответе.

Стало очевидно, нужен дополнительный слой, который разделяет релевантность ответа, насколько найденный текст соответствует вопросу, и его полноту, хватает ли информации для ответа. Итогом стал слой постобработки ответа, который фактически превратил поиск в многошаговый фильтр качества.

Одним из ключевых механизмов стало повторное ранжирование (rerank), которое заново переоценивает найденные фрагменты с учетом совместного взаимодействия с конкретным вопросом, выталкивая наверх действительно релевантные ответы.

Новый порядок топ-3 ответов выглядел так: ответ про расписание торгов (score: 0.94), порядок расчетов в нестандартные дни (score: 0.45, оценен ниже как шумный) и регламент торгов (score: 0.32)

Затем в игру вступила лексическая фильтрация (lexical filtering), которая отсеивает шум через простое совпадение ключевых слов, работая как безопасный и надежный фильтр.

Венчает этот слой метрика уверенности (confidence), которая оценивает достаточность и надежность найденного контекста для генерации. Если уверенность низкая, контекст противоречивый, информации недостаточно, тогда вместо того, чтобы рисковать и галлюцинировать система делает что-то более безопасное: уходит в веб-поиск, переключает на человека или же честно говорит о том, что нет точной информации по этому вопросу.

На практике эта комбинация резко сократила количество «уверенно неправильных» ответов. Но важно другое: система перестала быть линейной цепочкой «нашёл → ответил», и начала работать как фильтрующий контур: сначала проверяется качество контекста, и только затем LLM допускается к генерации.

Итоговый пайплайн промышленного ИИ-агента

После всех экспериментов со слоями предобработки, retrieval-стратегиями и постфильтрацией стало очевидно: «идеального» ответа не существует. Любая добавленная логика улучшает один сценарий, но усложняет другой. А значит система ветвится бесконечно, усложняя и нагромождая пайплайн. И тут мы подошли к развязке нашего сюжета: необходимости управлять самим процессом получения ответа.

Изначально агент был построен как классический линейный пайплайн: пользовательский запрос, слой векторного поиска, формирование контекста, генерация LLM, ответ пользователю. Такой линейный алгоритм выглядит аккуратно и предсказуемо, но в реальности такая схема быстро перестает работать, потому что появляются условия, которые ломают линейность:

  1. Итеративность улучшений. Запрос может проходить несколько циклов: предобработка, повторный retrieval, rerank, повторная проверка релевантности и полноты контекста, и важно не просто улучшать результат, а понимать, когда уже пора остановиться.

  2. Fallback во внешний мир. Если внутреннего контекста недостаточно для уверенного ответа, то иногда системе стоит выходить за пределы базы знаний, через веб-поиск или внешние источники, а иногда признать, что ответа нет и стоит «позвать оператора/сохранить вопрос для последующей обработки человеком».

  3. Выявление кейсов, когда отсутствует необходимость в LLM. Например, в базе знаний есть прямой ответ и любой синтез ухудшит результат.

Линейная архитектура плохо масштабируется под такую динамику. Она предполагает фиксированную последовательность шагов, тогда как промышленный ИИ-агент должен

  • возвращаться на предыдущие этапы,

  • пропускать узлы,

  • выбирать разные ветки исполнения,

  • и динамически адаптировать маршрут в зависимости от состояния контекста.

Поэтому я перешла на graph-based orchestration через LangGraph. Это стало не просто рефакторингом, а радикальной сменой архитектуры системы: вместо линейного процесса появился управляемый граф состояний. Каждый узел графа отвечает за отдельное действие, а переходы между ними зависят от данных, а не от фиксированного сценария.

В итоге агент был разбит на набор нод (узлов графа):

  • normalize — нормализация и семантическое расширение запроса,

  • analyze — определение intent и типа задачи,

  • plan — выбор стратегии обработки запроса,

  • route — маршрутизация (RAG / web / direct answer),

  • rag — слой retrieval + rerank + filtering,

  • synthesis — формирование финального ответа.

При этом важный момент: часть переходов между нодами пришлось несколько раз перерабатывать. Причина простая – реальные пользовательские запросы почти никогда не укладываются в заранее заданную схему маршрутизации.

Таким образом, ключевое изменение здесь не в самих этапах, а в их свойствах: каждый шаг теперь стал независим, повторяемым и условным. Graph-orchestration подход фактически объединяет retrieval слои, метрики и логику принятия решений в единую систему управления потоком. Да, сложность архитектуры выросла, но flow стал значительно более управляемым и нелинейным, где каждый этап может повторяться, пропускаться или маршрутизироваться в зависимости от состояния запроса и качества контекста.

В итоге у меня получился адаптивный ИИ-агент с query expansion, rerank-слоем, confidence-проверками, fallback-маршрутизацией и графовой оркестрацией исполнения.

Дальнейшие планы

Интересный эффект, который проявился уже в продакшене: иногда лучший ответ — это вообще отсутствие LLM. Если пользовательский запрос напрямую совпадает с фрагментом базы знаний, система находит точное совпадение, проходит confidence-проверку и возвращает результат напрямую, без генерации, без синтеза, без дополнений от LLM. На практике это оказалось: быстрее, дешевле и стабильнее, чем любой LLM-пайплайн даже с идеальным контекстом.

После всех итераций стало очевидно, что самым сложным оказались не embeddings, не LLM, и даже не оркестрация, как таковая. Самое сложное — quality retrieval. Проблема в том, что метрики «похожести» вопроса у ИИ-агента и реальная релевантность ответа для человека — это разные измерения. Модель работает в геометрии векторного пространства, тогда как человек оценивает результат инклюзивно: учитывает контекст, полноту, наличие ключевых ограничений, соответствие намерениям и смысловую достаточность.

Дополнительная сложность – семантический шум, недостаточность контекста. Векторный поиск неизбежно подтягивает соседние по смыслу области, и высокая близость ответов не гарантирует наличие корректного результата. Отсюда возникает ключевая проблема продакшен ИИ-агентов: система должна оценивать не только похожесть, но и достаточность ответа.

Следующий этап развития системы связан с усилением retrieval-слоя. В первую очередь я планирую переход к гибридному поиску, где BM25 дополняет векторный поиск и компенсирует слабые места семантических эмбеддингов. Параллельно думаю над расширением evaluation dataset, чтобы системно улучшать качество retrieval и формировать более устойчивую картину типовых ошибок.

Отдельное направление — логирование. Важно не просто фиксировать факт ошибки, но понимать ее структуру: на каком этапе произошла деградация, какой слой ее внес, какого рода несоответствие возникло. На основе таких данных можно построить полноценный feedback loop, который будет использовать реальные пользовательские запросы для улучшения системы. Также планируется доработка rerank-модели, калибровка confidence-метрик и более строгая проверка достаточности контекста перед генерацией.

В моем кейсе после всех итераций стало очевидно: ИИ-агент — это не про LLM как центральный элемент. Это система, где ключевую роль играют quality retrieval, decision logic и orchestration подход. В этой архитектуре LLM выступает скорее как synthesis layer, чем как центральный механизм принятия решений.

Если все упростить до сути, то современный промышленный ИИ-агент, это гибридная система оркестрации: retrieval как механизм извлечения фактов, graph как механизм управления потоком, эвристики как слой принятия решений и LLM как исполнитель, подключаемый по необходимости.

 Cегодня вокруг ИИ-агентов много хайпа — от «революции» до «пузыря». Но если убрать шум, остаётся довольно прагматичная инженерная реальность: это новый класс систем, в которых вместо ручной логики появляется управляемая LLM-оркестрация. И, возможно, главный сдвиг здесь не в том, что модели стали умнее, а в том, что мы наконец начали строить вокруг них системы, которые работают предсказуемо в продакшене.