• Русский
  • Создание пользовательской базы знаний

    Плагин Alauda Hyperflux поставляется со встроенной системной базой знаний, охватывающей Alauda Container Platform (ACP) и документацию продуктов Alauda. Наряду с ней Hyperflux поддерживает отдельную пользовательскую базу знаний, которую можно заполнить собственным содержимым — внутренними runbook, SRE playbook, проектной документацией, версиями документации по продуктам Alauda, которые не входят в поставляемый корпус, или любыми другими приватными Git repositories. Hyperflux выполняет поиск по обеим базам знаний при каждом запросе и объединяет результаты, поэтому добавление пользовательского корпуса расширяет поставляемую продуктовую базу знаний, а не заменяет её.

    Это руководство описывает путь, управляемый администратором: массовый импорт списка Git repositories в пользовательскую базу знаний с использованием builder внутри pod. (Для загрузки файлов конечными пользователями через chat UI используйте инструмент BYO Knowledge, добавленный в v1.3.1 — та же целевая база, но другой entry point.)

    Рабочий процесс выполняется внутри развернутого pod smart-doc. В образ уже включены исходный код builder, embedding model и нужное Python-окружение, а в pod уже есть подключение к PostgreSQL пользовательской базы знаний. Вам нужен только manifest с repository для импорта и доступ kubectl exec к глобальному cluster.

    Как работает pipeline embedding

    builder smart-doc преобразует список Git repositories в векторизованную базу знаний в два этапа:

    1. Prepare — клонирует repositories, разделяет каждый документ .md / .mdx по заголовкам и размеру chunk, затем вызывает LLM (тот же, который уже настроен для запущенного плагина Hyperflux) для генерации однопараграфного summary и нескольких репрезентативных вопросов для каждого документа. Результат: documents.json.
    2. Embed — загружает embedding model gte-multilingual-base, вычисляет embeddings как для chunks, так и для summary каждого документа, и записывает их в PostgreSQL пользовательской базы знаний (docvec_user_kb) под именем collection, которое читает запущенный server (user_defined_kb по умолчанию).

    После этого запущенный server подхватывает новый контент при следующем запросе — без изменения chart, без перезапуска pod. Системная база знаний при этом не затрагивается.

    ПРИМЕЧАНИЕ: BM25 index, используемый гибридным retrieval, не создаётся на этапе embed. Поставляемые дампы системной базы знаний содержат заранее построенный BM25 index, но база данных пользовательской KB создаётся пустой во время установки. Если в вашем deployment включён hybrid retrieval (по умолчанию), вы должны один раз создать BM25 index для collection пользовательской KB — см. Step 5.

    Предварительные требования

    • Доступ kubectl к cluster, на котором работает Hyperflux (глобальный cluster), с правом exec на pod smart-doc в namespace cpaas-system.
    • Доступ на чтение ко всем Git repositories, которые вы хотите импортировать. Если они приватные, подготовьте пару HTTPS user/token.
    • LLM endpoint с достаточной квотой. На этапе prepare выполняется один вызов LLM на каждый исходный документ (примерно 1 000–3 000 вызовов на базу знаний размера ACP). По умолчанию команды внутри pod используют LLM endpoint, уже настроенный для Hyperflux (тот, который был задан при установке через LLM Base URL / LLM API Key / LLM Model Name). Если у вашей учетной записи есть ограничения по rate limit, подготовьте отдельный endpoint с более высокой квотой и переопределите переменные окружения в exec session (Step 3).

    Вам не нужны отдельное Python-окружение на рабочей станции, загруженная копия gte-multilingual-base, отдельный экземпляр PostgreSQL или клон repository smart-doc — всё это уже встроено в container smart-doc.

    Step 1 — Опишите свой корпус

    Создайте JSON manifest со списком всех Git repositories, которые нужно импортировать. Сохраните его на локальной машине как my-kb.json (подойдет любое имя — вы скопируете файл в pod на Step 2).

    {
      "kb_version": "1.0",
      "repos": [
        {
          "git_repo": "https://github.com/myorg/internal-docs",
          "branch": "main",
          "doc_version": "1.0",
          "title": "Internal Docs",
          "doc_url_template": "/internal-docs/{{ABSOLUTE_URL.split('/docs/en/')[-1].replace('.mdx','.html').replace('.md','.html')}}",
          "origin": "internal",
          "sub_dirs": ["docs/en"],
          "doc_type": "md,mdx"
        }
      ]
    }

    Добавьте дополнительные записи repos, чтобы импортировать несколько repositories за один запуск.

    Справочник по полям:

    ПолеОписание
    git_repoGit URL. Для HTTPS auth используются GIT_USER / GIT_TOKEN (или GITHUB_USER / GITHUB_TOKEN для github.com).
    branch / tagBranch (по умолчанию main) или tag (если заданы оба, приоритет у tag).
    doc_versionМетка версии, сохраняемая для каждого chunk; используется в фильтрах retrieval.
    titleЧеловекочитаемое имя корпуса; отображается в цитатах ответа.
    doc_url_templateШаблон Jinja, формирующий относительный URL для каждого документа; на этапе retrieval конкатенируется с ONLINE_DOC_BASE_URL. Переменная ABSOLUTE_URL — локальный абсолютный путь документа.
    originСвободная метка категории, например internal, ACP.
    sub_dirsНеобязательно — импортировать только эти подкаталоги repository.
    doc_typemd, mdx или md,mdx.
    kb_versionПроставляется в каждом chunk в metadata.version; используется для проверки, что все chunks в дампе получены из одного и того же запуска prepare.

    Step 2 — Скопируйте manifest в pod smart-doc

    # Find the smart-doc pod (single-replica by default).
    POD=$(kubectl -n cpaas-system get pod -l app=smart-doc \
      -o jsonpath='{.items[0].metadata.name}')
    
    # Copy your manifest into the pod's /tmp (the only reliably writable path
    # under runAsUser=697; /workspace-smart-doc is read-only).
    kubectl -n cpaas-system cp my-kb.json "${POD}:/tmp/my-kb.json" -c serve

    Step 3 — Запустите prepare внутри pod

    Откройте интерактивную shell-сессию в container serve и выполните этап prepare:

    kubectl -n cpaas-system exec -it "${POD}" -c serve -- bash
    
    # --- inside the pod ---
    cd /tmp                           # writable; outputs land here
    
    # Required for doc_summary vectors. Read by split_doc.py at PREPARE time —
    # setting it later (at embed time) has no effect.
    export ENABLE_GEN_QUESTIONS=true
    
    # Only if your repos are private:
    export GIT_USER=<your-git-user>
    export GIT_TOKEN=<your-git-token>
    # For github.com use these instead:
    # export GITHUB_USER=<your-github-user>
    # export GITHUB_TOKEN=<your-github-token>
    
    # Optionally override the LLM endpoint for this session if the chart-default
    # one is rate-limited. The builder uses langchain's AzureChatOpenAI, so the
    # Azure-style env vars below are honoured; AZURE_OPENAI_API_VERSION defaults
    # to "2024-12-01-preview" if you omit it.
    # export LLM_BASE_URL=...
    # export LLM_API_KEY=...
    # export LLM_MODEL_NAME=...
    # export AZURE_OPENAI_DEPLOYMENT_NAME=...
    # export AZURE_OPENAI_API_VERSION=...      # optional
    
    python /opt/packages/emb_builder/smart_doc_builder.py prepare \
      --config /tmp/my-kb.json
    # → writes /tmp/documents.json

    Полезные флаги:

    • --dryrun — клонирует repositories и выводит список документов, но не вызывает LLM. Сначала используйте этот режим, чтобы проверить, что фильтры sub_dirs и doc_type соответствуют ожидаемым.

    ПРИМЕЧАНИЕ: prepare не кеширует ответы LLM между запусками — каждый вызов повторно выполняет по одному запросу LLM на каждый исходный документ. Планируйте полную стоимость на документ при каждом повторном прогоне и повторно запускайте prepare только тогда, когда действительно изменился исходный корпус (иначе повторно запускайте только embed для уже существующего documents.json).

    Step 4 — Запустите embed внутри pod

    Оставайтесь в той же shell-сессии, чтобы переменные окружения из Step 3 по-прежнему действовали:

    python /opt/packages/emb_builder/smart_doc_builder.py embed \
      --from-json /tmp/documents.json \
      --pg-conn-str "${PG_USER_KB_CONN_STR}" \
      --collection-name user_defined_kb \
      --vector-types chunk,doc_summary \
      --min-chunk-size 600 --max-chunk-size 2000 --chunk-overlap 200

    Chart уже экспортирует EMB_MODEL_NAME=/opt/gte-multilingual-base, DEVICE=cpu и PG_USER_KB_CONN_STR (указывающую на базу данных пользовательской KB docvec_user_kb), поэтому передавать --emb-model или --device не нужно. Явно передайте --pg-conn-str "${PG_USER_KB_CONN_STR}", поскольку значение по умолчанию в script — строка подключения к системной KB (PG_SYS_KB_CONN_STR).

    Что делают флаги:

    ФлагРекомендация
    --pg-conn-str "${PG_USER_KB_CONN_STR}"Указывает на базу данных пользовательской базы знаний. Не направляйте на PG_SYS_KB_CONN_STR, если только вы сознательно не пытаетесь заменить поставляемую продуктовую базу знаний (см. раздел «Replacing the system knowledge base» ниже).
    --collection-name user_defined_kbИмя collection, из которого запущенный server читает данные в docvec_user_kb. Используйте именно это значение — chart в настоящее время не предоставляет способа изменить имя collection пользовательской KB, которое читает server.
    --vector-types chunk,doc_summaryMulti-vector: каждый документ вносит как chunk vectors, так и summary vector уровня документа. Соответствует производственной форме retrieval — оставьте включённым.
    --min-chunk-size / --max-chunk-size / --chunk-overlapЗначения по умолчанию: 600 / 0 / 200 (см. вывод --help у embed); --max-chunk-size 0 означает разбиение только по заголовкам без верхней границы. Задайте верхнюю границу, например 20003000, если хотите, чтобы каждый длинный документ дополнительно разбивался на более мелкие chunks. Более крупные chunks немного улучшают recall для длинных документов, но используют больше token на ответ.

    ПРЕДУПРЕЖДЕНИЕ: Если --vector-types включает doc_summary, но documents.json был создан запуском prepare, в котором не был установлен ENABLE_GEN_QUESTIONS=true, embed молча создаст 0 summary vectors и лишь выведет в конце no_summary=N. Если значение no_summary высокое, повторно запустите prepare с ENABLE_GEN_QUESTIONS=true перед повторным запуском embed.

    ПРИМЕЧАНИЕ: container serve по умолчанию работает на CPU (DEVICE=cpu). Встраивание 5 000 chunks на CPU занимает примерно час; для небольшого внутреннего корпуса (несколько сотен документов) — несколько минут. Если вам нужен GPU throughput, запустите build на pod, запланированном на GPU (это выходит за рамки данного руководства), и используйте путь dump-and-restore между cluster, описанный далее.

    Этап embed не вызывает LLM; его можно недорого повторно запускать для того же documents.json, чтобы попробовать другой размер chunk или расширить существующую collection новыми документами.

    Step 5 — Создайте BM25 index для пользовательской базы знаний (один раз)

    База данных пользовательской KB создаётся пустой во время установки — в отличие от поставляемых дампов системной KB, в ней не создаётся BM25 index заранее. Если включён hybrid retrieval (по умолчанию), создайте index один раз после первого запуска embed:

    psql "${PG_USER_KB_CONN_STR}" -c "
      CREATE INDEX IF NOT EXISTS langchain_pg_embedding_bm25_idx
        ON langchain_pg_embedding
        USING bm25 (id, document)
        WITH (key_field='id');
    "

    Без этого index путь hybrid retrieval молча переключается на dense-only для пользовательской KB (результаты по-прежнему возвращаются, но без точного совпадения по ключевым словам).

    На этом всё — ни изменение chart, ни перезапуск pod не требуются. Запущенный server уже читает данные из docvec_user_kb / user_defined_kb при каждом запросе, поэтому ваш пользовательский корпус начинает влиять на ответы немедленно. Проверьте это, задав типовой вопрос через chat UI.

    (Необязательно) Multi-cluster: dump и restore

    Если вы хотите один раз собрать корпус и затем развернуть его в нескольких cluster, выполните pg_dump пользовательской KB после Step 4 и восстановите его на каждом целевом cluster:

    # --- on the source cluster, inside the smart-doc pod ---
    pg_dump "${PG_USER_KB_CONN_STR}" -Fc -f /tmp/user_kb.dump
    
    # --- on the workstation ---
    kubectl -n cpaas-system cp \
      "${POD}:/tmp/user_kb.dump" \
      ./user_kb.dump
    
    # --- for each target cluster ---
    TARGET_POD=$(kubectl -n cpaas-system get pod -l app=smart-doc \
      -o jsonpath='{.items[0].metadata.name}' --context <target-context>)
    
    kubectl -n cpaas-system --context <target-context> cp \
      ./user_kb.dump \
      "${TARGET_POD}:/tmp/user_kb.dump" -c serve
    
    kubectl -n cpaas-system --context <target-context> exec -it \
      "${TARGET_POD}" -c serve -- bash -c \
      "pg_restore -d \"\${PG_USER_KB_CONN_STR}\" /tmp/user_kb.dump"

    Затем выполните Step 5 (BM25 index) на каждом целевом cluster — index является per-database и сам по себе не сохраняется при restore в пустую DB (при restore в уже заполненную DB BM25 объединяется, если присутствует в дампе; для новой пользовательской KB после restore выполните CREATE INDEX).

    ПРИМЕЧАНИЕ: pg_restore дампа пользовательской KB в целевой cluster, где уже есть содержимое user-KB (например, предыдущие BYO uploads), вызовет конфликт на CREATE таблиц langchain. Для чистого overlay используйте вместо этого механизм swap chart или сначала удалите и заново создайте docvec_user_kb на целевом cluster. Обычный pg_restore наиболее безопасен только тогда, когда целевая пользовательская KB пуста.

    Замена поставляемой системной базы знаний (advanced)

    Описанный выше workflow добавляет данные в user KB и оставляет поставляемую продуктовую базу знаний без изменений. Если у вас другое требование — например, поставляемая документация Alauda в вашем окружении неверна, и вы хотите заменить её на внутреннюю версию — выполните тот же workflow внутри pod, но нацельтесь на системную KB:

    • --pg-conn-str "${PG_SYS_KB_CONN_STR}"
    • --collection-name <your-system-kb-collection-name>
    • Обновите pgconnect.pgCollectionName в chart, чтобы он указывал на имя вашей collection, и выполните повторный запуск.

    Этот путь требует изменения chart и отключает автоматические обновления системной KB при будущих релизах Hyperflux (проверка правила auto-swap не совпадёт с вашим пользовательским именем collection). Используйте его только тогда, когда расширения пользовательской KB недостаточно.

    Периодичность повторных запусков

    Пользовательские базы знаний устаревают быстрее, чем продуктовая документация. Планируйте повторный запуск prepare → embed по расписанию, соответствующему вашим source repositories:

    • Runbook, которые меняются ежедневно → nightly cron (Kubernetes CronJob, выполняющий те же команды внутри pod как одноразовый job) с повторным embedding в ту же collection user_defined_kb.
    • Архитектурная документация, обновляющаяся ежеквартально → ручной повторный запуск на каждом релизном рубеже.

    Повторный запуск embed для той же collection использует детерминированные row ID (make_row_id в smart_doc_builder.py:38-48), поэтому неизменённые chunks обновляются идемпотентно, а изменённые chunks перезаписываются — но строки для документов, которые были удалены из manifest, становятся сиротскими. Для чистой замены удалите и заново создайте collection перед повторным embedding:

    psql "${PG_USER_KB_CONN_STR}" -c "
      DELETE FROM langchain_pg_embedding
      WHERE collection_id = (SELECT uuid FROM langchain_pg_collection WHERE name='user_defined_kb');
      DELETE FROM langchain_pg_collection WHERE name='user_defined_kb';
    "

    Затем повторно выполните Step 4, чтобы заполнить данные заново. BM25 index на langchain_pg_embedding продолжает автоматически применяться к новым строкам, поэтому повторно выполнять Step 5 не нужно — если только вы не удаляли саму базу данных (например, для overlay через pg_restore в multi-cluster, описанного выше).

    Ограничения и особенности

    • Пользовательский корпус использует общую user KB вместе с загрузками через BYO Knowledge tool. Файлы, которые конечные пользователи загружают через chat UI (добавлено в v1.3.1), попадают в ту же collection user_defined_kb, что и корпус, управляемый администратором. Они сосуществуют, пока не конфликтуют URL; на практике это нормально, потому что BYO uploads используют отдельную схему URL. Если вы когда-нибудь удалите и заново создадите collection (раздел Re-roll cadence), BYO uploads в этой collection будут удалены вместе с вашим корпусом — если они важны, сначала сделайте резервную копию.
    • Фильтры версии системной KB не применяются к user KB. Когда пользователь задаёт вопрос, зависящий от версии (например, об ACP 4.3), системная KB фильтруется по этой версии, а user KB возвращает совпадения по всем версиям. Если ваш пользовательский корпус содержит несколько версий, ожидайте, что в ответах будут появляться chunks из разных версий.
    • Несоответствие embedding model — самая частая тихая ошибка: vectors, созданные чем-либо, кроме встроенной /opt/gte-multilingual-base, можно будет извлечь, но они всегда будут давать оценку близкую к нулю, поэтому ответы будут сводиться к «У меня недостаточно информации» без явной ошибки. Описанный здесь workflow внутри pod по умолчанию использует встроенную модель — переопределяйте EMB_MODEL_NAME только если точно понимаете, что делаете.