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

RAG-канвеер, з якім AI-агенты разважаюць, а не толькі робяць запыты

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

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

Крыніцы: How to Design a RAG Pipeline So AI Agents Reason, Not Just Query It

Агент вызваець працэс RAG і атрымлець спіс дакументаў. Што будзе далей?

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

Гэта мае значэнне, таму што агенты дзейнуюць на аднаковай інфармацыі. Дзеякія прыстроі для выяўлення галюцынацый можу пазначыць выдуманыя факты, але слепыя пункты ў процэсе атрымлення інфармацыі значна важкаяя да выяўлення. Агент упэўнена робіць выводы на аднаковай, непূরнай інфармацыі, і ніхто не даведаецца, што ён працягнуў. Звычны процэс разработкі — абробка, атрымленне, стварэнне — зовсім не мае сігнала зворотнай свярзкі.

Зробіце атрымленне інфармацыі відаваемым для агента

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

У зменшэньне таго, каб вярнуць просты спіс дакументаў, каркас вяртае болей насыцены об’ект. У яму знаходзяцца дакументы, значэнне доверлівасці, показнік разнаобразнасці выканаў (скількі разных домэнаў і які дзеяннік дат), сігналы паводле якіх відома, якія аспекты запытання былі рассмотрэныя, а якія застаўся без увагі, а таксама метаданы для адналежнага збору інфармацыі, такія як модэль укладання, розмер частак, параметры top-k і інфармацыя пра тое, чыі быў запусканы ранкер.

{
  "results": [Document, Document, Document],
  "confidence_score": 0.87,
  "source_diversity": {"domains": 3, "timestamps": ["2024-01", "2023-11", "2023-09"]},
  "coverage_signals": {
    "question_aspects_covered": ["technical", "cost"],
    "question_aspects_missing": ["compliance", "deployment"]
  },
  "retrieval_metadata": {
    "embedding_model": "text-embedding-3-large",
    "chunk_size": 512,
    "top_k": 5,
    "reranker_applied": true
  }
}

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

Тры слоі

Слоі 1: адзысківанне інструментаў

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

def retrieve_with_signals(query: str, top_k: int = 5):
    # Standard retrieval
    results = vector_db.query(query, top_k=top_k)

    # Capture raw signals
    similarity_scores = [r.score for r in results]
    sources = [r.metadata.get("source") for r in results]
    timestamps = [r.metadata.get("timestamp") for r in results]

    # Compute confidence as mean similarity
    confidence = sum(similarity_scores) / len(similarity_scores)

    return {
        "results": results,
        "confidence_score": confidence,
        "source_diversity": {
            "domains": len(set(sources)),
            "timestamps": sorted(set(timestamps))
        }
    }

Эта методыка не ўскладнюе процэс, адколі вы проста чытаеце даныя, якія вялікі час існавалі.

Слой 2: выявленне паводлівасці

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

Раздзеліце запіт на аспекты. Для запіту „Як запусціць мадэль з обмежэннямі за вартасцю?“ аспектамі можуць быць запуск, вартасць і обмежэння. Потым пераканайцеся, якія з іх прысутныя ў атрыманым тэксце. LLM або простая выкалекватароўка ключоўых слоў можа стварыць спіс аспектаў, а перакананне можа быць простым — шукаць кожны аспект у сумаваным тэксце дакумента. Функцыя паведамляе, якія аспекты былі паводліваны, якія не паводліваны, а таксама паказвае коефіцыент паводлівасці.

def detect_coverage(query: str, documents: list) -> dict:
    # Extract query aspects (simple approach: use an LLM or keyword extraction)
    aspects = extract_query_aspects(query)  # ["deployment", "cost"]

    # Check document coverage
    doc_text = " ".join([d.content for d in documents])
    covered = [a for a in aspects if a.lower() in doc_text.lower()]
    missing = [a for a in aspects if a not in covered]

    return {
        "question_aspects_covered": covered,
        "question_aspects_missing": missing,
        "coverage_ratio": len(covered) / len(aspects) if aspects else 1.0
    }

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

Слой 3: перадаць агенту

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

tools = [
    {
        "name": "search_with_reasoning",
        "description": "Search the knowledge base and receive coverage signals",
        "parameters": {
            "query": "str",
            "aspect_focus": "optional str (e.g., 'deployment' or 'cost')"
        }
    }
]

def search_with_reasoning(query: str, aspect_focus: str = None) -> dict:
    retrieval_output = retrieve_with_signals(query, top_k=5)
    coverage = detect_coverage(query, retrieval_output["results"])

    return {
        **retrieval_output,
        "coverage_signals": coverage,
        "recommendation": (
            "re-query" if coverage["coverage_ratio"] < 0.7 else "proceed"
        )
    }

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

Пераканацца, што сігналы заслуговуюць на довер'е

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

  • Точнасць сігналаў. Чы права пазначка довер'яйнасці дзеякім чынам прызначае якосць выкарыстоўвання інфармацыі? Задайце адоўга дваццаць запытанняў, рангаваце рэзультаты вручную з 1 да 5 і паў'язайце гэтыя рангі з пазначкай довер'яйнасці. Рэлевантны ціль — корэляцыя вышэй за 0.75.
  • Адказнасць на запытанні. Вручную пазначыце, якія аспекты кожнага запытання адпавядаюць дакументам, а потым паў'язайце гэта з рэзультатамі дэтэктара для адоўга дзесяці разнае запытанняў. Ціль — тачнасць вышэй за 85%.
  • Паведанне агента. Запісвайце кожнае рашэнне пра падзеўжанне запытання. Калі частка адказнасці меншая за 0.7 і большасцю часу прыводзіць да новага запытання, значыць агент зважае на сігналы.

Косты і ліміты

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

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

А сігналы ёсць гіюрыстыкамі. Высокі рэйтынг доверлівасці не гарантуе правільнага выважвання. Шырокі пакет задае агенту лепшыя, але не ідэальныя, даны, таму все раве неабходныя пераконтрольванні на наявнасць галюцынацый.

Чаму гэта карыстна

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

Пачатак работы

  1. У гэты тыдзень адрабатайце першы слой. Адкройце інформацыю пра рэгістрацыю рэзультатаў і разнаўраснасць джэраў, заносіце яе прыблізна на дзень і старацеся выявіць патэрны.
  2. Дадаце функцыю выявлення рэгістрацыі рэзультатаў для вашых найбольш падаючыхся тыпаў запытанняў і пераканаецеся ў яе рабоце на дзесяці прыкладах.
  3. Прыўяжыце яе да агента і вы мерыце, чы робіць ён новы пошук, калі рэгістрацыя рэзультатаў нізкая, і чы паспяшаецца яго аргументацыя.

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

Супаўзвязаныя матэрыялы

  • grep Beat Vector Search у тэстах памяці агента, і ролю грае таксідарыя таксама значна — Адзін доследжэнне 116 запытанняў LongMemEval паказала, што grep працуе лепшая за метод вектарнага пошуку, але спосаб, якім таксідарыя выдае рэзультаты, вплывае на точнасць не менш, чым сам прыем пошуку. Што можна выняць з гэтага.