# Актуальный векторный поиск по коду 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 powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_embeddings.ps1 -ConfigOnly ``` Запустить сервис с загрузкой образа: ```powershell powershell -NoProfile -ExecutionPolicy Bypass -File scripts/deploy_embeddings.ps1 -Pull ``` Первый запуск скачивает модель в постоянный кеш и поэтому может занять несколько минут. Скрипт ждёт `/health`, проверяет имя модели и делает реальный запрос к `/v1/embeddings`. ## Обновление векторов Сначала адаптер должен содержать актуальные текстовые chunks. Затем worker забирает только отсутствующие либо изменившиеся фрагменты: ```powershell 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`), поэтому векторы разных размеров никогда не смешиваются. ## Поиск ```powershell 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-хешами как с именами объектов. Перед первым глобальным поиском после обновления адаптера нужно постранично заполнить локальную карту владельцев: ```json { "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` как проверяемую производную копию.