Галоўная / Артыкулы / Дазволіце Блізнюкам выбраць источнік: FAISS, Tavily і Direct Answers у LangGraph

Дазволіце Блізнюкам выбраць источнік: FAISS, Tavily і Direct Answers у LangGraph

Створыце маленькія рабочая схема LangGraph, у якой Gemini направляе кожны запит да базы знаёмых FAISS, на пошук у інтернете за дапамою Tavily або да прымітнай адпаведзі, з руліванням структураваным выходам.

3771 слоў

Большасць пратэтыпаў для адпаведзення на запытанні праходзяць кожны запыт чераз адной і той жа стабільнай схеме, незважаючы на тое, што запытанні разлічаюцца па своіх трэбаваннях: дзеяныя залежаць ад дакументаў прыватных компаній, іншыя — ад фактов, якія зменяюцца ўсё час, а ўшыя — толькі ад загальных знанняў. У данай інструкцыі практычна показана компактная схема работы на Python, у якой мовны модель спачатку аналізуе кожна запытанне і направляе яго ў правыя месцы: у FAISS-хранілню вектараў для внутраніх знанняў, у Tavily для рэальных рэзультатаў з інтернету або безпасова ў Gemini. У канцы вы зрозумеете, як станы, вузлы і умовныя рэшткі выступаюць разам у LangGraph, чаму структураваны выхід робіць маршрутазатор LLM надзеяным, і дзе такія прыклады для навучэння патрабуюць даполненняя, прычаму яны магу быць выкорыстаны з рэальнымі корыстнікамі. Якщо вы хочаце болей шырокі каталог форм графаў, чытайце стацыю пра маршрутаванне, фан-аут.

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

Тры запитанні, тры розныя джерела

Уявіце трох прыемнікаў. Першы запитвае пра правіла відпачынку ў компаніи; на гэты запит можна адпаведаць толькі за дапамогою внутрашняях дакументаў. Другі хочаць дзеўянчыну погоду ў Уттаракхандзе; жаданых дакументаў там няма, таму системе патрэбна пераследжванне Інтарнету. Трэці запитвае, што такое RAG; модель вже знае адпаведзь, а ўзяць які-небудзь дадатак толькі паўышыць затрымку.

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

User Question
                               |
                               v
                       +----------------+
                       |   AI Router    |
                       |    (Gemini)    |
                       +----------------+
                         /      |      \
                        /       |       \
                       v        v        v
                    FAISS    Tavily    Gemini
                 Internal DB  Web      Direct
                       \        |        /
                        \       |       /
                         v      v       v
                       +----------------+
                       | Generate Answer|
                       |     Gemini     |
                       +----------------+
                               |
                               v
                            Answer

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

if "weather" in question:
    use_tavily()
elif "leave" in question:
    use_faiss()
else:
    use_gemini()

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

Генератыўскія AI, агенты і агентныя праблематыкі

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

Просты генератыўскі AI

У простейшам варыянце запыт перадаецца модэлі, і яна вяртае тое, што стварыла:

User Question
      |
      v
     LLM
      |
      v
    Answer

Ён можа поясніць прынцып RAG на адной з дадзеных для навчання, але не ведае ніч пра вашу політыку выпуску на час адпачынку.

Агенты, якія выкарыстоўваюць інструменты

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

User Question
      |
      v
     LLM
      |
      +------> Database
      |
      +------> Web Search
      |
      +------> API
      |
      v
    Answer

Напрыклад, на запит пра пагоду можна адпаведзець, з’явіўшыся да службы пагоды, а не прымусіваючы модель стварыць правдападобны прогназ.

Рабочыя процесы з агентамі

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

Question
   |
   v
Router
   |
   +----> FAISS
   |
   +----> Tavily
   |
   +----> Gemini

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

Настройка проекту

Патрэбны Python 3.10 або новейшая версія, ключ API для Google Gemini і ключ API для Tavily. Установіце бібліятэкі заодно:

pip install -U langchain langchain-google-genai langchain-community langgraph faiss-cpu tavily-python python-dotenv pydantic

Зберагаюце оба ключы ў файле .env, а не у коде выхіднага кода:

GOOGLE_API_KEY=your_google_api_key
TAVILY_API_KEY=your_tavily_api_key

Уключаны калексы для падчыркавання датасэтак, Pydantic для схемы маршрутаўвання, калексы дакументаў і FAISS ад LangChain, класы чата і эмбеддінгаў ад Gemini, прымітывы графа ад LangGraph і кліент Tavily:

import os
from typing import List, Literal
from typing_extensions import TypedDict
from dotenv import load_dotenv
from pydantic import BaseModel
from langchain_core.documents import Document
from langchain_community.vectorstores import FAISS
from langchain_google_genai import (
    ChatGoogleGenerativeAI,
    GoogleGenerativeAIEmbeddings,
)
from langgraph.graph import StateGraph, START, END
from tavily import TavilyClient

Наступны крок, паказаны як фрагмент у адной лініі, — гэта проста запуск зменных сяродовышча:

Load the environment variables:

За наявнасці override=True значэнні з .env маюцы прываліднасць над зменнымі, якія вже заданы ў вашай шэле:

load_dotenv(override=True)

Канфігурацыя Gemini для маршрутаўвання, адпаведзення на запытанні і стварэння эмбеддінгаў

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

model = ChatGoogleGenerativeAI(
    model="gemini-3.6-flash",
    max_tokens=None,
    timeout=None,
    max_retries=2,
    api_key=os.getenv("GOOGLE_API_KEY"),
)

Ідэнтыфікатары модэляў часта зменяюцца, таму пераканайцеся, што назва ў фрагменте супадае з актуальным спискам модэляў Gemini, прытым як вы яго запускаеце.

Эмбедынгі — это аднаэтная проблема, якую рашае окремы модэль. Gemini Embedding ператварае кожны документ у числовы вектор:

embeddings = GoogleGenerativeAIEmbeddings(
    model="models/gemini-embedding-001",
    google_api_key=os.getenv("GOOGLE_API_KEY"),
)

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

Маленькая внутраняя база знаёмых у FAISS

Ёнколі ўвага трэба было сфармаваць на процесе роботы, база знання мячыць толькі тры короткія дакументы: правілы варыцы грошаў пры 30 дзён, права на 20 оплачваных канікулярных дзёнаў з трэбою паведаміць пра це за семь дзён, а таксама часы падтрымкі у рабочыя дні. У рэальной системе гэтыя тэксты моглі б выйсці з інструкцый, PDF-файлаў, стораніцаў у Notion, заявкаў на падтрымку, внутрашняя дакументацыі або рэкордаў у базе даных.

documents = [
    Document(
        page_content="""
        Our company provides a 30-day refund policy.
        Customers can request a refund within 30 days of purchase.
        """
    ),
    Document(
        page_content="""
        Employees receive 20 paid vacation days per year.
        Vacation requests must be submitted at least 7 days in advance.
        """
    ),
    Document(
        page_content="""
        The company provides technical support from Monday to Friday,
        9 AM to 6 PM IST.
        """
    ),
]

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

vector_store = FAISS.from_documents(
    documents,
    embeddings,
)

retriever = vector_store.as_retriever(
    search_kwargs={"k": 3}
)

FAISS не розумее мовы; цэў індекс для пошуку найбліжэйшых суседаў. Модель імплентацыі ператварае прыйшэлы запит у вектор, а FAISS вяртае зберажаныя дакументы, чыія векторы знаходзяцца найбліжэ да яго.

Дадаць кліента Tavily для рэальнай інформацыі

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

tavily_client = TavilyClient(
    api_key=os.getenv("TAVILY_API_KEY")
)

Проектаванне спільнага стану

Стан — галоўная ідея ў LangGraph: аб’ект у виглядзе слоўніка з падазначэнням типа, які перавозится праз граф, з якого кожны вузол чытае і дае свой вклад. Для такога робіць патрабуецца запит, усі знайдзены дакументы, рэзультаты Tavily, выбраны выхадны матэрыял і канечнае адпаведзенне:

class AgentState(TypedDict):
    question: str
    documents: List[Document]
    tavily_response: str
    source: str
    answer: str

Канцэптуальна ён падобны на спільную картку, якую можа бачыць кожны крок:

AgentState
                    |
        +-----------+-----------+
        |           |           |
    question    documents    source
                    |
             tavily_response
                    |
                  answer

Вузел прыме якісьцю стан, выкарыстоўвае тыя поля, якія яго цікавяць, і вяртае апдэйты, якія LangGraph з’едынае перш чым перадаць стан наступнаму вузлу.

Вузел аднаходжэння дакументаў FAISS

Этот вузел бере запит зі стану, праходзіць яго через механізм аднаходжэння і зберагае падходячыя дакументы:

def retrieve_from_faiss(state : AgentState) -> AgentState:
    question = state['question']

    """ Fetch the details from the FAISS vector database
    """

    result = retriever.invoke(question)

    return {**state, "documents": result}

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

"What is our company leave policy?"

Для такога вхіднага дадзення апрантавальны механізм должен выдаць дакумент пра канікулы:

Employees receive 20 paid vacation days per year.
Vacation requests must be submitted at least 7 days in advance.

Узел пошуку Tavily

Узел веб-пошуку адправляе запит да Tavily з параметрам search_depth у значэнні advanced, а пасля выкарыстоўвае поле content з кожнага рэзультата:

def search_with_tavily(state: AgentState) -> AgentState:
    question = state['question']
    """ Using the Tavily to search the web and
      fetch the latest information about user query
    """

    response = tavilyClient.search(
        query=question,
        search_depth='advanced'
    )

    contents = [result["content"] for result in response["results"]]
    return {**state, "tavilyResponse":contents}

Этыя фрагменты становяцца контекстам, які Gemini чытае пад час стварэння адказу. Заўважыце, што узел вяртае список страк; якщо вы хочаце адзін блок тексту, з’едынітэ элементы перад ўявленням іх у памяць, каб поле адпавядала типу str, заявленаму ў стане.

Забезпечэнне надзяйнасці рутэра за дапамою структураванага выходу

Простакавы рутэр прасіе модель адпавясці однам з трохоў простых слоў:

Return only:
faiss
tavily
gemini

Моделі мовы не завжды прыменяюць інструкціі па форматаванні. Можна пачуць цэлы выраз:

I would choose tavily.

Або трохі іншы варыянт формулавання:

The best option is: tavily

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

class RouteDecision(BaseModel):
    source: Literal["faiss", "tavily", "gemini"]

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

router_model = model.with_structured_output(
    RouteDecision,
    method="json_schema",
)

Выхід перакантролюецца па типу Literal, таму некоректнае значэнне будзе праказана як адказ на адчыненне, а не прыведзе граф у невяліканае становішча.

Стварэнне вузла рашэння

У паведамленні працэўкі маршрута описваецца кожны варыянт: faiss для запытаў пра правілы компаніі і іншыя внутрашняе знаёмства, tavily для всьога, што патрабуе актуальных або веб-аснованых дакументаў, і gemini для загальных знаёмстваў, якім не патрабуецца ні таго, ні іншага:

def decide_source(state:AgentState)-> AgentState:
    question = state["question"]
    prompt = f"""
    Decide the best source for answering this question.

    Choose exactly one:

    faiss:
    Use when the question can be answered using our internal
    knowledge base.related to company policy and all

    tavily:
    Use when the question requires current, recent, or web-based
    information.

    gemini:
    Use when the question is general knowledge and does not
    require our internal documents or current web information.

    Question:
    {question}

    Return only one word:
    faiss, tavily, or gemini
    """

    response = model.invoke(prompt)
    # return response

    return {**state,"source":response.text}

Акружна паглядзіце на апошнія рэчы. У такой форме вузол яшчэ вызывае просты model і зберагае response.text, што ўсё той жа нестабільны падход з вольным текстам, описаны вышэй. Ёсць можлівасць скорасты роботу за дапамогою схемы, якщо замест таго вызваць router_model.invoke(prompt) і зберагчы атрыбут source рэзультата. Пасля такой змены маршрутацыйны прыстрой вяртае об’ект з адпаведнымі дадзеннямі, а не просты працэсаваны текст:

RouteDecision(source="faiss")

Указванне LangGraph, куды далей ісці

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

def route_source(
    state: AgentState,
) -> Literal["faiss", "tavily", "gemini"]:
    return state["source"]

Одна вузел адпаведнасці для кожнага маршруту

Усе тры вароцы завершаюцца ў аднам і тым жэ пасьлядку генеравання. Яна аналізуе source і стварае відпаведны запит: адзысканыя дакументы з’еднваюцца ў контэкст для FAISS, фрагменты пошуку як матэрыял для аднаго Tavily, або сама запытка для прямых адпаведзей:

# Generate the answer for the user
def generateAnswer(state:AgentState) -> AgentState:
    source = state["source"]
    question = state['question']
    documents = state['documents']
    tavilyResponse = state['tavilyResponse']

    if source == "faiss":
        context = "\n\n".join([doc.page_content for doc in documents])
        prompt = f"""Based on the following context answer the question below
           Context:
           {context}

        Question:
        {question}
           """
    elif source == "tavily":
        prompt = f""" Based on the following search result , use this as an reference and provdie the
         answer to the below question

         Context:
         {tavilyResponse}

         Question:
         {question}
        """
    else:
        prompt = f" Answer the following question : {question}"
    response = model.invoke(prompt)
    answer = response.content

    return {**state, "answer":answer}

Кожную адпаведзь пісае той самы модэль Gemini. Ядзінне, што зміняецца, — это контэкст, які ставится перед ягою; гэта ўсходнія ідея RAG: кращыя вхідныя даны, а не іншы модэль, даюць болей адпаведныя рашэння.

Зберагчы цістасць імен у момент складання фрагментаў

У этых фрагментах сумешаны два стыля называння, і несувязкі спрычыняюць бягаванне памылак, якщо ўставіць іх разам без змян. Стан адзначаецца як tavily_response, тады калі вузлы чытаюць і запішываюць tavilyResponse; кліент ствараецца як tavily_client, але вызываецца як tavilyClient; а функцыя адпаведзі даўаецца як generateAnswer, але рэгіструецца як generate_answer. Выберыце адну конвэнцію і застосавайце яе ўсюды перад запускам графа.

Складанне графа

У гэты момент элементы — это вузел прыняцтва рашэння плюс тры можлівыя продовжэнні:

decide_source
      |
      +----> faiss
      |
      +----> tavily
      |
      +----> gemini

Тут ёсць тонкасць. Маршрут gemini ўжо не являецца крокам адзыскання інфармацыі; ён означае „праяваць мім адзыскання і даўаць адпаведзь безпосередна“. Таму замест таго, каб стварыць порожні вузел для яго, гэты роўна можа выклікваты прямую вярсю да спакульнага вузла генеравання.

Пачніце з стварэння графа па типу стану:

workflow = StateGraph(AgentState)

Зарэгіструйце чатыры вузлы:

workflow.add_node("decide", decide_source)
workflow.add_node("faiss", retrieve_from_faiss)
workflow.add_node("tavily", search_with_tavily)
workflow.add_node("generate", generate_answer)

Зробіце вузел адлінення выхадным пунктам:

workflow.add_edge(START, "decide")

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

workflow.add_conditional_edges(
    "decide",
    route_source,
    {
        "faiss": "faiss",
        "tavily": "tavily",
        "gemini": "generate",
    },
)

Потым галузі адлінення та пошуку должны прыводзіць да стварэння адказу:

workflow.add_edge("faiss", "generate")
workflow.add_edge("tavily", "generate")

Стварэнне ёсць пасляпярдзевым крокам перад завершэнням графа:

workflow.add_edge("generate", END)

Кампіляванне ператварае вялічыну ў працюючую аплікацыю:

app = workflow.compile()

Завершаны граф

Полны прайсход, ад пачатку да канца:

START
                           |
                           v
                    +--------------+
                    |    decide    |
                    |    source    |
                    +--------------+
                     /      |      \
                    /       |       \
                   v        v        v
               +------+ +--------+ +---------+
               |FAISS | | Tavily | | Generate|
               |      | |        | | directly|
               +------+ +--------+ +---------+
                   \        |         /
                    \       |        /
                     v      v       v
                    +----------------+
                    |    generate    |
                    |     answer     |
                    +----------------+
                            |
                            v
                           END

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

Апробаванне трох паходжыў

Маленькі дапаможнік стварае пачатковы стан і запускае скомпіляваны прыкладак:

def ask_question(question: str):
    initial_state = {
        "question":question,
        "documents":[],
        "tavilyResponse":"",
        "source":""
    }

    result = app.invoke(initial_state)
    return result

Запит, які трэба адправіць у Інтернет

Запит пра пагоду трэба адправіць у Tavily:

result = ask_question(
    "What is the current weather in Uttarakhand?"
)

Адразу выведзіце выбраны выхадны матэрыял і створана адпаведнасць:

print("Source:", result["source"])
print("Answer:", result["answer"])

Апэктыўны паходж:

Source: tavily

Тэчныя умовы існуюць толькі ў Інтернете.

Запит пра загальныя знаёмства

Далей запытайце пра метод Retrieval Augmented Generation:

result = ask_question(
    "What is Retrieval Augmented Generation?"
)

Выведзіце рэзультат так сама:

print("Source:", result["source"])
print("Answer:", result["answer"])

Рутэр должен абоўсюды праігнораваць процес атрымання дадзеных:

Source: gemini

Модель можа сама поясніць гэтыя панявы.

Запит пра внутраню політыку

На завершанне – запит пра політку выпуску:

result = ask_question(
    "What is our company leave policy?"
)

І тыя ж выклікаючыя запісі:

print("Source:", result["source"])
print("Answer:", result["answer"])

Ці раз внутраня база знаёмасцей павінна дапамогчы:

Source: faiss

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

Чаму семантычная маршрутызацыя кращая за правіла на ключавыя словы

Ось зноў альтэрнатыва, запісаная жорсткая:

if "weather" in question:
    use_tavily()
elif "leave" in question:
    use_faiss()
else:
    use_gemini()

Падобныя правіла шыбка прастаюць актуальнымі. Узгадаймо, калі корыстнік запытаецца, чы робітна адмастрацыя працюе ў суботу. У гэтым запытанні няма жадных аднасцей да політык, пры тым як адпаведны адказ можа быць у внутраніх дасведчэннях. Маршрутызатор, базаваны на модэлі, можа з’ясавіць намер корыстніка; список ключавых слоў гэтага не можа зробіць, якщо толькі хтось не будзе прыглядацца за кожным выразам.

Эты ўпрадк таксама лепей масштабуецца. Калі з’яўляюцца новыя бэк-енды, такія як тые, што паказаны нижэй, вы расширяеце схему та запит у замен на стварэнне заплутанага набору умов:

SQL Database
Internal API
CRM
Customer Support System
Documentation
Web Search

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

Чы гэта справды АІ-агент?

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

FAISS
Tavily
Direct Gemini

Модель не мае можлівасці сама адмаўляцца зрабіць кашто-небудзь падобнае да наступнага, таму што такія можлівасці ёй ніколі не даваліся:

delete a database
send an email
call an arbitrary API

Архітектура выглядае як ланцюг адпаведнасцяў:

Developer defines possible actions
              |
              v
        LLM chooses action
              |
              v
        LangGraph executes
              |
              v
           Result

Гэтыя абмежэння ёсць перавагай: обмежаныя варыянты дапамагаюць прадбачаць поведзенне та яго аудытаваць у працэсе вырабніцтва.

Ролі кожнага компонента

LangGraph: двыжак рабочага прайсепта

LangGraph контролюе структуру прыкладніка: стан, вузлы, рэшткі, умовна маршрутацыя і порядак выканання. У абстрактным сэнсе кожны крок выконваецца за аднаковым шаблонам:

State
  |
  v
Node
  |
  v
Updated State
  |
  v
Conditional Edge
  |
  +----> Node A
  |
  +----> Node B
  |
  +----> Node C

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

FAISS: слой адзіскання

FAISS забезпечвае частку RAG системы. У спрасцаванай форме:

Company Documents
       |
       v
   Embeddings
       |
       v
     FAISS
       |
       v
Similar Documents
       |
       v
     Gemini
       |
       v
     Answer

Пры рэальнай разгортцы перед яй падключаецца канал прыему данных:

Documents
   |
   v
Load
   |
   v
Split into chunks
   |
   v
Generate embeddings
   |
   v
Store vectors
   |
   v
Retrieve relevant chunks
   |
   v
Generate answer

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

Tavily: пошук у Інтэрнете

Tavily керуе інформацыяй, якая зміняецца з часам:

User Question
      |
      v
   Router
      |
      v
    Tavily
      |
      v
 Search Results
      |
      v
    Gemini
      |
      v
    Answer

Тыповыя прыклады включаюць текущую пагоду, сэр'ёзныя новыні, няўжо выданыя продукты, апошню дакументацыю, няўжо выдарыліся заходы і даныя жывага рынку. У працэйным режыме таксама трэба адначасна вялікі выбор таго, як будуць цитаваны, фільтруваны, перакананы і адображаны результаты пошуку, адколькі веб-контэнт не ўсега є точным і не завжды безпечным для перадачы модэлю без пераканання.

Шаблон, які варта запамятаць

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

Internal Knowledge
        |
        +------ FAISS
Current Information
        |
        +------ Tavily
General Knowledge
        |
        +------ Gemini

Гэты выбор способнасці для кожнага запиту з’яўляецца практычна ў кожным серйозным агентнам прыкладзе практычнаўства.

Куды працаваць далей

Дадаць больш інструментаў

Маршрутызатор мог бы выбіраць з ўсё большай колькасці задніх частак:

SQL Database
REST APIs
CRM
Email
Calendar
Internal Documentation

Паўнейшая аптымізацыя процесу выкарыстоўвання дакументаў

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

Праверкі рашэнняў пра маршрутацыю

Этап праверкі межу рутэрам і інструментамі можа адхіліць неразумныя выборы і перайсці на абавесны варыянт:

Router
   |
   v
Validator
   |
   +---- valid ----> Tool
   |
   +---- invalid --> Fallback

Гэта становіць большую значнасць чым больш стае колькасць інструментаў.

Раскідванне неудач

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

Router
   |
   v
Tavily
   |
   X
Search failed
   |
   v
Fallback

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

Зрабіць можна ўважліва стежыць за роботай

Калі адпаведзь некоректная, неабходна знаты, на якім этапе выйшла проблема:

Wrong route?
      |
      v
Bad retrieval?
      |
      v
Bad search results?
      |
      v
Bad generation?

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

Увёсці циклы

Чырвоны граф вырабляе толькі адна рашынка:

Question
   |
   v
Router
   |
   v
Tool
   |
   v
Answer

Болей спроможны агент аналізуе тое, што знайшоў, і вяршыць, чы хацець зноў дзейсніць дзеяння:

Question
   |
   v
Reason
   |
   v
Tool
   |
   v
Evaluate Result
   |
   +---- Need more information?
   |            |
   |            v
   |          Tool
   |            |
   +------------+
   |
   v
Final Answer

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

Ключовыя выводы

Усія системы адпаведзаюць на аднае пытанне: як АІ-програма должна вяліць, звядзе каму прыйсці адпаведзенню? Готовы работаўы процес выглядае так:

User Question
                   |
                   v
                Gemini
                Router
                   |
        +----------+----------+
        |          |          |
        v          v          v
      FAISS      Tavily    Gemini
   Internal DB    Web      Direct
        |          |          |
        +----------+----------+
                   |
                   v
                Gemini
              Final Answer
  • У графе неабходна визначыць можлівасці та межы; нехай модэль выбірае сярод іх пад час выканання.
  • Для прыметаў карэспандэнціяў выкорыстоўваць структураваны выхід, і пераканацца, што вузел прыметаў дэйсна вызывае структураваную модэль.
  • Залічваць толькі адзін вузел генеравання адпаведзенняў, змінюючы толькі контэкст, які ёму даёмаць.
  • Расследжваць прыметы карэспандэнціяў як тэставаны компонент: фіксаваць прыметы та пераканацца, чы яны паспелі да рэпрезентатывных пытанняў.
  • Перад аддыяваннем большае колькасці інструментоў трэба дадаць можлівасці верыфікацыі, альтэрнатыўныя рашэнні і механізмы аблікавання стану, таму што кожны новы інструмент збільшае колькасць спосабоў, па якім можа збыцца адказ на запит.
  • Звярнуўшыся да гэтых аснов, іх можна практычна застаўляць у SQL-базах дадзеных, API, памяці, пры процэсе апраўлення запитоў чалавекам, у вузлах ацэнкі, пры прабах зноў і ў мульті-агентных сэтапах. Граф расте, але прынцып застаёцца тым жа: даўце модэлю корыстныя можлівасці, задаце правіла ўжытку іх і дазвольце яму самаму выбраць тое, што падходзіць для задання.

    Спакульна літэратура