Files
llm/docs/runbooks/1c-code-embeddings.md
2026-08-14 09:40:51 +03:00

133 lines
7.6 KiB
Markdown
Raw Permalink Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
# Актуальный векторный поиск по коду 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` как
проверяемую производную копию.