7.6 KiB
Актуальный векторный поиск по коду 1С
Цель: семантический поиск по локальному SQL-индексу адаптера без потери актуальности кода. Вектор является только производным кешем: перед выдачей адаптер сверяет найденные фрагменты с текущим состоянием конфигурации и отбрасывает либо переиндексирует устаревшие записи.
Выбранная модель
Qwen/Qwen3-Embedding-0.6B-GGUF, квантованиеQ8_0;- OpenAI-compatible endpoint на
http://docker-gpu.cin.su:8082; llama.cpp,--embedding --pooling last;- CPU-only (
--n-gpu-layers 0), чтобы не менять работающие GPU-сервисы; - endpoint возвращает 1024 измерения, клиент использует Matryoshka-срез до запрошенных 384 измерений и повторно нормализует его.
Образ llama.cpp зафиксирован digest, а модель — официальным repository/quant
селектором. Это исключает незаметную смену runtime при повторном deploy.
Модель и образ публичные, endpoint работает в изолированном тестовом контуре
без токена. Постоянный кеш модели хранится вне git в
Z:\LLM\models\cache\llama.cpp.
Развёртывание
Проверить итоговую конфигурацию:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_embeddings.ps1 -ConfigOnly
Запустить сервис с загрузкой образа:
powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_embeddings.ps1 -Pull
Первый запуск скачивает модель в постоянный кеш и поэтому может занять
несколько минут. Скрипт ждёт /health, проверяет имя модели и делает реальный
запрос к /v1/embeddings.
Обновление векторов
Сначала адаптер должен содержать актуальные текстовые chunks. Затем worker забирает только отсутствующие либо изменившиеся фрагменты:
python scripts/embed_1c_code_vectors.py `
--adapter-url http://docker.cin.su:8011/rpc `
--base-id upo_test `
--embedding-provider openai-compatible `
--embedding-model qwen3-embedding-0.6b `
--dimensions 384 `
--embedding-base-url http://docker-gpu.cin.su:8082 `
--limit 500 `
--batch-size 8 `
--chunk-kind routine `
--max-text-chars 4000 `
--json
Worker по умолчанию индексирует routine: процедуры и функции дают наиболее
точный контекст для программирования и заметно быстрее пересчитываются при
частых изменениях. Для диагностического покрытия модульных фрагментов можно
добавить второй --chunk-kind module; это более дорогой отдельный проход.
--max-text-chars не обрезает код молча: длинные chunks пропускаются в этом
проходе и остаются pending. Их нужно разбивать на окна отдельной задачей либо
индексировать в период низкой нагрузки с большим лимитом.
Размерность входит в имя кеша (openai-compatible:qwen3-embedding-0.6b@d384),
поэтому векторы разных размеров никогда не смешиваются.
Поиск
python scripts/search_1c_code_vectors.py `
"где рассчитывается сумма документа перед проведением" `
--adapter-url http://docker.cin.su:8011/rpc `
--base-id upo_test `
--embedding-provider openai-compatible `
--embedding-model qwen3-embedding-0.6b `
--dimensions 384 `
--embedding-base-url http://docker-gpu.cin.su:8082 `
--limit 10 `
--json
Поиск вызывается с strict=true и verify=true. Сохранённые изменения
Конфигуратора перекрывают активную конфигурацию, а удалённые/изменённые chunks
не возвращаются по старому вектору.
Для активного кода расширений хеш ConfigCAS разрешается через текущий
manifest расширения в descriptor объекта. Результат содержит обычные
kind/name, а также extension и extension_guid; вызывающему коду не нужно
работать с CAS-хешами как с именами объектов.
Перед первым глобальным поиском после обновления адаптера нужно постранично заполнить локальную карту владельцев:
{
"method": "metadata.module_owner_cache.backfill",
"payload": {
"base_id": "upo_test",
"limit": 50,
"kind_index": 0,
"offset": 0
}
}
Следующий вызов получает kind_index и offset из next_cursor. Повторять до
complete=true. Операция читает актуальные метаданные, но пишет только в
локальный SQLite адаптера. Найденные имена сразу добавляются в существующие
строки лексического и векторного индексов; перестраивать embeddings не нужно.
По умолчанию объекты без строк code index быстро пропускаются. deep=true
нужен только для отдельного фонового заполнения владельцев неиндексированных
модулей и не должен использоваться в интерактивном поиске.
Для Qwen3-Embedding клиент автоматически добавляет к векторизуемому запросу
англоязычную инструкцию поиска по исходному коду 1С, как рекомендует карточка
модели. В query адаптера остаётся исходный русский текст, поэтому лексическая
часть гибридного поиска не загрязняется служебным префиксом.
Отдельная векторная БД
На текущем этапе не требуется. Векторы хранятся рядом с индексом адаптера в
SQLite и выбираются линейным сканированием. Это проще и гарантирует атомарную
проверку актуальности. Отдельный ANN-движок имеет смысл только после замера
десятков тысяч актуальных chunks и неприемлемой задержки; источником истины всё
равно остаётся 1С/SQL, а ANN должен хранить chunk_id и text_sha1 как
проверяемую производную копию.