Initial project import
This commit is contained in:
@@ -0,0 +1,132 @@
|
||||
# Актуальный векторный поиск по коду 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` как
|
||||
проверяемую производную копию.
|
||||
Reference in New Issue
Block a user