Галоўная / Артыкулы

RAG без базы дадзеных вектараў: пайплайн у BigQuery SQL і таму, дзе ён не працуе

Створыце генераванне з падтрымкам разышчання выключна на BigQuery SQL, ад занурэнняў да падставленых адказаў, а пасля паглядзіце на косты, квоты і ліміты версіяў запытанняў.

Выдавец: REACTAPP.TOP11 хв чытання2592 слоў

Крыніцы: SQL Is All You Need: A Complete RAG Pipeline in SQL with BigQuery

База дадзеных вектараў, аранжар, служба эмбедынгу, клучы API, распадзеленыя між усімі імі, і тры цантэйнеры проста для адпаведзення на запытанні пра вашыя сабе дакументы. Гэта і форма генеравання з падтрымкай адзысквання інформацыі, якая выкліквалася ў большасці нарадчыкаў, і для большай групы варыянтав выкарыстання яе можа больш не быць неабходнаю.

Функцыі AI у BigQuery дазваляюць LLM паводзіцца як будзь-яны іншы оператар SQL, так сама, як гэта робяць оператары JOIN або WHERE. Эмбедынг, пошук вектараў і структураванае генераванне адбываюцца там, дзе вярзаны даныя, пад вашым IAM, логамі аўдыту і контролем выкарыстання рэсурсаў. Гэта таксама не ўзбудованы «закрыты» прастор адноўказовае модэлі — можна выкарыстоўваць Claude, Llama, Mistral і модэлі з адкрытым кодам з Hugging Face.

У наступных раздзелах аднаковы практычны прыём практыкуецца двума спосабамі на аднам публічным наборэ дадзейнаў, да якога можа з’явіцца кожны — корпусе новэй BBC за адрэсам bigquery-public-data.bbc_news.fulltext. Першы спосаб — гэта одноразовая версія на базе пакетных обработак, якая выкарыстоўвае стандартныя функцыі. Другі спосаб — гэта версія у прыглядзе, дзе корпус пастаеце актуальным праз дадзенні, якія прыходзяць. Пасля чаго даёмся чыстая аналіза тых момантов, дзе такі падход не працуе, і паказуецца, што Python застаецца лепшым рашэннем.

Тэхналогіі, якія прымутваюцца большасцю наставленняў

Стандартная наладка RAG зазвычай включае:

  1. Срэдства для стварэння эмбеджаў: хоставаная API або канцэнтры модэля, якія трэба запускаць і падтрымляць
  2. База дадзейнаў вектараў, якая даганяе ўсё больш выпавэльнікаў, больш расчытак і больш практычных прыёмаў для падтрымкі адпаведнасці з асалодным джэрэлам дадзейнаў
  3. Оркестратор, такі як LangChain, LlamaIndex або ручна напісаны код для сінхронізаціі
  • API для LLM з сае мерамі розміру трафіку і квотамі
  • Хостынг для всіх эўх элементаў, зазвычай калькі кантэйнераў, якія трэба пакаваць і сталоўна аптаваць
  • Працавайце з часткамі: пяць сістэм і прынеймна тры ключы API. А потым ёсць косц, пра які ніхто не гаворыць — адносна таго, што вашы даны пакідаюць склад. Кожная правіла карыстоўніцтва, політыка безпекі на рэвэлі і трэбаванні да аўдыту, якія ўбудованы ў BigQuery, перастаюць дзейсніцца ў момент, калі фрагменты экспортуюцца у званечны вектарны склад.

    Такая архітэктура існавала таму, што не было альтэрнатывы. Але прычыны змяніліся.

    LLM як оператар SQL

    Семья функцый AI.* у BigQuery стала загальна доступная. Для тэхналогіі RAG важныя тры элементы:

    • AI.GENERATE_EMBEDDING стварае эмбеддынгі масова з любай табелі.
    • VECTOR_SEARCH адзварачва сэмантычныя даны як вбудованая функцыя GoogleSQL. Вы можэце дадзіць індэкс IVF або TreeAH, пры чым TreeAH базуецца на алгорытме ScaNN ад Google.
    • AI.GENERATE — гэта функцыя, якая працуе з кожным рэядком і можа вярнуць структураваны выход праз output_schema; яна падходзіць там, дзе можа падходзіць любая значэнне, укладаючыся ў умовы SELECT, WHERE і нават JOIN.

    У вашам кодзе не павінны быць ніякія ключы. Автанація адбываецца праз з’яўленне з BigQuery — адмініструваны рахунак службы, якому вы аднойчы надаеце ролю. Існуе стандартнае з’яўленне, якае абмеркавае большую частку налагоджэння.

    Вы не прыкрэплены да Gemini

    Частая прытрымка — што гэта прыкрэпляе вас да Gemini. Аднак гэта не так, хоць дэталі часта неправільна разумеюцца. Функцыі бяруць два відзнакі.

    Функцыі загальнага прызначэння, такія як AI.GENERATE_TEXT, AI.GENERATE_TABLE і AI.GENERATE_EMBEDDING з параметрам MODEL, даюць вам паўны контроль над тым, які модэль будзе выкананы. Серэд падтрымваных аддаленых модэляў — сям’я Gemini, а таксама Anthropic Claude, Meta Llama і Mistral AI як кераваныя канцэнтры, і модэлі з адкрытым кодам з Hugging Face чыста Model Garden на платформе агентаў Google (ранейшая Vertex AI). Для модэляў з адкрытым кодам функцыя CREATE MODEL можа нават аўтаматычна запусціць модэль.

    Кераваныя функцыі (AI.IF, AI.CLASSIFY, AI.SCORE і скалярная AI.GENERATE калі заданы endpoint) — гэта спрыткі, падтрымваныя Gemini. BigQuery выбірае модэль і займаецца формулюванням запыткаў.

    Указваецца, што для дапэўнення супакоранасці трэбаеся включэнні з самастаянае хоставанаяя багатыязычнаяя модэль E5 або Qwen, пры чым Воблак здабывае адпаведныя адказы. Кожны з этых падходаў пачынаецца з адной тэкстовай запісі CREATE MODEL. Для включэнняя гэта ёсць ўсё, што трэба, адколі нічога далей не пераключаецца. Працэс генеравання мае адну умову.

    Першы падход: парадоксальная паўтараючаяся схема (зазвычай доступная)

    Гэты патэрн падходзіць для пакетнай і аналітычнай работы, калі корпус тэкста включаецца раз або за пазначаным графікам, а пасля — адбываюцца запыты.

    Крок 0: адноразовая наладка

    З’яўленне з’язку — гэты крок, які большасць інструкцый для працы з базамі дадзеных працягвае ігнораваць. Ооўсё ў тым, што гэта адказваны кантэкст адслужвання, праз які BigQuery падключаецца да модэляў, і яго ствараюць толькі аднажды.

    Калі у вас ёсць роль адміністратара BigQuery, шырэйшы спосаб — гэта стандартныя наладжэнні з’яўлення. У запісе запішыце WITH CONNECTION DEFAULT, і BigQuery сама ўсе наладзіць, аддаўшы неабходныя правыя на першым выкарыстоўванні.

    Калі ж вы хочаце самі кераваць наладжэнням з’яўлення, якое ў другім спосабе паказваецца як us.my_connection, для этага патрэбны два каманды: спачатку створыць наладжэнне рэсурса Cloud, а потым надаць яго адказвальнаму рахунку праву пад назвай Agent Platform User (roles/aiplatform.user, ранейша Vertex AI User).

    PROJECT_ID=my-poject-id
    
    # 1. Create a Cloud resource connection (its location must match your dataset)
    bq mk --connection --location=US --project_id=$PROJECT_ID \
      --connection_type=CLOUD_RESOURCE my_connection
    
    # 2. Grant the connection's service account the Agent Platform User role
    gcloud projects add-iam-policy-binding $PROJECT_ID \
      --member="serviceAccount:$(bq show --format=prettyjson \
        --connection $PROJECT_ID.US.my_connection | jq -r .cloudResource.serviceAccountId)" \
      --role=roles/aiplatform.user
    

    Тое, дзе вы надаеце роль, залежыць ад таго, як апыляецца да модэлю: у праекце, які ўладае модэлю, калі вы пасылаеце імя, або ў праекце з URL канцачнай точкі, калі вы пасылаеце цэлы URL. Автанацыя завершаецца там, з адной роллю і без ключоў.

    Далей выкарыстоўваецца модэль embedding, паўтараючы стандартныя наладжэнні з’яўлення:

    CREATE OR REPLACE MODEL `rag_demo_us.emb_model`
      REMOTE WITH CONNECTION DEFAULT
      OPTIONS (ENDPOINT = 'gemini-embedding-001');
    

    Гэта заява ўсё, што трэба для запуску службы вбудоввання. Не існуе кантэйнера, няма тэрміналу для масштабавання і няма ключа для замены. Калі вы запускаеце мадэль на адкрытым кодзе, проста заменіце ў яе URL тэрмінал.

    Крок 1: вбудовваць корпус

    Одна заява вбудоввае статты BBC:

    CREATE OR REPLACE TABLE `rag_demo_us.news_emb` AS
    SELECT *
    FROM AI.GENERATE_EMBEDDING(
      MODEL `rag_demo_us.emb_model`,
      (
        SELECT title, body AS content
        FROM `bigquery-public-data.bbc_news.fulltext`
        WHERE category = 'tech'
      ),
      STRUCT('RETRIEVAL_DOCUMENT' AS task_type)
    );
    

    Есць два моманты, якія лёгкая працяя заўсёды працягнуць. У запытцы на ввод неабходнае наяўнасць столбца пад назвай content, які можа быць перайменаваны, а дадаць столбец title павышае якасць эмбедынгу для RETRIEVAL_DOCUMENT. Таксама важлівы task_type: для корпусу выкорыстоўваеце RETRIEVAL_DOCUMENT, а для запыткі корыстувальніка — RETRIEVAL_QUERY, адтак як асіметрычны эмбедынг значна павышае якасць аднаходжэння інфармацыі.

    Утварэная табліца мае вашы столбцы-перадачы і дадае трохі новых створаных столбцоў. embedding мае вектар, statistics — гэта значэнне у фармаце JSON з паказаннем token_count і truncated, а status адзвярняе адныя бягі. Заўважыце, што новейшыя версіі AI.GENERATE_EMBEDDING вяртаюць embedding, а не ml_generate_embedding_result, які быў у старэйшых інструкцыях ML.GENERATE_EMBEDDING. Сумешчанне гэтых двух фарматаў — гэта класычны прыклад неправільнага копіювання-выклейвання.

    Першая прыгучка: тыямная частковая неудача. Аб’яднаная задача можа завершыцца успехам, адзначыячы загаловы рэзультат, аднак окольныя рэкорды можу зазнаць неудачы чырвонай прычыны — напрыклад, праз перагрузку квотай або трыбулі з сервісам. BigQuery адзвярцаецца пра гэта для кожнага рэкорда ў поле status; пустая строчка означае успех, таму завжды выкарыстоўваеце фільтрацыю WHERE status = ''. Калі паралельныя аб’яднанні зустрэнуць прычыны, связаныя з выкарыстанымі рэсурсамі, Google аддае скрыпты для павторных спроб обработкі з даўней далёкасці, а таксама пакет Dataform, які будзе ператвараць задачы, пакуль не будзе обработаны кожны рэкорд.

    Другая прыгучка: тыямная атрымоўка. У поле statistics кожнага рэкорда паказваецца колькасць токенаў і флаг атрымоўкі. Новыя статыі складаюцца з калькі соткаў токенаў, але дакументы, дыягональнае розмір якіх перавышае ліміт вхідных дадзенняў модэлю, будуць атрыманыя ў атрымоўанай форме без жадных паўтарэнняў. Для дужа дзяўнасных дакументаў трэба сочыць за флагам атрымоўкі і загадзя іх раздзеляць на часткі.

    Шаг 2: за неабавесць, дадаць індэкс

    Маленькі корпусы можаць іх працяваць без іх, таму што VECTOR_SEARCH пераходзіць на просты пошук за дапамою сіловага. Пры вялікіх масштабах неабяжна стварыць такі корпус:

    CREATE OR REPLACE VECTOR INDEX news_idx
    ON `rag_demo_us.news_emb`(embedding)
    OPTIONS (index_type = 'IVF', distance_type = 'COSINE');
    

    Калькілівыя дзеянні, якія можна спакаваць: падтрымкай індэкса здзейсніваецца за вас у фонавым рэжыме, радкі, якія дадаюцца пазней, можна шукаць адразу (BigQuery скануе неіндэксаваны залішак сіловым спосабам), табліцы размаху менш 10 MB не атрымуюць індэкса, а версія Standard не падтрымляе індэксы.

    Шаг 3: адзысканне і стварэнне ў аднам запытанні

    Уключыце запытанне, атрымайце пяць лепшых статэйкаў, адпрацаваце запыт і створыце напісаны адказ:

    SELECT
      AI.GENERATE(
        (
          'Answer using only this context:\n',
          STRING_AGG(base.content, '\n---\n'),
          '\nQuestion: what were the major browser security stories?'
        ),
        endpoint      => 'gemini-2.5-flash',
        output_schema => 'answer STRING, confidence FLOAT64, sources ARRAY<STRING>'
      ).*
    FROM VECTOR_SEARCH(
      TABLE `rag_demo_us.news_emb`, 'embedding',
      (
        SELECT embedding
        FROM AI.GENERATE_EMBEDDING(
          MODEL `rag_demo_us.emb_model`,
          (SELECT 'major browser security stories' AS content),
          STRUCT('RETRIEVAL_QUERY' AS task_type)
        )
      ),
      top_k => 5
    );
    

    Асалевы канал складаецца з апошніх дзесятка ліній, у яму няма LangChain, няма зовнішньага сховішча вектараў і няма нічага, што трэба размясціць. А output_schema задае столбцы з вказанымі тыпамі для адпаведзення, значэннем доверы і джэрамі, а не куском JSON, які трэба парсаваць і на які трэба спадзявацца.

    Аднак мерыя версіі для аднаго запыту ёсць серьзёзныя. Даныя не застаюцца стацыярнымі: прыходзяць новыя статыі, зміняюцца апісанні, а тыкеты апдэююцца. Кожная дадзенне або зміна значыць павтарэнне выканання заповедзі на стварэнне вектара, выявленне змян, кераванне павторнымі спробамі і назіранне за застарэлымі данымі.

    Другі падход: корпус, які сам сабе падтрымлівае (перадвыклак)

    Аўтонамнае стварэнне вектараў — гэта рашэнні. Заявіце вектар як створаны столбец, і BigQuery будзе сам падтрымліваць яго у актуальным стане:

    CREATE TABLE `rag_demo_us.news_live` (
      title STRING,
      body  STRING,
      body_embedding STRUCT<result ARRAY<FLOAT64>, status STRING>
        GENERATED ALWAYS AS (
          AI.EMBED(
            body,
            connection_id => 'us.my_connection',
            endpoint      => 'gemini-embedding-001')
        ) STORED OPTIONS (asynchronous = TRUE)
    );
    

    Потым увайсце даны з будзь-якага месца:

    INSERT INTO `rag_demo_us.news_live` (title, body)
    SELECT title, body
    FROM `bigquery-public-data.bbc_news.fulltext`
    WHERE category = 'tech';
    

    Этот матэрыял варта прачытаць два разы. За дапамою GENERATED ALWAYS AS AI.EMBED(...) інфармацыя, якая генеруецца, стае метаданамі таблыцы, а не кодам канвэю. Як толькі адменістратор адначытае або апдэйтуе стовпец сыроў, BigQuery стварае або апдэйтуе вектар у фонавым рэжыме. Калі задана настройка asynchronous = TRUE, адначытанне даных не чакае на выкананне модэлю, а праця з генераванням інфармацыі вядзецца у фонавых процэсах, працы якіх у історыі заданнях маюць прыметнік gc_. Стовпец мае фармат STRUCT<result, status>, таму будзь-якія неудачы паказваюцца для кожнай строкі окрэма і не ігнаруюцца.

    Па выбору модэлі, у прыкладзе выкарыстоўваецца gemini-embedding-001, таму што ён быў загальна доступны і паставіўся добра ў табелі лідэраў мультыязычных MTEB у тым часе. У стандартным прыкладзе дасягненняў выкарыстоўваецца text-embedding-005, які таксама працюе на однакова хорашаўшым чынам. Неабходна врачымаць адна наследкі: стандартны выхід мае 3072 выміры, тады калі модэлі text-embedding — 768, і гэта падвышае вітраты на зберохват і індэксаванне. Ёжы ад гэтага, прагледзіце можлівасць выкарыстоўваць меньшы розмер праз model_params у AI.EMBED. Модэль трэнуецца у стыле матрыёшкі, таму ёе можна легка скорачыць да 768 або 256 вымераў.

    Запыты таксама стаюць простыяйшымі. AI.SEARCH вышукае, з якой модэлі была створана табліца, і сам адразу включые запытаваны тэкст:

    SELECT base.title, base.body, distance
    FROM AI.SEARCH(
      TABLE `rag_demo_us.news_live`, 'body',
      'major browser security stories',
      top_k => 5
    );
    

    Тэкст шукаецца ў столцы з тэкстам, а склад керуе вектарамі у тле. Тут таксама падтрымліваюцца вектарныя індэксы: створыце іх у выходным столцы, і навчанне пачынаецца, калі 80% рэядоў маюць эмбеддынгі.

    Для усяго, што будзе вікорыстоўвацца у працэсе, важна самэ гэтае выданне. Падход «однаго разу» ёсць толькі дэманстрацыяй, тады як самастойна падтрымваемы корпус — гэта расклад, які можна вядомаць гады.

    Адзін пункт застосоўваецца: гэты частак належыць да прэвью, па правілах, якія могу змяніцца раней, чым запускаецца GA. Таксама памятайце, што кожная табліца мае адну столбець автагенераванага embedingu, што вставкі трэба выкананы пакетамі, а не частаючыя DML-операцыі, таму што адночасныя DML-операцыі можу запаздзіць генераванне, і што копіі, клонаванні і снімкі несу даныя без налаштавання генеравання. У прыметках да выдання сказана, што яго можна актывацыяць на новых чы асушчэствуючых табліцах за дапамою CREATE TABLE чы ALTER TABLE. Прыметкі да выдання BigQuery ёсць аўтарытэтным джэрэлам па статусе функцый, таму пераканайцеся ў іх перад стварэнням.

    Што вы отрымаеце без дадатковых зусілляў

    Гэта і частка, якой дакладней заўсёды трэба звяртаць увагу командам з апрацоўкі даных, але якой прыдзеляе мінімум увагі.

    • Безпека на рэвені і ступенях столца пераходзіць і ў VECTOR_SEARCH. Рэвен, які корыстнік не мае права бачыць, ніколі не прабачаецца як кантэкст RAG. Падтрымка такой гаранціі за дапамою сінхронізаванай званачайнай базы вектараў ёсць складной.
    • IAM — ўжо ўсё, што ёсць ў модэлі аутантыкацыі. У зменных сяродавысці няма ключоў, а таксама няма інструкцый для перыядычнай замены ўсяго пайплайну.
    • Логі аўдыту, прызначэнне костоў і квоты — усё гэта выходзіць з інфраструктуры, якую вялікая команда платформы вядома адрабоўвае. Вы нават можэце вылучыць паказанні за кожны заданні праз метку bigquery_job_id_prefix у рэжыме Cloud Billing.
    • Няма неабходнасці запускаць заданні сінхронізацыі. Вектары знаходзяцца пры самых рэвенах, якія яны опісваюць, таму база вектараў не можа адстаць ад складзішча, калі існуе толькі адна база. З автонамнымі эмбедынгамі таксама няма неабходнасці ў заданніх на апдэйт з адпаведным власнікам.

    Лепшая інфраструктура — гэта тая, якую вы ніколі не выкорыстоўваеце.

    Дзе ўсё ламаецца

    1. Расчыты ведуцца па токенам, і Gemini 2.5 таксуе таксама за працэс размышлення. Гэтыя мадэлі беруць плату за токены разумовых дзеянь дапамогаючы да выходных рэзультатаў. Для задач класыфікацыі, калі у model_params задаць бюджэт на размышлення равным нулю, гэта зменшыць як час адпаведзення, так і вітраты. Якшо прыйняць гэты крок, вартасці батчаў будуць раставаць без жадных паўтарэнняў. Спачатку выкарыстоўваюце AI.COUNT_TOKENS, ўбачыць апрыксіматывную канцыянту.
    2. Складныя запыткі могу даставіць модэлю іншыя колькісці рэкордаў, чым вы спадзяваліся. Частымі прычынамі ёсць оператыры JOIN і ORDER BY з параметрам LIMIT. Google радзіць спачатку запісаць даныя у табліцу, а пасля выконваць апрацоўку над гэтай табліцай.
  • Квоты сушчэствуюць рэальна. Працэс вставкі дадзеных абмежаваны квотамі на колькісць токенав на хвілі, якія за замовчаннем станавяць каля каля кількох мільйонаў. Гэта падходзіць для большасці завад, але для вставкі цэлага азерыша дадзеных за ноч час патрэбна падготовка, або ж вікорыстоўваць функцыю Provisioned Throughput з параметрам request_type => 'dedicated'.
  • VECTOR_SEARCH оплачваецца за колькісць сканаваных байтаў. У сістэме з цэнаваннем за запіт лічыцца базовая табліца, індэкс і сам запіт. Размясціце столбцы STORING у індэксе, ў такі спосаб прымусова не будзе патрэба з’яўляцца знову да базовай табліцы, і можна будзе ранішэ фільтрацыяваць дадзеныя за дапамогою оператара WHERE на гэтых столбцах.
  • Няма нічога, што могла б версіявацыяваць вашы запіты. Запіт — гэта проста строка ў SQL, таму няма рэестру, тэстаў тыпу A/B чы ўстатку для ацэнкі. Команды, якія ўсё тыдзень перэрабляюць запіты асістэнта, відчуваюць гэта, і самэлькі корыстны ў такіх случаях невялікі слой на Python чы dbt, які зберагае запіты як версіяваныя настройкі.
  • Пераканайцеся ў статусе

    Статус функцыйяў можа змяніцца, таму пераканайцеся. Як было спачатку адзвярнуто, AI.GENERATE і AI.GENERATE_TABLE сталі доступныя для шырокага вжытку ў падзеўніку 2026 года, а партнерскія мадэлі (Claude, Llama, Mistral) — у першай палове 2025 года. Функцыйі прыгляду, такія як автонамныя эмбедынгі, моглі змяніцца з тэх падзеў, і самэлькі корыстны ў такіх случаях прыглянуцца да прыметак выдання.

    Чы SQL дэйсна ўсё, што вам патрэбна?

    З гэтага выходзяць тры заключэнні.

    Для пакетнай і аналітычнай RAG гэта варта серйознага расследавання. Класыфікацыя дакументаў, семантычная дэдуплікацыя, пайплайны абгараджэння і внутрашнія запытанні-адказы на кантролюемых дадзенах усе спрыяюць падходу, пры якому база дадзенаў выступае як аснова, з точка зору кантролю, простасці і абоўсюднага косту, пры чым вы можаеце самі выбраць мадэль.

    Корпус, які постаўляецца зменяецца столькі часу, — гэта іншы случай, і автонамныя эмбеддынгі змінююць баланс. Пошук ніколі не быў складнай часткай прымененай RAG. Складнасць створала ўзаемная супараднасць вектараў з актуальнымі дадзеннямі, а створаны столбець усунуў усю гэтую катэгорыю работ.

    Навык — гэта знанне таго, дзе знаходзіцца межа. Чат для корыстнікаў, які працуе за пару секунд, все ўсё ж выкарыстоўвае спецыяльны слой аддачы, жыццёвы цыкл запытанняў все ўсё ж выкарыстоўвае версіяванне, а косц за токен все ўсё ж выкарыстоўвае монітарынг. Гэтыя абмежэнні не зніклі. Яны проста перасунуліся.

    Для дальшага чытання даследжэнні Google BigQuery апавярнююць адгляд генератыўскага ІІ і матрыцу падтрымкі модэляў, каманду CREATE MODEL для партнерскіх і відкрытых модэляў, каманды AI.GENERATE, AI.GENERATE_EMBEDDING, AI.SEARCH, аўтонамную генерацыю эмбеддынга, функцыі пошуку, калектывнае кераванне вектарнымі індэксамі і прыметкі па выданню.