Архив рубрики ~Лента новостей~

Как мы с Claude Code учились оценивать качество RAG системы

1
Как мы с Claude Code учились оценивать качество RAG системы
Как мы с Claude Code учились оценивать качество RAG системы

Уверен, на Хабре найдётся немало статей, посвященных оценке качества RAG систем. Тема по-прежнему остаётся актуальной, потому что даже готовые библиотеки вроде RAGAS не очень-то работают из коробки, требуют навыков программирования и некоторой квалификации. При этом сам процесс оценки — повторение достаточно простых операций и мне всегда хотелось переложить его на AI-ассистента.

Повод попробовать появился неожиданно: свободное время и курс по Claude Code на Stepik. Для финала как раз нужен был проект, посвященный автоматизации реальной рутинной задачи, желательно без кода (курс про вайб-воркинг, для непрограммистов). Конечно, я сразу вспомнил про задачу оценки качества. Дальше — честная история со всеми проблемами. Забегая вперёд, скажу, что совсем без программирования не вышло. Но, может, это профессиональная деформация.

Шаг первый и первый фейл

Как начать? Я взял собственный готовый бенчмарк, таблицу с кейсами «вопрос; ответ; контекст» и отдал Клоду. Он быстро понял, что там русский язык UTF-8, но не определил разделитель полей, так как я использую точку с запятой в CSV, привычка. Дал подсказку. На что он сразу предупредил что будет гигантский расход токенов, а ещё ему нужен ключ, чтобы использовать SDK Anthropic. Ключа у меня нет, Клод предложил использовать эвристики на регулярных выражениях. Мы попробовали на одной метрике. Результат — 100% качество, что конечно жёсткая неправда. А ещё была путаница в чанках контекста, которые были склеены в один блок текста в бенчмарке.

Шаг второй. Внешняя модель

Регулярные выражения помогают только в одном случае, если в вопросе, контексте и ответе есть какой-то код, аббревиатура или шаблон, который легко извлечь. В других случаях нужен LLM-судья. И я решил его сделать на внешней модели. Выбрал gpt-4o-mini от прокси-провайдера, она часто используется в примерах для библиотеки RAGAS.

В RAGAS много метрик, не все из них полезны я планировал использовать только три. Они оценивают не качество ответа, а качество контекста, который система передаёт в модель.

Метрики

Точность контекста, Context Precision
оценивает, насколько высоко в выдаче RAG ранжированы чанки, полезные для правильного ответа. Чем выше полезный чанк, тем выше метрика.

Релевантность контекста, Context Relevance
оценивает, насколько высоко ранжированы чанки, релевантные вопросу пользователя. В отличие от Precision, не требует эталонного ответа.

Полнота контекста, Context Recall
оценивает, какая доля значимых фактов из эталонного ответа подтверждается найденным контекстом

Context Precision и Context Recall — метрики RAGAS. Context Relevance, если не ошибаюсь, нет. Она обычно получается выше чем Precision, нужно настраивать промпт, зато «не подсматривает в ответ».

В качестве первой пробной метрики решил взять Context Precision. Провёл пару экспериментов, Клод без проблем запускает скрипты из командной строки (пришлось сделать виртуальное окружение на Python). И главное — он не против внешних моделей для рутины, даже пишет, что это штатный режим, верим.

А вот проблема с парсингом контекста, если все чанки в одной ячейке таблицы, никуда не делась. Я попробовал вставлять в контекст разделители между чанками, оказалось не очень-то и надежно. Тогда появилась идея оставить в бенчмарке только вопрос и ответ, а контекст получать из RAG системы в процессе оценки каждого кейса. Это не только упростило подготовку бенчмарка, теперь я легко мог менять количество чанков в контексте.

Шаг третий. Сервис RAG и танцы вокруг MCP

План: сделать простенькую RAG систему с векторным поиском, добавить Model Context Protocol и далее использовать в субагентах. За пару часов я собрал её на FastAPI, LangChain и ChromaDB, загрузил туда тестовый контекст, всё проверил и решил добавить MCP. С библиотекой fastapi_mcp — пять минут работы.

Оказалось, не всё так просто. Клод упорно отказывался находить MCP сервер. Я прямо указывал на .mcp.json в проектной папке, на что он отвечал, что вероятно RAG система запущена после старта сессии, и что надо всё перезапустить. Ситуация повторялась снова и снова. Решил, что нужен какой-то тестер, нашёл MCP inspector (нужен Node.js).

Инспектор помог понять следующее — ни с каким видом транспорта (SSE, HTTP) моя система на запросы не отвечает, а вот если включить MCP Proxy, всё сразу начинает работать и в консоли появляется заветное 202 Accepted. Значит проблема в транспорте, который я использую. Ещё несколько экспериментов и решение было найдено, спасибо Google!

Решение

1. В блок импорта основного скрипта api.py добавить
from fastapi.middleware.cors import CORSMiddleware

2. Перед инструкциями app.include вставить блок кода

app.add_middleware( CORSMiddleware, allow_origins=[«*»], # Or specify your Web UI’s origin allow_credentials=True, allow_methods=[«GET», «POST», «OPTIONS»], allow_headers=[«*»], )NOVOSTI

3. Использовать mcp.mount() вместо mount_sse() или mount_http(), хотя это устаревшая инструкция.

Полагаю, что есть ещё варианты, которые решают проблему. Код сервера со всем необходимым — в репозитории. А README к нему, как и к этому проекту, подготовил Клод. Вот уж точно полезный навык.

Шаг четвертый. «Шумные» субагенты

Сделал два субагента — один для Context Precision, он «видит» из бенчмарка вопрос, ответ и получает контекст из RAG системы, второй — для Context Relevance. Этот, в отличие от первого, не видит ответа и оценивает контекст только по вопросу.

Клод без каких либо проблем справился с этими агентами. Увы, они оказались слишком шумными, контекстное окно засорялось прямо на глазах, по 1-2k на один кейс бенчмарка (у меня 48 кейсов и два варианта вопросов — попроще и посложнее). Клод предложил для субагентов добавить инструкцию «Do not narrate your steps between tool calls», это не очень помогло в плане токенов.

Шаг пятый. Легкий навык и инструменты

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

{ «case_id»: 0, «question»: «question text», «answer»: «answer text», «context»: [«chunk_1», «chunk_2», «chunk_3», «chunk_4»], «labels»: [1, 0, 1, 1], «explanation»: [«explanation_1», «explanation_2», «explanation_3», «explanation_4»], «score»: 0.875 }

Уточнив у Клода, в каком виде ему удобнее было бы с такой структурой работать, выяснил, что лучше всего подходит JSONL, текст, где каждая строка — отдельный JSON. На том и порешили.

Далее план был следующий — сделать инструмент с командной строкой (eval_context.py), который бы выполнял всю основную работу. Проходил последовательно по кейсам, запускал тесты и записывал результаты в отчёт. А навык всё запускал и управлял параметрами оценки.

Чтобы упростить код я взял свою готовую библиотеку CPCR_lib.py, это тоже обёртка для LLM-судьи, которая умеет выносить вердикт для оценок по всем трём метрикам.

Схема компонентов проекта
Схема компонентов проекта

Нужный класс импортируется в eval_context.py, так мы экономим токены на генерации промптов. Они не попадают в контекстное окно.

MCP в этой версии используется только как необязательная проверка доступности RAG системы. Оставил для будущих релизов. Все запросы — через REST API, что нормально для инструмента на Python. Если у кого-то получилось подключить FastAPI через MCP без дополнительных усилий, поделитесь, пожалуйста, рецептом в комментариях.

Объяснил Клоду изменения в архитектуре и попросил три вещи:
1. подготовить навык для работы с инструментом eval_context.py
2. сделать HTML вьювер для отчетов с учетом особенностей Recall (контекст склеен в один кусок,
а вместо чанков оцениваются факты)
3. подготовить дашборд для оценок по всем трём метрикам.

Навык— name: rag-evaluation description: Запускает инструменты оценки качества RAG-системы, когда пользователь просит оценить RAG, запустить метрику, или произносит слова: «оцени», «запусти оценку», «рассчитай метрику», «Context Precision», «Context Relevance», «Context Recall». — # RAG Evaluation Skill Этот skill запускает оценку качества RAG-системы по выбранной метрике. ## Trigger Используй этот skill когда пользователь просит оценить RAG, запустить метрику, или произносит слова: «оцени», «запусти оценку», «рассчитай метрику», «Context Precision», «Context Relevance», «Context Recall». ## Процедура ### 1. Собери параметры Используй инструмент `AskUserQuestion` — задай все четыре вопроса одновременно с вариантами для клика: 1. **Метрика** — `precision` / `relevance` / `recall` 2. **Benchmark файл** — `benchmark_simple.csv` / `benchmark_hard.csv` 3. **max_k** — `3` / `5` / `7` 4. **Количество кейсов** — `5` / `10` / `все` ### 2. Запусти скрипт «`powershell venvScriptspython.exe eval_context.py —scenario <scenario> —benchmark benchmarks/<file> —max-k <max_k> —cases <cases> «` Если пользователь не указал `—cases`, не передавай этот параметр (обработаются все кейсы). ### 3. Сообщи результат После завершения скрипта сообщи пользователю: — Mean метрику — Путь к JSONL файлу — Путь к Markdown отчёту

AskUserQuestion — внутренний инструмент Клод, даёт пользователю выбор из вариантов и превращает это в текстовые инструкции.

Прошу не удивляться PowerShell, проект сделан на windows-машине.

Универсальный вьювер для отчетов: Кейсы детализируются. Есть вердикт по каждому чанку.

JSONL viewer
JSONL viewer

Дашборд для трех метрик. Красотища 🙂 Можно посмотреть вклад каждого кейса в общую оценку.

002a6fed8bb8c1105da5d222fafa9b59

Подвожу итог. Оценка качества для одной метрики в расчёте на 10 кейсов занимает примерно 2-3 минуты (RAG работает на CPU). Расход токенов минимальный, в районе 500-800 на метрику. В качестве судьи можно использовать локальную модель. Рекомендация: модель не хуже 27b.

Оценку по всем трем метрикам и всем кейсам в проекте я делал несколько раз. Суммарно на LLM-судью получилось около 2М токенов (примерно 60 рублей). И ещё около 415k токенов в Claude Code на разработку: в районе 400k на все предыдущие шаги и 15k на финальную часть вместе с тестами. В плане работы, если бы делал то же самое в Python-ноутбуках — написание скриптов, отладку кода, прогон кейсов, подготовка отчетов, анализ результатов — полагаю, это заняло бы неделю на весь бенчмарк.

Источник: habr.com

Оцените материал:

Поделиться
Понравилась статья? Расскажите другим
ВКонтакте
Читайте также
Новости робототехники HEBI Robotics получает грант НАСА СБИР на ускорение создания миниатюрных приводов Новости робототехники Как компании по автоматизации внедряют ИИ, не привязываясь к отдельному поставщику Новости робототехники Внутри роскошного роботакси Uber, которое тестируют компании Lucid и Nuro. Архив рубрики ~Коротко из Telegram~ Alibaba вывела Qwen3.8-Max из preview: это MoE-флагман на 2,4 трлн… Архив рубрики ~Коротко из Telegram~ OpenAI показали, чем занималась её следующая модель Astra: она выдала… Новости робототехники У берегов Новороссийска морские дроны ВСУ потопили контейнеровоз FESCO «Янина» Новости робототехники Google DeepMind утверждает, что Gemini Robotics 2 позволяет полностью контролировать тело Новости робототехники Хлеб будущего: от руля комбайна к управлению роботизированным флотом Архив рубрики ~Коротко из Telegram~ 🎬 Dreamina Seedance 2.5 — теперь видео до 30 секунд без… Архив рубрики ~Коротко из Telegram~ Что ИИ-агенты делают, когда у них есть доступ к деньгам… Архив рубрики ~Коротко из Telegram~ Лучшие генераторы видео на ИИ Прошлись по свежим рейтингам с… Архив рубрики ~Коротко из Telegram~ Perplexity превратила Spaces в Projects Теперь в одном проекте можно… Архив рубрики ~Коротко из Telegram~ Мозговой имплант впервые помог вернуть движения парализованным рукам Если раньше… Архив рубрики ~Коротко из Telegram~ В США библиотеки учат людей жить без ИИ По всей… Новости робототехники HEBI Robotics получает грант НАСА СБИР на ускорение создания миниатюрных приводов Новости робототехники Как компании по автоматизации внедряют ИИ, не привязываясь к отдельному поставщику Новости робототехники Внутри роскошного роботакси Uber, которое тестируют компании Lucid и Nuro. Архив рубрики ~Коротко из Telegram~ Alibaba вывела Qwen3.8-Max из preview: это MoE-флагман на 2,4 трлн… Архив рубрики ~Коротко из Telegram~ OpenAI показали, чем занималась её следующая модель Astra: она выдала… Новости робототехники У берегов Новороссийска морские дроны ВСУ потопили контейнеровоз FESCO «Янина» Новости робототехники Google DeepMind утверждает, что Gemini Robotics 2 позволяет полностью контролировать тело Новости робототехники Хлеб будущего: от руля комбайна к управлению роботизированным флотом Архив рубрики ~Коротко из Telegram~ 🎬 Dreamina Seedance 2.5 — теперь видео до 30 секунд без… Архив рубрики ~Коротко из Telegram~ Что ИИ-агенты делают, когда у них есть доступ к деньгам… Архив рубрики ~Коротко из Telegram~ Лучшие генераторы видео на ИИ Прошлись по свежим рейтингам с… Архив рубрики ~Коротко из Telegram~ Perplexity превратила Spaces в Projects Теперь в одном проекте можно… Архив рубрики ~Коротко из Telegram~ Мозговой имплант впервые помог вернуть движения парализованным рукам Если раньше… Архив рубрики ~Коротко из Telegram~ В США библиотеки учат людей жить без ИИ По всей…

Оставить комментарий