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

Фільтрацыя метаданных для Databricks RAG за дапамою ai_extract і ai_prep_search

Аб’яднайце функціі ai_parse_document, ai_extract v2.1 і ai_prep_search так, каб кожны фрагмент меў введаныя метаданныя, якія дазволяюць алгорытму Vector Search фільтруваць іх перад ранжаванням за ступенем сэроднечы.

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

Крыніцы: Adding ai_extract to the mix: building a unified RAG pipeline with three Databricks SQL AI functions

Пайплайн Databricks, створаны на базе функцыі SQL AI ai_prep_search, ужо выканае багато задач. У ўскладненыя дакументы, якія былі распакаваны, праўяцца семантычныя і кантэкстуальна збагачаныя фрагменты, якія стаюць гатовымі для вектарнага пошуку. Працэс просты: распакаваць дакументы, падготавіць фрагменты, прыблізіць іх да фармату табелі Delta і створыць для яе індэкс.

Адзін раз чаго не хапае, калі гэты працэс працюе над корпусам дакументаў, у даным случыку — над сэткам інструкцыйяў к Orion Robotics. Самыя фрагменты дакументаў ў парадку. Поле chunk_to_embed несе правільны кантэкст дакумента, а chunk_to_retrieve настолькі чысты, што можа быць выданы ШЫ. Проблемы пачынаюцца пад час запіта, таму што няма надзеянага спосабу фільтрацыі. Запіт на кшталт "Знайдзіце мне інструкцыю па прыстрое Orion Motion Controller" можа быць задоволены толькі за дапамогою сэмантычнай супараднасці, адколі індэкс не мае структураваных столбцоў, такіх як document_type, product_name чы target_audience.

Для агент-адрасаванага пошуку гэта сапраўдны прынт. Чысты семантычны пошук добра працуе ў дэмаверсіі. У рэальных умовах агент павінен скасці прастор пошуку перад запускам аналізу вектарнай сэмабельнасці, і фільтры метадаў адносна гэта і робяць. Рашэння — адключыць ai_extract v2.1 да пайплайну.

Чаму важны фільтры метадаў

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

Уявіце агента, які ужо знае, што корыстувальніку патрэбны інструкцыі для Orion Arm. Класафікацыя 10 000 фрагментоў з усіх відэйнаў дакументаў была б марнай. Лепшы план — спачатку скасаваць непатрэбныя даны, залішыўшы толькі актуальныя дакументы, а потым выкарыстаць метод вектарнай схожасці, каб апранумерараваць найболей прыдатныя варыянты ў гэтай меньшай групе. Databricks Vector Search дазваляе цэе за дапамогою столбцоў-фільтраў, задаўных пад час стварэння індэксу.

Але ёсць проблема: метаданы павінны быць чыстымі, адпаведнымі і правільна заданымі па тыпу. Калі у аднай строчцы document_type мае значэнне "User Manual", у іншай — "manual", а ў трэцій — нічога, фільтры не будуць працаваць правільна. У такім случае якасць выкарыстоўвання дакументаў будзе падлай, і знадобяцца гадзіны на адлучэнне прычыны, хоча справжняя прычына — гэта нэадпаведныя метаданы, створаныя раней.

ai_extract v2.1 рашыяе гэтыя проблема. Ён выкарыстоўвае структураваны VARIANT, які ствараецца за дапамой ai_parse_document, і вяртае метаданы з паказаным тыпам, якія пераканальваюцца па схеме. Полы-энумератары фіксуюць конкрэтныя значэння, полы-строкі керуюць выкарыстоўваннем вольнага тэксту, а масівы выкарыстоўваюцца для полаў з колькіма значэннямі. Паколькі выкарыстоўванне тэксту адбываецца па схеме, выходны рэзультат застаецца аднаковым у всіх дасягах, нават калі ў яных разныя структуры.

Тры функцыі, тры задачы

Функцыі не перакрываюць адзіну другога, таму пры аналізе нотбукі лепш іх раздзеліць.

  1. ai_parse_document v2.0 ператварае неструктураваныя бінарныя файлы (PDF, DOCX, адпраўкі) у структураваны VARIANT, выявляючы блакіткі тэксту, загалоўкі, таблыцы, рэчы, рамкі і іерархію раздэлаў. Ён знае структурную сутнасць дасяга, але не мае жаданняў пра тое, пра шта ён.
  • ai_extract v2.1 берае аналізаваны VARIANT і, следуяя схеме, яку задае корыстнік, выкарыстоўвае яе для выявлення метаданых на рэвэле дакумента. Ён розумее тэкст толькі тады, калі схема вказвае, што трэба шукаць. Рэзультатам яе работы ёст маўчыны VARIANT з полямі з пазначэннем тыпу, такімі як document_title, document_type, product_name і target_audience, а таксама іншымі, якія былі заданы. У версіі 2.1 былі адключаны показатэлі доверлівасці і цітаты, і гэта ўсё, што трэба выкарыстоўваць.
  • ai_prep_search дзельніць аналізаваны VARIANT на семантычныя часткі, гатовыя для пошуку, выкарыстоўваючы структурныя паказнікі, атрыбутаваныя падчас аналізу (рамкі, тыпы элементаў, іерархія раздэлаў). Ён не чыпае метаданых на рэвэле дакумента, адтуды гэта належыць да функцыі ai_extract.
  • Кожная функцыя мае адну задачу, а весь працэс складаецца з ўсіх іх.

    Шаг за шагам у зошыце

    Зошыца працюе з корпусам Orion Robotics, які знаходзіцца ў Unity Catalog Volume і складаецца з PDF-файлов, файлав DOCX і адпраўк. Спачатку выкалічваецца:

    SELECT
      path,
      ai_parse_document(
        content,
        MAP('version', '2.0')
      ) AS parsed
    FROM READ_FILES(
      '/Volumes/<YOUR_CATALOG>/<YOUR_SCHEMA>/orion_docs/',
      format => 'binaryFile'
    )
    

    Кожны файл у цій калектазе чытаецца як бінарны і ператвараецца у структураваны VARIANT. Рэштычна выбор версіі 2.0 ёсць розумным, калі тая схема абараняе коордынаты рамкі і опісы фігураў, ад яых залежыць ai_prep_search для прыняцця рашэнняў па часткаванні. Якшто застацца на стандартным варыянце, Databricks можа зменіць працэс пад час адпрацоўкі даных.

    Прыкладны запуск даў такі рэзультат:

    Наступны запіт выкарыстоўвае метаданы з апрацаванага выходу:

    WITH parsed_documents AS (
      SELECT path, ai_parse_document(content, MAP('version', '2.0')) AS parsed
      FROM READ_FILES('/Volumes/<YOUR_CATALOG>/<YOUR_SCHEMA>/orion_docs/', format => 'binaryFile')
    )
    SELECT
      path,
      ai_extract(
        parsed,
        '{
          "document_title":  {"type": "string", "description": "Main title or heading of the document"},
          "document_type":   {"type": "enum", "labels": ["manual", "datasheet", "guide", "report", "specification", "policy", "other"]},
          "product_name":    {"type": "string", "description": "Primary product or system referenced"},
          "version":         {"type": "string", "description": "Document or product version if mentioned"},
          "key_topics":      {"type": "array", "items": {"type": "string"}},
          "target_audience": {"type": "enum", "labels": ["engineer", "operator", "manager", "customer", "general"]}
        }',
        MAP(
          'version', '2.1',
          'instructions', 'These are technical documents from Orion Robotics. Extract metadata that would help users filter and find relevant documents.'
        )
      ) AS metadata
    FROM parsed_documents
    

    Дэякі віборы потрэбуюць пояснення. Чыць document_type і target_audience ясны якісь, аджэ фільтры потрэбуюцы закрытый набяк значэнакоў. Як вольны тэксты ёны могуць вернутыся як „manual“, „User Manual“ або „technical manual“, што блакірае працэс падахвання. Апыткі instructions даеякі фон, тутыльныя документыяцыялі зярэйкі Orion Robotics, таму выхлаванне падахванняў павярэйшаецца. Таксама, параметры ai_extract прымаеякі зярэйкі з ai_parse_document такімі, якія е, без перакладу ў працавы тэкст.

    Выхлаванне зярэйкі з прымэрзаў:

    Чыськаване падахванняў будзе далей:

    WITH parsed_documents AS ( ... )
    SELECT
      path,
      ai_prep_search(parsed) AS chunked
    FROM parsed_documents
    

    ai_prep_search выкарыстоўвае той самы аналізаваны ВАРЫЯНТ. Дакументы дзелююцца на часткі, якія зберагаюцца ў масе document.contents, і кожная частка мае атрыбуты chunk_id, chunk_position, chunk_to_retrieve і chunk_to_embed. Пяршыя два атрыбуты ўмышлена не ўтвараюць таго ж тэксту.

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

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

    Прыклад выходу:

    Аб’еднаванне усяго разам

    Складзены запыткі — гэта там, дзе сукупнасць частак стае ўсёю картынай:

    WITH parsed_documents AS (
      SELECT path, ai_parse_document(content, MAP('version', '2.0')) AS parsed
      FROM READ_FILES('/Volumes/<YOUR_CATALOG>/<YOUR_SCHEMA>/orion_docs/', format => 'binaryFile')
    ),
    doc_metadata AS (
      SELECT
        path,
        parsed,
        ai_extract(
          parsed,
          '{ ... }',
          MAP('version', '2.1', 'instructions', 'These are technical documents from Orion Robotics. Extract metadata for search filtering.')
        ) AS metadata
      FROM parsed_documents
    ),
    doc_chunks AS (
      SELECT path, ai_prep_search(parsed) AS chunked
      FROM doc_metadata
    )
    SELECT
      chunk.value:chunk_id::STRING          AS chunk_id,
      chunk.value:chunk_position::INT       AS chunk_position,
      chunk.value:chunk_to_retrieve::STRING AS chunk_to_retrieve,
      chunk.value:chunk_to_embed::STRING    AS chunk_to_embed,
      doc_chunks.chunked:document.source_uri::STRING AS source_uri,
      dm.metadata:response:document_title::STRING    AS document_title,
      dm.metadata:response:document_type::STRING     AS document_type,
      dm.metadata:response:product_name::STRING      AS product_name,
      dm.metadata:response:version::STRING           AS doc_version,
      dm.metadata:response:target_audience::STRING   AS target_audience
    FROM
      doc_chunks
      JOIN doc_metadata dm ON doc_chunks.path = dm.path,
      LATERAL variant_explode(doc_chunks.chunked:document.contents) AS chunk
    

    LATERAL variant_explode крок раскрывае зануржаныя масівы чакаў у рады. Аперацыя JOIN па шляху прыяўляе метаданы на рэвэле дакумента да кожнага чака таго дакумента. Рэзультатам яе ёсць адны рад на кожны чак, які мае як поля для выкарыстоўвання, так і столбцы метаданаў, якія можна фільтрацыяваць. Гэтае ўтварэнне зберагаецца ў табліцы Delta і выкарыстоўваецца для заправлення індэкса Vector Search.

    Рэзультат працы з прыкладам:

    Табліца ствараецца так:

    CREATE OR REPLACE TABLE <YOUR_CATALOG>.<YOUR_SCHEMA>.orion_docs_rag_chunks AS
    -- [full CTE chain from Step 4]
    

    Пасля стварэння таблыцы создаецца індэкс Mosaic AI Vector Search Delta Sync з наступнымі настройкамі:

    1. Столбец для імпліментацыі: chunk_to_embed
    2. Основны ключ: chunk_id
    3. Поле для фільтрацыі: doc_version, а таксама document_type, product_name і target_audience

    chunk_id застаецца стабільным з адной разу запуску да іншага, ён складаецца з ID дакумента і пазычкі чанка. З-за гэтаго даджэнтныя абнаўленні методам MERGE для таблыцы Delta залішаюць чанкі без змян, утамульваючы неабяжлівую перэструктурацыю індэкса, што ў значныяй меры эканоміце калі корпус дакумента апдэлюецца па раскладзе.

    Рынкі ў час запіту

    Карысць паўтараецца тады, калі корыстнік ставя запіт, а не ў час завантажэння. Прыпустым, запіт звучыць так: "Знайсці інструкцыю па прыстрое Orion Motion Controller". Тады працэс аднаходжэння дакумента можа вестыцца у два етапы:

    1. Адаптавайце фільтры метадаў, якія паслужаюць для адпаведнасці, напрыклад document_type = “guide” і product_name = “Orion Motion Controller”.
    2. Выканаўцайце запыт і ведзіце пошук толькі сярод дакументаў, якія паспелі за гэтымі фільтрамі.

    Без ai_extract агент завісіць толькі ад семантычнай супадзімасці. Для кальколька супаднаючых дакументаў гэта можа быць прыемна. Але калі мова йдзе пра тыячы файлаў, якія абліваюць разныя продукты, тыпы і аўдытарыі, гэта стае ненадзейным. Метадаўы, адаснованыя на перыядычных значэннях, вырашаюць гэтыя проблемы: агенту не трэба здагадваліцца, чы гэта інструкцыя чы практычны кіяс, і ён проста фільтруе за параметрам document_type = “manual” для атрымання точных рэзультаатаў.

    Ліміты і косцы

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

    ai_extract прызводзіць да адныяўшчых віткоў і затрымкаў, адколі для кожнага дакумента трэба ўжо адна вызовка LLM. Delta Sync можа прыхіліцца да дакументаў, якія не зменіліся, але першая повная апрацоўка можа застацца дорогай, таму розумна ўжо перад пачатком апрацоўкі всего корпуса адбавіць тэсты на прыкладах.

    Ўжывайце версію 2.0 функцыі ai_parse_document, калі яе выходны даныя VARIANT падаюць у ai_prep_search або ai_extract. Гэтая версія прадае рамкі абмежэння, тыпы элементаў і апісанні фігураў. Сырый тэкст можа быць пераданы ў ai_extract, хоця тады губяцца структурныя перавагі парсінгу.

    Заканчэнне працы над дызайном

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

    1. ai_parse_document фіксуе структуру дакумента.
    2. ai_extract фіксуе корыстныя метаданныя.
    3. ai_prep_search стварае сэмантычныя чаккі.

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

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